Merge "New storage test case: Bonnie++"
[yardstick.git] / tests / unit / benchmark / contexts / test_node.py
1 #!/usr/bin/env python
2
3 ##############################################################################
4 # Copyright (c) 2015-2017 Huawei Technologies Co.,Ltd and others.
5 #
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 ##############################################################################
11
12 # Unittest for yardstick.benchmark.contexts.node
13
14 from __future__ import absolute_import
15 import os
16 import unittest
17 import errno
18 import mock
19
20 from yardstick.common import constants as consts
21 from yardstick.benchmark.contexts import node
22
23
24 class NodeContextTestCase(unittest.TestCase):
25
26     PREFIX = 'yardstick.benchmark.contexts.node'
27
28     NODES_SAMPLE = "nodes_sample.yaml"
29     NODES_DUPLICATE_SAMPLE = "nodes_duplicate_sample.yaml"
30
31     def setUp(self):
32         self.test_context = node.NodeContext()
33         self.os_path_join = os.path.join
34
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)
38         return file_path
39
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, {})
49
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")
54
55         def path_join(*args):
56             if args == (consts.YARDSTICK_ROOT_PATH, error_path):
57                 return special_path
58             return self.os_path_join(*args)
59
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()
64         read_calls = 0
65
66         with self.assertRaises(KeyError):
67             self.test_context.init({})
68
69         self.assertEqual(read_mock.call_count, read_calls)
70
71         attrs = {
72             'name': 'foo',
73             'file': error_path,
74         }
75         read_mock.side_effect = IOError(errno.EBUSY, 'busy')
76         with self.assertRaises(IOError) as raised:
77             self.test_context.init(attrs)
78
79         read_calls += 1
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))
84
85         read_mock.side_effect = IOError(errno.ENOENT, 'not found')
86         with self.assertRaises(IOError) as raised:
87             self.test_context.init(attrs)
88
89         read_calls += 2
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))
94
95     def test_read_config_file(self):
96
97         attrs = {
98             'name': 'foo',
99             'file': self._get_file_abspath(self.NODES_SAMPLE)
100         }
101
102         self.test_context.init(attrs)
103
104         self.assertIsNotNone(self.test_context.read_config_file())
105
106     def test__dispatch_script(self):
107
108         attrs = {
109             'name': 'foo',
110             'file': self._get_file_abspath(self.NODES_SAMPLE)
111         }
112
113         self.test_context.init(attrs)
114
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)
118
119     def test__dispatch_ansible(self):
120
121         attrs = {
122             'name': 'foo',
123             'file': self._get_file_abspath(self.NODES_SAMPLE)
124         }
125
126         self.test_context.init(attrs)
127
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)
133
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'))
139
140     def test_successful_init(self):
141
142         attrs = {
143             'name': 'foo',
144             'file': self._get_file_abspath(self.NODES_SAMPLE)
145         }
146
147         self.test_context.init(attrs)
148
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")
156
157     def test__get_server_with_dic_attr_name(self):
158
159         attrs = {
160             'name': 'foo',
161             'file': self._get_file_abspath(self.NODES_SAMPLE)
162         }
163
164         self.test_context.init(attrs)
165
166         attr_name = {'name': 'foo.bar'}
167         result = self.test_context._get_server(attr_name)
168
169         self.assertEqual(result, None)
170
171     def test__get_server_not_found(self):
172
173         attrs = {
174             'name': 'foo',
175             'file': self._get_file_abspath(self.NODES_SAMPLE)
176         }
177
178         self.test_context.init(attrs)
179
180         attr_name = 'bar.foo'
181         result = self.test_context._get_server(attr_name)
182
183         self.assertEqual(result, None)
184
185     def test__get_server_mismatch(self):
186
187         attrs = {
188             'name': 'foo',
189             'file': self._get_file_abspath(self.NODES_SAMPLE)
190         }
191
192         self.test_context.init(attrs)
193
194         attr_name = 'bar.foo1'
195         result = self.test_context._get_server(attr_name)
196
197         self.assertEqual(result, None)
198
199     def test__get_server_duplicate(self):
200
201         attrs = {
202             'name': 'foo',
203             'file': self._get_file_abspath(self.NODES_DUPLICATE_SAMPLE)
204         }
205
206         self.test_context.init(attrs)
207
208         attr_name = 'node1.foo'
209         with self.assertRaises(ValueError):
210             self.test_context._get_server(attr_name)
211
212     def test__get_server_found(self):
213
214         attrs = {
215             'name': 'foo',
216             'file': self._get_file_abspath(self.NODES_SAMPLE)
217         }
218
219         self.test_context.init(attrs)
220
221         attr_name = 'node1.foo'
222         result = self.test_context._get_server(attr_name)
223
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')
228
229     @mock.patch('{}.NodeContext._dispatch_script'.format(PREFIX))
230     def test_deploy(self, dispatch_script_mock):
231         obj = node.NodeContext()
232         obj.env = {
233             'type': 'script'
234         }
235         obj.deploy()
236         self.assertTrue(dispatch_script_mock.called)
237
238     @mock.patch('{}.NodeContext._dispatch_ansible'.format(PREFIX))
239     def test_deploy_anisible(self, dispatch_ansible_mock):
240         obj = node.NodeContext()
241         obj.env = {
242             'type': 'ansible'
243         }
244         obj.deploy()
245         self.assertTrue(dispatch_ansible_mock.called)
246
247     @mock.patch('{}.NodeContext._dispatch_script'.format(PREFIX))
248     def test_undeploy(self, dispatch_script_mock):
249         obj = node.NodeContext()
250         obj.env = {
251             'type': 'script'
252         }
253         obj.undeploy()
254         self.assertTrue(dispatch_script_mock.called)
255
256     @mock.patch('{}.NodeContext._dispatch_ansible'.format(PREFIX))
257     def test_undeploy_anisble(self, dispatch_ansible_mock):
258         obj = node.NodeContext()
259         obj.env = {
260             'type': 'ansible'
261         }
262         obj.undeploy()
263         self.assertTrue(dispatch_ansible_mock.called)
264
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'
271         obj.nodes = [{
272             'name': node_name_args,
273             'user': 'ubuntu',
274             'ip': '10.10.10.10',
275             'pwd': 'ubuntu',
276         }]
277
278         info = {'script': 'computecapacity.bash'}
279         execute_mock.return_value = (0, '', '')
280         obj._execute_remote_script('node5', info)
281
282         self.assertTrue(put_file_mock.called)
283         self.assertTrue(execute_mock.called)
284
285     @mock.patch('{}.NodeContext._execute_local_script'.format(PREFIX))
286     def test_execute_script_local(self, local_execute_mock):
287         node_name = 'local'
288         info = {}
289         node.NodeContext()._execute_script(node_name, info)
290         self.assertTrue(local_execute_mock.called)
291
292     @mock.patch('{}.NodeContext._execute_remote_script'.format(PREFIX))
293     def test_execute_script_remote(self, remote_execute_mock):
294         node_name = 'node5'
295         info = {}
296         node.NodeContext()._execute_script(node_name, info)
297         self.assertTrue(remote_execute_mock.called)
298
299     def test_get_script(self):
300         script_args = 'hello.bash'
301         info_args = {
302             'script': script_args
303         }
304         script, options = node.NodeContext()._get_script(info_args)
305         self.assertEqual(script_args, script)
306         self.assertEqual('', options)
307
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)
314
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()
319         obj.nodes = [{
320             'name': node_name_args,
321             'user': 'ubuntu',
322             'ip': '10.10.10.10',
323             'pwd': 'ubuntu',
324         }]
325         obj._get_client(node_name_args)
326         self.assertTrue(wait_mock.called)
327
328     def test_get_server(self):
329         self.test_context.name = 'vnf1'
330         self.test_context.nodes = [{'name': 'my', 'value': 100}]
331
332         with self.assertRaises(ValueError):
333             self.test_context.get_server('my.vnf2')
334
335         expected = {'name': 'my.vnf1', 'value': 100, 'interfaces': {}}
336         result = self.test_context.get_server('my.vnf1')
337         self.assertDictEqual(result, expected)
338
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}
343
344         with self.assertRaises(ValueError):
345             self.test_context.get_context_from_server('my.vnf2')
346
347         result = self.test_context.get_context_from_server('my.vnf1')
348         self.assertIs(result, self.test_context)
349
350     def test__get_network(self):
351         network1 = {
352             'name': 'net_1',
353             'vld_id': 'vld111',
354             'segmentation_id': 'seg54',
355             'network_type': 'type_a',
356             'physical_network': 'phys',
357         }
358         network2 = {
359             'name': 'net_2',
360             'vld_id': 'vld999',
361         }
362         self.test_context.networks = {
363             'a': network1,
364             'b': network2,
365         }
366
367         attr_name = {}
368         self.assertIsNone(self.test_context._get_network(attr_name))
369
370         attr_name = {'vld_id': 'vld777'}
371         self.assertIsNone(self.test_context._get_network(attr_name))
372
373         self.assertIsNone(self.test_context._get_network(None))
374
375         attr_name = 'vld777'
376         self.assertIsNone(self.test_context._get_network(attr_name))
377
378         attr_name = {'vld_id': 'vld999'}
379         expected = {
380             "name": 'net_2',
381             "vld_id": 'vld999',
382             "segmentation_id": None,
383             "network_type": None,
384             "physical_network": None,
385         }
386         result = self.test_context._get_network(attr_name)
387         self.assertDictEqual(result, expected)
388
389         attr_name = 'a'
390         expected = network1
391         result = self.test_context._get_network(attr_name)
392         self.assertDictEqual(result, expected)
393
394
395 def main():
396     unittest.main()
397
398
399 if __name__ == '__main__':
400     main()