Merge "Testcase to find storage bottlenecks using Yardstick for Multistack"
[yardstick.git] / yardstick / tests / unit / benchmark / core / test_task.py
1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 import os
11
12 import mock
13 import unittest
14
15 from yardstick.benchmark.core import task
16 from yardstick.common import constants as consts
17
18
19 class TaskTestCase(unittest.TestCase):
20
21     @mock.patch.object(task, 'Context')
22     def test_parse_nodes_with_context_same_context(self, mock_context):
23         scenario_cfg = {
24             "nodes": {
25                 "host": "node1.LF",
26                 "target": "node2.LF"
27             }
28         }
29         server_info = {
30             "ip": "10.20.0.3",
31             "user": "root",
32             "key_filename": "/root/.ssh/id_rsa"
33         }
34         mock_context.get_server.return_value = server_info
35
36         context_cfg = task.parse_nodes_with_context(scenario_cfg)
37
38         self.assertEqual(context_cfg["host"], server_info)
39         self.assertEqual(context_cfg["target"], server_info)
40
41     def test_set_dispatchers(self):
42         t = task.Task()
43         output_config = {"DEFAULT": {"dispatcher": "file, http"}}
44         t._set_dispatchers(output_config)
45         self.assertEqual(output_config, output_config)
46
47     @mock.patch.object(task, 'DispatcherBase')
48     def test__do_output(self, mock_dispatcher):
49         t = task.Task()
50         output_config = {"DEFAULT": {"dispatcher": "file, http"}}
51         mock_dispatcher.get = mock.MagicMock(return_value=[mock.MagicMock(),
52                                                            mock.MagicMock()])
53         self.assertEqual(None, t._do_output(output_config, {}))
54
55     @mock.patch.object(task, 'Context')
56     def test_parse_networks_from_nodes(self, mock_context):
57         nodes = {
58             'node1': {
59                 'interfaces': {
60                     'mgmt': {
61                         'network_name': 'mgmt',
62                     },
63                     'xe0': {
64                         'network_name': 'uplink_0',
65                     },
66                     'xe1': {
67                         'network_name': 'downlink_0',
68                     },
69                 },
70             },
71             'node2': {
72                 'interfaces': {
73                     'mgmt': {
74                         'network_name': 'mgmt',
75                     },
76                     'uplink_0': {
77                         'network_name': 'uplink_0',
78                     },
79                     'downlink_0': {
80                         'network_name': 'downlink_0',
81                     },
82                 },
83             },
84         }
85
86         mock_context.get_network.side_effect = iter([
87             None,
88             {
89                 'name': 'mgmt',
90                 'network_type': 'flat',
91             },
92             {},
93             {
94                 'name': 'uplink_0',
95                 'subnet_cidr': '10.20.0.0/16',
96             },
97             {
98                 'name': 'downlink_0',
99                 'segmentation_id': '1001',
100             },
101             {
102                 'name': 'uplink_1',
103             },
104         ])
105
106         # one for each interface
107         expected_get_network_calls = 6
108         expected = {
109             'mgmt': {'name': 'mgmt', 'network_type': 'flat'},
110             'uplink_0': {'name': 'uplink_0', 'subnet_cidr': '10.20.0.0/16'},
111             'uplink_1': {'name': 'uplink_1'},
112             'downlink_0': {'name': 'downlink_0', 'segmentation_id': '1001'},
113         }
114
115         networks = task.get_networks_from_nodes(nodes)
116         self.assertEqual(mock_context.get_network.call_count, expected_get_network_calls)
117         self.assertDictEqual(networks, expected)
118
119     @mock.patch.object(task, 'Context')
120     @mock.patch.object(task, 'base_runner')
121     def test_run(self, mock_base_runner, *args):
122         scenario = {
123             'host': 'athena.demo',
124             'target': 'ares.demo',
125             'runner': {
126                 'duration': 60,
127                 'interval': 1,
128                 'type': 'Duration'
129             },
130             'type': 'Ping'
131         }
132
133         t = task.Task()
134         runner = mock.Mock()
135         runner.join.return_value = 0
136         runner.get_output.return_value = {}
137         runner.get_result.return_value = []
138         mock_base_runner.Runner.get.return_value = runner
139         t._run([scenario], False, "yardstick.out")
140         self.assertTrue(runner.run.called)
141
142     @mock.patch.object(os, 'environ')
143     def test_check_precondition(self, mock_os_environ):
144         cfg = {
145             'precondition': {
146                 'installer_type': 'compass',
147                 'deploy_scenarios': 'os-nosdn',
148                 'pod_name': 'huawei-pod1'
149             }
150         }
151
152         t = task.TaskParser('/opt')
153         mock_os_environ.get.side_effect = ['compass',
154                                            'os-nosdn',
155                                            'huawei-pod1']
156         result = t._check_precondition(cfg)
157         self.assertTrue(result)
158
159     def test_parse_suite_no_constraint_no_args(self):
160         SAMPLE_SCENARIO_PATH = "no_constraint_no_args_scenario_sample.yaml"
161         t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
162         with mock.patch.object(os, 'environ',
163                         new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
164             task_files, task_args, task_args_fnames = t.parse_suite()
165
166         self.assertEqual(task_files[0], self.change_to_abspath(
167                          'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
168         self.assertEqual(task_files[1], self.change_to_abspath(
169                          'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
170
171         self.assertIsNone(task_args[0])
172         self.assertIsNone(task_args[1])
173         self.assertIsNone(task_args_fnames[0])
174         self.assertIsNone(task_args_fnames[1])
175
176     def test_parse_suite_no_constraint_with_args(self):
177         SAMPLE_SCENARIO_PATH = "no_constraint_with_args_scenario_sample.yaml"
178         t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
179         with mock.patch.object(os, 'environ',
180                         new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
181             task_files, task_args, task_args_fnames = t.parse_suite()
182
183         self.assertEqual(task_files[0], self.change_to_abspath(
184                          'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
185         self.assertEqual(task_files[1], self.change_to_abspath(
186                          'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
187         self.assertIsNone(task_args[0])
188         self.assertEqual(task_args[1],
189                          '{"host": "node1.LF","target": "node2.LF"}')
190         self.assertIsNone(task_args_fnames[0])
191         self.assertIsNone(task_args_fnames[1])
192
193     def test_parse_suite_with_constraint_no_args(self):
194         SAMPLE_SCENARIO_PATH = "with_constraint_no_args_scenario_sample.yaml"
195         t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
196         with mock.patch.object(os, 'environ',
197                         new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
198             task_files, task_args, task_args_fnames = t.parse_suite()
199         self.assertEqual(task_files[0], self.change_to_abspath(
200                          'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
201         self.assertEqual(task_files[1], self.change_to_abspath(
202                          'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
203         self.assertIsNone(task_args[0])
204         self.assertIsNone(task_args[1])
205         self.assertIsNone(task_args_fnames[0])
206         self.assertIsNone(task_args_fnames[1])
207
208     def test_parse_suite_with_constraint_with_args(self):
209         SAMPLE_SCENARIO_PATH = "with_constraint_with_args_scenario_sample.yaml"
210         t = task.TaskParser(self._get_file_abspath(SAMPLE_SCENARIO_PATH))
211         with mock.patch('os.environ',
212                         new={'NODE_NAME': 'huawei-pod1', 'INSTALLER_TYPE': 'compass'}):
213             task_files, task_args, task_args_fnames = t.parse_suite()
214
215         self.assertEqual(task_files[0], self.change_to_abspath(
216                          'tests/opnfv/test_cases/opnfv_yardstick_tc037.yaml'))
217         self.assertEqual(task_files[1], self.change_to_abspath(
218                          'tests/opnfv/test_cases/opnfv_yardstick_tc043.yaml'))
219         self.assertIsNone(task_args[0])
220         self.assertEqual(task_args[1],
221                          '{"host": "node1.LF","target": "node2.LF"}')
222         self.assertIsNone(task_args_fnames[0])
223         self.assertIsNone(task_args_fnames[1])
224
225     def test_parse_options(self):
226         options = {
227             'openstack': {
228                 'EXTERNAL_NETWORK': '$network'
229             },
230             'nodes': ['node1', '$node'],
231             'host': '$host'
232         }
233
234         t = task.Task()
235         t.outputs = {
236             'network': 'ext-net',
237             'node': 'node2',
238             'host': 'server.yardstick'
239         }
240
241         expected_result = {
242             'openstack': {
243                 'EXTERNAL_NETWORK': 'ext-net'
244             },
245             'nodes': ['node1', 'node2'],
246             'host': 'server.yardstick'
247         }
248
249         actual_result = t._parse_options(options)
250         self.assertEqual(expected_result, actual_result)
251
252
253     def test_change_server_name_host_str(self):
254         scenario = {'host': 'demo'}
255         suffix = '-8'
256         task.change_server_name(scenario, suffix)
257         self.assertEqual('demo-8', scenario['host'])
258
259     def test_change_server_name_host_dict(self):
260         scenario = {'host': {'name': 'demo'}}
261         suffix = '-8'
262         task.change_server_name(scenario, suffix)
263         self.assertEqual('demo-8', scenario['host']['name'])
264
265     def test_change_server_name_target_str(self):
266         scenario = {'target': 'demo'}
267         suffix = '-8'
268         task.change_server_name(scenario, suffix)
269         self.assertEqual('demo-8', scenario['target'])
270
271     def test_change_server_name_target_dict(self):
272         scenario = {'target': {'name': 'demo'}}
273         suffix = '-8'
274         task.change_server_name(scenario, suffix)
275         self.assertEqual('demo-8', scenario['target']['name'])
276
277     @mock.patch('six.moves.builtins.open', side_effect=mock.mock_open())
278     @mock.patch.object(task, 'utils')
279     @mock.patch('logging.root')
280     def test_set_log(self, mock_logging_root, *args):
281         task_obj = task.Task()
282         task_obj.task_id = 'task_id'
283         task_obj._set_log()
284         mock_logging_root.addHandler.assert_called()
285
286     def _get_file_abspath(self, filename):
287         curr_path = os.path.dirname(os.path.abspath(__file__))
288         file_path = os.path.join(curr_path, filename)
289         return file_path
290
291     def change_to_abspath(self, filepath):
292         return os.path.join(consts.YARDSTICK_ROOT_PATH, filepath)
293
294
295 def main():
296     unittest.main()
297
298
299 if __name__ == '__main__':
300     main()