aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick/tests/unit/benchmark/core
diff options
context:
space:
mode:
Diffstat (limited to 'yardstick/tests/unit/benchmark/core')
-rw-r--r--yardstick/tests/unit/benchmark/core/__init__.py0
-rw-r--r--yardstick/tests/unit/benchmark/core/no_constraint_no_args_scenario_sample.yaml21
-rw-r--r--yardstick/tests/unit/benchmark/core/no_constraint_with_args_scenario_sample.yaml23
-rw-r--r--yardstick/tests/unit/benchmark/core/test_plugin.py148
-rw-r--r--yardstick/tests/unit/benchmark/core/test_report.py584
-rw-r--r--yardstick/tests/unit/benchmark/core/test_task.py644
-rw-r--r--yardstick/tests/unit/benchmark/core/test_testcase.py35
-rw-r--r--yardstick/tests/unit/benchmark/core/with_constraint_no_args_scenario_sample.yaml24
-rw-r--r--yardstick/tests/unit/benchmark/core/with_constraint_with_args_scenario_sample.yaml26
9 files changed, 1505 insertions, 0 deletions
diff --git a/yardstick/tests/unit/benchmark/core/__init__.py b/yardstick/tests/unit/benchmark/core/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/core/__init__.py
diff --git a/yardstick/tests/unit/benchmark/core/no_constraint_no_args_scenario_sample.yaml b/yardstick/tests/unit/benchmark/core/no_constraint_no_args_scenario_sample.yaml
new file mode 100644
index 000000000..44c4a31ff
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/core/no_constraint_no_args_scenario_sample.yaml
@@ -0,0 +1,21 @@
+##############################################################################
+# Copyright (c) 2017 Huawei Technologies Co.,Ltd 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+# Huawei US bare daily task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "os-nosdn-nofeature-ha"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+ file_name: opnfv_yardstick_tc037.yaml
+-
+ file_name: opnfv_yardstick_tc043.yaml
+
diff --git a/yardstick/tests/unit/benchmark/core/no_constraint_with_args_scenario_sample.yaml b/yardstick/tests/unit/benchmark/core/no_constraint_with_args_scenario_sample.yaml
new file mode 100644
index 000000000..ced13f19e
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/core/no_constraint_with_args_scenario_sample.yaml
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright (c) 2017 Huawei Technologies Co.,Ltd 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+# Huawei US bare daily task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "os-nosdn-nofeature-ha"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+ file_name: opnfv_yardstick_tc037.yaml
+-
+ file_name: opnfv_yardstick_tc043.yaml
+ task_args:
+ huawei-pod1: '{"host": "node1.LF","target": "node2.LF"}'
+
diff --git a/yardstick/tests/unit/benchmark/core/test_plugin.py b/yardstick/tests/unit/benchmark/core/test_plugin.py
new file mode 100644
index 000000000..53621316b
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/core/test_plugin.py
@@ -0,0 +1,148 @@
+##############################################################################
+# Copyright (c) 2016 Huawei Technologies Co.,Ltd 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import copy
+import os
+import pkg_resources
+
+import mock
+import six
+import testtools
+
+from yardstick import ssh
+from yardstick.benchmark.core import plugin
+from yardstick.tests import fixture
+
+
+class PluginTestCase(testtools.TestCase):
+
+ FILE = """
+schema: "yardstick:plugin:0.1"
+
+plugins:
+ name: sample
+
+deployment:
+ ip: 10.1.0.50
+ user: root
+ password: root
+"""
+
+ NAME = 'sample'
+ DEPLOYMENT = {'ip': '10.1.0.50', 'user': 'root', 'password': 'root'}
+
+ def setUp(self):
+ super(PluginTestCase, self).setUp()
+ self.plugin_parser = plugin.PluginParser(mock.Mock())
+ self.plugin = plugin.Plugin()
+ self.useFixture(fixture.PluginParserFixture(PluginTestCase.FILE))
+
+ self._mock_ssh_from_node = mock.patch.object(ssh.SSH, 'from_node')
+ self.mock_ssh_from_node = self._mock_ssh_from_node.start()
+ self.mock_ssh_obj = mock.Mock()
+ self.mock_ssh_from_node.return_value = self.mock_ssh_obj
+ self.mock_ssh_obj.wait = mock.Mock()
+ self.mock_ssh_obj._put_file_shell = mock.Mock()
+ self._mock_log_info = mock.patch.object(plugin.LOG, 'info')
+ self.mock_log_info = self._mock_log_info.start()
+
+ self.addCleanup(self._cleanup)
+
+ def _cleanup(self):
+ self._mock_ssh_from_node.stop()
+ self._mock_log_info.stop()
+
+ @mock.patch.object(six.moves.builtins, 'print')
+ def test_install(self, *args):
+ args = mock.Mock()
+ args.input_file = [mock.Mock()]
+ with mock.patch.object(self.plugin, '_install_setup') as \
+ mock_install, \
+ mock.patch.object(self.plugin, '_run') as mock_run:
+ self.plugin.install(args)
+ mock_install.assert_called_once_with(PluginTestCase.NAME,
+ PluginTestCase.DEPLOYMENT)
+ mock_run.assert_called_once_with(PluginTestCase.NAME)
+
+ @mock.patch.object(six.moves.builtins, 'print')
+ def test_remove(self, *args):
+ args = mock.Mock()
+ args.input_file = [mock.Mock()]
+ with mock.patch.object(self.plugin, '_remove_setup') as \
+ mock_remove, \
+ mock.patch.object(self.plugin, '_run') as mock_run:
+ self.plugin.remove(args)
+ mock_remove.assert_called_once_with(PluginTestCase.NAME,
+ PluginTestCase.DEPLOYMENT)
+ mock_run.assert_called_once_with(PluginTestCase.NAME)
+
+ @mock.patch.object(pkg_resources, 'resource_filename',
+ return_value='script')
+ def test__install_setup(self, mock_resource_filename):
+ plugin_name = 'plugin_name'
+ self.plugin._install_setup(plugin_name, PluginTestCase.DEPLOYMENT)
+ mock_resource_filename.assert_called_once_with(
+ 'yardstick.resources', 'scripts/install/' + plugin_name + '.bash')
+ self.mock_ssh_from_node.assert_called_once_with(
+ PluginTestCase.DEPLOYMENT)
+ self.mock_ssh_obj.wait.assert_called_once_with(timeout=600)
+ self.mock_ssh_obj._put_file_shell.assert_called_once_with(
+ 'script', '~/{0}.sh'.format(plugin_name))
+
+ @mock.patch.object(pkg_resources, 'resource_filename',
+ return_value='script')
+ @mock.patch.object(os, 'environ', return_value='1.2.3.4')
+ def test__install_setup_with_ip_local(self, mock_os_environ,
+ mock_resource_filename):
+ plugin_name = 'plugin_name'
+ deployment = copy.deepcopy(PluginTestCase.DEPLOYMENT)
+ deployment['ip'] = 'local'
+ self.plugin._install_setup(plugin_name, deployment)
+ mock_os_environ.__getitem__.assert_called_once_with('JUMP_HOST_IP')
+ mock_resource_filename.assert_called_once_with(
+ 'yardstick.resources',
+ 'scripts/install/' + plugin_name + '.bash')
+ self.mock_ssh_from_node.assert_called_once_with(
+ deployment, overrides={'ip': os.environ["JUMP_HOST_IP"]})
+ self.mock_ssh_obj.wait.assert_called_once_with(timeout=600)
+ self.mock_ssh_obj._put_file_shell.assert_called_once_with(
+ 'script', '~/{0}.sh'.format(plugin_name))
+
+ @mock.patch.object(pkg_resources, 'resource_filename',
+ return_value='script')
+ def test__remove_setup(self, mock_resource_filename):
+ plugin_name = 'plugin_name'
+ self.plugin._remove_setup(plugin_name, PluginTestCase.DEPLOYMENT)
+ mock_resource_filename.assert_called_once_with(
+ 'yardstick.resources',
+ 'scripts/remove/' + plugin_name + '.bash')
+ self.mock_ssh_from_node.assert_called_once_with(
+ PluginTestCase.DEPLOYMENT)
+ self.mock_ssh_obj.wait.assert_called_once_with(timeout=600)
+ self.mock_ssh_obj._put_file_shell.assert_called_once_with(
+ 'script', '~/{0}.sh'.format(plugin_name))
+
+ @mock.patch.object(pkg_resources, 'resource_filename',
+ return_value='script')
+ @mock.patch.object(os, 'environ', return_value='1.2.3.4')
+ def test__remove_setup_with_ip_local(self, mock_os_environ,
+ mock_resource_filename):
+ plugin_name = 'plugin_name'
+ deployment = copy.deepcopy(PluginTestCase.DEPLOYMENT)
+ deployment['ip'] = 'local'
+ self.plugin._remove_setup(plugin_name, deployment)
+ mock_os_environ.__getitem__.assert_called_once_with('JUMP_HOST_IP')
+ mock_resource_filename.assert_called_once_with(
+ 'yardstick.resources',
+ 'scripts/remove/' + plugin_name + '.bash')
+ self.mock_ssh_from_node.assert_called_once_with(
+ deployment, overrides={'ip': os.environ["JUMP_HOST_IP"]})
+ self.mock_ssh_obj.wait.assert_called_once_with(timeout=600)
+ self.mock_ssh_obj._put_file_shell.mock_os_environ(
+ 'script', '~/{0}.sh'.format(plugin_name))
diff --git a/yardstick/tests/unit/benchmark/core/test_report.py b/yardstick/tests/unit/benchmark/core/test_report.py
new file mode 100644
index 000000000..89fb1e90a
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/core/test_report.py
@@ -0,0 +1,584 @@
+##############################################################################
+# Copyright (c) 2017 Rajesh Kudaka.
+# Copyright (c) 2018-2019 Intel Corporation.
+#
+# 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import mock
+import six
+import unittest
+import uuid
+
+from api.utils import influx
+from yardstick.benchmark.core import report
+from yardstick.cmd.commands import change_osloobj_to_paras
+
+GOOD_YAML_NAME = 'fake_name'
+GOOD_TASK_ID = str(uuid.uuid4())
+GOOD_DB_FIELDKEYS = [{'fieldKey': 'fake_key'}]
+GOOD_DB_METRICS = [{
+ 'fake_key': 1.234,
+ 'time': '0000-00-00T12:34:56.789012Z',
+ }]
+GOOD_TIMESTAMP = ['12:34:56.789012']
+BAD_YAML_NAME = 'F@KE_NAME'
+BAD_TASK_ID = 'aaaaaa-aaaaaaaa-aaaaaaaaaa-aaaaaa'
+MORE_DB_FIELDKEYS = [
+ {'fieldKey': 'fake_key'},
+ {'fieldKey': 'str_str'},
+ {'fieldKey': u'str_unicode'},
+ {u'fieldKey': 'unicode_str'},
+ {u'fieldKey': u'unicode_unicode'},
+ ]
+MORE_DB_METRICS = [{
+ 'fake_key': None,
+ 'time': '0000-00-00T00:00:00.000000Z',
+ }, {
+ 'fake_key': 123,
+ 'time': '0000-00-00T00:00:01.000000Z',
+ }, {
+ 'fake_key': 4.56,
+ 'time': '0000-00-00T00:00:02.000000Z',
+ }, {
+ 'fake_key': 9876543210987654321,
+ 'time': '0000-00-00T00:00:03.000000Z',
+ }, {
+ 'fake_key': 'str_str value',
+ 'time': '0000-00-00T00:00:04.000000Z',
+ }, {
+ 'fake_key': u'str_unicode value',
+ 'time': '0000-00-00T00:00:05.000000Z',
+ }, {
+ u'fake_key': 'unicode_str value',
+ 'time': '0000-00-00T00:00:06.000000Z',
+ }, {
+ u'fake_key': u'unicode_unicode value',
+ 'time': '0000-00-00T00:00:07.000000Z',
+ }, {
+ 'fake_key': '7.89',
+ 'time': '0000-00-00T00:00:08.000000Z',
+ }, {
+ 'fake_key': '1011',
+ 'time': '0000-00-00T00:00:09.000000Z',
+ }, {
+ 'fake_key': '9876543210123456789',
+ 'time': '0000-00-00T00:00:10.000000Z',
+ }]
+MORE_TIMESTAMP = ['00:00:%02d.000000' % n for n in range(len(MORE_DB_METRICS))]
+MORE_EMPTY_DATA = [None] * len(MORE_DB_METRICS)
+MORE_EXPECTED_TABLE_VALS = {
+ 'Timestamp': MORE_TIMESTAMP,
+ 'fake_key': [
+ None,
+ 123,
+ 4.56,
+ 9876543210987654321 if six.PY3 else 9.876543210987655e+18,
+ None,
+ None,
+ None,
+ None,
+ 7.89,
+ 1011,
+ 9876543210123456789 if six.PY3 else 9.876543210123457e+18,
+ ],
+ 'str_str': MORE_EMPTY_DATA,
+ 'str_unicode': MORE_EMPTY_DATA,
+ 'unicode_str': MORE_EMPTY_DATA,
+ 'unicode_unicode': MORE_EMPTY_DATA,
+ }
+MORE_EXPECTED_DATASETS = [{
+ 'label': key,
+ 'data': MORE_EXPECTED_TABLE_VALS[key],
+ }
+ for key in map(str, [field['fieldKey'] for field in MORE_DB_FIELDKEYS])
+ ]
+
+
+class JSTreeTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.jstree = report.JSTree()
+
+ def test__create_node(self):
+ _id = "tg__0.DropPackets"
+
+ expected_data = [
+ {"id": "tg__0", "text": "tg__0", "parent": "#"},
+ {"id": "tg__0.DropPackets", "text": "DropPackets", "parent": "tg__0"}
+ ]
+ self.jstree._create_node(_id)
+
+ self.assertEqual(self.jstree._created_nodes, ['#', 'tg__0', 'tg__0.DropPackets'])
+ self.assertEqual(self.jstree.jstree_data, expected_data)
+
+ def test_format_for_jstree(self):
+ data = [
+ 'tg__0.DropPackets',
+ 'tg__0.LatencyAvg.5', 'tg__0.LatencyAvg.6',
+ 'tg__0.LatencyMax.5', 'tg__0.LatencyMax.6',
+ 'tg__0.RxThroughput', 'tg__0.TxThroughput',
+ 'tg__1.DropPackets',
+ 'tg__1.LatencyAvg.5', 'tg__1.LatencyAvg.6',
+ 'tg__1.LatencyMax.5', 'tg__1.LatencyMax.6',
+ 'tg__1.RxThroughput', 'tg__1.TxThroughput',
+ 'vnf__0.curr_packets_in', 'vnf__0.packets_dropped', 'vnf__0.packets_fwd',
+ ]
+
+ expected_output = [
+ {"id": "tg__0", "text": "tg__0", "parent": "#"},
+ {"id": "tg__0.DropPackets", "text": "DropPackets", "parent": "tg__0"},
+ {"id": "tg__0.LatencyAvg", "text": "LatencyAvg", "parent": "tg__0"},
+ {"id": "tg__0.LatencyAvg.5", "text": "5", "parent": "tg__0.LatencyAvg"},
+ {"id": "tg__0.LatencyAvg.6", "text": "6", "parent": "tg__0.LatencyAvg"},
+ {"id": "tg__0.LatencyMax", "text": "LatencyMax", "parent": "tg__0"},
+ {"id": "tg__0.LatencyMax.5", "text": "5", "parent": "tg__0.LatencyMax"},
+ {"id": "tg__0.LatencyMax.6", "text": "6", "parent": "tg__0.LatencyMax"},
+ {"id": "tg__0.RxThroughput", "text": "RxThroughput", "parent": "tg__0"},
+ {"id": "tg__0.TxThroughput", "text": "TxThroughput", "parent": "tg__0"},
+ {"id": "tg__1", "text": "tg__1", "parent": "#"},
+ {"id": "tg__1.DropPackets", "text": "DropPackets", "parent": "tg__1"},
+ {"id": "tg__1.LatencyAvg", "text": "LatencyAvg", "parent": "tg__1"},
+ {"id": "tg__1.LatencyAvg.5", "text": "5", "parent": "tg__1.LatencyAvg"},
+ {"id": "tg__1.LatencyAvg.6", "text": "6", "parent": "tg__1.LatencyAvg"},
+ {"id": "tg__1.LatencyMax", "text": "LatencyMax", "parent": "tg__1"},
+ {"id": "tg__1.LatencyMax.5", "text": "5", "parent": "tg__1.LatencyMax"},
+ {"id": "tg__1.LatencyMax.6", "text": "6", "parent": "tg__1.LatencyMax"},
+ {"id": "tg__1.RxThroughput", "text": "RxThroughput", "parent": "tg__1"},
+ {"id": "tg__1.TxThroughput", "text": "TxThroughput", "parent": "tg__1"},
+ {"id": "vnf__0", "text": "vnf__0", "parent": "#"},
+ {"id": "vnf__0.curr_packets_in", "text": "curr_packets_in", "parent": "vnf__0"},
+ {"id": "vnf__0.packets_dropped", "text": "packets_dropped", "parent": "vnf__0"},
+ {"id": "vnf__0.packets_fwd", "text": "packets_fwd", "parent": "vnf__0"},
+ ]
+
+ result = self.jstree.format_for_jstree(data)
+ self.assertEqual(expected_output, result)
+
+
+class ReportTestCase(unittest.TestCase):
+
+ def setUp(self):
+ super(ReportTestCase, self).setUp()
+ self.param = change_osloobj_to_paras({})
+ self.param.yaml_name = [GOOD_YAML_NAME]
+ self.param.task_id = [GOOD_TASK_ID]
+ self.rep = report.Report()
+
+ def test___init__(self):
+ self.assertEqual([], self.rep.Timestamp)
+ self.assertEqual("", self.rep.yaml_name)
+ self.assertEqual("", self.rep.task_id)
+
+ def test__validate(self):
+ self.rep._validate(GOOD_YAML_NAME, GOOD_TASK_ID)
+ self.assertEqual(GOOD_YAML_NAME, self.rep.yaml_name)
+ self.assertEqual(GOOD_TASK_ID, str(self.rep.task_id))
+
+ def test__validate_invalid_yaml_name(self):
+ with six.assertRaisesRegex(self, ValueError, "yaml*"):
+ self.rep._validate(BAD_YAML_NAME, GOOD_TASK_ID)
+
+ def test__validate_invalid_task_id(self):
+ with six.assertRaisesRegex(self, ValueError, "task*"):
+ self.rep._validate(GOOD_YAML_NAME, BAD_TASK_ID)
+
+ @mock.patch.object(influx, 'query')
+ def test__get_fieldkeys(self, mock_query):
+ mock_query.return_value = GOOD_DB_FIELDKEYS
+ self.rep.yaml_name = GOOD_YAML_NAME
+ self.rep.task_id = GOOD_TASK_ID
+ self.assertEqual(GOOD_DB_FIELDKEYS, self.rep._get_fieldkeys())
+
+ @mock.patch.object(influx, 'query')
+ def test__get_fieldkeys_nodbclient(self, mock_query):
+ mock_query.side_effect = RuntimeError
+ self.assertRaises(RuntimeError, self.rep._get_fieldkeys)
+
+ @mock.patch.object(influx, 'query')
+ def test__get_fieldkeys_testcase_not_found(self, mock_query):
+ mock_query.return_value = []
+ self.rep.yaml_name = GOOD_YAML_NAME
+ self.rep.task_id = GOOD_TASK_ID
+ six.assertRaisesRegex(self, KeyError, "Test case", self.rep._get_fieldkeys)
+
+ @mock.patch.object(influx, 'query')
+ def test__get_metrics(self, mock_query):
+ mock_query.return_value = GOOD_DB_METRICS
+ self.rep.yaml_name = GOOD_YAML_NAME
+ self.rep.task_id = GOOD_TASK_ID
+ self.assertEqual(GOOD_DB_METRICS, self.rep._get_metrics())
+
+ @mock.patch.object(influx, 'query')
+ def test__get_metrics_task_not_found(self, mock_query):
+ mock_query.return_value = []
+ self.rep.yaml_name = GOOD_YAML_NAME
+ self.rep.task_id = GOOD_TASK_ID
+ six.assertRaisesRegex(self, KeyError, "Task ID", self.rep._get_metrics)
+
+ @mock.patch.object(influx, 'query')
+ def test__get_task_start_time(self, mock_query):
+ self.rep.yaml_name = GOOD_YAML_NAME
+ self.rep.task_id = GOOD_TASK_ID
+ mock_query.return_value = [{
+ u'free.memory0.used': u'9789088',
+ u'free.memory0.available': u'22192984',
+ u'free.memory0.shared': u'219152',
+ u'time': u'2019-01-22T16:20:14.568075776Z',
+ }]
+ expected = "2019-01-22T16:20:14.568075776Z"
+
+ self.assertEqual(
+ expected,
+ self.rep._get_task_start_time()
+ )
+
+ def test__get_task_start_time_task_not_found(self):
+ pass
+
+ @mock.patch.object(influx, 'query')
+ def test__get_task_end_time(self, mock_query):
+ self.rep.yaml_name = GOOD_YAML_NAME
+ self.rep.task_id = GOOD_TASK_ID
+ # TODO(elfoley): write this test!
+ mock_query.return_value = [{
+
+ }]
+
+ @mock.patch.object(influx, 'query')
+ def test__get_baro_metrics(self, mock_query):
+ self.rep.yaml_name = GOOD_YAML_NAME
+ self.rep.task_id = GOOD_TASK_ID
+ self.rep._get_task_start_time = mock.Mock(return_value=0)
+ self.rep._get_task_end_time = mock.Mock(return_value=0)
+
+ influx_return_values = ([{
+ u'value': 324050, u'instance': u'0', u'host': u'myhostname',
+ u'time': u'2018-12-19T14:11:25.383698038Z',
+ u'type_instance': u'user', u'type': u'cpu',
+ }, {
+ u'value': 193798, u'instance': u'0', u'host': u'myhostname',
+ u'time': u'2018-12-19T14:11:25.383712594Z',
+ u'type_instance': u'system', u'type': u'cpu',
+ }, {
+ u'value': 324051, u'instance': u'0', u'host': u'myhostname',
+ u'time': u'2018-12-19T14:11:35.383696624Z',
+ u'type_instance': u'user', u'type': u'cpu',
+ }, {
+ u'value': 193800, u'instance': u'0', u'host': u'myhostname',
+ u'time': u'2018-12-19T14:11:35.383713481Z',
+ u'type_instance': u'system', u'type': u'cpu',
+ }, {
+ u'value': 324054, u'instance': u'0', u'host': u'myhostname',
+ u'time': u'2018-12-19T14:11:45.3836966789Z',
+ u'type_instance': u'user', u'type': u'cpu',
+ }, {
+ u'value': 193801, u'instance': u'0', u'host': u'myhostname',
+ u'time': u'2018-12-19T14:11:45.383716296Z',
+ u'type_instance': u'system', u'type': u'cpu',
+ }],
+ [{
+ u'value': 3598453000, u'host': u'myhostname',
+ u'time': u'2018-12-19T14:11:25.383698038Z',
+ u'type_instance': u'0', u'type': u'cpufreq',
+ }, {
+ u'value': 3530250000, u'type_instance': u'0', u'host': u'myhostname',
+ u'time': u'2018-12-19T14:11:35.383712594Z', u'type': u'cpufreq',
+ }, {
+ u'value': 3600281000, u'type_instance': u'0', u'host': u'myhostname',
+ u'time': u'2018-12-19T14:11:45.383696624Z', u'type': u'cpufreq',
+ }],
+ )
+
+ def ret_vals(vals):
+ for x in vals:
+ yield x
+ while True:
+ yield []
+
+ mock_query.side_effect = ret_vals(influx_return_values)
+
+ BARO_EXPECTED_METRICS = {
+ 'Timestamp': [
+ '14:11:25.3836', '14:11:25.3837',
+ '14:11:35.3836', '14:11:35.3837',
+ '14:11:45.3836', '14:11:45.3837'],
+ 'myhostname.cpu_value.cpu.user.0': {
+ '14:11:25.3836': 324050,
+ '14:11:35.3836': 324051,
+ '14:11:45.3836': 324054,
+ },
+ 'myhostname.cpu_value.cpu.system.0': {
+ '14:11:25.3837': 193798,
+ '14:11:35.3837': 193800,
+ '14:11:45.3837': 193801,
+ },
+ 'myhostname.cpufreq_value.cpufreq.0': {
+ '14:11:25.3836': 3598453000,
+ '14:11:35.3837': 3530250000,
+ '14:11:45.3836': 3600281000,
+ }
+ }
+ self.assertEqual(
+ BARO_EXPECTED_METRICS,
+ self.rep._get_baro_metrics()
+ )
+
+ def test__get_timestamps(self):
+
+ metrics = MORE_DB_METRICS
+ self.assertEqual(
+ MORE_TIMESTAMP,
+ self.rep._get_timestamps(metrics)
+ )
+
+ def test__format_datasets(self):
+ metric_name = "free.memory0.used"
+ metrics = [{
+ u'free.memory1.free': u'1958664',
+ u'free.memory0.used': u'9789560',
+ }, {
+ u'free.memory1.free': u'1958228',
+ u'free.memory0.used': u'9789790',
+ }, {
+ u'free.memory1.free': u'1956156',
+ u'free.memory0.used': u'9791092',
+ }, {
+ u'free.memory1.free': u'1956280',
+ u'free.memory0.used': u'9790796',
+ }]
+ self.assertEqual(
+ [9789560, 9789790, 9791092, 9790796,],
+ self.rep._format_datasets(metric_name, metrics)
+ )
+
+ def test__format_datasets_val_none(self):
+ metric_name = "free.memory0.used"
+ metrics = [{
+ u'free.memory1.free': u'1958664',
+ u'free.memory0.used': 9876543109876543210,
+ }, {
+ u'free.memory1.free': u'1958228',
+ }, {
+ u'free.memory1.free': u'1956156',
+ u'free.memory0.used': u'9791092',
+ }, {
+ u'free.memory1.free': u'1956280',
+ u'free.memory0.used': u'9790796',
+ }]
+
+ exp0 = 9876543109876543210 if six.PY3 else 9.876543109876543e+18
+ self.assertEqual(
+ [exp0, None, 9791092, 9790796],
+ self.rep._format_datasets(metric_name, metrics)
+ )
+
+ def test__format_datasets_val_incompatible(self):
+ metric_name = "free.memory0.used"
+ metrics = [{
+ u'free.memory0.used': "some incompatible value",
+ }, {
+ }]
+ self.assertEqual(
+ [None, None],
+ self.rep._format_datasets(metric_name, metrics)
+ )
+
+ def test__combine_times(self):
+ yard_times = [
+ '00:00:00.000000',
+ '00:00:01.000000',
+ '00:00:02.000000',
+ '00:00:06.000000',
+ '00:00:08.000000',
+ '00:00:09.000000',
+ ]
+ baro_times = [
+ '00:00:01.000000',
+ '00:00:03.000000',
+ '00:00:04.000000',
+ '00:00:05.000000',
+ '00:00:07.000000',
+ '00:00:10.000000',
+ ]
+ expected_combo = [
+ '00:00:00.000000',
+ '00:00:01.000000',
+ '00:00:02.000000',
+ '00:00:03.000000',
+ '00:00:04.000000',
+ '00:00:05.000000',
+ '00:00:06.000000',
+ '00:00:07.000000',
+ '00:00:08.000000',
+ '00:00:09.000000',
+ '00:00:10.000000',
+ ]
+
+ actual_combo = self.rep._combine_times(yard_times, baro_times)
+ self.assertEqual(len(expected_combo), len(actual_combo))
+
+ self.assertEqual(
+ expected_combo,
+ actual_combo,
+ )
+
+ def test__combine_times_2(self):
+ time1 = ['14:11:25.383698', '14:11:25.383712', '14:11:35.383696',]
+ time2 = [
+ '16:20:14.568075', '16:20:24.575083',
+ '16:20:34.580989', '16:20:44.586801', ]
+ time_exp = [
+ '14:11:25.383698', '14:11:25.383712', '14:11:35.383696',
+ '16:20:14.568075', '16:20:24.575083', '16:20:34.580989',
+ '16:20:44.586801',
+ ]
+ self.assertEqual(time_exp, self.rep._combine_times(time1, time2))
+
+ def test__combine_metrics(self):
+ BARO_METRICS = {
+ 'myhostname.cpu_value.cpu.user.0': {
+ '14:11:25.3836': 324050, '14:11:35.3836': 324051,
+ '14:11:45.3836': 324054,
+ },
+ 'myhostname.cpu_value.cpu.system.0': {
+ '14:11:25.3837': 193798, '14:11:35.3837': 193800,
+ '14:11:45.3837': 193801,
+ }
+ }
+ BARO_TIMES = [
+ '14:11:25.3836', '14:11:25.3837', '14:11:35.3836',
+ '14:11:35.3837', '14:11:45.3836', '14:11:45.3837',
+ ]
+ YARD_METRICS = {
+ 'free.memory9.free': {
+ '16:20:14.5680': 1958244, '16:20:24.5750': 1955964,
+ '16:20:34.5809': 1956040, '16:20:44.5868': 1956428,
+ },
+ 'free.memory7.used': {
+ '16:20:14.5680': 9789068, '16:20:24.5750': 9791284,
+ '16:20:34.5809': 9791228, '16:20:44.5868': 9790692,
+ },
+ 'free.memory2.total':{
+ '16:20:14.5680': 32671288, '16:20:24.5750': 32671288,
+ '16:20:34.5809': 32671288, '16:20:44.5868': 32671288,
+ },
+ 'free.memory7.free': {
+ '16:20:14.5680': 1958368, '16:20:24.5750': 1956104,
+ '16:20:34.5809': 1956040, '16:20:44.5868': 1956552,
+ },
+ 'free.memory1.used': {
+ '16:20:14.5680': 9788872, '16:20:24.5750': 9789212,
+ '16:20:34.5809': 9791168, '16:20:44.5868': 9790996,
+ },
+ }
+ YARD_TIMES = [
+ '16:20:14.5680', '16:20:24.5750',
+ '16:20:34.5809', '16:20:44.5868',
+ ]
+
+ expected_output = {
+ 'myhostname.cpu_value.cpu.user.0': [{
+ 'x': '14:11:25.3836', 'y': 324050, }, {
+ 'x': '14:11:35.3836', 'y': 324051, }, {
+ 'x': '14:11:45.3836', 'y': 324054, }],
+ 'myhostname.cpu_value.cpu.system.0' : [{
+ 'x': '14:11:25.3837', 'y': 193798, }, {
+ 'x': '14:11:35.3837', 'y': 193800, }, {
+ 'x': '14:11:45.3837', 'y': 193801, }],
+ 'free.memory9.free': [{
+ 'x': '16:20:14.5680', 'y': 1958244, }, {
+ 'x': '16:20:24.5750', 'y': 1955964, }, {
+ 'x': '16:20:34.5809', 'y': 1956040, }, {
+ 'x': '16:20:44.5868', 'y': 1956428, }],
+ 'free.memory7.used': [{
+ 'x': '16:20:14.5680', 'y': 9789068, }, {
+ 'x': '16:20:24.5750', 'y': 9791284, }, {
+ 'x': '16:20:34.5809', 'y': 9791228, }, {
+ 'x': '16:20:44.5868', 'y': 9790692, }],
+ 'free.memory2.total': [{
+ 'x': '16:20:14.5680', 'y': 32671288, }, {
+ 'x': '16:20:24.5750', 'y': 32671288, }, {
+ 'x': '16:20:34.5809', 'y': 32671288, }, {
+ 'x': '16:20:44.5868', 'y': 32671288, }],
+ 'free.memory7.free': [{
+ 'x': '16:20:14.5680', 'y': 1958368, }, {
+ 'x': '16:20:24.5750', 'y': 1956104, }, {
+ 'x': '16:20:34.5809', 'y': 1956040, }, {
+ 'x': '16:20:44.5868', 'y': 1956552, }],
+ 'free.memory1.used': [{
+ 'x': '16:20:14.5680', 'y': 9788872, }, {
+ 'x': '16:20:24.5750', 'y': 9789212, }, {
+ 'x': '16:20:34.5809', 'y': 9791168, }, {
+ 'x': '16:20:44.5868', 'y': 9790996, }],
+ }
+
+ actual_output, _, _ = self.rep._combine_metrics(
+ BARO_METRICS, BARO_TIMES, YARD_METRICS, YARD_TIMES
+ )
+ self.assertEquals(
+ sorted(expected_output.keys()),
+ sorted(actual_output.keys())
+ )
+
+ self.assertEquals(
+ expected_output,
+ actual_output,
+ )
+
+ @mock.patch.object(report.Report, '_get_metrics')
+ @mock.patch.object(report.Report, '_get_fieldkeys')
+ def test__generate_common(self, mock_keys, mock_metrics):
+ mock_metrics.return_value = MORE_DB_METRICS
+ mock_keys.return_value = MORE_DB_FIELDKEYS
+ datasets, table_vals = self.rep._generate_common(self.param)
+ self.assertEqual(MORE_EXPECTED_DATASETS, datasets)
+ self.assertEqual(MORE_EXPECTED_TABLE_VALS, table_vals)
+
+ @mock.patch.object(report.Report, '_get_metrics')
+ @mock.patch.object(report.Report, '_get_fieldkeys')
+ @mock.patch.object(report.Report, '_validate')
+ def test_generate(self, mock_valid, mock_keys, mock_metrics):
+ mock_metrics.return_value = GOOD_DB_METRICS
+ mock_keys.return_value = GOOD_DB_FIELDKEYS
+ self.rep.generate(self.param)
+ mock_valid.assert_called_once_with(GOOD_YAML_NAME, GOOD_TASK_ID)
+ mock_metrics.assert_called_once_with()
+ mock_keys.assert_called_once_with()
+ self.assertEqual(GOOD_TIMESTAMP, self.rep.Timestamp)
+
+ @mock.patch.object(report.Report, '_get_baro_metrics')
+ @mock.patch.object(report.Report, '_get_metrics')
+ @mock.patch.object(report.Report, '_get_fieldkeys')
+ @mock.patch.object(report.Report, '_validate')
+ def test_generate_nsb(
+ self, mock_valid, mock_keys, mock_metrics, mock_baro_metrics):
+
+ mock_metrics.return_value = GOOD_DB_METRICS
+ mock_keys.return_value = GOOD_DB_FIELDKEYS
+ BARO_METRICS = {
+ # TODO: is timestamp needed here?
+ 'Timestamp': [
+ '14:11:25.383698', '14:11:25.383712', '14:11:35.383696',
+ '14:11:35.383713', '14:11:45.383700', '14:11:45.383716'],
+ 'myhostname.cpu_value.cpu.user.0': {
+ '14:11:25.383698': 324050,
+ '14:11:35.383696': 324051,
+ '14:11:45.383700': 324054,
+ },
+ 'myhostname.cpu_value.cpu.system.0': {
+ '14:11:25.383712': 193798,
+ '14:11:35.383713': 193800,
+ '14:11:45.383716': 193801,
+ }
+ }
+ mock_baro_metrics.return_value = BARO_METRICS
+
+ self.rep.generate_nsb(self.param)
+ mock_valid.assert_called_once_with(GOOD_YAML_NAME, GOOD_TASK_ID)
+ mock_metrics.assert_called_once_with()
+ mock_keys.assert_called_once_with()
+ self.assertEqual(GOOD_TIMESTAMP, self.rep.Timestamp)
diff --git a/yardstick/tests/unit/benchmark/core/test_task.py b/yardstick/tests/unit/benchmark/core/test_task.py
new file mode 100644
index 000000000..0f09b3e59
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/core/test_task.py
@@ -0,0 +1,644 @@
+##############################################################################
+# Copyright (c) 2015 Huawei Technologies Co.,Ltd 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import copy
+import io
+import logging
+import os
+import sys
+
+import mock
+import six
+from six.moves import builtins
+import unittest
+import uuid
+import collections
+
+from yardstick.benchmark.contexts import base
+from yardstick.benchmark.contexts import dummy
+from yardstick.benchmark.core import task
+from yardstick.common import constants as consts
+from yardstick.common import exceptions
+from yardstick.common import task_template
+from yardstick.common import utils
+
+
+class TaskTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self._mock_log = mock.patch.object(task, 'LOG')
+ self.mock_log = self._mock_log.start()
+ self.addCleanup(self._stop_mock)
+
+ def _stop_mock(self):
+ self._mock_log.stop()
+
+ @mock.patch.object(base, 'Context')
+ def test_parse_nodes_with_context_same_context(self, mock_context):
+ scenario_cfg = {
+ "nodes": {
+ "host": "node1.LF",
+ "target": "node2.LF"
+ }
+ }
+ server_info = {
+ "ip": "10.20.0.3",
+ "user": "root",
+ "key_filename": "/root/.ssh/id_rsa"
+ }
+ mock_context.get_server.return_value = server_info
+
+ context_cfg = task.parse_nodes_with_context(scenario_cfg)
+
+ self.assertEqual(context_cfg["host"], server_info)
+ self.assertEqual(context_cfg["target"], server_info)
+
+ def test_set_dispatchers(self):
+ t = task.Task()
+ output_config = {"DEFAULT": {"dispatcher": "file, http"}}
+ t._set_dispatchers(output_config)
+ self.assertEqual(output_config, output_config)
+
+ @mock.patch.object(task, 'DispatcherBase')
+ def test__do_output(self, mock_dispatcher):
+ t = task.Task()
+ output_config = {"DEFAULT": {"dispatcher": "file, http"}}
+
+ dispatcher1 = mock.MagicMock()
+ dispatcher1.__dispatcher_type__ = 'file'
+
+ dispatcher2 = mock.MagicMock()
+ dispatcher2.__dispatcher_type__ = 'http'
+
+ mock_dispatcher.get = mock.MagicMock(return_value=[dispatcher1,
+ dispatcher2])
+ self.assertIsNone(t._do_output(output_config, {}))
+
+ @mock.patch.object(base, 'Context')
+ def test_parse_networks_from_nodes(self, mock_context):
+ nodes = {
+ 'node1': {
+ 'interfaces': {
+ 'mgmt': {
+ 'network_name': 'mgmt',
+ },
+ 'xe0': {
+ 'network_name': 'uplink_0',
+ },
+ 'xe1': {
+ 'network_name': 'downlink_0',
+ },
+ },
+ },
+ 'node2': {
+ 'interfaces': {
+ 'mgmt': {
+ 'network_name': 'mgmt',
+ },
+ 'uplink_0': {
+ 'network_name': 'uplink_0',
+ },
+ 'downlink_0': {
+ 'network_name': 'downlink_0',
+ },
+ },
+ },
+ }
+
+ mock_context.get_network.side_effect = iter([
+ None,
+ {
+ 'name': 'mgmt',
+ 'network_type': 'flat',
+ },
+ {},
+ {
+ 'name': 'uplink_0',
+ 'subnet_cidr': '10.20.0.0/16',
+ },
+ {
+ 'name': 'downlink_0',
+ 'segmentation_id': '1001',
+ },
+ {
+ 'name': 'uplink_1',
+ },
+ ])
+
+ # one for each interface
+ expected_get_network_calls = 6
+ expected = {
+ 'mgmt': {'name': 'mgmt', 'network_type': 'flat'},
+ 'uplink_0': {'name': 'uplink_0', 'subnet_cidr': '10.20.0.0/16'},
+ 'uplink_1': {'name': 'uplink_1'},
+ 'downlink_0': {'name': 'downlink_0', 'segmentation_id': '1001'},
+ }
+
+ networks = task.get_networks_from_nodes(nodes)
+ self.assertEqual(mock_context.get_network.call_count, expected_get_network_calls)
+ self.assertDictEqual(networks, expected)
+
+ @mock.patch.object(base, 'Context')
+ @mock.patch.object(task, 'base_runner')
+ def test_run(self, mock_base_runner, *args):
+ scenario = {
+ 'host': 'athena.demo',
+ 'target': 'ares.demo',
+ 'runner': {
+ 'duration': 60,
+ 'interval': 1,
+ 'type': 'Duration'
+ },
+ 'type': 'Ping'
+ }
+
+ t = task.Task()
+ runner = mock.Mock()
+ runner.join.return_value = 0
+ runner.get_output.return_value = {}
+ runner.get_result.return_value = []
+ mock_base_runner.Runner.get.return_value = runner
+ t._run([scenario], False, "yardstick.out")
+ runner.run.assert_called_once()
+
+ @mock.patch.object(base, 'Context')
+ @mock.patch.object(task, 'base_runner')
+ def test_run_ProxDuration(self, mock_base_runner, *args):
+ scenario = {
+ 'host': 'athena.demo',
+ 'target': 'ares.demo',
+ 'runner': {
+ 'duration': 60,
+ 'interval': 1,
+ 'sampled': 'yes',
+ 'confirmation': 1,
+ 'type': 'ProxDuration'
+ },
+ 'type': 'Ping'
+ }
+
+ t = task.Task()
+ runner = mock.Mock()
+ runner.join.return_value = 0
+ runner.get_output.return_value = {}
+ runner.get_result.return_value = []
+ mock_base_runner.Runner.get.return_value = runner
+ t._run([scenario], False, "yardstick.out")
+ runner.run.assert_called_once()
+
+ @mock.patch.object(os, 'environ')
+ def test_check_precondition(self, mock_os_environ):
+ cfg = {
+ 'precondition': {
+ 'installer_type': 'compass',
+ 'deploy_scenarios': 'os-nosdn',
+ 'pod_name': 'huawei-pod1'
+ }
+ }
+
+ t = task.TaskParser('/opt')
+ mock_os_environ.get.side_effect = ['compass',
+ 'os-nosdn',
+ 'huawei-pod1']
+ result = t._check_precondition(cfg)
+ self.assertTrue(result)
+
+ def test_parse_suite_no_constraint_no_args(self):
+ SAMPLE_SCENARIO_PATH = "no_constraint_no_args_scenario_sample.yaml"
+ t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
+ with mock.patch.object(os, 'environ',
+ new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
+ task_files, task_args, task_args_fnames = t.parse_suite()
+
+ self.assertEqual(task_files[0], self.change_to_abspath(
+ 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
+ self.assertEqual(task_files[1], self.change_to_abspath(
+ 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
+ self.assertIsNone(task_args[0])
+ self.assertIsNone(task_args[1])
+ self.assertIsNone(task_args_fnames[0])
+ self.assertIsNone(task_args_fnames[1])
+
+ def test_parse_suite_no_constraint_with_args(self):
+ SAMPLE_SCENARIO_PATH = "no_constraint_with_args_scenario_sample.yaml"
+ t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
+ with mock.patch.object(os, 'environ',
+ new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
+ task_files, task_args, task_args_fnames = t.parse_suite()
+
+ self.assertEqual(task_files[0], self.change_to_abspath(
+ 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
+ self.assertEqual(task_files[1], self.change_to_abspath(
+ 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
+ self.assertIsNone(task_args[0])
+ self.assertEqual(task_args[1],
+ '{"host": "node1.LF","target": "node2.LF"}')
+ self.assertIsNone(task_args_fnames[0])
+ self.assertIsNone(task_args_fnames[1])
+
+ def test_parse_suite_with_constraint_no_args(self):
+ SAMPLE_SCENARIO_PATH = "with_constraint_no_args_scenario_sample.yaml"
+ t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
+ with mock.patch.object(os, 'environ',
+ new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
+ task_files, task_args, task_args_fnames = t.parse_suite()
+ self.assertEqual(task_files[0], self.change_to_abspath(
+ 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
+ self.assertEqual(task_files[1], self.change_to_abspath(
+ 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
+ self.assertIsNone(task_args[0])
+ self.assertIsNone(task_args[1])
+ self.assertIsNone(task_args_fnames[0])
+ self.assertIsNone(task_args_fnames[1])
+
+ def test_parse_suite_with_constraint_with_args(self):
+ SAMPLE_SCENARIO_PATH = "with_constraint_with_args_scenario_sample.yaml"
+ t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
+ with mock.patch('os.environ',
+ new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
+ task_files, task_args, task_args_fnames = t.parse_suite()
+
+ self.assertEqual(task_files[0], self.change_to_abspath(
+ 'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
+ self.assertEqual(task_files[1], self.change_to_abspath(
+ 'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
+ self.assertIsNone(task_args[0])
+ self.assertEqual(task_args[1],
+ '{"host": "node1.LF","target": "node2.LF"}')
+ self.assertIsNone(task_args_fnames[0])
+ self.assertIsNone(task_args_fnames[1])
+
+ def test_parse_options(self):
+ options = {
+ 'openstack': {
+ 'EXTERNAL_NETWORK': '$network'
+ },
+ 'nodes': ['node1', '$node'],
+ 'host': '$host'
+ }
+
+ t = task.Task()
+ t.outputs = {
+ 'network': 'ext-net',
+ 'node': 'node2',
+ 'host': 'server.yardstick'
+ }
+
+ expected_result = {
+ 'openstack': {
+ 'EXTERNAL_NETWORK': 'ext-net'
+ },
+ 'nodes': ['node1', 'node2'],
+ 'host': 'server.yardstick'
+ }
+
+ actual_result = t._parse_options(options)
+ self.assertEqual(expected_result, actual_result)
+
+ def test_parse_options_no_teardown(self):
+ options = {
+ 'openstack': {
+ 'EXTERNAL_NETWORK': '$network'
+ },
+ 'nodes': ['node1', '$node'],
+ 'host': '$host',
+ 'contexts' : {'name': "my-context",
+ 'no_teardown': True}
+ }
+
+ t = task.Task()
+ t.outputs = {
+ 'network': 'ext-net',
+ 'node': 'node2',
+ 'host': 'server.yardstick'
+ }
+
+ expected_result = {
+ 'openstack': {
+ 'EXTERNAL_NETWORK': 'ext-net'
+ },
+ 'nodes': ['node1', 'node2'],
+ 'host': 'server.yardstick',
+ 'contexts': {'name': 'my-context',
+ 'no_teardown': True,
+ }
+ }
+
+ actual_result = t._parse_options(options)
+ self.assertEqual(expected_result, actual_result)
+
+ @mock.patch.object(builtins, 'open', side_effect=mock.mock_open())
+ @mock.patch.object(task, 'utils')
+ @mock.patch.object(logging, 'root')
+ def test_set_log(self, mock_logging_root, *args):
+ task_obj = task.Task()
+ task_obj.task_id = 'task_id'
+ task_obj._set_log()
+ mock_logging_root.addHandler.assert_called()
+
+ def _get_file_abspath(self, filename):
+ curr_path = os.path.dirname(os.path.abspath(__file__))
+ file_path = os.path.join(curr_path, filename)
+ return file_path
+
+ def change_to_abspath(self, filepath):
+ return os.path.join(consts.YARDSTICK_ROOT_PATH, filepath)
+
+
+class TaskParserTestCase(unittest.TestCase):
+
+ TASK = """
+{% set value1 = value1 or 'var1' %}
+{% set value2 = value2 or 'var2' %}
+key1: {{ value1 }}
+key2:
+ - {{ value2 }}"""
+
+ TASK_RENDERED_1 = u"""
+
+
+key1: var1
+key2:
+ - var2"""
+
+ TASK_RENDERED_2 = u"""
+
+
+key1: var3
+key2:
+ - var4"""
+
+ def setUp(self):
+ self.parser = task.TaskParser('fake/path')
+ self.scenario = {
+ 'host': 'athena.demo',
+ 'target': 'kratos.demo',
+ 'targets': [
+ 'ares.demo', 'mars.demo'
+ ],
+ 'options': {
+ 'server_name': {
+ 'host': 'jupiter.demo',
+ 'target': 'saturn.demo',
+ },
+ },
+ 'nodes': {
+ 'tg__0': 'tg_0.demo',
+ 'vnf__0': 'vnf_0.demo',
+ }
+ }
+
+ @staticmethod
+ def _remove_contexts():
+ for context in base.Context.list:
+ context._delete_context()
+ base.Context.list = []
+
+ def test__change_node_names(self):
+
+ ctx_attrs = {
+ 'name': 'demo',
+ 'task_id': '1234567890',
+ 'servers': [
+ 'athena', 'kratos',
+ 'ares', 'mars',
+ 'jupiter', 'saturn',
+ 'tg_0', 'vnf_0'
+ ]
+ }
+
+ my_context = dummy.DummyContext()
+ self.addCleanup(self._remove_contexts)
+ my_context.init(ctx_attrs)
+
+ expected_scenario = {
+ 'host': 'athena.demo-12345678',
+ 'target': 'kratos.demo-12345678',
+ 'targets': [
+ 'ares.demo-12345678', 'mars.demo-12345678'
+ ],
+ 'options': {
+ 'server_name': {
+ 'host': 'jupiter.demo-12345678',
+ 'target': 'saturn.demo-12345678',
+ },
+ },
+ 'nodes': {
+ 'tg__0': 'tg_0.demo-12345678',
+ 'vnf__0': 'vnf_0.demo-12345678',
+ }
+ }
+
+ scenario = copy.deepcopy(self.scenario)
+
+ self.parser._change_node_names(scenario, [my_context])
+ self.assertEqual(scenario, expected_scenario)
+
+ def test__change_node_names_context_not_found(self):
+ scenario = copy.deepcopy(self.scenario)
+ self.assertRaises(exceptions.ScenarioConfigContextNameNotFound,
+ self.parser._change_node_names,
+ scenario, [])
+
+ def test__change_node_names_context_name_unchanged(self):
+ ctx_attrs = {
+ 'name': 'demo',
+ 'task_id': '1234567890',
+ 'flags': {
+ 'no_setup': True,
+ 'no_teardown': True
+ }
+ }
+
+ my_context = dummy.DummyContext()
+ self.addCleanup(self._remove_contexts)
+ my_context.init(ctx_attrs)
+
+ scenario = copy.deepcopy(self.scenario)
+ expected_scenario = copy.deepcopy(self.scenario)
+
+ self.parser._change_node_names(scenario, [my_context])
+ self.assertEqual(scenario, expected_scenario)
+
+ def test__change_node_names_options_empty(self):
+ ctx_attrs = {
+ 'name': 'demo',
+ 'task_id': '1234567890'
+ }
+
+ my_context = dummy.DummyContext()
+ self.addCleanup(self._remove_contexts)
+ my_context.init(ctx_attrs)
+ scenario = copy.deepcopy(self.scenario)
+ scenario['options'] = None
+
+ self.parser._change_node_names(scenario, [my_context])
+ self.assertIsNone(scenario['options'])
+
+ def test__change_node_names_options_server_name_empty(self):
+ ctx_attrs = {
+ 'name': 'demo',
+ 'task_id': '1234567890'
+ }
+
+ my_context = dummy.DummyContext()
+ self.addCleanup(self._remove_contexts)
+ my_context.init(ctx_attrs)
+ scenario = copy.deepcopy(self.scenario)
+ scenario['options']['server_name'] = None
+
+ self.parser._change_node_names(scenario, [my_context])
+ self.assertIsNone(scenario['options']['server_name'])
+
+ def test__change_node_names_target_map(self):
+ ctx_attrs = {
+ 'name': 'demo',
+ 'task_id': '1234567890'
+ }
+ my_context = dummy.DummyContext()
+ self.addCleanup(self._remove_contexts)
+ my_context.init(ctx_attrs)
+ scenario = copy.deepcopy(self.scenario)
+ scenario['nodes'] = {
+ 'tg__0': {
+ 'name': 'tg__0.demo',
+ 'public_ip_attr': "1.1.1.1",
+ },
+ 'vnf__0': {
+ 'name': 'vnf__0.demo',
+ 'public_ip_attr': "2.2.2.2",
+ }
+ }
+ self.parser._change_node_names(scenario, [my_context])
+ for target in scenario['nodes'].values():
+ self.assertIsInstance(target, collections.Mapping)
+
+ def test__change_node_names_not_target_map(self):
+ ctx_attrs = {
+ 'name': 'demo',
+ 'task_id': '1234567890'
+ }
+ my_context = dummy.DummyContext()
+ self.addCleanup(self._remove_contexts)
+ my_context.init(ctx_attrs)
+ scenario = copy.deepcopy(self.scenario)
+ self.parser._change_node_names(scenario, [my_context])
+ for target in scenario['nodes'].values():
+ self.assertNotIsInstance(target, collections.Mapping)
+
+ def test__parse_tasks(self):
+ task_obj = task.Task()
+ _uuid = uuid.uuid4()
+ task_obj.task_id = _uuid
+ task_files = ['/directory/task_file_name.yml']
+ mock_parser = mock.Mock()
+ mock_parser.parse_task.return_value = {'rendered': 'File content'}
+ mock_args = mock.Mock()
+ mock_args.render_only = False
+
+ tasks = task_obj._parse_tasks(mock_parser, task_files, mock_args,
+ ['arg1'], ['file_arg1'])
+ self.assertEqual(
+ [{'rendered': 'File content', 'case_name': 'task_file_name'}],
+ tasks)
+ mock_parser.parse_task.assert_called_once_with(
+ _uuid, 'arg1', 'file_arg1')
+
+ @mock.patch.object(sys, 'exit')
+ @mock.patch.object(utils, 'write_file')
+ @mock.patch.object(utils, 'makedirs')
+ def test__parse_tasks_render_only(self, mock_makedirs, mock_write_file,
+ mock_exit):
+ task_obj = task.Task()
+ _uuid = uuid.uuid4()
+ task_obj.task_id = _uuid
+ task_files = ['/directory/task_file_name.yml']
+ mock_parser = mock.Mock()
+ mock_parser.parse_task.return_value = {'rendered': 'File content'}
+ mock_args = mock.Mock()
+ mock_args.render_only = '/output_directory'
+
+ task_obj._parse_tasks(mock_parser, task_files, mock_args,
+ ['arg1'], ['file_arg1'])
+ mock_makedirs.assert_called_once_with('/output_directory')
+ mock_write_file.assert_called_once_with(
+ '/output_directory/000-task_file_name.yml', 'File content')
+ mock_exit.assert_called_once_with(0)
+
+ def test__render_task_no_args(self):
+ task_parser = task.TaskParser('task_file')
+ task_str = io.StringIO(six.text_type(self.TASK))
+ with mock.patch.object(six.moves.builtins, 'open',
+ return_value=task_str) as mock_open:
+ parsed, rendered = task_parser._render_task(None, None)
+
+ self.assertEqual(self.TASK_RENDERED_1, rendered)
+ self.assertEqual({'key1': 'var1', 'key2': ['var2']}, parsed)
+ mock_open.assert_called_once_with('task_file')
+
+ def test__render_task_arguments(self):
+ task_parser = task.TaskParser('task_file')
+ task_str = io.StringIO(six.text_type(self.TASK))
+ with mock.patch.object(six.moves.builtins, 'open',
+ return_value=task_str) as mock_open:
+ parsed, rendered = task_parser._render_task('value1: "var1"', None)
+
+ self.assertEqual(self.TASK_RENDERED_1, rendered)
+ self.assertEqual({'key1': 'var1', 'key2': ['var2']}, parsed)
+ mock_open.assert_called_once_with('task_file')
+
+ def test__render_task_file_arguments(self):
+ task_parser = task.TaskParser('task_file')
+ with mock.patch.object(six.moves.builtins, 'open') as mock_open:
+ mock_open.side_effect = (
+ io.StringIO(six.text_type('value2: var4')),
+ io.StringIO(six.text_type(self.TASK))
+ )
+ parsed, rendered = task_parser._render_task('value1: "var3"',
+ 'args_file')
+
+ self.assertEqual(self.TASK_RENDERED_2, rendered)
+ self.assertEqual({'key1': 'var3', 'key2': ['var4']}, parsed)
+ mock_open.assert_has_calls([mock.call('args_file'),
+ mock.call('task_file')])
+
+ @mock.patch.object(builtins, 'print')
+ def test__render_task_error_arguments(self, *args):
+ with self.assertRaises(exceptions.TaskRenderArgumentError):
+ task.TaskParser('task_file')._render_task('value1="var3"', None)
+
+ def test__render_task_error_task_file(self):
+ task_parser = task.TaskParser('task_file')
+ with mock.patch.object(six.moves.builtins, 'open') as mock_open:
+ mock_open.side_effect = (
+ io.StringIO(six.text_type('value2: var4')),
+ IOError()
+ )
+ with self.assertRaises(exceptions.TaskReadError):
+ task_parser._render_task('value1: "var3"', 'args_file')
+
+ mock_open.assert_has_calls([mock.call('args_file'),
+ mock.call('task_file')])
+
+ def test__render_task_render_error(self):
+ task_parser = task.TaskParser('task_file')
+ with mock.patch.object(six.moves.builtins, 'open') as mock_open, \
+ mock.patch.object(task_template.TaskTemplate, 'render',
+ side_effect=TypeError) as mock_render:
+ mock_open.side_effect = (
+ io.StringIO(six.text_type('value2: var4')),
+ io.StringIO(six.text_type(self.TASK))
+ )
+ with self.assertRaises(exceptions.TaskRenderError):
+ task_parser._render_task('value1: "var3"', 'args_file')
+
+ mock_open.assert_has_calls([mock.call('args_file'),
+ mock.call('task_file')])
+ mock_render.assert_has_calls(
+ [mock.call(self.TASK, value1='var3', value2='var4')])
diff --git a/yardstick/tests/unit/benchmark/core/test_testcase.py b/yardstick/tests/unit/benchmark/core/test_testcase.py
new file mode 100644
index 000000000..077848d77
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/core/test_testcase.py
@@ -0,0 +1,35 @@
+##############################################################################
+# Copyright (c) 2015 Huawei Technologies Co.,Ltd 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import mock
+from six.moves import builtins
+
+from yardstick.benchmark.core import testcase
+from yardstick.tests.unit import base as ut_base
+
+
+class Arg(object):
+
+ def __init__(self):
+ self.casename = ('opnfv_yardstick_tc001', )
+
+
+class TestcaseTestCase(ut_base.BaseUnitTestCase):
+
+ def test_list_all(self):
+ t = testcase.Testcase()
+ result = t.list_all("")
+ self.assertIsInstance(result, list)
+
+ @mock.patch.object(builtins, 'print')
+ def test_show(self, *args):
+ t = testcase.Testcase()
+ casename = Arg()
+ result = t.show(casename)
+ self.assertTrue(result)
diff --git a/yardstick/tests/unit/benchmark/core/with_constraint_no_args_scenario_sample.yaml b/yardstick/tests/unit/benchmark/core/with_constraint_no_args_scenario_sample.yaml
new file mode 100644
index 000000000..168d4b01a
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/core/with_constraint_no_args_scenario_sample.yaml
@@ -0,0 +1,24 @@
+##############################################################################
+# Copyright (c) 2017 Huawei Technologies Co.,Ltd 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+# Huawei US bare daily task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "os-nosdn-nofeature-ha"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+ file_name: opnfv_yardstick_tc037.yaml
+-
+ file_name: opnfv_yardstick_tc043.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+
diff --git a/yardstick/tests/unit/benchmark/core/with_constraint_with_args_scenario_sample.yaml b/yardstick/tests/unit/benchmark/core/with_constraint_with_args_scenario_sample.yaml
new file mode 100644
index 000000000..299e5de56
--- /dev/null
+++ b/yardstick/tests/unit/benchmark/core/with_constraint_with_args_scenario_sample.yaml
@@ -0,0 +1,26 @@
+##############################################################################
+# Copyright (c) 2017 Huawei Technologies Co.,Ltd 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
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+---
+# Huawei US bare daily task suite
+
+schema: "yardstick:suite:0.1"
+
+name: "os-nosdn-nofeature-ha"
+test_cases_dir: "tests/opnfv/test_cases/"
+test_cases:
+-
+ file_name: opnfv_yardstick_tc037.yaml
+-
+ file_name: opnfv_yardstick_tc043.yaml
+ constraint:
+ installer: compass
+ pod: huawei-pod1
+ task_args:
+ huawei-pod1: '{"host": "node1.LF","target": "node2.LF"}'
+