3 ##############################################################################
4 # Copyright (c) 2015-2017 Huawei Technologies Co.,Ltd and others.
6 # All rights reserved. This program and the accompanying materials
7 # are made available under the terms of the Apache License, Version 2.0
8 # which accompanies this distribution, and is available at
9 # http://www.apache.org/licenses/LICENSE-2.0
10 ##############################################################################
12 # Unittest for yardstick.benchmark.contexts.node
14 from __future__ import absolute_import
20 from yardstick.common import constants as consts
21 from yardstick.benchmark.contexts import node
24 class NodeContextTestCase(unittest.TestCase):
26 PREFIX = 'yardstick.benchmark.contexts.node'
28 NODES_SAMPLE = "nodes_sample.yaml"
29 NODES_DUPLICATE_SAMPLE = "nodes_duplicate_sample.yaml"
32 self.test_context = node.NodeContext()
33 self.os_path_join = os.path.join
35 def _get_file_abspath(self, filename):
36 curr_path = os.path.dirname(os.path.abspath(__file__))
37 file_path = self.os_path_join(curr_path, filename)
40 def test___init__(self):
41 self.assertIsNone(self.test_context.name)
42 self.assertIsNone(self.test_context.file_path)
43 self.assertEqual(self.test_context.nodes, [])
44 self.assertEqual(self.test_context.controllers, [])
45 self.assertEqual(self.test_context.computes, [])
46 self.assertEqual(self.test_context.baremetals, [])
47 self.assertEqual(self.test_context.env, {})
48 self.assertEqual(self.test_context.attrs, {})
50 @mock.patch('{}.os.path.join'.format(PREFIX))
51 def test_init_negative(self, mock_path_join):
52 special_path = '/foo/bar/error_file'
53 error_path = self._get_file_abspath("error_file")
56 if args == (consts.YARDSTICK_ROOT_PATH, error_path):
58 return self.os_path_join(*args)
60 # we can't count mock_path_join calls because
61 # it can catch join calls for .pyc files.
62 mock_path_join.side_effect = path_join
63 self.test_context.read_config_file = read_mock = mock.Mock()
66 with self.assertRaises(KeyError):
67 self.test_context.init({})
69 self.assertEqual(read_mock.call_count, read_calls)
75 read_mock.side_effect = IOError(errno.EBUSY, 'busy')
76 with self.assertRaises(IOError) as raised:
77 self.test_context.init(attrs)
80 self.assertEqual(read_mock.called, read_calls)
81 self.assertIn(attrs['file'], self.test_context.file_path)
82 self.assertEqual(raised.exception.errno, errno.EBUSY)
83 self.assertEqual(str(raised.exception), str(read_mock.side_effect))
85 read_mock.side_effect = IOError(errno.ENOENT, 'not found')
86 with self.assertRaises(IOError) as raised:
87 self.test_context.init(attrs)
90 self.assertEqual(read_mock.call_count, read_calls)
91 self.assertEqual(self.test_context.file_path, special_path)
92 self.assertEqual(raised.exception.errno, errno.ENOENT)
93 self.assertEqual(str(raised.exception), str(read_mock.side_effect))
95 def test_read_config_file(self):
99 'file': self._get_file_abspath(self.NODES_SAMPLE)
102 self.test_context.init(attrs)
104 self.assertIsNotNone(self.test_context.read_config_file())
106 def test__dispatch_script(self):
110 'file': self._get_file_abspath(self.NODES_SAMPLE)
113 self.test_context.init(attrs)
115 self.test_context.env = {'bash': [{'script': 'dummy'}]}
116 self.test_context._execute_script = mock.Mock()
117 self.assertEqual(self.test_context._dispatch_script('bash'), None)
119 def test__dispatch_ansible(self):
123 'file': self._get_file_abspath(self.NODES_SAMPLE)
126 self.test_context.init(attrs)
128 self.test_context.env = {'ansible': [{'script': 'dummy'}]}
129 self.test_context._do_ansible_job = mock.Mock()
130 self.assertEqual(self.test_context._dispatch_ansible('ansible'), None)
131 self.test_context.env = {}
132 self.assertEqual(self.test_context._dispatch_ansible('ansible'), None)
134 @mock.patch("{}.subprocess".format(PREFIX))
135 def test__do_ansible_job(self, mock_subprocess):
136 mock_subprocess.Popen = mock.MagicMock()
137 mock_subprocess.communicate = mock.Mock()
138 self.assertEqual(None, self.test_context._do_ansible_job('dummy'))
140 def test_successful_init(self):
144 'file': self._get_file_abspath(self.NODES_SAMPLE)
147 self.test_context.init(attrs)
149 self.assertEqual(self.test_context.name, "foo")
150 self.assertEqual(len(self.test_context.nodes), 4)
151 self.assertEqual(len(self.test_context.controllers), 2)
152 self.assertEqual(len(self.test_context.computes), 1)
153 self.assertEqual(self.test_context.computes[0]["name"], "node3")
154 self.assertEqual(len(self.test_context.baremetals), 1)
155 self.assertEqual(self.test_context.baremetals[0]["name"], "node4")
157 def test__get_server_with_dic_attr_name(self):
161 'file': self._get_file_abspath(self.NODES_SAMPLE)
164 self.test_context.init(attrs)
166 attr_name = {'name': 'foo.bar'}
167 result = self.test_context._get_server(attr_name)
169 self.assertEqual(result, None)
171 def test__get_server_not_found(self):
175 'file': self._get_file_abspath(self.NODES_SAMPLE)
178 self.test_context.init(attrs)
180 attr_name = 'bar.foo'
181 result = self.test_context._get_server(attr_name)
183 self.assertEqual(result, None)
185 def test__get_server_mismatch(self):
189 'file': self._get_file_abspath(self.NODES_SAMPLE)
192 self.test_context.init(attrs)
194 attr_name = 'bar.foo1'
195 result = self.test_context._get_server(attr_name)
197 self.assertEqual(result, None)
199 def test__get_server_duplicate(self):
203 'file': self._get_file_abspath(self.NODES_DUPLICATE_SAMPLE)
206 self.test_context.init(attrs)
208 attr_name = 'node1.foo'
209 with self.assertRaises(ValueError):
210 self.test_context._get_server(attr_name)
212 def test__get_server_found(self):
216 'file': self._get_file_abspath(self.NODES_SAMPLE)
219 self.test_context.init(attrs)
221 attr_name = 'node1.foo'
222 result = self.test_context._get_server(attr_name)
224 self.assertEqual(result['ip'], '10.229.47.137')
225 self.assertEqual(result['name'], 'node1.foo')
226 self.assertEqual(result['user'], 'root')
227 self.assertEqual(result['key_filename'], '/root/.yardstick_key')
229 @mock.patch('{}.NodeContext._dispatch_script'.format(PREFIX))
230 def test_deploy(self, dispatch_script_mock):
231 obj = node.NodeContext()
236 self.assertTrue(dispatch_script_mock.called)
238 @mock.patch('{}.NodeContext._dispatch_ansible'.format(PREFIX))
239 def test_deploy_anisible(self, dispatch_ansible_mock):
240 obj = node.NodeContext()
245 self.assertTrue(dispatch_ansible_mock.called)
247 @mock.patch('{}.NodeContext._dispatch_script'.format(PREFIX))
248 def test_undeploy(self, dispatch_script_mock):
249 obj = node.NodeContext()
254 self.assertTrue(dispatch_script_mock.called)
256 @mock.patch('{}.NodeContext._dispatch_ansible'.format(PREFIX))
257 def test_undeploy_anisble(self, dispatch_ansible_mock):
258 obj = node.NodeContext()
263 self.assertTrue(dispatch_ansible_mock.called)
265 @mock.patch('{}.ssh.SSH._put_file_shell'.format(PREFIX))
266 @mock.patch('{}.ssh.SSH.execute'.format(PREFIX))
267 def test_execute_remote_script(self, execute_mock, put_file_mock):
268 obj = node.NodeContext()
269 obj.env = {'prefix': 'yardstick.benchmark.scenarios.compute'}
270 node_name_args = 'node5'
272 'name': node_name_args,
278 info = {'script': 'computecapacity.bash'}
279 execute_mock.return_value = (0, '', '')
280 obj._execute_remote_script('node5', info)
282 self.assertTrue(put_file_mock.called)
283 self.assertTrue(execute_mock.called)
285 @mock.patch('{}.NodeContext._execute_local_script'.format(PREFIX))
286 def test_execute_script_local(self, local_execute_mock):
289 node.NodeContext()._execute_script(node_name, info)
290 self.assertTrue(local_execute_mock.called)
292 @mock.patch('{}.NodeContext._execute_remote_script'.format(PREFIX))
293 def test_execute_script_remote(self, remote_execute_mock):
296 node.NodeContext()._execute_script(node_name, info)
297 self.assertTrue(remote_execute_mock.called)
299 def test_get_script(self):
300 script_args = 'hello.bash'
302 'script': script_args
304 script, options = node.NodeContext()._get_script(info_args)
305 self.assertEqual(script_args, script)
306 self.assertEqual('', options)
308 def test_node_info(self):
309 node_name_args = 'node5'
310 obj = node.NodeContext()
311 obj.nodes = [{'name': node_name_args, 'check': node_name_args}]
312 node_info = obj._get_node_info(node_name_args)
313 self.assertEqual(node_info.get('check'), node_name_args)
315 @mock.patch('{}.ssh.SSH.wait'.format(PREFIX))
316 def test_get_client(self, wait_mock):
317 node_name_args = 'node5'
318 obj = node.NodeContext()
320 'name': node_name_args,
325 obj._get_client(node_name_args)
326 self.assertTrue(wait_mock.called)
328 def test_get_server(self):
329 self.test_context.name = 'vnf1'
330 self.test_context.nodes = [{'name': 'my', 'value': 100}]
332 with self.assertRaises(ValueError):
333 self.test_context.get_server('my.vnf2')
335 expected = {'name': 'my.vnf1', 'value': 100, 'interfaces': {}}
336 result = self.test_context.get_server('my.vnf1')
337 self.assertDictEqual(result, expected)
339 def test_get_context_from_server(self):
340 self.test_context.name = 'vnf1'
341 self.test_context.nodes = [{'name': 'my', 'value': 100}]
342 self.test_context.attrs = {'attr1': 200}
344 with self.assertRaises(ValueError):
345 self.test_context.get_context_from_server('my.vnf2')
347 result = self.test_context.get_context_from_server('my.vnf1')
348 self.assertIs(result, self.test_context)
350 def test__get_network(self):
354 'segmentation_id': 'seg54',
355 'network_type': 'type_a',
356 'physical_network': 'phys',
362 self.test_context.networks = {
368 self.assertIsNone(self.test_context._get_network(attr_name))
370 attr_name = {'vld_id': 'vld777'}
371 self.assertIsNone(self.test_context._get_network(attr_name))
373 self.assertIsNone(self.test_context._get_network(None))
376 self.assertIsNone(self.test_context._get_network(attr_name))
378 attr_name = {'vld_id': 'vld999'}
382 "segmentation_id": None,
383 "network_type": None,
384 "physical_network": None,
386 result = self.test_context._get_network(attr_name)
387 self.assertDictEqual(result, expected)
391 result = self.test_context._get_network(attr_name)
392 self.assertDictEqual(result, expected)
399 if __name__ == '__main__':