Overhaul ansible-test code coverage and injector. (#53510)

This commit is contained in:
Matt Clay 2019-03-13 07:14:12 -07:00 committed by GitHub
parent 3bdbe24861
commit a8e328f474
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 253 additions and 370 deletions

View file

@ -15,6 +15,9 @@ import sys
import hashlib
import difflib
import filecmp
import random
import string
import shutil
import lib.pytar
import lib.thread
@ -50,12 +53,13 @@ from lib.util import (
is_binary_file,
find_executable,
raw_command,
get_coverage_path,
get_python_path,
get_available_port,
generate_pip_command,
find_python,
get_docker_completion,
named_temporary_file,
COVERAGE_OUTPUT_PATH,
)
from lib.docker_util import (
@ -112,6 +116,7 @@ from lib.metadata import (
from lib.integration import (
integration_test_environment,
integration_test_config_file,
setup_common_temp_dir,
)
SUPPORTED_PYTHON_VERSIONS = (
@ -359,7 +364,7 @@ def command_network_integration(args):
instances = [] # type: list [lib.thread.WrappedThread]
if args.platform:
get_coverage_path(args, args.python_executable) # initialize before starting threads
get_python_path(args, args.python_executable) # initialize before starting threads
configs = dict((config['platform_version'], config) for config in args.metadata.instance_config)
@ -527,7 +532,7 @@ def command_windows_integration(args):
httptester_id = None
if args.windows:
get_coverage_path(args, args.python_executable) # initialize before starting threads
get_python_path(args, args.python_executable) # initialize before starting threads
configs = dict((config['platform_version'], config) for config in args.metadata.instance_config)
@ -833,6 +838,12 @@ def command_integration_filtered(args, targets, all_targets, inventory_path, pre
current_environment = None # type: EnvironmentDescription | None
# common temporary directory path that will be valid on both the controller and the remote
# it must be common because it will be referenced in environment variables that are shared across multiple hosts
common_temp_path = '/tmp/ansible-test-%s' % ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(8))
setup_common_temp_dir(args, common_temp_path)
try:
for target in targets_iter:
if args.start_at and not found:
@ -863,11 +874,11 @@ def command_integration_filtered(args, targets, all_targets, inventory_path, pre
if cloud_environment:
cloud_environment.setup_once()
run_setup_targets(args, test_dir, target.setup_once, all_targets_dict, setup_targets_executed, inventory_path, False)
run_setup_targets(args, test_dir, target.setup_once, all_targets_dict, setup_targets_executed, inventory_path, common_temp_path, False)
start_time = time.time()
run_setup_targets(args, test_dir, target.setup_always, all_targets_dict, setup_targets_executed, inventory_path, True)
run_setup_targets(args, test_dir, target.setup_always, all_targets_dict, setup_targets_executed, inventory_path, common_temp_path, True)
if not args.explain:
# create a fresh test directory for each test target
@ -879,9 +890,9 @@ def command_integration_filtered(args, targets, all_targets, inventory_path, pre
try:
if target.script_path:
command_integration_script(args, target, test_dir, inventory_path)
command_integration_script(args, target, test_dir, inventory_path, common_temp_path)
else:
command_integration_role(args, target, start_at_task, test_dir, inventory_path)
command_integration_role(args, target, start_at_task, test_dir, inventory_path, common_temp_path)
start_at_task = None
finally:
if post_target:
@ -945,6 +956,15 @@ 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_save_path = 'test/results/coverage'
for filename in os.listdir(coverage_temp_path):
shutil.copy(os.path.join(coverage_temp_path, filename), os.path.join(coverage_save_path, filename))
remove_tree(common_temp_path)
results_path = 'test/results/data/%s-%s.json' % (args.command, re.sub(r'[^0-9]', '-', str(datetime.datetime.utcnow().replace(microsecond=0))))
data = dict(
@ -1086,7 +1106,7 @@ rdr pass inet proto tcp from any to any port 443 -> 127.0.0.1 port 8443
raise ApplicationError('No supported port forwarding mechanism detected.')
def run_setup_targets(args, test_dir, target_names, targets_dict, targets_executed, inventory_path, always):
def run_setup_targets(args, test_dir, target_names, targets_dict, targets_executed, inventory_path, temp_path, always):
"""
:type args: IntegrationConfig
:type test_dir: str
@ -1094,6 +1114,7 @@ def run_setup_targets(args, test_dir, target_names, targets_dict, targets_execut
:type targets_dict: dict[str, IntegrationTarget]
:type targets_executed: set[str]
:type inventory_path: str
:type temp_path: str
:type always: bool
"""
for target_name in target_names:
@ -1108,9 +1129,9 @@ def run_setup_targets(args, test_dir, target_names, targets_dict, targets_execut
make_dirs(test_dir)
if target.script_path:
command_integration_script(args, target, test_dir, inventory_path)
command_integration_script(args, target, test_dir, inventory_path, temp_path)
else:
command_integration_role(args, target, None, test_dir, inventory_path)
command_integration_role(args, target, None, test_dir, inventory_path, temp_path)
targets_executed.add(target_name)
@ -1156,12 +1177,13 @@ def integration_environment(args, target, test_dir, inventory_path, ansible_conf
return env
def command_integration_script(args, target, test_dir, inventory_path):
def command_integration_script(args, target, test_dir, inventory_path, temp_path):
"""
:type args: IntegrationConfig
:type target: IntegrationTarget
:type test_dir: str
:type inventory_path: str
:type temp_path: str
"""
display.info('Running %s integration test script' % target.name)
@ -1190,16 +1212,17 @@ def command_integration_script(args, target, test_dir, inventory_path):
cmd += ['-e', '@%s' % config_path]
coverage = args.coverage and 'non_local/' not in target.aliases
intercept_command(args, cmd, target_name=target.name, env=env, cwd=cwd, coverage=coverage)
intercept_command(args, cmd, target_name=target.name, env=env, cwd=cwd, temp_path=temp_path, coverage=coverage)
def command_integration_role(args, target, start_at_task, test_dir, inventory_path):
def command_integration_role(args, target, start_at_task, test_dir, inventory_path, temp_path):
"""
:type args: IntegrationConfig
:type target: IntegrationTarget
:type start_at_task: str | None
:type test_dir: str
:type inventory_path: str
:type temp_path: str
"""
display.info('Running %s integration test role' % target.name)
@ -1273,7 +1296,7 @@ def command_integration_role(args, target, start_at_task, test_dir, inventory_pa
env['ANSIBLE_ROLES_PATH'] = os.path.abspath(os.path.join(test_env.integration_dir, 'targets'))
coverage = args.coverage and 'non_local/' not in target.aliases
intercept_command(args, cmd, target_name=target.name, env=env, cwd=cwd, coverage=coverage)
intercept_command(args, cmd, target_name=target.name, env=env, cwd=cwd, temp_path=temp_path, coverage=coverage)
def command_units(args):