summaryrefslogtreecommitdiff
path: root/test/lib/ansible_test/_internal
diff options
context:
space:
mode:
authorMatt Clay <matt@mystile.com>2021-05-14 17:19:40 -0700
committerMatt Clay <matt@mystile.com>2021-05-17 10:37:42 -0700
commitce0405679706e110c08eda65b36617a84d4a4de8 (patch)
tree39877b402cb432ab7ee724506c28deb7dc7e8e3d /test/lib/ansible_test/_internal
parente875e91363f58396777aad6f7cdb04f8a813b5cd (diff)
downloadansible-ce0405679706e110c08eda65b36617a84d4a4de8.tar.gz
Expand delegation options for coverage commands.
Diffstat (limited to 'test/lib/ansible_test/_internal')
-rw-r--r--test/lib/ansible_test/_internal/cli.py25
-rw-r--r--test/lib/ansible_test/_internal/commands/coverage/__init__.py11
-rw-r--r--test/lib/ansible_test/_internal/commands/coverage/combine.py66
-rw-r--r--test/lib/ansible_test/_internal/commands/coverage/erase.py6
-rw-r--r--test/lib/ansible_test/_internal/commands/coverage/html.py8
-rw-r--r--test/lib/ansible_test/_internal/commands/coverage/report.py4
-rw-r--r--test/lib/ansible_test/_internal/commands/coverage/xml.py8
7 files changed, 99 insertions, 29 deletions
diff --git a/test/lib/ansible_test/_internal/cli.py b/test/lib/ansible_test/_internal/cli.py
index 4d547ade58..2cc78f5236 100644
--- a/test/lib/ansible_test/_internal/cli.py
+++ b/test/lib/ansible_test/_internal/cli.py
@@ -108,14 +108,17 @@ from .util_common import (
from .commands.coverage.combine import (
command_coverage_combine,
+ CoverageCombineConfig,
)
from .commands.coverage.erase import (
command_coverage_erase,
+ CoverageEraseConfig,
)
from .commands.coverage.html import (
command_coverage_html,
+ CoverageHtmlConfig,
)
from .commands.coverage.report import (
@@ -125,6 +128,7 @@ from .commands.coverage.report import (
from .commands.coverage.xml import (
command_coverage_xml,
+ CoverageXmlConfig,
)
from .commands.coverage.analyze.targets.generate import (
@@ -154,7 +158,6 @@ from .commands.coverage.analyze.targets.missing import (
from .commands.coverage import (
COVERAGE_GROUPS,
- CoverageConfig,
)
if t.TYPE_CHECKING:
@@ -579,6 +582,10 @@ def parse_args():
add_environments(coverage_common, argparse, isolated_delegation=False)
+ coverage_common_isolated_delegation = argparse.ArgumentParser(add_help=False, parents=[common])
+
+ add_environments(coverage_common_isolated_delegation, argparse)
+
coverage = subparsers.add_parser('coverage',
help='code coverage management and reporting')
@@ -588,11 +595,11 @@ def parse_args():
add_coverage_analyze(coverage_subparsers, coverage_common)
coverage_combine = coverage_subparsers.add_parser('combine',
- parents=[coverage_common],
+ parents=[coverage_common_isolated_delegation],
help='combine coverage data and rewrite remote paths')
coverage_combine.set_defaults(func=command_coverage_combine,
- config=CoverageConfig)
+ config=CoverageCombineConfig)
coverage_combine.add_argument('--export',
help='directory to export combined coverage files to')
@@ -604,10 +611,10 @@ def parse_args():
help='erase coverage data files')
coverage_erase.set_defaults(func=command_coverage_erase,
- config=CoverageConfig)
+ config=CoverageEraseConfig)
coverage_report = coverage_subparsers.add_parser('report',
- parents=[coverage_common],
+ parents=[coverage_common_isolated_delegation],
help='generate console coverage report')
coverage_report.set_defaults(func=command_coverage_report,
@@ -629,20 +636,20 @@ def parse_args():
add_extra_coverage_options(coverage_report)
coverage_html = coverage_subparsers.add_parser('html',
- parents=[coverage_common],
+ parents=[coverage_common_isolated_delegation],
help='generate html coverage report')
coverage_html.set_defaults(func=command_coverage_html,
- config=CoverageConfig)
+ config=CoverageHtmlConfig)
add_extra_coverage_options(coverage_html)
coverage_xml = coverage_subparsers.add_parser('xml',
- parents=[coverage_common],
+ parents=[coverage_common_isolated_delegation],
help='generate xml coverage report')
coverage_xml.set_defaults(func=command_coverage_xml,
- config=CoverageConfig)
+ config=CoverageXmlConfig)
add_extra_coverage_options(coverage_xml)
diff --git a/test/lib/ansible_test/_internal/commands/coverage/__init__.py b/test/lib/ansible_test/_internal/commands/coverage/__init__.py
index e21c302486..940dd2e325 100644
--- a/test/lib/ansible_test/_internal/commands/coverage/__init__.py
+++ b/test/lib/ansible_test/_internal/commands/coverage/__init__.py
@@ -59,12 +59,6 @@ class CoverageConfig(EnvironmentConfig):
def __init__(self, args): # type: (t.Any) -> None
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: t.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
- self.export = args.export if 'export' in args else None # type: str
- self.coverage = False # temporary work-around to support intercept_command in cover.py
-
def initialize_coverage(args): # type: (CoverageConfig) -> coverage_module
"""Delegate execution if requested, install requirements, then import and return the coverage module. Raises an exception if coverage is not available."""
@@ -111,6 +105,11 @@ def run_coverage(args, output_file, command, cmd): # type: (CoverageConfig, str
intercept_command(args, target_name='coverage', env=env, cmd=cmd, disable_coverage=True)
+def get_all_coverage_files(): # type: () -> t.List[str]
+ """Return a list of all coverage file paths."""
+ return get_python_coverage_files() + get_powershell_coverage_files()
+
+
def get_python_coverage_files(path=None): # type: (t.Optional[str]) -> t.List[str]
"""Return the list of Python coverage file paths."""
return get_coverage_files('python', path)
diff --git a/test/lib/ansible_test/_internal/commands/coverage/combine.py b/test/lib/ansible_test/_internal/commands/coverage/combine.py
index f163dff76b..0dd6f0fa87 100644
--- a/test/lib/ansible_test/_internal/commands/coverage/combine.py
+++ b/test/lib/ansible_test/_internal/commands/coverage/combine.py
@@ -5,6 +5,8 @@ __metaclass__ = type
import os
import json
+from ... import types as t
+
from ...target import (
walk_compile_targets,
walk_powershell_targets,
@@ -17,7 +19,7 @@ from ...io import (
from ...util import (
ANSIBLE_TEST_DATA_ROOT,
display,
- find_executable,
+ ApplicationError,
)
from ...util_common import (
@@ -27,10 +29,19 @@ from ...util_common import (
write_json_test_results,
)
+from ...executor import (
+ Delegate,
+)
+
+from ...data import (
+ data_context,
+)
+
from . import (
enumerate_python_arcs,
enumerate_powershell_lines,
get_collection_path_regexes,
+ get_all_coverage_files,
get_python_coverage_files,
get_python_modules,
get_powershell_coverage_files,
@@ -44,9 +55,28 @@ from . import (
def command_coverage_combine(args):
"""Patch paths in coverage files and merge into a single file.
- :type args: CoverageConfig
+ :type args: CoverageCombineConfig
:rtype: list[str]
"""
+ if args.delegate:
+ if args.docker or args.remote:
+ paths = get_all_coverage_files()
+ exported_paths = [path for path in paths if path.endswith('=coverage.combined')]
+
+ if not exported_paths:
+ raise ExportedCoverageDataNotFound()
+
+ pairs = [(path, os.path.relpath(path, data_context().content.root)) for path in exported_paths]
+
+ def coverage_callback(files): # type: (t.List[t.Tuple[str, str]]) -> None
+ """Add the coverage files to the payload file list."""
+ display.info('Including %d exported coverage file(s) in payload.' % len(pairs), verbosity=1)
+ files.extend(pairs)
+
+ data_context().register_payload_callback(coverage_callback)
+
+ raise Delegate()
+
paths = _command_coverage_combine_powershell(args) + _command_coverage_combine_python(args)
for path in paths:
@@ -55,9 +85,18 @@ def command_coverage_combine(args):
return paths
+class ExportedCoverageDataNotFound(ApplicationError):
+ """Exception when no combined coverage data is present yet is required."""
+ def __init__(self):
+ super(ExportedCoverageDataNotFound, self).__init__(
+ 'Coverage data must be exported before processing with the `--docker` or `--remote` option.\n'
+ 'Export coverage with `ansible-test coverage combine` using the `--export` option.\n'
+ 'The exported files must be in the directory: %s/' % ResultType.COVERAGE.relative_path)
+
+
def _command_coverage_combine_python(args):
"""
- :type args: CoverageConfig
+ :type args: CoverageCombineConfig
:rtype: list[str]
"""
coverage = initialize_coverage(args)
@@ -136,7 +175,7 @@ def _command_coverage_combine_python(args):
def _command_coverage_combine_powershell(args):
"""
- :type args: CoverageConfig
+ :type args: CoverageCombineConfig
:rtype: list[str]
"""
coverage_files = get_powershell_coverage_files()
@@ -217,7 +256,7 @@ def _command_coverage_combine_powershell(args):
def _get_coverage_targets(args, walk_func):
"""
- :type args: CoverageConfig
+ :type args: CoverageCombineConfig
:type walk_func: Func
:rtype: list[tuple[str, int]]
"""
@@ -240,7 +279,7 @@ def _get_coverage_targets(args, walk_func):
def _build_stub_groups(args, sources, default_stub_value):
"""
- :type args: CoverageConfig
+ :type args: CoverageCombineConfig
:type sources: List[tuple[str, int]]
:type default_stub_value: Func[List[str]]
:rtype: dict
@@ -273,7 +312,7 @@ def _build_stub_groups(args, sources, default_stub_value):
def get_coverage_group(args, coverage_file):
"""
- :type args: CoverageConfig
+ :type args: CoverageCombineConfig
:type coverage_file: str
:rtype: str
"""
@@ -306,3 +345,16 @@ def get_coverage_group(args, coverage_file):
group = group.lstrip('=')
return group
+
+
+class CoverageCombineConfig(CoverageConfig):
+ """Configuration for the coverage combine command."""
+ def __init__(self, args): # type: (t.Any) -> None
+ super(CoverageCombineConfig, self).__init__(args)
+
+ self.group_by = frozenset(args.group_by) if args.group_by else frozenset() # type: t.FrozenSet[str]
+ self.all = args.all # type: bool
+ self.stub = args.stub # type: bool
+
+ # only available to coverage combine
+ self.export = args.export if 'export' in args else False # type: str
diff --git a/test/lib/ansible_test/_internal/commands/coverage/erase.py b/test/lib/ansible_test/_internal/commands/coverage/erase.py
index 7ba9608dfb..7a41f56f47 100644
--- a/test/lib/ansible_test/_internal/commands/coverage/erase.py
+++ b/test/lib/ansible_test/_internal/commands/coverage/erase.py
@@ -13,7 +13,7 @@ from . import (
)
-def command_coverage_erase(args): # type: (CoverageConfig) -> None
+def command_coverage_erase(args): # type: (CoverageEraseConfig) -> None
"""Erase code coverage data files collected during test runs."""
coverage_dir = ResultType.COVERAGE.path
@@ -25,3 +25,7 @@ def command_coverage_erase(args): # type: (CoverageConfig) -> None
if not args.explain:
os.remove(path)
+
+
+class CoverageEraseConfig(CoverageConfig):
+ """Configuration for the coverage erase command."""
diff --git a/test/lib/ansible_test/_internal/commands/coverage/html.py b/test/lib/ansible_test/_internal/commands/coverage/html.py
index 717f237d0e..b34e1ef4ec 100644
--- a/test/lib/ansible_test/_internal/commands/coverage/html.py
+++ b/test/lib/ansible_test/_internal/commands/coverage/html.py
@@ -18,17 +18,17 @@ from ...util_common import (
from .combine import (
command_coverage_combine,
+ CoverageCombineConfig,
)
from . import (
run_coverage,
- CoverageConfig,
)
def command_coverage_html(args):
"""
- :type args: CoverageConfig
+ :type args: CoverageHtmlConfig
"""
output_files = command_coverage_combine(args)
@@ -43,3 +43,7 @@ def command_coverage_html(args):
run_coverage(args, output_file, 'html', ['-i', '-d', dir_name])
display.info('HTML report generated: file:///%s' % os.path.join(dir_name, 'index.html'))
+
+
+class CoverageHtmlConfig(CoverageCombineConfig):
+ """Configuration for the coverage html command."""
diff --git a/test/lib/ansible_test/_internal/commands/coverage/report.py b/test/lib/ansible_test/_internal/commands/coverage/report.py
index ae13b0db50..498d543403 100644
--- a/test/lib/ansible_test/_internal/commands/coverage/report.py
+++ b/test/lib/ansible_test/_internal/commands/coverage/report.py
@@ -18,11 +18,11 @@ from ...data import (
from .combine import (
command_coverage_combine,
+ CoverageCombineConfig,
)
from . import (
run_coverage,
- CoverageConfig,
)
@@ -143,7 +143,7 @@ def _generate_powershell_output_report(args, coverage_file):
return report
-class CoverageReportConfig(CoverageConfig):
+class CoverageReportConfig(CoverageCombineConfig):
"""Configuration for the coverage report command."""
def __init__(self, args):
"""
diff --git a/test/lib/ansible_test/_internal/commands/coverage/xml.py b/test/lib/ansible_test/_internal/commands/coverage/xml.py
index b02520ec5b..2296ef61c2 100644
--- a/test/lib/ansible_test/_internal/commands/coverage/xml.py
+++ b/test/lib/ansible_test/_internal/commands/coverage/xml.py
@@ -36,17 +36,17 @@ from ...data import (
from .combine import (
command_coverage_combine,
+ CoverageCombineConfig,
)
from . import (
run_coverage,
- CoverageConfig,
)
def command_coverage_xml(args):
"""
- :type args: CoverageConfig
+ :type args: CoverageXmlConfig
"""
output_files = command_coverage_combine(args)
@@ -189,3 +189,7 @@ def _add_cobertura_package(packages, package_name, package_data):
})
return total_lines_hit, total_line_count
+
+
+class CoverageXmlConfig(CoverageCombineConfig):
+ """Configuration for the coverage xml command."""