Merge "Assign static IP to VM for standalone context"
[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 import contexts
22 from yardstick.benchmark.contexts import base
23 from yardstick.benchmark.contexts.standalone import model
24 from yardstick.benchmark.contexts.standalone import sriov
25
26
27 class SriovContextTestCase(unittest.TestCase):
28
29     NODES_SAMPLE = "nodes_sample.yaml"
30     NODES_SRIOV_SAMPLE = "nodes_sriov_sample.yaml"
31     NODES_DUPLICATE_SAMPLE = "nodes_duplicate_sample.yaml"
32
33     ATTRS = {
34         'name': contexts.CONTEXT_STANDALONESRIOV,
35         'task_id': '1234567890',
36         'file': 'pod',
37         'flavor': {},
38         'servers': {},
39         'networks': {},
40     }
41
42     NETWORKS = {
43         'mgmt': {'cidr': '152.16.100.10/24'},
44         'private_0': {
45             'phy_port': "0000:05:00.0",
46             'vpci': "0000:00:07.0",
47             'cidr': '152.16.100.10/24',
48             'interface': 'if0',
49             'mac': "00:00:00:00:00:01",
50             'vf_pci': {'vf_pci': 0},
51             'gateway_ip': '152.16.100.20'},
52         'public_0': {
53             'phy_port': "0000:05:00.1",
54             'vpci': "0000:00:08.0",
55             'cidr': '152.16.40.10/24',
56             'interface': 'if0',
57             'vf_pci': {'vf_pci': 0},
58             'mac': "00:00:00:00:00:01",
59             'gateway_ip': '152.16.100.20'},
60     }
61
62     def setUp(self):
63         self.attrs = {
64             'name': 'foo',
65             'task_id': '1234567890',
66             'file': self._get_file_abspath(self.NODES_SRIOV_SAMPLE),
67         }
68         self.sriov = sriov.SriovContext()
69         self.addCleanup(self._remove_contexts)
70
71     @staticmethod
72     def _remove_contexts():
73         for context in base.Context.list:
74             context._delete_context()
75         base.Context.list = []
76
77     @mock.patch.object(model, 'StandaloneContextHelper')
78     @mock.patch.object(model, 'Libvirt')
79     @mock.patch.object(model, 'Server')
80     def test___init__(self, mock_helper, mock_libvirt, mock_server):
81         # pylint: disable=unused-argument
82         # NOTE(ralonsoh): this test doesn't cover function execution.
83         self.sriov.helper = mock_helper
84         self.sriov.vnf_node = mock_server
85         self.assertIsNone(self.sriov.file_path)
86         self.assertTrue(self.sriov.first_run)
87
88     def test_init(self):
89         self.sriov.helper.parse_pod_file = mock.Mock(return_value=[{}, {}, {}])
90         self.assertIsNone(self.sriov.init(self.ATTRS))
91
92     @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
93     def test_deploy(self, *args):
94         # NOTE(ralonsoh): this test doesn't cover function execution.
95         self.sriov.vm_deploy = False
96         self.assertIsNone(self.sriov.deploy())
97
98         self.sriov.vm_deploy = True
99         self.sriov.host_mgmt = {}
100         self.sriov.install_req_libs = mock.Mock()
101         self.sriov.get_nic_details = mock.Mock(return_value={})
102         self.sriov.setup_sriov_context = mock.Mock(return_value={})
103         self.sriov.wait_for_vnfs_to_start = mock.Mock(return_value={})
104         self.assertIsNone(self.sriov.deploy())
105
106     @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
107     @mock.patch.object(model, 'Libvirt')
108     def test_undeploy(self, mock_libvirt, mock_ssh):
109         # pylint: disable=unused-argument
110         # NOTE(ralonsoh): the pylint exception should be removed.
111         self.sriov.vm_deploy = False
112         self.assertIsNone(self.sriov.undeploy())
113
114         self.sriov.vm_deploy = True
115         self.sriov.connection = mock_ssh
116         self.sriov.vm_names = ['vm-0', 'vm-1']
117         self.sriov.drivers = ['vm-0', 'vm-1']
118         self.assertIsNone(self.sriov.undeploy())
119
120     def _get_file_abspath(self, filename):
121         curr_path = os.path.dirname(os.path.abspath(__file__))
122         file_path = os.path.join(curr_path, filename)
123         return file_path
124
125     def test__get_server_with_dic_attr_name(self):
126
127         self.sriov.init(self.attrs)
128
129         attr_name = {'name': 'foo.bar'}
130         result = self.sriov._get_server(attr_name)
131
132         self.assertEqual(result, None)
133
134     def test__get_server_not_found(self):
135
136         self.sriov.helper.parse_pod_file = mock.Mock(return_value=[{}, {}, {}])
137         self.sriov.init(self.attrs)
138
139         attr_name = 'bar.foo'
140         result = self.sriov._get_server(attr_name)
141
142         self.assertEqual(result, None)
143
144     def test__get_server_mismatch(self):
145
146         self.sriov.init(self.attrs)
147
148         attr_name = 'bar.foo1'
149         result = self.sriov._get_server(attr_name)
150
151         self.assertEqual(result, None)
152
153     def test__get_server_duplicate(self):
154
155         self.attrs['file'] = self._get_file_abspath(self.NODES_DUPLICATE_SAMPLE)
156
157         self.sriov.init(self.attrs)
158
159         attr_name = 'node1.foo-12345678'
160         with self.assertRaises(ValueError):
161             self.sriov._get_server(attr_name)
162
163     def test__get_server_found(self):
164
165         self.sriov.init(self.attrs)
166
167         attr_name = 'node1.foo-12345678'
168         result = self.sriov._get_server(attr_name)
169
170         self.assertEqual(result['ip'], '10.229.47.137')
171         self.assertEqual(result['name'], 'node1.foo-12345678')
172         self.assertEqual(result['user'], 'root')
173         self.assertEqual(result['key_filename'], '/root/.yardstick_key')
174
175     def test__get_physical_node_for_server(self):
176         attrs = self.attrs
177         attrs.update({'servers': {'server1': {}}})
178         self.sriov.init(attrs)
179
180         # When server is not from this context
181         result = self.sriov._get_physical_node_for_server('server1.another-context')
182         self.assertIsNone(result)
183
184         # When node_name is not from this context
185         result = self.sriov._get_physical_node_for_server('fake.foo-12345678')
186         self.assertIsNone(result)
187
188         result = self.sriov._get_physical_node_for_server('server1.foo-12345678')
189         self.assertEqual(result, 'node5.foo')
190
191     def test__get_server_no_task_id(self):
192         self.attrs['flags'] = {'no_setup': True}
193         self.sriov.init(self.attrs)
194
195         attr_name = 'node1.foo'
196         result = self.sriov._get_server(attr_name)
197
198         self.assertEqual(result['ip'], '10.229.47.137')
199         self.assertEqual(result['name'], 'node1.foo')
200         self.assertEqual(result['user'], 'root')
201         self.assertEqual(result['key_filename'], '/root/.yardstick_key')
202
203     # TODO(elfoley): Split this test
204     # There are at least two sets of inputs/outputs
205     def test__get_network(self):
206         network1 = {
207             'name': 'net_1',
208             'vld_id': 'vld111',
209             'segmentation_id': 'seg54',
210             'network_type': 'type_a',
211             'physical_network': 'phys',
212         }
213         network2 = {
214             'name': 'net_2',
215             'vld_id': 'vld999',
216         }
217         self.sriov.networks = {
218             'a': network1,
219             'b': network2,
220         }
221
222         attr_name = {}
223         self.assertIsNone(self.sriov._get_network(attr_name))
224
225         attr_name = {'vld_id': 'vld777'}
226         self.assertIsNone(self.sriov._get_network(attr_name))
227
228         self.assertIsNone(self.sriov._get_network(None))
229
230         attr_name = 'vld777'
231         self.assertIsNone(self.sriov._get_network(attr_name))
232
233         attr_name = {'vld_id': 'vld999'}
234         expected = {
235             "name": 'net_2',
236             "vld_id": 'vld999',
237             "segmentation_id": None,
238             "network_type": None,
239             "physical_network": None,
240         }
241         result = self.sriov._get_network(attr_name)
242         self.assertDictEqual(result, expected)
243
244         attr_name = 'a'
245         expected = network1
246         result = self.sriov._get_network(attr_name)
247         self.assertDictEqual(result, expected)
248
249     def test_configure_nics_for_sriov(self):
250         with mock.patch("yardstick.ssh.SSH") as ssh:
251             ssh_mock = mock.Mock(autospec=ssh.SSH)
252             ssh_mock.execute = \
253                 mock.Mock(return_value=(0, "a", ""))
254             ssh.return_value = ssh_mock
255         self.sriov.vm_deploy = True
256         self.sriov.connection = ssh_mock
257         self.sriov.vm_names = ['vm-0', 'vm-1']
258         self.sriov.drivers = []
259         self.sriov.networks = self.NETWORKS
260         self.sriov.helper.get_mac_address = mock.Mock(return_value="")
261         self.sriov._get_vf_data = mock.Mock(return_value="")
262         self.assertIsNone(self.sriov.configure_nics_for_sriov())
263
264     @mock.patch.object(ssh, 'SSH', return_value=(0, "a", ""))
265     @mock.patch.object(model.Libvirt, 'add_sriov_interfaces',
266                        return_value='out_xml')
267     def test__enable_interfaces(self, mock_add_sriov, mock_ssh):
268         self.sriov.vm_deploy = True
269         self.sriov.connection = mock_ssh
270         self.sriov.vm_names = ['vm-0', 'vm-1']
271         self.sriov.drivers = []
272         self.sriov.networks = self.NETWORKS
273         self.assertEqual(
274             'out_xml',
275             self.sriov._enable_interfaces(0, 0, ['private_0'], 'test'))
276         mock_add_sriov.assert_called_once_with(
277             '0000:00:0a.0', 0, self.NETWORKS['private_0']['mac'], 'test')
278
279     @mock.patch.object(model.StandaloneContextHelper, 'check_update_key')
280     @mock.patch.object(model.Libvirt, 'build_vm_xml')
281     @mock.patch.object(model.Libvirt, 'check_if_vm_exists_and_delete')
282     @mock.patch.object(model.Libvirt, 'write_file')
283     @mock.patch.object(model.Libvirt, 'virsh_create_vm')
284     def test_setup_sriov_context(self, mock_create_vm, mock_write_file, mock_check,
285                                  mock_build_vm_xml, mock_check_update_key):
286         self.sriov.servers = {
287             'vnf_0': {
288                 'network_ports': {
289                     'mgmt': {'cidr': '152.16.100.10/24'},
290                     'xe0': ['private_0'],
291                     'xe1': ['public_0']
292                 }
293             }
294         }
295         connection = mock.Mock()
296         self.sriov.connection = connection
297         self.sriov.host_mgmt = {'ip': '1.2.3.4'}
298         self.sriov.vm_flavor = 'flavor'
299         self.sriov.networks = 'networks'
300         self.sriov.configure_nics_for_sriov = mock.Mock()
301         self.sriov._name_task_id = 'fake_name'
302         cfg = '/tmp/vm_sriov_0.xml'
303         vm_name = 'vm-0'
304         mac = '00:00:00:00:00:01'
305         xml_out = mock.Mock()
306         mock_build_vm_xml.return_value = (xml_out, mac)
307         mock_check_update_key.return_value = 'node_2'
308         cdrom_img = '/var/lib/libvirt/images/cdrom-0.img'
309
310         with mock.patch.object(self.sriov, 'vnf_node') as mock_vnf_node, \
311                 mock.patch.object(self.sriov, '_enable_interfaces') as \
312                 mock_enable_interfaces:
313             mock_enable_interfaces.return_value = 'out_xml'
314             mock_vnf_node.generate_vnf_instance = mock.Mock(
315                 return_value='node_1')
316             nodes_out = self.sriov.setup_sriov_context()
317         mock_check_update_key.assert_called_once_with(connection, 'node_1', vm_name,
318                                                       self.sriov._name_task_id, cdrom_img,
319                                                       mac)
320         self.assertEqual(['node_2'], nodes_out)
321         mock_vnf_node.generate_vnf_instance.assert_called_once_with(
322             'flavor', 'networks', '1.2.3.4', 'vnf_0',
323             self.sriov.servers['vnf_0'], '00:00:00:00:00:01')
324         mock_build_vm_xml.assert_called_once_with(
325             connection, 'flavor', vm_name, 0, cdrom_img)
326         mock_create_vm.assert_called_once_with(connection, cfg)
327         mock_check.assert_called_once_with(vm_name, connection)
328         mock_write_file.assert_called_once_with(cfg, 'out_xml')
329         mock_enable_interfaces.assert_has_calls([
330             mock.call(0, mock.ANY, ['private_0'], mock.ANY),
331             mock.call(0, mock.ANY, ['public_0'], mock.ANY)], any_order=True)
332
333     def test__get_vf_data(self):
334         with mock.patch("yardstick.ssh.SSH") as ssh:
335             ssh_mock = mock.Mock(autospec=ssh.SSH)
336             ssh_mock.execute = \
337                 mock.Mock(return_value=(0, "a", ""))
338             ssh_mock.put = \
339                 mock.Mock(return_value=(0, "a", ""))
340             ssh.return_value = ssh_mock
341         self.sriov.vm_deploy = True
342         self.sriov.connection = ssh_mock
343         self.sriov.vm_names = ['vm-0', 'vm-1']
344         self.sriov.drivers = []
345         self.sriov.servers = {
346             'vnf_0': {
347                 'network_ports': {
348                     'mgmt': {'cidr': '152.16.100.10/24'},
349                     'xe0': ['private_0'],
350                     'xe1': ['public_0']
351                 }
352             }
353         }
354         self.sriov.networks = self.NETWORKS
355         self.sriov.helper.get_virtual_devices = mock.Mock(
356             return_value={'0000:00:01.0': ''})
357         self.assertIsNotNone(self.sriov._get_vf_data(
358             '0000:00:01.0', '00:00:00:00:00:01', 'if0'))