예제 #1
0
    def test_plugin2(self):
        self.make_render_and_caller()

        cov = coverage.Coverage(omit=["*quux*"])
        CheckUniqueFilenames.hook(cov, '_should_trace')
        CheckUniqueFilenames.hook(cov, '_check_include_omit_etc')
        cov.set_option("run:plugins", ["tests.plugin2"])

        self.start_import_stop(cov, "caller")

        # The way plugin2 works, a file named foo_7.html will be claimed to
        # have 7 lines in it.  If render() was called with line number 4,
        # then the plugin will claim that lines 4 and 5 were executed.
        _, statements, missing, _ = cov.analysis("foo_7.html")
        self.assertEqual(statements, [1, 2, 3, 4, 5, 6, 7])
        self.assertEqual(missing, [1, 2, 3, 6, 7])
        self.assertIn("foo_7.html", line_counts(cov.get_data()))

        _, statements, missing, _ = cov.analysis("bar_4.html")
        self.assertEqual(statements, [1, 2, 3, 4])
        self.assertEqual(missing, [1, 4])
        self.assertIn("bar_4.html", line_counts(cov.get_data()))

        self.assertNotIn("quux_5.html", line_counts(cov.get_data()))

        _, statements, missing, _ = cov.analysis("uni_3.html")
        self.assertEqual(statements, [1, 2, 3])
        self.assertEqual(missing, [1])
        self.assertIn("uni_3.html", line_counts(cov.get_data()))
예제 #2
0
    def coverage_usepkgs(self, **kwargs):
        """Run coverage on usepkgs and return the line summary.

        Arguments are passed to the `coverage.Coverage` constructor.

        """
        cov = coverage.Coverage(**kwargs)
        cov.start()
        import usepkgs  # pragma: nested   # pylint: disable=import-error, unused-import
        cov.stop()      # pragma: nested
        data = cov.get_data()
        summary = line_counts(data)
        for k, v in list(summary.items()):
            assert k.endswith(".py")
            summary[k[:-3]] = v
        return summary
예제 #3
0
    def coverage_usepkgs(self, **kwargs):
        """Run coverage on usepkgs and return the line summary.

        Arguments are passed to the `coverage.Coverage` constructor.

        """
        cov = coverage.Coverage(**kwargs)
        cov.start()
        import usepkgs  # pragma: nested   # pylint: disable=import-error, unused-import
        cov.stop()  # pragma: nested
        data = cov.get_data()
        summary = line_counts(data)
        for k, v in list(summary.items()):
            assert k.endswith(".py")
            summary[k[:-3]] = v
        return summary
예제 #4
0
    def do_debug(self, args):
        """Implementation of 'coverage debug'."""

        if not args:
            show_help(
                "What information would you like: config, data, sys, premain?")
            return ERR

        for info in args:
            if info == 'sys':
                sys_info = self.coverage.sys_info()
                print(info_header("sys"))
                for line in info_formatter(sys_info):
                    print(" %s" % line)
            elif info == 'data':
                self.coverage.load()
                data = self.coverage.get_data()
                print(info_header("data"))
                print("path: %s" % self.coverage.get_data().data_filename())
                if data:
                    print("has_arcs: %r" % data.has_arcs())
                    summary = line_counts(data, fullpath=True)
                    filenames = sorted(summary.keys())
                    print("\n%d files:" % len(filenames))
                    for f in filenames:
                        line = "%s: %d lines" % (f, summary[f])
                        plugin = data.file_tracer(f)
                        if plugin:
                            line += " [%s]" % plugin
                        print(line)
                else:
                    print("No data collected")
            elif info == 'config':
                print(info_header("config"))
                config_info = self.coverage.config.__dict__.items()
                for line in info_formatter(config_info):
                    print(" %s" % line)
            elif info == "premain":
                print(info_header("premain"))
                from coverage.debug import short_stack
                print(short_stack())
            else:
                show_help("Don't know what you mean by %r" % info)
                return ERR

        return OK
예제 #5
0
    def do_debug(self, args):
        """Implementation of 'coverage debug'."""

        if not args:
            show_help(
                "What information would you like: config, data, sys, premain?")
            return ERR

        for info in args:
            if info == 'sys':
                sys_info = self.coverage.sys_info()
                print(info_header("sys"))
                for line in info_formatter(sys_info):
                    print(f" {line}")
            elif info == 'data':
                self.coverage.load()
                data = self.coverage.get_data()
                print(info_header("data"))
                print(f"path: {data.data_filename()}")
                if data:
                    print(f"has_arcs: {data.has_arcs()!r}")
                    summary = line_counts(data, fullpath=True)
                    filenames = human_sorted(summary.keys())
                    print(f"\n{len(filenames)} files:")
                    for f in filenames:
                        line = f"{f}: {summary[f]} lines"
                        plugin = data.file_tracer(f)
                        if plugin:
                            line += f" [{plugin}]"
                        print(line)
                else:
                    print("No data collected")
            elif info == 'config':
                print(info_header("config"))
                config_info = self.coverage.config.__dict__.items()
                for line in info_formatter(config_info):
                    print(f" {line}")
            elif info == "premain":
                print(info_header("premain"))
                print(short_stack())
            else:
                show_help(f"Don't know what you mean by {info!r}")
                return ERR

        return OK
예제 #6
0
    def test_append_data(self):
        self.make_b_or_c_py()

        out = self.run_command("coverage run b_or_c.py b")
        assert out == 'done\n'
        self.assert_exists(".coverage")
        self.assert_file_count(".coverage.*", 0)

        out = self.run_command("coverage run --append b_or_c.py c")
        assert out == 'done\n'
        self.assert_exists(".coverage")
        self.assert_file_count(".coverage.*", 0)

        # Read the coverage file and see that b_or_c.py has all 8 lines
        # executed.
        data = coverage.CoverageData()
        data.read()
        assert line_counts(data)['b_or_c.py'] == 8
예제 #7
0
    def test_combine_with_rc(self):
        self.make_b_or_c_py()

        self.make_file(".coveragerc", """\
            [run]
            source = .
            parallel = true
            """)

        out = self.run_command("coverage run b_or_c.py b")
        assert out == 'done\n'
        self.assert_doesnt_exist(".coverage")

        out = self.run_command("coverage run b_or_c.py c")
        assert out == 'done\n'
        self.assert_doesnt_exist(".coverage")

        # After two runs, there should be two .coverage.machine.123 files.
        self.assert_file_count(".coverage.*", 2)

        # Combine the parallel coverage data files into .coverage .
        self.run_command("coverage combine")
        self.assert_exists(".coverage")
        self.assert_exists(".coveragerc")

        # After combining, there should be only the .coverage file.
        self.assert_file_count(".coverage.*", 0)

        # Read the coverage file and see that b_or_c.py has all 8 lines
        # executed.
        data = coverage.CoverageData()
        data.read()
        assert line_counts(data)['b_or_c.py'] == 8

        # Reporting should still work even with the .rc file
        out = self.run_command("coverage report")
        assert out == textwrap.dedent("""\
            Name        Stmts   Miss  Cover
            -------------------------------
            b_or_c.py       8      0   100%
            -------------------------------
            TOTAL           8      0   100%
            """)
예제 #8
0
    def test_fork(self):
        self.make_file("fork.py", """\
            import os

            def child():
                print('Child!')

            def main():
                ret = os.fork()

                if ret == 0:
                    child()
                else:
                    os.waitpid(ret, 0)

            main()
            """)

        out = self.run_command("coverage run -p fork.py")
        assert out == 'Child!\n'
        self.assert_doesnt_exist(".coverage")

        # After running the forking program, there should be two
        # .coverage.machine.123 files.
        self.assert_file_count(".coverage.*", 2)

        # The two data files should have different random numbers at the end of
        # the file name.
        data_files = glob.glob(".coverage.*")
        nums = {name.rpartition(".")[-1] for name in data_files}
        assert len(nums) == 2, f"Same random: {data_files}"

        # Combine the parallel coverage data files into .coverage .
        self.run_command("coverage combine")
        self.assert_exists(".coverage")

        # After combining, there should be only the .coverage file.
        self.assert_file_count(".coverage.*", 0)

        data = coverage.CoverageData()
        data.read()
        assert line_counts(data)['fork.py'] == 9
예제 #9
0
    def test_fullcoverage(self):
        # fullcoverage is a trick to get stdlib modules measured from
        # the very beginning of the process. Here we import os and
        # then check how many lines are measured.
        self.make_file("getenv.py", """\
            import os
            print("FOOEY == %s" % os.getenv("FOOEY"))
            """)

        fullcov = os.path.join(os.path.dirname(coverage.__file__), "fullcoverage")
        self.set_environ("FOOEY", "BOO")
        self.set_environ("PYTHONPATH", fullcov)
        out = self.run_command("python -X frozen_modules=off -m coverage run -L getenv.py")
        assert out == "FOOEY == BOO\n"
        data = coverage.CoverageData()
        data.read()
        # The actual number of executed lines in os.py when it's
        # imported is 120 or so.  Just running os.getenv executes
        # about 5.
        assert line_counts(data)['os.py'] > 50
예제 #10
0
    def do_debug(self, args):
        """Implementation of 'coverage debug'."""

        if not args:
            show_help("What information would you like: config, data, sys?")
            return ERR

        for info in args:
            if info == 'sys':
                sys_info = self.coverage.sys_info()
                print(info_header("sys"))
                for line in info_formatter(sys_info):
                    print(" %s" % line)
            elif info == 'data':
                self.coverage.load()
                data = self.coverage.get_data()
                print(info_header("data"))
                print("path: %s" % self.coverage.get_data().data_filename())
                if data:
                    print("has_arcs: %r" % data.has_arcs())
                    summary = line_counts(data, fullpath=True)
                    filenames = sorted(summary.keys())
                    print("\n%d files:" % len(filenames))
                    for f in filenames:
                        line = "%s: %d lines" % (f, summary[f])
                        plugin = data.file_tracer(f)
                        if plugin:
                            line += " [%s]" % plugin
                        print(line)
                else:
                    print("No data collected")
            elif info == 'config':
                print(info_header("config"))
                config_info = self.coverage.config.__dict__.items()
                for line in info_formatter(config_info):
                    print(" %s" % line)
            else:
                show_help("Don't know what you mean by %r" % info)
                return ERR

        return OK
예제 #11
0
    def try_some_code(self, code, concurrency, the_module, expected_out=None):
        """Run some concurrency testing code and see that it was all covered.

        `code` is the Python code to execute.  `concurrency` is the name of
        the concurrency regime to test it under.  `the_module` is the imported
        module that must be available for this to work at all. `expected_out`
        is the text we expect the code to produce.

        """

        self.make_file("try_it.py", code)

        cmd = "coverage run --concurrency=%s try_it.py" % concurrency
        out = self.run_command(cmd)

        expected_cant_trace = cant_trace_msg(concurrency, the_module)

        if expected_cant_trace is not None:
            self.assertEqual(out, expected_cant_trace)
        else:
            # We can fully measure the code if we are using the C tracer, which
            # can support all the concurrency, or if we are using threads.
            if expected_out is None:
                expected_out = "%d\n" % (sum(range(self.QLIMIT)))
            print(code)
            self.assertEqual(out, expected_out)

            # Read the coverage file and see that try_it.py has all its lines
            # executed.
            data = coverage.CoverageData(".coverage")
            data.read()

            # If the test fails, it's helpful to see this info:
            fname = abs_file("try_it.py")
            linenos = data.lines(fname)
            print("{0}: {1}".format(len(linenos), linenos))
            print_simple_annotation(code, linenos)

            lines = line_count(code)
            self.assertEqual(line_counts(data)['try_it.py'], lines)
예제 #12
0
    def try_some_code(self, code, concurrency, the_module, expected_out=None):
        """Run some concurrency testing code and see that it was all covered.

        `code` is the Python code to execute.  `concurrency` is the name of
        the concurrency regime to test it under.  `the_module` is the imported
        module that must be available for this to work at all. `expected_out`
        is the text we expect the code to produce.

        """

        self.make_file("try_it.py", code)

        cmd = "coverage run --concurrency=%s try_it.py" % concurrency
        out = self.run_command(cmd)

        expected_cant_trace = cant_trace_msg(concurrency, the_module)

        if expected_cant_trace is not None:
            assert out == expected_cant_trace
        else:
            # We can fully measure the code if we are using the C tracer, which
            # can support all the concurrency, or if we are using threads.
            if expected_out is None:
                expected_out = "%d\n" % (sum(range(self.QLIMIT)))
            print(code)
            assert out == expected_out

            # Read the coverage file and see that try_it.py has all its lines
            # executed.
            data = coverage.CoverageData(".coverage")
            data.read()

            # If the test fails, it's helpful to see this info:
            fname = abs_file("try_it.py")
            linenos = data.lines(fname)
            print(f"{len(linenos)}: {linenos}")
            print_simple_annotation(code, linenos)

            lines = line_count(code)
            assert line_counts(data)['try_it.py'] == lines
예제 #13
0
    def test_append_data_with_different_file(self):
        self.make_b_or_c_py()

        self.make_file(".coveragerc", """\
            [run]
            data_file = .mycovdata
            """)

        out = self.run_command("coverage run b_or_c.py b")
        assert out == 'done\n'
        self.assert_doesnt_exist(".coverage")
        self.assert_exists(".mycovdata")

        out = self.run_command("coverage run --append b_or_c.py c")
        assert out == 'done\n'
        self.assert_doesnt_exist(".coverage")
        self.assert_exists(".mycovdata")

        # Read the coverage file and see that b_or_c.py has all 8 lines
        # executed.
        data = coverage.CoverageData(".mycovdata")
        data.read()
        assert line_counts(data)['b_or_c.py'] == 8
예제 #14
0
    def test_subprocess_with_pth_files(self):
        # An existing data file should not be read when a subprocess gets
        # measured automatically.  Create the data file here with bogus data in
        # it.
        data = coverage.CoverageData(".mycovdata")
        data.add_lines({os.path.abspath('sub.py'): range(100)})
        data.write()

        self.make_file("coverage.ini", """\
            [run]
            data_file = .mycovdata
            """)
        self.set_environ("COVERAGE_PROCESS_START", "coverage.ini")
        import main             # pylint: disable=unused-import, import-error

        with open("out.txt") as f:
            assert f.read() == "Hello, world!\n"

        # Read the data from .coverage
        self.assert_exists(".mycovdata")
        data = coverage.CoverageData(".mycovdata")
        data.read()
        assert line_counts(data)['sub.py'] == 3
예제 #15
0
 def assert_line_counts(self, covdata, counts, fullpath=False):
     """Check that the line_counts of `covdata` is `counts`."""
     self.assertEqual(line_counts(covdata, fullpath), counts)
예제 #16
0
 def assert_line_counts(self, covdata, counts, fullpath=False):
     """Check that the line_counts of `covdata` is `counts`."""
     assert line_counts(covdata, fullpath) == counts
예제 #17
0
 def assert_line_counts(self, covdata, counts, fullpath=False):
     """Check that the line_counts of `covdata` is `counts`."""
     self.assertEqual(line_counts(covdata, fullpath), counts)
예제 #18
0
    def test_pth_and_source_work_together(self, dashm, package, source):
        """Run the test for a particular combination of factors.

        The arguments are all strings:

        * `dashm`: Either "" (run the program as a file) or "-m" (run the
          program as a module).

        * `package`: Either "" (put the source at the top level) or a
          package name to use to hold the source.

        * `source`: Either "main" or "sub", which file to use as the
          ``--source`` argument.

        """
        def fullname(modname):
            """What is the full module name for `modname` for this test?"""
            if package and dashm:
                return '.'.join((package, modname))
            else:
                return modname

        def path(basename):
            """Where should `basename` be created for this test?"""
            return os.path.join(package, basename)

        # Main will run sub.py.
        self.make_file(path("main.py"), """\
            import %s
            a = 2
            b = 3
            """ % fullname('sub'))
        if package:
            self.make_file(path("__init__.py"), "")
        # sub.py will write a few lines.
        self.make_file(path("sub.py"), """\
            # Avoid 'with' so Jython can play along.
            f = open("out.txt", "w")
            f.write("Hello, world!")
            f.close()
            """)
        self.make_file("coverage.ini", """\
            [run]
            source = %s
            """ % fullname(source))

        self.set_environ("COVERAGE_PROCESS_START", "coverage.ini")

        if dashm:
            cmd = "python -m %s" % fullname('main')
        else:
            cmd = "python %s" % path('main.py')

        self.run_command(cmd)

        with open("out.txt") as f:
            assert f.read() == "Hello, world!"

        # Read the data from .coverage
        self.assert_exists(".coverage")
        data = coverage.CoverageData()
        data.read()
        summary = line_counts(data)
        assert summary[source + '.py'] == 3
        assert len(summary) == 1