summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dovetail/test_runner.py56
-rw-r--r--dovetail/utils/dovetail_config.py13
-rw-r--r--dovetail/utils/dovetail_utils.py28
-rw-r--r--etc/conf/yardstick_config.yml10
-rw-r--r--etc/userconfig/pod.yaml.sample26
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