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