Merge changes from topics 'YARDSTICK-1218', 'YARDSTICK-1216', 'YARDSTICK-1215', ...
[yardstick.git] / yardstick / tests / unit / benchmark / contexts / standalone / test_sriov.py
1 # Copyright (c) 2016-2017 Intel Corporation
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import os
16
17 import mock
18 import unittest
19
20 from yardstick import ssh
21 from yardstick.benchmark.contexts import base
22 from yardstick.benchmark.contexts.standalone import model
23 from yardstick.benchmark.contexts.standalone import sriov
24
25
26 class SriovContextTestCase(unittest.TestCase):
27
28     NODES_SAMPLE = "nodes_sample.yaml"
29     NODES_SRIOV_SAMPLE = "nodes_sriov_sample.yaml"
30     NODES_DUPLICATE_SAMPLE = "nodes_duplicate_sample.yaml"
31
32     ATTRS = {
33         'name': 'StandaloneSriov',
34         'task_id': '1234567890',
35         'file': 'pod',
36         'flavor': {},
37         'servers': {},
38         'networks': {},
39     }
40
41     NETWORKS = {
42         'mgmt': {'cidr': '152.16.100.10/24'},
43         'private_0': {
44             'phy_port': "0000:05:00.0",
45             'vpci': "0000:00:07.0",
46             'cidr': '152.16.100.10/24',
47             'interface': 'if0',
48             'mac': "00:00:00:00:00:01",
49             'vf_pci': {'vf_pci': 0},
50             'gateway_ip': '152.16.100.20'},
51         'public_0': {
52             'phy_port': "0000:05:00.1",
53             'vpci': "0000:00:08.0",
54             'cidr': '152.16.40.10/24',
55             'interface': 'if0',
56             'vf_pci': {'vf_pci': 0},
57             'mac': "00:00:00:00:00:01",
58             'gateway_ip': '152.16.100.20'},
59     }
60
61     def setUp(self):
62         self.attrs = {
63             'name': 'foo',
64             'task_id': '1234567890',
65             'file': self._get_file_abspath(self.NODES_SRIOV_SAMPLE)
66         }
67         self.sriov = sriov.SriovContext()
68         self.addCleanup(self._remove_contexts)
69
70     @staticmethod
71     def _remove_contexts():
72         for context in base.Context.list:
73             context._delete_context()
74         base.Context.list = []
75
76     @mock.patch.object(model, 'StandaloneContextHelper')
77     @mock.patch.object(model, 'Libvirt')
78     @mock.patch.object(model, 'Server')
79     def test___init__(self, mock_helper, mock_libvirt, mock_server):
80         # pylint: disable=unused-argument
81         # NOTE(ralonsoh): this test doesn't cover function execution.
82         self.sriov.helper = mock_helper
83         self.sriov.vnf_node = mock_server
84         self.assertIsNone(self.sriov.file_path)
85         self.assertTrue(self.sriov.first_run)
86
87     def test_init(self):
88         self.sriov.helper.parse_pod_file = mock.Mock(return_value=[{}, {}, {}])
89         self.assertIsNone(self.sriov.init(self.ATTRS))
90
91     @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
92     def test_deploy(self, *args):
93         # NOTE(ralonsoh): this test doesn't cover function execution.
94         self.sriov.vm_deploy = False
95         self.assertIsNone(self.sriov.deploy())
96
97         self.sriov.vm_deploy = True
98         self.sriov.host_mgmt = {}
99         self.sriov.install_req_libs = mock.Mock()
100         self.sriov.get_nic_details = mock.Mock(return_value={})
101         self.sriov.setup_sriov_context = mock.Mock(return_value={})
102         self.sriov.wait_for_vnfs_to_start = mock.Mock(return_value={})
103         self.assertIsNone(self.sriov.deploy())
104
105     @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
106     @mock.patch.object(model, 'Libvirt')
107     def test_undeploy(self, mock_libvirt, mock_ssh):
108         # pylint: disable=unused-argument
109         # NOTE(ralonsoh): the pylint exception should be removed.
110         self.sriov.vm_deploy = False
111         self.assertIsNone(self.sriov.undeploy())
112
113         self.sriov.vm_deploy = True
114         self.sriov.connection = mock_ssh
115         self.sriov.vm_names = ['vm_0', 'vm_1']
116         self.sriov.drivers = ['vm_0', 'vm_1']
117         self.assertIsNone(self.sriov.undeploy())
118
119     def _get_file_abspath(self, filename):
120         curr_path = os.path.dirname(os.path.abspath(__file__))
121         file_path = os.path.join(curr_path, filename)
122         return file_path
123
124     def test__get_server_with_dic_attr_name(self):
125
126         self.sriov.init(self.attrs)
127
128         attr_name = {'name': 'foo.bar'}
129         result = self.sriov._get_server(attr_name)
130
131         self.assertEqual(result, None)
132
133     def test__get_server_not_found(self):
134
135         self.sriov.helper.parse_pod_file = mock.Mock(return_value=[{}, {}, {}])
136         self.sriov.init(self.attrs)
137
138         attr_name = 'bar.foo'
139         result = self.sriov._get_server(attr_name)
140
141         self.assertEqual(result, None)
142
143     def test__get_server_mismatch(self):
144
145         self.sriov.init(self.attrs)
146
147         attr_name = 'bar.foo1'
148         result = self.sriov._get_server(attr_name)
149
150         self.assertEqual(result, None)
151
152     def test__get_server_duplicate(self):
153
154         self.attrs['file'] = self._get_file_abspath(self.NODES_DUPLICATE_SAMPLE)
155
156         self.sriov.init(self.attrs)
157
158         attr_name = 'node1.foo-12345678'
159         with self.assertRaises(ValueError):
160             self.sriov._get_server(attr_name)
161
162     def test__get_server_found(self):
163
164         self.sriov.init(self.attrs)
165
166         attr_name = 'node1.foo-12345678'
167         result = self.sriov._get_server(attr_name)
168
169         self.assertEqual(result['ip'], '10.229.47.137')
170         self.assertEqual(result['name'], 'node1.foo-12345678')
171         self.assertEqual(result['user'], 'root')
172         self.assertEqual(result['key_filename'], '/root/.yardstick_key')
173
174     def test__get_server_no_task_id(self):
175         self.attrs['flags'] = {'no_setup': True}
176         self.sriov.init(self.attrs)
177
178         attr_name = 'node1.foo'
179         result = self.sriov._get_server(attr_name)
180
181         self.assertEqual(result['ip'], '10.229.47.137')
182         self.assertEqual(result['name'], 'node1.foo')
183         self.assertEqual(result['user'], 'root')
184         self.assertEqual(result['key_filename'], '/root/.yardstick_key')
185
186     # TODO(elfoley): Split this test
187     # There are at least two sets of inputs/outputs
188     def test__get_network(self):
189         network1 = {
190             'name': 'net_1',
191             'vld_id': 'vld111',
192             'segmentation_id': 'seg54',
193             'network_type': 'type_a',
194             'physical_network': 'phys',
195         }
196         network2 = {
197             'name': 'net_2',
198             'vld_id': 'vld999',
199         }
200         self.sriov.networks = {
201             'a': network1,
202             'b': network2,
203         }
204
205         attr_name = {}
206         self.assertIsNone(self.sriov._get_network(attr_name))
207
208         attr_name = {'vld_id': 'vld777'}
209         self.assertIsNone(self.sriov._get_network(attr_name))
210
211         self.assertIsNone(self.sriov._get_network(None))
212
213         attr_name = 'vld777'
214         self.assertIsNone(self.sriov._get_network(attr_name))
215
216         attr_name = {'vld_id': 'vld999'}
217         expected = {
218             "name": 'net_2',
219             "vld_id": 'vld999',
220             "segmentation_id": None,
221             "network_type": None,
222             "physical_network": None,
223         }
224         result = self.sriov._get_network(attr_name)
225         self.assertDictEqual(result, expected)
226
227         attr_name = 'a'
228         expected = network1
229         result = self.sriov._get_network(attr_name)
230         self.assertDictEqual(result, expected)
231
232     def test_configure_nics_for_sriov(self):
233         with mock.patch("yardstick.ssh.SSH") as ssh:
234             ssh_mock = mock.Mock(autospec=ssh.SSH)
235             ssh_mock.execute = \
236                 mock.Mock(return_value=(0, "a", ""))
237             ssh.return_value = ssh_mock
238         self.sriov.vm_deploy = True
239         self.sriov.connection = ssh_mock
240         self.sriov.vm_names = ['vm_0', 'vm_1']
241         self.sriov.drivers = []
242         self.sriov.networks = self.NETWORKS
243         self.sriov.helper.get_mac_address = mock.Mock(return_value="")
244         self.sriov._get_vf_data = mock.Mock(return_value="")
245         self.assertIsNone(self.sriov.configure_nics_for_sriov())
246
247     @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
248     @mock.patch.object(model.Libvirt, 'add_sriov_interfaces',
249                        return_value='out_xml')
250     def test__enable_interfaces(self, mock_add_sriov, mock_ssh):
251         self.sriov.vm_deploy = True
252         self.sriov.connection = mock_ssh
253         self.sriov.vm_names = ['vm_0', 'vm_1']
254         self.sriov.drivers = []
255         self.sriov.networks = self.NETWORKS
256         self.assertEqual(
257             'out_xml',
258             self.sriov._enable_interfaces(0, 0, ['private_0'], 'test'))
259         mock_add_sriov.assert_called_once_with(
260             '0000:00:0a.0', 0, self.NETWORKS['private_0']['mac'], 'test')
261
262     @mock.patch.object(model.Libvirt, 'build_vm_xml')
263     @mock.patch.object(model.Libvirt, 'check_if_vm_exists_and_delete')
264     @mock.patch.object(model.Libvirt, 'write_file')
265     @mock.patch.object(model.Libvirt, 'virsh_create_vm')
266     def test_setup_sriov_context(self, mock_create_vm, mock_write_file,
267                                  mock_check, mock_build_vm_xml):
268         self.sriov.servers = {
269             'vnf_0': {
270                 'network_ports': {
271                     'mgmt': {'cidr': '152.16.100.10/24'},
272                     'xe0': ['private_0'],
273                     'xe1': ['public_0']
274                 }
275             }
276         }
277         connection = mock.Mock()
278         self.sriov.connection = connection
279         self.sriov.host_mgmt = {'ip': '1.2.3.4'}
280         self.sriov.vm_flavor = 'flavor'
281         self.sriov.networks = 'networks'
282         self.sriov.configure_nics_for_sriov = mock.Mock()
283         cfg = '/tmp/vm_sriov_0.xml'
284         vm_name = 'vm_0'
285         xml_out = mock.Mock()
286         mock_build_vm_xml.return_value = (xml_out, '00:00:00:00:00:01')
287
288         with mock.patch.object(self.sriov, 'vnf_node') as mock_vnf_node, \
289                 mock.patch.object(self.sriov, '_enable_interfaces') as \
290                 mock_enable_interfaces:
291             mock_enable_interfaces.return_value = 'out_xml'
292             mock_vnf_node.generate_vnf_instance = mock.Mock(
293                 return_value='node')
294             nodes_out = self.sriov.setup_sriov_context()
295         self.assertEqual(['node'], nodes_out)
296         mock_vnf_node.generate_vnf_instance.assert_called_once_with(
297             'flavor', 'networks', '1.2.3.4', 'vnf_0',
298             self.sriov.servers['vnf_0'], '00:00:00:00:00:01')
299         mock_build_vm_xml.assert_called_once_with(
300             connection, 'flavor', vm_name, 0)
301         mock_create_vm.assert_called_once_with(connection, cfg)
302         mock_check.assert_called_once_with(vm_name, connection)
303         mock_write_file.assert_called_once_with(cfg, 'out_xml')
304         mock_enable_interfaces.assert_has_calls([
305             mock.call(0, mock.ANY, ['private_0'], mock.ANY),
306             mock.call(0, mock.ANY, ['public_0'], mock.ANY)], any_order=True)
307
308     def test__get_vf_data(self):
309         with mock.patch("yardstick.ssh.SSH") as ssh:
310             ssh_mock = mock.Mock(autospec=ssh.SSH)
311             ssh_mock.execute = \
312                 mock.Mock(return_value=(0, "a", ""))
313             ssh_mock.put = \
314                 mock.Mock(return_value=(0, "a", ""))
315             ssh.return_value = ssh_mock
316         self.sriov.vm_deploy = True
317         self.sriov.connection = ssh_mock
318         self.sriov.vm_names = ['vm_0', 'vm_1']
319         self.sriov.drivers = []
320         self.sriov.servers = {
321             'vnf_0': {
322                 'network_ports': {
323                     'mgmt': {'cidr': '152.16.100.10/24'},
324                     'xe0': ['private_0'],
325                     'xe1': ['public_0']
326                 }
327             }
328         }
329         self.sriov.networks = self.NETWORKS
330         self.sriov.helper.get_virtual_devices = mock.Mock(
331             return_value={'0000:00:01.0': ''})
332         self.assertIsNotNone(self.sriov._get_vf_data(
333             '0000:00:01.0', '00:00:00:00:00:01', 'if0'))