Merge "nsb_setup.sh fails to build DPDK"
[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.Libvirt, 'build_vm_xml')
280     @mock.patch.object(model.Libvirt, 'check_if_vm_exists_and_delete')
281     @mock.patch.object(model.Libvirt, 'write_file')
282     @mock.patch.object(model.Libvirt, 'virsh_create_vm')
283     def test_setup_sriov_context(self, mock_create_vm, mock_write_file,
284                                  mock_check, mock_build_vm_xml):
285         self.sriov.servers = {
286             'vnf_0': {
287                 'network_ports': {
288                     'mgmt': {'cidr': '152.16.100.10/24'},
289                     'xe0': ['private_0'],
290                     'xe1': ['public_0']
291                 }
292             }
293         }
294         connection = mock.Mock()
295         self.sriov.connection = connection
296         self.sriov.host_mgmt = {'ip': '1.2.3.4'}
297         self.sriov.vm_flavor = 'flavor'
298         self.sriov.networks = 'networks'
299         self.sriov.configure_nics_for_sriov = mock.Mock()
300         cfg = '/tmp/vm_sriov_0.xml'
301         vm_name = 'vm_0'
302         xml_out = mock.Mock()
303         mock_build_vm_xml.return_value = (xml_out, '00:00:00:00:00:01')
304
305         with mock.patch.object(self.sriov, 'vnf_node') as mock_vnf_node, \
306                 mock.patch.object(self.sriov, '_enable_interfaces') as \
307                 mock_enable_interfaces:
308             mock_enable_interfaces.return_value = 'out_xml'
309             mock_vnf_node.generate_vnf_instance = mock.Mock(
310                 return_value='node')
311             nodes_out = self.sriov.setup_sriov_context()
312         self.assertEqual(['node'], nodes_out)
313         mock_vnf_node.generate_vnf_instance.assert_called_once_with(
314             'flavor', 'networks', '1.2.3.4', 'vnf_0',
315             self.sriov.servers['vnf_0'], '00:00:00:00:00:01')
316         mock_build_vm_xml.assert_called_once_with(
317             connection, 'flavor', vm_name, 0)
318         mock_create_vm.assert_called_once_with(connection, cfg)
319         mock_check.assert_called_once_with(vm_name, connection)
320         mock_write_file.assert_called_once_with(cfg, 'out_xml')
321         mock_enable_interfaces.assert_has_calls([
322             mock.call(0, mock.ANY, ['private_0'], mock.ANY),
323             mock.call(0, mock.ANY, ['public_0'], mock.ANY)], any_order=True)
324
325     def test__get_vf_data(self):
326         with mock.patch("yardstick.ssh.SSH") as ssh:
327             ssh_mock = mock.Mock(autospec=ssh.SSH)
328             ssh_mock.execute = \
329                 mock.Mock(return_value=(0, "a", ""))
330             ssh_mock.put = \
331                 mock.Mock(return_value=(0, "a", ""))
332             ssh.return_value = ssh_mock
333         self.sriov.vm_deploy = True
334         self.sriov.connection = ssh_mock
335         self.sriov.vm_names = ['vm_0', 'vm_1']
336         self.sriov.drivers = []
337         self.sriov.servers = {
338             'vnf_0': {
339                 'network_ports': {
340                     'mgmt': {'cidr': '152.16.100.10/24'},
341                     'xe0': ['private_0'],
342                     'xe1': ['public_0']
343                 }
344             }
345         }
346         self.sriov.networks = self.NETWORKS
347         self.sriov.helper.get_virtual_devices = mock.Mock(
348             return_value={'0000:00:01.0': ''})
349         self.assertIsNotNone(self.sriov._get_vf_data(
350             '0000:00:01.0', '00:00:00:00:00:01', 'if0'))