diff options
-rw-r--r-- | dovetail/test_runner.py | 56 | ||||
-rw-r--r-- | dovetail/utils/dovetail_config.py | 13 | ||||
-rw-r--r-- | dovetail/utils/dovetail_utils.py | 28 | ||||
-rw-r--r-- | etc/conf/yardstick_config.yml | 10 | ||||
-rw-r--r-- | etc/userconfig/pod.yaml.sample | 26 |
5 files changed, 125 insertions, 8 deletions
diff --git a/dovetail/test_runner.py b/dovetail/test_runner.py index d2697f6d..934efb74 100644 --- a/dovetail/test_runner.py +++ b/dovetail/test_runner.py @@ -7,13 +7,18 @@ # http://www.apache.org/licenses/LICENSE-2.0 # -import os import json -import utils.dovetail_utils as dt_utils -import utils.dovetail_logger as dt_logger -from utils.dovetail_config import DovetailConfig as dt_cfg +import os + +import jinja2 +import jinja2.meta +import yaml from 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 class DockerRunner(object): @@ -143,9 +148,52 @@ class FunctestRunner(DockerRunner): 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) + + @staticmethod + def _render(task_template, **kwargs): + return jinja2.Template(task_template).render(**kwargs) + + @staticmethod + def _add_testcase_info(testcase, config_item=None): + if not config_item: + config_item = {} + config_item['validate_testcase'] = testcase.validate_testcase() + config_item['testcase'] = testcase.name() + return config_item + + def _update_yardstick_config(self, testcase): + 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): + return None + try: + process_info = pod_info['process_info'] + except KeyError as e: + 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) + dt_cfg.dovetail_config.update(full_task_yaml) + return dt_cfg.dovetail_config class BottlenecksRunner(DockerRunner): diff --git a/dovetail/utils/dovetail_config.py b/dovetail/utils/dovetail_config.py index d3b54192..b152cc8a 100644 --- a/dovetail/utils/dovetail_config.py +++ b/dovetail/utils/dovetail_config.py @@ -21,9 +21,16 @@ class DovetailConfig(object): cls.dovetail_config = yaml.safe_load(f) for extra_config_file in cls.dovetail_config['include_config']: - with open(os.path.join(conf_path, extra_config_file)) as f: - extra_config = yaml.safe_load(f) - cls.dovetail_config.update(extra_config) + + # The yardstick config file needs to be parsed later. + # Because it's related to the exact test case. + if extra_config_file.startswith("yardstick"): + continue + else: + file_path = os.path.join(conf_path, extra_config_file) + with open(file_path) as f: + extra_config = yaml.safe_load(f) + cls.dovetail_config.update(extra_config) path = os.path.join(conf_path, cls.dovetail_config['cli_file_name']) with open(path) as f: diff --git a/dovetail/utils/dovetail_utils.py b/dovetail/utils/dovetail_utils.py index 2c16ca71..be2974b6 100644 --- a/dovetail/utils/dovetail_utils.py +++ b/dovetail/utils/dovetail_utils.py @@ -379,3 +379,31 @@ def get_hosts_info(logger=None): logger.error("There is no key {} in file {}" .format(e, hosts_config_file)) return hosts_config + + +def read_yaml_file(file_path, logger=None): + if not os.path.isfile(file_path): + logger.error("File {} doesn't exist.".format(file_path)) + return None + try: + with open(file_path, 'r') as f: + content = yaml.safe_load(f) + return content + except Exception as e: + logger.exception("Failed to read file {}, exception: {}" + .format(file_path, e)) + return None + + +def read_plain_file(file_path, logger=None): + if not os.path.isfile(file_path): + logger.error("File {} doesn't exist.".format(file_path)) + return None + try: + with open(file_path, 'r') as f: + content = f.read() + return content + except Exception as e: + logger.exception("Failed to read file {}, exception: {}" + .format(file_path, e)) + return None diff --git a/etc/conf/yardstick_config.yml b/etc/conf/yardstick_config.yml index bbb2133e..1b924d85 100644 --- a/etc/conf/yardstick_config.yml +++ b/etc/conf/yardstick_config.yml @@ -1,4 +1,10 @@ --- + +{% set attack_host = attack_host or '' %} +{% set attack_process = attack_process or '' %} +{% set validate_testcase = validate_testcase or '' %} +{% set testcase = testcase or '' %} + yardstick: image_name: opnfv/yardstick docker_tag: opnfv-5.1.0 @@ -12,7 +18,9 @@ yardstick: - "cd /home/opnfv/repos/yardstick && source /etc/yardstick/openstack.creds && yardstick task start tests/opnfv/test_cases/{{validate_testcase}}.yaml --output-file /home/opnfv/yardstick/results/{{testcase}}.out - --task-args '{'file': '/home/opnfv/userconfig/pre_config/pod.yaml'}'" + --task-args '{'file': '/home/opnfv/userconfig/pre_config/pod.yaml', + 'attack_host': {{attack_host}}, + 'attack_process': {{attack_process}}}'" post_condition: - 'echo this is post_condition' result: diff --git a/etc/userconfig/pod.yaml.sample b/etc/userconfig/pod.yaml.sample index 26636a6b..71b276a5 100644 --- a/etc/userconfig/pod.yaml.sample +++ b/etc/userconfig/pod.yaml.sample @@ -48,3 +48,29 @@ nodes: ip: 10.1.0.54 user: root key_filename: /root/.ssh/id_rsa + +# The options of this section include: +# testcase_name: the name of test case +# attack_process: the name of the process this test case attempt to kill +# attack_host: one of the hosts given in section 'nodes' which is the primary host of attack_process +# +# if not set, it will use the default value of yardstick test case config +# the default attack_host of all test cases is 'node1' +# the default attack_process of all test cases are +# dovetail.ha.tc001: nova-api +# dovetail.ha.tc002: neutron-server +# dovetail.ha.tc003: keystone +# dovetail.ha.tc004: glance-api +# dovetail.ha.tc005: cinder-api +# dovetail.ha.tc008: haproxy +# dovetail.ha.tc010: rabbitmq-server +# dovetail.ha.tc011: neutron-l3-agent + +# process_info: +# - +# testcase_name: dovetail.ha.tc008 +# attack_host: node2 +# +# - +# testcase_name: dovetail.ha.tc010 +# attack_process: rabbitmq |