diff options
Diffstat (limited to 'dovetail/test_runner.py')
-rw-r--r-- | dovetail/test_runner.py | 294 |
1 files changed, 170 insertions, 124 deletions
diff --git a/dovetail/test_runner.py b/dovetail/test_runner.py index c9260418..266bdc20 100644 --- a/dovetail/test_runner.py +++ b/dovetail/test_runner.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# grakiss.wanglei@huawei.com +# Copyright (c) 2018 grakiss.wanglei@huawei.com and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 # which accompanies this distribution, and is available at @@ -14,14 +14,14 @@ import jinja2 import jinja2.meta import yaml -from container import Container +from dovetail.container import Container from dovetail import constants -from utils.dovetail_config import DovetailConfig as dt_cfg -import utils.dovetail_utils as dt_utils -import utils.dovetail_logger as dt_logger +from dovetail.utils.dovetail_config import DovetailConfig as dt_cfg +import dovetail.utils.dovetail_utils as dt_utils +import dovetail.utils.dovetail_logger as dt_logger -class DockerRunner(object): +class Runner(object): logger = None @@ -29,70 +29,70 @@ class DockerRunner(object): self.testcase = testcase self.logger.debug('Create runner: {}'.format(self.type)) + def archive_logs(self): + result_path = os.path.join(os.environ['DOVETAIL_HOME'], 'results') + src_files = dt_utils.get_value_from_dict( + 'report.source_archive_files', self.testcase.testcase) + dest_files = dt_utils.get_value_from_dict( + 'report.dest_archive_files', self.testcase.testcase) + if not src_files and not dest_files: + return True + if not (src_files and dest_files) or len(src_files) != len(dest_files): + self.logger.error("Can't find corresponding 'result_dest_files' " + "for 'result_source_files' with testcase {}" + .format(self.testcase.name())) + return False + res = True + for index in range(0, len(src_files)): + src_file_path = os.path.join(result_path, src_files[index]) + dest_file_path = os.path.join(result_path, dest_files[index]) + if os.path.isfile(src_file_path): + os.renames(src_file_path, dest_file_path) + else: + self.logger.error("Can't find file {}.".format(src_file_path)) + res = False + return res + + +class DockerRunner(Runner): + + def __init__(self, testcase): + super(DockerRunner, self).__init__(testcase) + @classmethod def create_log(cls): cls.logger = dt_logger.Logger(__name__ + '.DockerRunner').getLogger() - def pre_copy(self, container_id=None, dest_path=None, - src_file=None, exist_file=None): - if not dest_path: - self.logger.error("There has no dest_path in {} config file." - .format(self.testcase.name())) - return None - if src_file: - self.testcase.mk_src_file() - file_path = dt_cfg.dovetail_config[self.type]['result']['dir'] - src_path = os.path.join(file_path, src_file) - if exist_file: - file_path = dt_cfg.dovetail_config[self.type]['config']['dir'] - src_path = os.path.join(file_path, 'pre_config', exist_file) - - Container.pre_copy(container_id, src_path, dest_path) - return dest_path - def run(self): + container = Container(self.testcase) + docker_image = container.get_docker_image() if dt_cfg.dovetail_config['offline']: - exist = Container.check_image_exist(self.testcase.validate_type()) + exist = container.get_image_id(docker_image) if not exist: self.logger.error("{} image doesn't exist, can't run offline." .format(self.testcase.validate_type())) return else: - if not Container.pull_image(self.testcase.validate_type()): + if not container.pull_image(docker_image): self.logger.error("Failed to pull the image.") return - # for sdnvpn, there is a need to download needed images to config_dir - # in dovetail_config.yml first. - if 'sdnvpn' in str(self.testcase.name()): - img_name = dt_cfg.dovetail_config['sdnvpn_image'] - img_file = os.path.join(dt_cfg.dovetail_config['images_dir'], - img_name) - if not os.path.isfile(img_file): - self.logger.error('Image {} not found.'.format(img_name)) - return - container_id = Container.create(self.testcase.validate_type(), - self.testcase.name()) + + container_id, msg = container.create(docker_image) if not container_id: self.logger.error('Failed to create container.') + self.logger.error(msg) return self.logger.debug('container id: {}'.format(container_id)) - dest_path = self.testcase.pre_copy_path("dest_path") - src_file_name = self.testcase.pre_copy_path("src_file") - exist_file_name = self.testcase.pre_copy_path("exist_src_file") - - if src_file_name or exist_file_name: - if not self.pre_copy(container_id, dest_path, src_file_name, - exist_file_name): - return + self.testcase.mk_src_file() cmds = self.testcase.pre_condition() if cmds: for cmd in cmds: - ret, msg = Container.exec_cmd(container_id, cmd) + ret, msg = container.exec_cmd(cmd) if ret != 0: - self.logger.error("Failed to exec all pre_condition cmds.") + self.logger.error('Failed to exec all pre_condition cmds.') break if not self.testcase.prepare_cmd(self.type): @@ -100,7 +100,7 @@ class DockerRunner(object): 'Failed to prepare test case: {}'.format(self.testcase.name())) else: for cmd in self.testcase.cmds: - ret, msg = Container.exec_cmd(container_id, cmd) + ret, msg = container.exec_cmd(cmd) if ret != 0: self.logger.error('Failed to exec {}, ret: {}, msg: {}' .format(cmd, ret, msg)) @@ -109,51 +109,10 @@ class DockerRunner(object): cmds = self.testcase.post_condition() if cmds: for cmd in cmds: - ret, msg = Container.exec_cmd(container_id, cmd) - self.testcase.cleaned(True) - - Container.clean(container_id, self.type) - - def save_logs(self): - pass - - -class FunctestRunner(DockerRunner): - - def __init__(self, testcase): - self.type = 'functest' - super(FunctestRunner, self).__init__(testcase) - - def save_logs(self): - validate_testcase = self.testcase.validate_testcase() - test_area = self.testcase.name().split(".")[1] - result_path = os.path.join(os.environ["DOVETAIL_HOME"], 'results') - dest_path = os.path.join(result_path, test_area + '_logs') - dest_file = os.path.join(dest_path, self.testcase.name() + '.log') - if validate_testcase == 'tempest_custom': - source_file = os.path.join(result_path, 'tempest', 'tempest.log') - elif validate_testcase == 'refstack_defcore': - source_file = os.path.join(result_path, 'refstack', 'refstack.log') - elif validate_testcase == 'bgpvpn': - source_file = os.path.join(result_path, 'bgpvpn.log') - else: - source_file = None - if source_file: - if os.path.isfile(source_file): - os.renames(source_file, dest_file) - else: - self.logger.error("Tempest log file for test case {} is not " - "found.".format(self.testcase.name())) - + container.exec_cmd(cmd) -class YardstickRunner(DockerRunner): - - config_file_name = 'yardstick_config.yml' - - def __init__(self, testcase): - self.type = 'yardstick' - super(YardstickRunner, self).__init__(testcase) - self._update_yardstick_config(testcase) + if not dt_cfg.dovetail_config['noclean']: + container.clean() @staticmethod def _render(task_template, **kwargs): @@ -165,72 +124,124 @@ class YardstickRunner(DockerRunner): config_item = {} config_item['validate_testcase'] = testcase.validate_testcase() config_item['testcase'] = testcase.name() + config_item['os_insecure'] = os.getenv('OS_INSECURE') + if 'DEPLOY_SCENARIO' in os.environ: + config_item['deploy_scenario'] = os.environ['DEPLOY_SCENARIO'] + config_item['dovetail_home'] = os.getenv('DOVETAIL_HOME') + config_item['debug'] = os.getenv('DEBUG') + config_item['build_tag'] = dt_cfg.dovetail_config['build_tag'] + config_item['cacert'] = os.getenv('OS_CACERT') + config_item['host_url'] = os.getenv('HOST_URL') + config_item['csar_file'] = os.getenv('CSAR_FILE') + config_item['heat_templates_archive'] = os.getenv('VNF_ARCHIVE_NAME') return config_item - def _update_yardstick_config(self, testcase): + def _update_config(self, testcase, update_pod=True): config_item = None - pod_file = os.path.join(dt_cfg.dovetail_config['config_dir'], - dt_cfg.dovetail_config['pod_file']) config_file = os.path.join(constants.CONF_PATH, self.config_file_name) - pod_info = dt_utils.read_yaml_file(pod_file, self.logger) task_template = dt_utils.read_plain_file(config_file, self.logger) - if not (pod_info and task_template): + if not task_template: return None - try: - process_info = pod_info['process_info'] - except KeyError as e: - process_info = None - if process_info: - for item in process_info: + if update_pod: + pod_file = os.path.join(dt_cfg.dovetail_config['config_dir'], + dt_cfg.dovetail_config['pod_file']) + pod_info = dt_utils.read_yaml_file(pod_file, self.logger) + if pod_info: try: - if item['testcase_name'] == testcase.name(): - config_item = self._add_testcase_info(testcase, item) - break + process_info = pod_info['process_info'] except KeyError as e: - self.logger.error('Need key {} in {}'.format(e, item)) + process_info = None + else: + process_info = None + if process_info: + for item in process_info: + try: + if item['testcase_name'] == testcase.name(): + config_item = self._add_testcase_info( + testcase, item) + break + except KeyError as e: + self.logger.error('Need key {} in {}'.format(e, item)) if not config_item: config_item = self._add_testcase_info(testcase) full_task = self._render(task_template, **config_item) - full_task_yaml = yaml.load(full_task) + full_task_yaml = yaml.safe_load(full_task) dt_cfg.dovetail_config.update(full_task_yaml) return dt_cfg.dovetail_config +class FunctestRunner(DockerRunner): + + config_file_name = 'functest_config.yml' + + def __init__(self, testcase): + self.type = 'functest' + super(FunctestRunner, self).__init__(testcase) + endpoint_file = os.path.join(dt_cfg.dovetail_config['result_dir'], + 'endpoint_info.json') + if not os.path.isfile(endpoint_file): + dt_utils.get_openstack_info(self.logger) + self._update_config(testcase) + + +class FunctestK8sRunner(DockerRunner): + + config_file_name = 'functest-k8s_config.yml' + + def __init__(self, testcase): + self.type = 'functest-k8s' + super(FunctestK8sRunner, self).__init__(testcase) + self._update_config(testcase, update_pod=False) + + +class YardstickRunner(DockerRunner): + + config_file_name = 'yardstick_config.yml' + + def __init__(self, testcase): + self.type = 'yardstick' + super(YardstickRunner, self).__init__(testcase) + endpoint_file = os.path.join(dt_cfg.dovetail_config['result_dir'], + 'endpoint_info.json') + if not os.path.isfile(endpoint_file): + dt_utils.get_openstack_info(self.logger) + self._update_config(testcase) + + class BottlenecksRunner(DockerRunner): + config_file_name = 'bottlenecks_config.yml' + def __init__(self, testcase): self.type = 'bottlenecks' super(BottlenecksRunner, self).__init__(testcase) + endpoint_file = os.path.join(dt_cfg.dovetail_config['result_dir'], + 'endpoint_info.json') + if not os.path.isfile(endpoint_file): + dt_utils.get_openstack_info(self.logger) + self._update_config(testcase) -class ShellRunner(object): - - logger = None +class ShellRunner(Runner): @classmethod def create_log(cls): cls.logger = dt_logger.Logger(__name__ + '.ShellRunner').getLogger() def __init__(self, testcase): - super(ShellRunner, self).__init__() - self.testcase = testcase self.type = 'shell' - self.logger.debug('Create runner: {}'.format(self.type)) + super(ShellRunner, self).__init__(testcase) def run(self): testcase_passed = 'PASS' - prepare_failed = False result = {'pass': 'PASS', 'results': []} - if not self.testcase.prepared(): - cmds = self.testcase.pre_condition() - for cmd in cmds: - ret, msg = dt_utils.exec_cmd(cmd, self.logger) - result['results'].append((cmd, ret, msg)) - if ret != 0: - prepare_failed = True - break - if not prepare_failed: - self.testcase.prepared(True) + cmds = self.testcase.pre_condition() + for cmd in cmds: + ret, msg = dt_utils.exec_cmd(cmd, self.logger) + result['results'].append((cmd, ret, msg)) + if ret != 0: + self.logger.error('Failed to execute all pre_condition cmds.') + break if not self.testcase.prepare_cmd(self.type): self.logger.error( @@ -260,6 +271,38 @@ class ShellRunner(object): 'exception: {}'.format(result_filename, e)) +class OnapVtpRunner(DockerRunner): + + config_file_name = 'onap-vtp_config.yml' + + def __init__(self, testcase): + self.type = 'onap-vtp' + super(OnapVtpRunner, self).__init__(testcase) + env_file = os.path.join(dt_cfg.dovetail_config['config_dir'], + dt_cfg.dovetail_config['env_file']) + if not os.path.isfile(env_file): + self.logger.error('File {} does not exist.'.format(env_file)) + return + dt_utils.source_env(env_file) + self._update_config(testcase, update_pod=False) + + +class OnapVvpRunner(DockerRunner): + + config_file_name = 'onap-vvp_config.yml' + + def __init__(self, testcase): + self.type = 'onap-vvp' + super(OnapVvpRunner, self).__init__(testcase) + env_file = os.path.join(dt_cfg.dovetail_config['config_dir'], + dt_cfg.dovetail_config['env_file']) + if not os.path.isfile(env_file): + self.logger.error('File {} does not exist.'.format(env_file)) + return + dt_utils.source_env(env_file) + self._update_config(testcase, update_pod=False) + + class TestRunnerFactory(object): TEST_RUNNER_MAP = { @@ -267,6 +310,9 @@ class TestRunnerFactory(object): "yardstick": YardstickRunner, "bottlenecks": BottlenecksRunner, "shell": ShellRunner, + "functest-k8s": FunctestK8sRunner, + "onap-vtp": OnapVtpRunner, + "onap-vvp": OnapVvpRunner } @classmethod |