diff --git a/test/runner/lib/cover.py b/test/runner/lib/cover.py index 741ecc5eb37..074ba146d8d 100644 --- a/test/runner/lib/cover.py +++ b/test/runner/lib/cover.py @@ -7,6 +7,7 @@ import re from lib.target import ( walk_module_targets, + walk_compile_targets, ) from lib.util import ( @@ -44,6 +45,14 @@ def command_coverage_combine(args): counter = 0 groups = {} + if args.all or args.stub: + sources = sorted(os.path.abspath(target.path) for target in walk_compile_targets()) + else: + sources = [] + + if args.stub: + groups['=stub'] = dict((source, set()) for source in sources) + for coverage_file in coverage_files: counter += 1 display.info('[%4d/%4d] %s' % (counter, len(coverage_files), coverage_file), verbosity=2) @@ -115,6 +124,9 @@ def command_coverage_combine(args): updated.add_arcs({filename: list(arc_data[filename])}) + if args.all: + updated.add_arcs(dict((source, []) for source in sources)) + if not args.explain: output_file = COVERAGE_FILE + group updated.write_file(output_file) @@ -130,7 +142,7 @@ def command_coverage_report(args): output_files = command_coverage_combine(args) for output_file in output_files: - if args.group_by: + if args.group_by or args.stub: display.info('>>> Coverage Group: %s' % ' '.join(os.path.basename(output_file).split('=')[1:])) env = common_environment() @@ -238,3 +250,5 @@ class CoverageConfig(EnvironmentConfig): super(CoverageConfig, self).__init__(args, 'coverage') self.group_by = frozenset(args.group_by) if 'group_by' in args and args.group_by else set() # type: frozenset[str] + self.all = args.all if 'all' in args else False # type: bool + self.stub = args.stub if 'stub' in args else False # type: bool diff --git a/test/runner/test.py b/test/runner/test.py index 71e7b1f7ac7..e19e9899845 100755 --- a/test/runner/test.py +++ b/test/runner/test.py @@ -516,6 +516,14 @@ def add_extra_coverage_options(parser): choices=lib.cover.COVERAGE_GROUPS, help='group output by: %s' % ', '.join(lib.cover.COVERAGE_GROUPS)) + parser.add_argument('--all', + action='store_true', + help='include all python source files') + + parser.add_argument('--stub', + action='store_true', + help='generate empty report of all python source files') + def add_extra_docker_options(parser, integration=True): """ diff --git a/test/utils/shippable/shippable.sh b/test/utils/shippable/shippable.sh index 553135ad3c8..84fc01785e9 100755 --- a/test/utils/shippable/shippable.sh +++ b/test/utils/shippable/shippable.sh @@ -52,7 +52,15 @@ find lib/ansible/modules -type d -empty -print -delete function cleanup { if find test/results/coverage/ -mindepth 1 -name '.*' -prune -o -print -quit | grep -q .; then - ansible-test coverage xml --color -v --requirements --group-by command --group-by version + # for complete on-demand coverage generate a report for all files with no coverage on the "other" job so we only have one copy + if [ "${COVERAGE}" ] && [ "${CHANGED}" == "" ] && [ "${TEST}" == "other" ]; then + stub="--stub" + else + stub="" + fi + + # shellcheck disable=SC2086 + ansible-test coverage xml --color -v --requirements --group-by command --group-by version ${stub:+"$stub"} cp -a test/results/reports/coverage=*.xml shippable/codecoverage/ # upload coverage report to codecov.io only when using complete on-demand coverage