Move ansible-test coverage config to test/lib/
This commit is contained in:
parent
2e7d36a3f9
commit
5f67b5a757
11 changed files with 79 additions and 72 deletions
26
.coveragerc
26
.coveragerc
|
@ -1,26 +0,0 @@
|
|||
# This configuration file is used for manual execution of coverage
|
||||
# as well as for tests run through ansible-test.
|
||||
|
||||
[run]
|
||||
branch = True
|
||||
|
||||
# Enable concurrency. This also enables parallel mode, which results in
|
||||
# multiple coverage files being created. Concurrency allows us to collect
|
||||
# results from multiple tests simultaneously, as well as supporting multiple
|
||||
# test runs, such as from integration tests.
|
||||
concurrency = multiprocessing
|
||||
parallel = True
|
||||
|
||||
# When running tests through ansible-test, this option is overridden by
|
||||
# the COVERAGE_FILE environment variable. This option is present for
|
||||
# convenience when running coverage manually from this directory.
|
||||
data_file = test/results/coverage/coverage
|
||||
|
||||
# Don't collect or report code coverage from files matching these patterns.
|
||||
omit =
|
||||
*/python*/dist-packages/*
|
||||
*/python*/site-packages/*
|
||||
*/python*/distutils/*
|
||||
*/pyshared/*
|
||||
*/pytest
|
||||
*/AnsiballZ_*.py
|
|
@ -2,7 +2,6 @@ include README.rst
|
|||
include COPYING
|
||||
include SYMLINK_CACHE.json
|
||||
include requirements.txt
|
||||
include .coveragerc
|
||||
include shippable.yml
|
||||
include bin/ansible-test
|
||||
include examples/hosts
|
||||
|
|
0
test/lib/ansible_test/_data/coveragerc
Normal file
0
test/lib/ansible_test/_data/coveragerc
Normal file
|
@ -836,7 +836,6 @@ class PathMapper:
|
|||
|
||||
if path in (
|
||||
'shippable.yml',
|
||||
'.coveragerc',
|
||||
):
|
||||
return all_tests(self.args) # test infrastructure, run all tests
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ from .util import (
|
|||
display,
|
||||
ApplicationError,
|
||||
common_environment,
|
||||
ANSIBLE_TEST_DATA_ROOT,
|
||||
)
|
||||
|
||||
from .util_common import (
|
||||
|
@ -37,6 +38,7 @@ from .data import (
|
|||
COVERAGE_DIR = 'test/results/coverage'
|
||||
COVERAGE_FILE = os.path.join(COVERAGE_DIR, 'coverage')
|
||||
COVERAGE_GROUPS = ('command', 'target', 'environment', 'version')
|
||||
COVERAGE_CONFIG_PATH = os.path.join(ANSIBLE_TEST_DATA_ROOT, 'coveragerc')
|
||||
|
||||
|
||||
def command_coverage_combine(args):
|
||||
|
@ -239,7 +241,7 @@ def command_coverage_report(args):
|
|||
|
||||
env = common_environment()
|
||||
env.update(dict(COVERAGE_FILE=output_file))
|
||||
run_command(args, env=env, cmd=['coverage', 'report'] + options)
|
||||
run_command(args, env=env, cmd=['coverage', 'report', '--rcfile', COVERAGE_CONFIG_PATH] + options)
|
||||
|
||||
|
||||
def command_coverage_html(args):
|
||||
|
@ -252,7 +254,7 @@ def command_coverage_html(args):
|
|||
dir_name = 'test/results/reports/%s' % os.path.basename(output_file)
|
||||
env = common_environment()
|
||||
env.update(dict(COVERAGE_FILE=output_file))
|
||||
run_command(args, env=env, cmd=['coverage', 'html', '-i', '-d', dir_name])
|
||||
run_command(args, env=env, cmd=['coverage', 'html', '--rcfile', COVERAGE_CONFIG_PATH, '-i', '-d', dir_name])
|
||||
|
||||
|
||||
def command_coverage_xml(args):
|
||||
|
@ -265,7 +267,7 @@ def command_coverage_xml(args):
|
|||
xml_name = 'test/results/reports/%s.xml' % os.path.basename(output_file)
|
||||
env = common_environment()
|
||||
env.update(dict(COVERAGE_FILE=output_file))
|
||||
run_command(args, env=env, cmd=['coverage', 'xml', '-i', '-o', xml_name])
|
||||
run_command(args, env=env, cmd=['coverage', 'xml', '--rcfile', COVERAGE_CONFIG_PATH, '-i', '-o', xml_name])
|
||||
|
||||
|
||||
def command_coverage_erase(args):
|
||||
|
|
|
@ -13,7 +13,7 @@ from .config import (
|
|||
)
|
||||
|
||||
from .util import (
|
||||
COVERAGE_CONFIG_PATH,
|
||||
COVERAGE_CONFIG_NAME,
|
||||
remove_tree,
|
||||
)
|
||||
|
||||
|
@ -35,16 +35,18 @@ def coverage_context(args): # type: (TestConfig) -> None
|
|||
|
||||
def coverage_setup(args): # type: (TestConfig) -> None
|
||||
"""Set up code coverage configuration before running tests."""
|
||||
if args.coverage and data_context().content.collection:
|
||||
coverage_config = generate_collection_coverage_config(args)
|
||||
if not args.coverage:
|
||||
return
|
||||
|
||||
if args.explain:
|
||||
args.coverage_config_base_path = '/tmp/coverage-temp-dir'
|
||||
else:
|
||||
args.coverage_config_base_path = tempfile.mkdtemp()
|
||||
coverage_config = generate_coverage_config(args)
|
||||
|
||||
with open(os.path.join(args.coverage_config_base_path, COVERAGE_CONFIG_PATH), 'w') as coverage_config_path_fd:
|
||||
coverage_config_path_fd.write(coverage_config)
|
||||
if args.explain:
|
||||
args.coverage_config_base_path = '/tmp/coverage-temp-dir'
|
||||
else:
|
||||
args.coverage_config_base_path = tempfile.mkdtemp()
|
||||
|
||||
with open(os.path.join(args.coverage_config_base_path, COVERAGE_CONFIG_NAME), 'w') as coverage_config_path_fd:
|
||||
coverage_config_path_fd.write(coverage_config)
|
||||
|
||||
|
||||
def coverage_cleanup(args): # type: (TestConfig) -> None
|
||||
|
@ -54,8 +56,38 @@ def coverage_cleanup(args): # type: (TestConfig) -> None
|
|||
args.coverage_config_base_path = None
|
||||
|
||||
|
||||
def generate_collection_coverage_config(args): # type: (TestConfig) -> str
|
||||
def generate_coverage_config(args): # type: (TestConfig) -> str
|
||||
"""Generate code coverage configuration for tests."""
|
||||
if data_context().content.collection:
|
||||
coverage_config = generate_collection_coverage_config(args)
|
||||
else:
|
||||
coverage_config = generate_ansible_coverage_config()
|
||||
|
||||
return coverage_config
|
||||
|
||||
|
||||
def generate_ansible_coverage_config(): # type: () -> str
|
||||
"""Generate code coverage configuration for Ansible tests."""
|
||||
coverage_config = '''
|
||||
[run]
|
||||
branch = True
|
||||
concurrency = multiprocessing
|
||||
parallel = True
|
||||
|
||||
omit =
|
||||
*/python*/dist-packages/*
|
||||
*/python*/site-packages/*
|
||||
*/python*/distutils/*
|
||||
*/pyshared/*
|
||||
*/pytest
|
||||
*/AnsiballZ_*.py
|
||||
'''
|
||||
|
||||
return coverage_config
|
||||
|
||||
|
||||
def generate_collection_coverage_config(args): # type: (TestConfig) -> str
|
||||
"""Generate code coverage configuration for Ansible Collection tests."""
|
||||
coverage_config = '''
|
||||
[run]
|
||||
branch = True
|
||||
|
|
|
@ -58,7 +58,7 @@ from .util import (
|
|||
find_python,
|
||||
get_docker_completion,
|
||||
get_remote_completion,
|
||||
COVERAGE_OUTPUT_PATH,
|
||||
COVERAGE_OUTPUT_NAME,
|
||||
cmd_quote,
|
||||
ANSIBLE_ROOT,
|
||||
ANSIBLE_TEST_DATA_ROOT,
|
||||
|
@ -985,7 +985,7 @@ def command_integration_filtered(args, targets, all_targets, inventory_path, pre
|
|||
finally:
|
||||
if not args.explain:
|
||||
if args.coverage:
|
||||
coverage_temp_path = os.path.join(common_temp_path, COVERAGE_OUTPUT_PATH)
|
||||
coverage_temp_path = os.path.join(common_temp_path, COVERAGE_OUTPUT_NAME)
|
||||
coverage_save_path = 'test/results/coverage'
|
||||
|
||||
for filename in os.listdir(coverage_temp_path):
|
||||
|
|
|
@ -23,8 +23,8 @@ from ..util import (
|
|||
ApplicationError,
|
||||
display,
|
||||
make_dirs,
|
||||
COVERAGE_CONFIG_PATH,
|
||||
COVERAGE_OUTPUT_PATH,
|
||||
COVERAGE_CONFIG_NAME,
|
||||
COVERAGE_OUTPUT_NAME,
|
||||
MODE_DIRECTORY,
|
||||
MODE_DIRECTORY_WRITE,
|
||||
MODE_FILE,
|
||||
|
@ -37,7 +37,7 @@ from ..util_common import (
|
|||
)
|
||||
|
||||
from ..coverage_util import (
|
||||
generate_collection_coverage_config,
|
||||
generate_coverage_config,
|
||||
)
|
||||
|
||||
from ..cache import (
|
||||
|
@ -48,10 +48,6 @@ from ..cloud import (
|
|||
CloudEnvironmentConfig,
|
||||
)
|
||||
|
||||
from ..data import (
|
||||
data_context,
|
||||
)
|
||||
|
||||
|
||||
def setup_common_temp_dir(args, path):
|
||||
"""
|
||||
|
@ -64,22 +60,20 @@ def setup_common_temp_dir(args, path):
|
|||
os.mkdir(path)
|
||||
os.chmod(path, MODE_DIRECTORY)
|
||||
|
||||
coverage_config_path = os.path.join(path, COVERAGE_CONFIG_PATH)
|
||||
if args.coverage:
|
||||
coverage_config_path = os.path.join(path, COVERAGE_CONFIG_NAME)
|
||||
|
||||
if data_context().content.collection:
|
||||
coverage_config = generate_collection_coverage_config(args)
|
||||
coverage_config = generate_coverage_config(args)
|
||||
|
||||
with open(coverage_config_path, 'w') as coverage_config_fd:
|
||||
coverage_config_fd.write(coverage_config)
|
||||
else:
|
||||
shutil.copy(os.path.join(ANSIBLE_ROOT, COVERAGE_CONFIG_PATH), coverage_config_path)
|
||||
|
||||
os.chmod(coverage_config_path, MODE_FILE)
|
||||
os.chmod(coverage_config_path, MODE_FILE)
|
||||
|
||||
coverage_output_path = os.path.join(path, COVERAGE_OUTPUT_PATH)
|
||||
coverage_output_path = os.path.join(path, COVERAGE_OUTPUT_NAME)
|
||||
|
||||
os.mkdir(coverage_output_path)
|
||||
os.chmod(coverage_output_path, MODE_DIRECTORY_WRITE)
|
||||
os.mkdir(coverage_output_path)
|
||||
os.chmod(coverage_output_path, MODE_DIRECTORY_WRITE)
|
||||
|
||||
|
||||
def generate_dependency_map(integration_targets):
|
||||
|
|
|
@ -79,7 +79,7 @@ class ManageWindowsCI:
|
|||
|
||||
for dummy in range(1, 120):
|
||||
try:
|
||||
intercept_command(self.core_ci.args, cmd, 'ping', env=env)
|
||||
intercept_command(self.core_ci.args, cmd, 'ping', env=env, disable_coverage=True)
|
||||
return
|
||||
except SubprocessError:
|
||||
time.sleep(10)
|
||||
|
@ -171,7 +171,7 @@ class ManageNetworkCI:
|
|||
|
||||
for dummy in range(1, 90):
|
||||
try:
|
||||
intercept_command(self.core_ci.args, cmd, 'ping', env=env)
|
||||
intercept_command(self.core_ci.args, cmd, 'ping', env=env, disable_coverage=True)
|
||||
return
|
||||
except SubprocessError:
|
||||
time.sleep(10)
|
||||
|
|
|
@ -59,8 +59,8 @@ try:
|
|||
except AttributeError:
|
||||
MAXFD = -1
|
||||
|
||||
COVERAGE_CONFIG_PATH = '.coveragerc'
|
||||
COVERAGE_OUTPUT_PATH = 'coverage'
|
||||
COVERAGE_CONFIG_NAME = 'coveragerc'
|
||||
COVERAGE_OUTPUT_NAME = 'coverage'
|
||||
|
||||
ANSIBLE_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
|
||||
ANSIBLE_TEST_ROOT = os.path.join(ANSIBLE_ROOT, 'test', 'lib', 'ansible_test')
|
||||
|
|
|
@ -11,8 +11,8 @@ import textwrap
|
|||
|
||||
from .util import (
|
||||
common_environment,
|
||||
COVERAGE_CONFIG_PATH,
|
||||
COVERAGE_OUTPUT_PATH,
|
||||
COVERAGE_CONFIG_NAME,
|
||||
COVERAGE_OUTPUT_NAME,
|
||||
display,
|
||||
find_python,
|
||||
ANSIBLE_ROOT,
|
||||
|
@ -155,16 +155,22 @@ def get_coverage_environment(args, target_name, version, temp_path, module_cover
|
|||
# config and results are in a temporary directory
|
||||
coverage_config_base_path = temp_path
|
||||
coverage_output_base_path = temp_path
|
||||
else:
|
||||
elif args.coverage_config_base_path:
|
||||
# unit tests, sanity tests and other special cases (localhost only)
|
||||
# config and results are in the source tree
|
||||
coverage_config_base_path = args.coverage_config_base_path or ANSIBLE_ROOT
|
||||
# config is in a temporary directory
|
||||
# results are in the source tree
|
||||
coverage_config_base_path = args.coverage_config_base_path
|
||||
coverage_output_base_path = os.path.abspath(os.path.join('test/results'))
|
||||
else:
|
||||
raise Exception('No temp path and no coverage config base path. Check for missing coverage_context usage.')
|
||||
|
||||
config_file = os.path.join(coverage_config_base_path, COVERAGE_CONFIG_PATH)
|
||||
coverage_file = os.path.join(coverage_output_base_path, COVERAGE_OUTPUT_PATH, '%s=%s=%s=%s=coverage' % (
|
||||
config_file = os.path.join(coverage_config_base_path, COVERAGE_CONFIG_NAME)
|
||||
coverage_file = os.path.join(coverage_output_base_path, COVERAGE_OUTPUT_NAME, '%s=%s=%s=%s=coverage' % (
|
||||
args.command, target_name, args.coverage_label or 'local-%s' % version, 'python-%s' % version))
|
||||
|
||||
if not args.explain and not os.path.exists(config_file):
|
||||
raise Exception('Missing coverage config file: %s' % config_file)
|
||||
|
||||
if args.coverage_check:
|
||||
# cause the 'coverage' module to be found, but not imported or enabled
|
||||
coverage_file = ''
|
||||
|
@ -190,7 +196,7 @@ def get_coverage_environment(args, target_name, version, temp_path, module_cover
|
|||
|
||||
|
||||
def intercept_command(args, cmd, target_name, env, capture=False, data=None, cwd=None, python_version=None, temp_path=None, module_coverage=True,
|
||||
virtualenv=None):
|
||||
virtualenv=None, disable_coverage=False):
|
||||
"""
|
||||
:type args: TestConfig
|
||||
:type cmd: collections.Iterable[str]
|
||||
|
@ -203,6 +209,7 @@ def intercept_command(args, cmd, target_name, env, capture=False, data=None, cwd
|
|||
:type temp_path: str | None
|
||||
:type module_coverage: bool
|
||||
:type virtualenv: str | None
|
||||
:type disable_coverage: bool
|
||||
:rtype: str | None, str | None
|
||||
"""
|
||||
if not env:
|
||||
|
@ -223,7 +230,7 @@ def intercept_command(args, cmd, target_name, env, capture=False, data=None, cwd
|
|||
env['ANSIBLE_TEST_PYTHON_VERSION'] = version
|
||||
env['ANSIBLE_TEST_PYTHON_INTERPRETER'] = interpreter
|
||||
|
||||
if args.coverage:
|
||||
if args.coverage and not disable_coverage:
|
||||
# add the necessary environment variables to enable code coverage collection
|
||||
env.update(get_coverage_environment(args, target_name, version, temp_path, module_coverage))
|
||||
|
||||
|
|
Loading…
Reference in a new issue