Beispiel #1
0
def coverage(project, logger, reactor):
    em = reactor.execution_manager  # type: ExecutionManager

    source_path = nc(
        project.expand_path(project.get_property("coverage_source_path")))

    module_names = discover_modules(source_path)
    module_file_suffixes = discover_module_files(source_path)

    module_exceptions = as_list(project.get_property("coverage_exceptions"))
    module_names, module_files, omit_patterns = _filter_covered_modules(
        logger, module_names, module_file_suffixes, module_exceptions,
        source_path)

    for idx, module_name in enumerate(module_names):
        logger.debug("Module %r (file %r) coverage to be verified",
                     module_name, module_files[idx])

    coverage_config = dict(
        data_file=project.expand_path("$dir_target",
                                      "%s.coverage" % project.name),
        data_suffix=False,
        cover_pylib=False,
        config_file=False,
        branch=True,
        debug=as_list(project.get_property("coverage_debug")),
        context=project.name)

    project.set_property("__coverage_config", coverage_config)

    patch_coverage()

    from coverage import coverage as coverage_factory

    cov = coverage_factory(**coverage_config)
    cov.erase()
    cov.save()

    for covered_task in project.get_property(
            "__covered_tasks"):  # type: CoveredTask
        if em.is_task_in_current_execution_plan(covered_task.name):
            task_cov = run_coverage(project, logger, reactor, covered_task,
                                    source_path, module_names, module_files,
                                    omit_patterns)

            cov._data.update(task_cov._data)

    cov.save()

    failure = _build_coverage_report(project, logger,
                                     "%s coverage" % project.name,
                                     project.name, "", cov, source_path,
                                     module_names, module_files)

    if failure:
        raise failure
Beispiel #2
0
def do_coverage(project, logger, reactor, execution_prefix, execution_name,
                target_task, shortest_plan):
    """
    This function MUST ALWAYS execute in a fork.
    The sys.modules will be manipulated extensively to stage the tests properly, which may affect execute down the line.
    It's best to simple let this method exit and the fork die rather than to try to recover.
    """
    source_tree_path = project.get_property("dir_source_main_python")
    reset_modules = project.get_property("%s_reset_modules" % execution_prefix)
    allow_non_imported_modules = project.get_property(
        "%s_allow_non_imported_modules" % execution_prefix)
    module_names = _discover_modules_to_cover(project)

    for module_name in module_names:
        logger.debug("Module '%s' coverage to be verified", module_name)

    if reset_modules and not is_windows():
        _delete_non_essential_modules()
        __import__("pybuilder.plugins.python")  # Reimport self

    # Starting fresh
    from coverage import coverage as coverage_factory

    coverage = coverage_factory(cover_pylib=False,
                                branch=True,
                                source=[source_tree_path])

    patch_multiprocessing(coverage.config)
    try:
        try:
            _start_coverage(project, coverage)

            if shortest_plan:
                reactor.execute_task_shortest_plan(target_task)
            else:
                reactor.execute_task(target_task)
        finally:
            _stop_coverage(project, coverage)
    finally:
        reverse_patch_multiprocessing()

    module_exceptions = project.get_property("%s_exceptions" %
                                             execution_prefix)
    modules, non_imported_modules = _list_all_covered_modules(
        logger, module_names, module_exceptions, allow_non_imported_modules)

    failure = _build_coverage_report(project, logger, execution_name,
                                     execution_prefix, coverage, modules)

    if non_imported_modules and not allow_non_imported_modules:
        raise BuildFailedException(
            "Some modules have not been imported and have no coverage")

    if failure:
        raise failure
Beispiel #3
0
    def start(self, pipe):
        # type: (RemoteObjectPipe) -> None
        from .._coverage_util import patch_coverage

        patch_coverage()

        from coverage import coverage as coverage_factory

        coverage = coverage_factory(*self.cov_args, **self.cov_kwargs)
        self.coverage = coverage
        coverage.start()
Beispiel #4
0
def do_coverage(project, logger, reactor, execution_prefix, execution_name, target_task, shortest_plan):
    """
    This function MUST ALWAYS execute in a fork.
    The sys.modules will be manipulated extensively to stage the tests properly, which may affect execute down the line.
    It's best to simple let this method exit and the fork die rather than to try to recover.
    """
    source_tree_path = project.get_property("dir_source_main_python")
    reset_modules = project.get_property("%s_reset_modules" % execution_prefix)
    allow_non_imported_modules = project.get_property("%s_allow_non_imported_modules" % execution_prefix)
    module_names = _discover_modules_to_cover(project)

    for module_name in module_names:
        logger.debug("Module '%s' coverage to be verified", module_name)

    if reset_modules and not is_windows():
        _delete_non_essential_modules()
        __import__("pybuilder.plugins.python")  # Reimport self

    # Starting fresh
    from coverage import coverage as coverage_factory

    coverage = coverage_factory(cover_pylib=False, branch=True, source=[source_tree_path])

    patch_multiprocessing(coverage.config)
    try:
        try:
            _start_coverage(project, coverage)

            if shortest_plan:
                reactor.execute_task_shortest_plan(target_task)
            else:
                reactor.execute_task(target_task)
        finally:
            _stop_coverage(project, coverage)
    finally:
        reverse_patch_multiprocessing()

    module_exceptions = project.get_property("%s_exceptions" % execution_prefix)
    modules, non_imported_modules = _list_all_covered_modules(logger, module_names, module_exceptions,
                                                              allow_non_imported_modules)

    failure = _build_coverage_report(project, logger, execution_name, execution_prefix, coverage, modules)

    if non_imported_modules and not allow_non_imported_modules:
        raise BuildFailedException("Some modules have not been imported and have no coverage")

    if failure:
        raise failure
Beispiel #5
0
    # Make sure we can actually load coverage
    CoverageImporter(config["cov_parent_dir"]).install()

    sys.path.append(main_file_dir)

    from _coverage_util import save_normalized_coverage, patch_coverage

    del sys.path[-1]

    # Patch coverage
    patch_coverage()

    from coverage import coverage as coverage_factory
    from coverage.execfile import PyRunner

    coverage = coverage_factory(*(config.get("cov_args", ())),
                                **(config.get("cov_kwargs", {})))
    source_path = config["cov_source_path"]
    omit_patterns = config["cov_omit_patterns"]

    args = sys.argv
    module = False
    if args and args[0] == "-m":
        module = True
        args = args[1:]

    runner = PyRunner(args, as_module=module)
    runner.prepare()

    coverage.start()
    try:
        runner.run()
def do_coverage(project, logger, reactor, execution_prefix, execution_name, target_task, shortest_plan):
    from coverage import coverage as coverage_factory

    source_tree_path = project.get_property("dir_source_main_python")
    coverage = coverage_factory(cover_pylib=False, source=[source_tree_path])
    _start_coverage(coverage)
    project.set_property('__running_coverage', True)  # tell other plugins that we are not really unit testing right now
    if shortest_plan:
        reactor.execute_task_shortest_plan(target_task)
    else:
        reactor.execute_task(target_task)
    project.set_property('__running_coverage', False)

    _stop_coverage(coverage, project, logger, execution_prefix)

    coverage_too_low = False
    threshold = project.get_property("%s_threshold_warn" % execution_prefix)
    exceptions = project.get_property("%s_exceptions" % execution_prefix)

    report = {
        "module_names": []
    }

    sum_lines = 0
    sum_lines_not_covered = 0

    module_names = _discover_modules_to_cover(project)
    modules = []
    for module_name in module_names:
        try:
            module = sys.modules[module_name]
        except KeyError:
            logger.warn("Module not imported: {0}. No coverage information available.".format(module_name))
            continue

        modules.append(module)

        module_report_data = build_module_report(coverage, module)
        should_ignore_module = module_name in exceptions

        if not should_ignore_module:
            sum_lines += module_report_data[0]
            sum_lines_not_covered += module_report_data[2]

        module_report = {
            "module": module_name,
            "coverage": module_report_data[4],
            "sum_lines": module_report_data[0],
            "lines": module_report_data[1],
            "sum_lines_not_covered": module_report_data[2],
            "lines_not_covered": module_report_data[3],
        }

        report["module_names"].append(module_report)

        if module_report_data[4] < threshold:
            msg = "Test coverage below %2d%% for %s: %2d%%" % (threshold, module_name, module_report_data[4])
            if not should_ignore_module:
                logger.warn(msg)
                coverage_too_low = True
            else:
                logger.info(msg)

    if sum_lines == 0:
        overall_coverage = 0
    else:
        overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines
    report["overall_coverage"] = overall_coverage

    if overall_coverage < threshold:
        logger.warn("Overall %s is below %2d%%: %2d%%", execution_name, threshold, overall_coverage)
        coverage_too_low = True
    else:
        logger.info("Overall %s is %2d%%", execution_name, overall_coverage)

    project.write_report("%s.json" % execution_prefix, render_report(report))

    _write_summary_report(coverage, project, modules, execution_prefix)

    if coverage_too_low and project.get_property("%s_break_build" % execution_prefix):
        raise BuildFailedException("Test coverage for at least one module is below %d%%", threshold)
Beispiel #7
0
def run_coverage(project, logger, reactor, covered_task, source_path,
                 module_names, module_files, omit_patterns):
    config_prefix = covered_task.config_prefix
    logger.info("Collecting coverage information for %r", str(covered_task))

    if project.get_property("%scoverage_fork" % config_prefix) is not None:
        logger.warn(
            "%scoverage_fork is deprecated, coverage always runs in a spawned process",
            config_prefix)

    if project.get_property("%scoverage_reload_modules" %
                            config_prefix) is not None:
        logger.warn(
            "%scoverage_reload_modules is deprecated - modules are no longer reloaded",
            config_prefix)

    if project.get_property("%scoverage_reset_modules" %
                            config_prefix) is not None:
        logger.warn(
            "%scoverage_reset_modules is deprecated - modules are no longer reset",
            config_prefix)

    if project.get_property("%scoverage_allow_non_imported_modules" %
                            config_prefix) is not None:
        logger.warn(
            "%scoverage_allow_non_imported_modules- modules are no longer imported",
            config_prefix)

    if project.get_property("%scoverage_branch_threshold_warn" %
                            config_prefix) == 0:
        logger.warn(
            "%scoverage_branch_threshold_warn is 0 and branch coverage will not be checked",
            config_prefix)

    if project.get_property("%scoverage_branch_partial_threshold_warn" %
                            config_prefix) == 0:
        logger.warn(
            "%scoverage_branch_partial_threshold_warn is 0 and partial branch coverage will not be checked",
            config_prefix)

    coverage_config = dict(
        data_file=project.expand_path("$dir_target",
                                      "%s.coverage" % covered_task.filename),
        data_suffix=True,
        cover_pylib=False,
        config_file=False,
        branch=True,
        context=str(covered_task),
        debug=as_list(
            project.get_property("%scoverage_debug" % config_prefix,
                                 project.get_property("coverage_debug"))),
        concurrency=project.get_property(
            "%scoverage_concurrency" % config_prefix,
            project.get_property("coverage_concurrency")))

    from coverage import coverage as coverage_factory

    cov = coverage_factory(**coverage_config)
    cov.erase()

    cov_tool = CoverageTool(source_path, omit_patterns, **coverage_config)

    em = reactor.execution_manager

    reactor.add_tool(cov_tool)
    try:
        coverage_env_name = project.get_property("%scoverage_python_env" %
                                                 config_prefix)
        if coverage_env_name:
            current_python_env = reactor.python_env_registry[coverage_env_name]
            reactor.python_env_registry.push_override(
                coverage_env_name,
                _override_python_env_for_coverage(current_python_env,
                                                  coverage_config, source_path,
                                                  omit_patterns))
        try:
            em.execute_task(covered_task.task,
                            logger=logger,
                            project=project,
                            reactor=reactor,
                            _executable=covered_task.executable)
        finally:
            if coverage_env_name:
                reactor.python_env_registry.pop_override(coverage_env_name)
    finally:
        reactor.remove_tool(cov_tool)

    cov.combine()
    cov.save()

    failure = _build_coverage_report(project, logger,
                                     covered_task.coverage_name,
                                     covered_task.filename, config_prefix, cov,
                                     source_path, module_names, module_files)

    if failure:
        raise failure

    return cov
Beispiel #8
0
def do_coverage(project, logger, reactor):
    from coverage import coverage as coverage_factory

    source_tree_path = project.get_property("dir_source_main_python")
    coverage = coverage_factory(cover_pylib=False, source=[source_tree_path])
    start_coverage(coverage)
    project.set_property(
        '__running_coverage', True
    )  # tell other plugins that we are not really unit testing right now
    reactor.execute_task("run_unit_tests")
    project.set_property('__running_coverage', False)

    stop_coverage(coverage, project, logger)

    coverage_too_low = False
    threshold = project.get_property("coverage_threshold_warn")
    exceptions = project.get_property("coverage_exceptions")

    report = {"module_names": []}

    sum_lines = 0
    sum_lines_not_covered = 0

    module_names = discover_modules_to_cover(project)
    modules = []
    for module_name in module_names:
        try:
            module = sys.modules[module_name]
        except KeyError:
            logger.warn(
                "Module not imported: {0}. No coverage information available.".
                format(module_name))
            continue

        modules.append(module)

        module_report_data = build_module_report(coverage, module)
        should_ignore_module = module_name in exceptions

        if not should_ignore_module:
            sum_lines += module_report_data[0]
            sum_lines_not_covered += module_report_data[2]

        module_report = {
            "module": module_name,
            "coverage": module_report_data[4],
            "sum_lines": module_report_data[0],
            "lines": module_report_data[1],
            "sum_lines_not_covered": module_report_data[2],
            "lines_not_covered": module_report_data[3],
        }

        report["module_names"].append(module_report)

        if module_report_data[4] < threshold:
            msg = "Test coverage below %2d%% for %s: %2d%%" % (
                threshold, module_name, module_report_data[4])
            if not should_ignore_module:
                logger.warn(msg)
                coverage_too_low = True
            else:
                logger.info(msg)

    if sum_lines == 0:
        overall_coverage = 0
    else:
        overall_coverage = (sum_lines -
                            sum_lines_not_covered) * 100 / sum_lines
    report["overall_coverage"] = overall_coverage

    if overall_coverage < threshold:
        logger.warn("Overall coverage is below %2d%%: %2d%%", threshold,
                    overall_coverage)
        coverage_too_low = True
    else:
        logger.info("Overall coverage is %2d%%", overall_coverage)

    project.write_report("coverage.json", render_report(report))

    write_summary_report(coverage, project, modules)

    if coverage_too_low and project.get_property("coverage_break_build"):
        raise BuildFailedException(
            "Test coverage for at least one module is below %d%%", threshold)
Beispiel #9
0
def do_coverage(project, logger, reactor, execution_prefix, execution_name, target_task, shortest_plan):
    """
    This function MUST ALWAYS execute in a fork.
    The sys.modules will be manipulated extensively to stage the tests properly, which may affect execute down the line.
    It's best to simple let this method exit and the fork die rather than to try to recover.
    """
    source_tree_path = project.get_property("dir_source_main_python")
    module_names = _discover_modules_to_cover(project)

    for module_name in module_names:
        logger.debug("Module '%s' coverage to be verified", module_name)

    _delete_non_essential_modules()
    __import__("pybuilder.plugins.python")  # Reimport self

    # Starting fresh
    from coverage import coverage as coverage_factory

    coverage = coverage_factory(cover_pylib=False, branch=True, source=[source_tree_path])

    try:
        project.set_property('__running_coverage',
                             True)  # tell other plugins that we are not really unit testing right now
        _start_coverage(coverage)

        if shortest_plan:
            reactor.execute_task_shortest_plan(target_task)
        else:
            reactor.execute_task(target_task)
    finally:
        _stop_coverage(coverage)
        project.set_property('__running_coverage', False)

    coverage_too_low = False
    threshold = project.get_property("%s_threshold_warn" % execution_prefix)
    exceptions = project.get_property("%s_exceptions" % execution_prefix)

    report = {
        "module_names": []
    }

    sum_lines = 0
    sum_lines_not_covered = 0

    modules = []
    for module_name in module_names:
        try:
            module = sys.modules[module_name]
        except KeyError:
            logger.warn("Module '%s' was not imported by the covered tests", module_name)
            try:
                module = __import__(module_name)
            except SyntaxError as e:
                logger.warn("Coverage for module '%s' cannot be established - syntax error: %s",
                            module_name, e)
                continue

        if module not in modules:
            modules.append(module)

        module_report_data = build_module_report(coverage, module)
        should_ignore_module = module_name in exceptions

        if not should_ignore_module:
            sum_lines += module_report_data[0]
            sum_lines_not_covered += module_report_data[2]

        module_report = {
            "module": module_name,
            "coverage": module_report_data[4],
            "sum_lines": module_report_data[0],
            "lines": module_report_data[1],
            "sum_lines_not_covered": module_report_data[2],
            "lines_not_covered": module_report_data[3],
        }

        logger.debug("Module coverage report: %s", module_report)
        report["module_names"].append(module_report)
        if module_report_data[4] < threshold:
            msg = "Test coverage below %2d%% for %s: %2d%%" % (threshold, module_name, module_report_data[4])
            if not should_ignore_module:
                logger.warn(msg)
                coverage_too_low = True
            else:
                logger.info(msg)

    if sum_lines == 0:
        overall_coverage = 0
    else:
        overall_coverage = (sum_lines - sum_lines_not_covered) * 100 / sum_lines
    report["overall_coverage"] = overall_coverage

    if overall_coverage < threshold:
        logger.warn("Overall %s is below %2d%%: %2d%%", execution_name, threshold, overall_coverage)
        coverage_too_low = True
    else:
        logger.info("Overall %s is %2d%%", execution_name, overall_coverage)

    project.write_report("%s.json" % execution_prefix, render_report(report))

    _write_summary_report(coverage, project, modules, execution_prefix, execution_name)

    if coverage_too_low and project.get_property("%s_break_build" % execution_prefix):
        raise BuildFailedException("Test coverage for at least one module is below %d%%", threshold)
Beispiel #10
0
def do_coverage(project, logger, reactor, execution_prefix, execution_name,
                target_task, shortest_plan):
    """
    This function MUST ALWAYS execute in a fork.
    The sys.modules will be manipulated extensively to stage the tests properly, which may affect execute down the line.
    It's best to simple let this method exit and the fork die rather than to try to recover.
    """
    source_tree_path = project.get_property("dir_source_main_python")
    module_names = _discover_modules_to_cover(project)

    for module_name in module_names:
        logger.debug("Module '%s' coverage to be verified", module_name)

    _delete_non_essential_modules()
    __import__("pybuilder.plugins.python")  # Reimport self

    # Starting fresh
    from coverage import coverage as coverage_factory

    coverage = coverage_factory(cover_pylib=False,
                                branch=True,
                                source=[source_tree_path])

    try:
        project.set_property(
            '__running_coverage', True
        )  # tell other plugins that we are not really unit testing right now
        _start_coverage(coverage)

        if shortest_plan:
            reactor.execute_task_shortest_plan(target_task)
        else:
            reactor.execute_task(target_task)
    finally:
        _stop_coverage(coverage)
        project.set_property('__running_coverage', False)

    coverage_too_low = False
    threshold = project.get_property("%s_threshold_warn" % execution_prefix)
    exceptions = project.get_property("%s_exceptions" % execution_prefix)

    report = {"module_names": []}

    sum_lines = 0
    sum_lines_not_covered = 0

    modules = []
    for module_name in module_names:
        try:
            module = sys.modules[module_name]
        except KeyError:
            logger.warn("Module '%s' was not imported by the covered tests",
                        module_name)
            try:
                module = __import__(module_name)
            except SyntaxError as e:
                logger.warn(
                    "Coverage for module '%s' cannot be established - syntax error: %s",
                    module_name, e)
                continue

        if module not in modules:
            modules.append(module)

        module_report_data = build_module_report(coverage, module)
        should_ignore_module = module_name in exceptions

        if not should_ignore_module:
            sum_lines += module_report_data[0]
            sum_lines_not_covered += module_report_data[2]

        module_report = {
            "module": module_name,
            "coverage": module_report_data[4],
            "sum_lines": module_report_data[0],
            "lines": module_report_data[1],
            "sum_lines_not_covered": module_report_data[2],
            "lines_not_covered": module_report_data[3],
        }

        logger.debug("Module coverage report: %s", module_report)
        report["module_names"].append(module_report)
        if module_report_data[4] < threshold:
            msg = "Test coverage below %2d%% for %s: %2d%%" % (
                threshold, module_name, module_report_data[4])
            if not should_ignore_module:
                logger.warn(msg)
                coverage_too_low = True
            else:
                logger.info(msg)

    if sum_lines == 0:
        overall_coverage = 0
    else:
        overall_coverage = (sum_lines -
                            sum_lines_not_covered) * 100 / sum_lines
    report["overall_coverage"] = overall_coverage

    if overall_coverage < threshold:
        logger.warn("Overall %s is below %2d%%: %2d%%", execution_name,
                    threshold, overall_coverage)
        coverage_too_low = True
    else:
        logger.info("Overall %s is %2d%%", execution_name, overall_coverage)

    project.write_report("%s.json" % execution_prefix, render_report(report))

    _write_summary_report(coverage, project, modules, execution_prefix,
                          execution_name)

    if coverage_too_low and project.get_property(
            "%s_break_build" % execution_prefix):
        raise BuildFailedException(
            "Test coverage for at least one module is below %d%%", threshold)