Merge "Replace assertEqual(x, True|False) with assert[True|False](x)"
[yardstick.git] / tests / unit / benchmark / contexts / standalone / test_model.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 copy
16 import os
17 import unittest
18 import mock
19
20 from xml.etree import ElementTree
21
22 from yardstick.benchmark.contexts.standalone.model import Libvirt
23 from yardstick.benchmark.contexts.standalone import model
24 from yardstick.network_services import utils
25
26
27 XML_SAMPLE = """<?xml version="1.0"?>
28 <domain type="kvm">
29     <devices>
30     </devices>
31 </domain>
32 """
33
34 XML_SAMPLE_INTERFACE = """<?xml version="1.0"?>
35 <domain type="kvm">
36     <devices>
37         <interface>
38         </interface>
39     </devices>
40 </domain>
41 """
42
43 class ModelLibvirtTestCase(unittest.TestCase):
44
45     def setUp(self):
46         self.xml = ElementTree.ElementTree(
47             element=ElementTree.fromstring(XML_SAMPLE))
48         self.pci_address_str = '0001:04:03.2'
49         self.pci_address = utils.PciAddress(self.pci_address_str)
50         self.mac = '00:00:00:00:00:01'
51         self._mock_write_xml = mock.patch.object(ElementTree.ElementTree,
52                                                  'write')
53         self.mock_write_xml = self._mock_write_xml.start()
54
55         self.addCleanup(self._cleanup)
56
57     def _cleanup(self):
58         self._mock_write_xml.stop()
59
60     def test_check_if_vm_exists_and_delete(self):
61         with mock.patch("yardstick.ssh.SSH") as ssh:
62             ssh_mock = mock.Mock(autospec=ssh.SSH)
63             ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
64             ssh.return_value = ssh_mock
65         # NOTE(ralonsoh): this test doesn't cover function execution.
66         model.Libvirt.check_if_vm_exists_and_delete("vm_0", ssh_mock)
67
68     def test_virsh_create_vm(self):
69         with mock.patch("yardstick.ssh.SSH") as ssh:
70             ssh_mock = mock.Mock(autospec=ssh.SSH)
71             ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
72             ssh.return_value = ssh_mock
73         # NOTE(ralonsoh): this test doesn't cover function execution.
74         model.Libvirt.virsh_create_vm(ssh_mock, "vm_0")
75
76     def test_virsh_destroy_vm(self):
77         with mock.patch("yardstick.ssh.SSH") as ssh:
78             ssh_mock = mock.Mock(autospec=ssh.SSH)
79             ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
80             ssh.return_value = ssh_mock
81         # NOTE(ralonsoh): this test doesn't cover function execution.
82         model.Libvirt.virsh_destroy_vm("vm_0", ssh_mock)
83
84     def test_add_interface_address(self):
85         xml = ElementTree.ElementTree(
86             element=ElementTree.fromstring(XML_SAMPLE_INTERFACE))
87         interface = xml.find('devices').find('interface')
88         result = model.Libvirt._add_interface_address(interface, self.pci_address)
89         self.assertEqual('pci', result.get('type'))
90         self.assertEqual('0x{}'.format(self.pci_address.domain),
91                          result.get('domain'))
92         self.assertEqual('0x{}'.format(self.pci_address.bus),
93                          result.get('bus'))
94         self.assertEqual('0x{}'.format(self.pci_address.slot),
95                          result.get('slot'))
96         self.assertEqual('0x{}'.format(self.pci_address.function),
97                          result.get('function'))
98
99     def test_add_ovs_interfaces(self):
100         xml_input = mock.Mock()
101         with mock.patch.object(ElementTree, 'parse', return_value=self.xml) \
102                 as mock_parse:
103             xml = copy.deepcopy(self.xml)
104             mock_parse.return_value = xml
105             model.Libvirt.add_ovs_interface(
106                 '/usr/local', 0, self.pci_address_str, self.mac, xml_input)
107             mock_parse.assert_called_once_with(xml_input)
108             self.mock_write_xml.assert_called_once_with(xml_input)
109             interface = xml.find('devices').find('interface')
110             self.assertEqual('vhostuser', interface.get('type'))
111             mac = interface.find('mac')
112             self.assertEqual(self.mac, mac.get('address'))
113             source = interface.find('source')
114             self.assertEqual('unix', source.get('type'))
115             self.assertEqual('/usr/local/var/run/openvswitch/dpdkvhostuser0',
116                              source.get('path'))
117             self.assertEqual('client', source.get('mode'))
118             _model = interface.find('model')
119             self.assertEqual('virtio', _model.get('type'))
120             driver = interface.find('driver')
121             self.assertEqual('4', driver.get('queues'))
122             host = driver.find('host')
123             self.assertEqual('off', host.get('mrg_rxbuf'))
124             self.assertIsNotNone(interface.find('address'))
125
126     def test_add_sriov_interfaces(self):
127         xml_input = mock.Mock()
128         with mock.patch.object(ElementTree, 'parse', return_value=self.xml) \
129                 as mock_parse:
130             xml = copy.deepcopy(self.xml)
131             mock_parse.return_value = xml
132             vm_pci = '0001:05:04.2'
133             model.Libvirt.add_sriov_interfaces(
134                 vm_pci, self.pci_address_str, self.mac, xml_input)
135             mock_parse.assert_called_once_with(xml_input)
136             self.mock_write_xml.assert_called_once_with(xml_input)
137             interface = xml.find('devices').find('interface')
138             self.assertEqual('yes', interface.get('managed'))
139             self.assertEqual('hostdev', interface.get('type'))
140             mac = interface.find('mac')
141             self.assertEqual(self.mac, mac.get('address'))
142             source = interface.find('source')
143             source_address = source.find('address')
144             self.assertIsNotNone(source.find('address'))
145
146             self.assertEqual('pci', source_address.get('type'))
147             self.assertEqual('0x' + self.pci_address_str.split(':')[0],
148                              source_address.get('domain'))
149             self.assertEqual('0x' + self.pci_address_str.split(':')[1],
150                              source_address.get('bus'))
151             self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[0],
152                              source_address.get('slot'))
153             self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[1],
154                              source_address.get('function'))
155
156             interface_address = interface.find('address')
157             self.assertEqual('pci', interface_address.get('type'))
158             self.assertEqual('0x' + vm_pci.split(':')[0],
159                              interface_address.get('domain'))
160             self.assertEqual('0x' + vm_pci.split(':')[1],
161                              interface_address.get('bus'))
162             self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[0],
163                              interface_address.get('slot'))
164             self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[1],
165                              interface_address.get('function'))
166
167     def test_create_snapshot_qemu(self):
168         result = "/var/lib/libvirt/images/0.qcow2"
169         with mock.patch("yardstick.ssh.SSH") as ssh:
170             ssh_mock = mock.Mock(autospec=ssh.SSH)
171             ssh_mock.execute = \
172                 mock.Mock(return_value=(0, "a", ""))
173             ssh.return_value = ssh_mock
174         image = model.Libvirt.create_snapshot_qemu(ssh_mock, "0", "ubuntu.img")
175         self.assertEqual(image, result)
176
177     @mock.patch.object(model.Libvirt, 'pin_vcpu_for_perf')
178     @mock.patch.object(model.Libvirt, 'create_snapshot_qemu')
179     def test_build_vm_xml(self, mock_create_snapshot_qemu,
180                           *args):
181         # NOTE(ralonsoh): this test doesn't cover function execution. This test
182         # should also check mocked function calls.
183         cfg_file = 'test_config_file.cfg'
184         self.addCleanup(os.remove, cfg_file)
185         result = [4]
186         with mock.patch("yardstick.ssh.SSH") as ssh:
187             ssh_mock = mock.Mock(autospec=ssh.SSH)
188             ssh_mock.execute = \
189                 mock.Mock(return_value=(0, "a", ""))
190             ssh.return_value = ssh_mock
191         mock_create_snapshot_qemu.return_value = "0.img"
192
193         status = model.Libvirt.build_vm_xml(ssh_mock, {}, cfg_file, 'vm_0', 0)
194         self.assertEqual(status[0], result[0])
195
196     def test_update_interrupts_hugepages_perf(self):
197         with mock.patch("yardstick.ssh.SSH") as ssh:
198             ssh_mock = mock.Mock(autospec=ssh.SSH)
199             ssh_mock.execute = \
200                 mock.Mock(return_value=(0, "a", ""))
201             ssh.return_value = ssh_mock
202         # NOTE(ralonsoh): 'update_interrupts_hugepages_perf' always return
203         # None, this check is trivial.
204         #status = Libvirt.update_interrupts_hugepages_perf(ssh_mock)
205         #self.assertIsNone(status)
206         Libvirt.update_interrupts_hugepages_perf(ssh_mock)
207
208     @mock.patch("yardstick.benchmark.contexts.standalone.model.CpuSysCores")
209     @mock.patch.object(model.Libvirt, 'update_interrupts_hugepages_perf')
210     def test_pin_vcpu_for_perf(self, *args):
211         # NOTE(ralonsoh): test mocked methods/variables.
212         with mock.patch("yardstick.ssh.SSH") as ssh:
213             ssh_mock = mock.Mock(autospec=ssh.SSH)
214             ssh_mock.execute = \
215                 mock.Mock(return_value=(0, "a", ""))
216             ssh.return_value = ssh_mock
217         status = Libvirt.pin_vcpu_for_perf(ssh_mock, 4)
218         self.assertIsNotNone(status)
219
220 class StandaloneContextHelperTestCase(unittest.TestCase):
221
222     NODE_SAMPLE = "nodes_sample.yaml"
223     NODE_SRIOV_SAMPLE = "nodes_sriov_sample.yaml"
224
225     NETWORKS = {
226         'mgmt': {'cidr': '152.16.100.10/24'},
227         'private_0': {
228          'phy_port': "0000:05:00.0",
229          'vpci': "0000:00:07.0",
230          'cidr': '152.16.100.10/24',
231          'gateway_ip': '152.16.100.20'},
232         'public_0': {
233          'phy_port': "0000:05:00.1",
234          'vpci': "0000:00:08.0",
235          'cidr': '152.16.40.10/24',
236          'gateway_ip': '152.16.100.20'}
237     }
238
239     def setUp(self):
240         self.helper = model.StandaloneContextHelper()
241
242     def test___init__(self):
243         self.assertIsNone(self.helper.file_path)
244
245     def test_install_req_libs(self):
246         with mock.patch("yardstick.ssh.SSH") as ssh:
247             ssh_mock = mock.Mock(autospec=ssh.SSH)
248             ssh_mock.execute = \
249                 mock.Mock(return_value=(1, "a", ""))
250             ssh.return_value = ssh_mock
251         # NOTE(ralonsoh): this test doesn't cover function execution. This test
252         # should also check mocked function calls.
253         model.StandaloneContextHelper.install_req_libs(ssh_mock)
254
255     def test_get_kernel_module(self):
256         with mock.patch("yardstick.ssh.SSH") as ssh:
257             ssh_mock = mock.Mock(autospec=ssh.SSH)
258             ssh_mock.execute = \
259                 mock.Mock(return_value=(1, "i40e", ""))
260             ssh.return_value = ssh_mock
261         # NOTE(ralonsoh): this test doesn't cover function execution. This test
262         # should also check mocked function calls.
263         model.StandaloneContextHelper.get_kernel_module(
264             ssh_mock, "05:00.0", None)
265
266     @mock.patch.object(model.StandaloneContextHelper, 'get_kernel_module')
267     def test_get_nic_details(self, mock_get_kernel_module):
268         with mock.patch("yardstick.ssh.SSH") as ssh:
269             ssh_mock = mock.Mock(autospec=ssh.SSH)
270             ssh_mock.execute = mock.Mock(return_value=(1, "i40e ixgbe", ""))
271             ssh.return_value = ssh_mock
272         mock_get_kernel_module.return_value = "i40e"
273         # NOTE(ralonsoh): this test doesn't cover function execution. This test
274         # should also check mocked function calls.
275         model.StandaloneContextHelper.get_nic_details(
276             ssh_mock, self.NETWORKS, 'dpdk-devbind.py')
277
278     def test_get_virtual_devices(self):
279         pattern = "PCI_SLOT_NAME=0000:05:00.0"
280         with mock.patch("yardstick.ssh.SSH") as ssh:
281             ssh_mock = mock.Mock(autospec=ssh.SSH)
282             ssh_mock.execute = \
283                     mock.Mock(return_value=(1, pattern, ""))
284             ssh.return_value = ssh_mock
285         # NOTE(ralonsoh): this test doesn't cover function execution. This test
286         # should also check mocked function calls.
287         model.StandaloneContextHelper.get_virtual_devices(
288             ssh_mock, '0000:00:05.0')
289
290     def _get_file_abspath(self, filename):
291         curr_path = os.path.dirname(os.path.abspath(__file__))
292         file_path = os.path.join(curr_path, filename)
293         return file_path
294
295     def test_read_config_file(self):
296         self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE)
297         status = self.helper.read_config_file()
298         self.assertIsNotNone(status)
299
300     def test_parse_pod_file(self):
301         self.helper.file_path = self._get_file_abspath("dummy")
302         self.assertRaises(IOError, self.helper.parse_pod_file,
303                           self.helper.file_path)
304
305         self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE)
306         self.assertRaises(TypeError, self.helper.parse_pod_file,
307                           self.helper.file_path)
308
309         self.helper.file_path = self._get_file_abspath(self.NODE_SRIOV_SAMPLE)
310         self.assertIsNotNone(self.helper.parse_pod_file(self.helper.file_path))
311
312     def test_get_mac_address(self):
313         status = model.StandaloneContextHelper.get_mac_address()
314         self.assertIsNotNone(status)
315
316     @mock.patch('yardstick.ssh.SSH')
317     def test_get_mgmt_ip(self, *args):
318         # NOTE(ralonsoh): test mocked methods/variables.
319         with mock.patch("yardstick.ssh.SSH") as ssh:
320             ssh_mock = mock.Mock(autospec=ssh.SSH)
321             ssh_mock.execute = mock.Mock(
322                 return_value=(1, "1.2.3.4 00:00:00:00:00:01", ""))
323             ssh.return_value = ssh_mock
324         # NOTE(ralonsoh): this test doesn't cover function execution. This test
325         # should also check mocked function calls.
326         status = model.StandaloneContextHelper.get_mgmt_ip(
327             ssh_mock, "00:00:00:00:00:01", "1.1.1.1/24", {})
328         self.assertIsNotNone(status)
329
330     @mock.patch('yardstick.ssh.SSH')
331     def test_get_mgmt_ip_no(self, *args):
332         # NOTE(ralonsoh): test mocked methods/variables.
333         with mock.patch("yardstick.ssh.SSH") as ssh:
334             ssh_mock = mock.Mock(autospec=ssh.SSH)
335             ssh_mock.execute = \
336                     mock.Mock(return_value=(1, "", ""))
337             ssh.return_value = ssh_mock
338         # NOTE(ralonsoh): this test doesn't cover function execution. This test
339         # should also check mocked function calls.
340         model.WAIT_FOR_BOOT = 0
341         status = model.StandaloneContextHelper.get_mgmt_ip(
342             ssh_mock, "99", "1.1.1.1/24", {})
343         self.assertIsNone(status)
344
345
346 class ServerTestCase(unittest.TestCase):
347
348     NETWORKS = {
349         'mgmt': {'cidr': '152.16.100.10/24'},
350         'private_0': {
351          'phy_port': "0000:05:00.0",
352          'vpci': "0000:00:07.0",
353          'driver': 'i40e',
354          'mac': '',
355          'cidr': '152.16.100.10/24',
356          'gateway_ip': '152.16.100.20'},
357         'public_0': {
358          'phy_port': "0000:05:00.1",
359          'vpci': "0000:00:08.0",
360          'driver': 'i40e',
361          'mac': '',
362          'cidr': '152.16.40.10/24',
363          'gateway_ip': '152.16.100.20'}
364     }
365
366     def setUp(self):
367         self.server = model.Server()
368
369     def test___init__(self):
370         self.assertIsNotNone(self.server)
371
372     def test_build_vnf_interfaces(self):
373         vnf = {
374             "network_ports": {
375                 'mgmt': {'cidr': '152.16.100.10/24'},
376                 'xe0': ['private_0'],
377                 'xe1': ['public_0'],
378             }
379         }
380         status = model.Server.build_vnf_interfaces(vnf, self.NETWORKS)
381         self.assertIsNotNone(status)
382
383     def test_generate_vnf_instance(self):
384         vnf = {
385             "network_ports": {
386                 'mgmt': {'cidr': '152.16.100.10/24'},
387                 'xe0': ['private_0'],
388                 'xe1': ['public_0'],
389             }
390         }
391         status = self.server.generate_vnf_instance(
392             {}, self.NETWORKS, '1.1.1.1/24', 'vm_0', vnf, '00:00:00:00:00:01')
393         self.assertIsNotNone(status)
394
395 class OvsDeployTestCase(unittest.TestCase):
396
397     NETWORKS = {
398         'mgmt': {'cidr': '152.16.100.10/24'},
399         'private_0': {
400          'phy_port': "0000:05:00.0",
401          'vpci': "0000:00:07.0",
402          'driver': 'i40e',
403          'mac': '',
404          'cidr': '152.16.100.10/24',
405          'gateway_ip': '152.16.100.20'},
406         'public_0': {
407          'phy_port': "0000:05:00.1",
408          'vpci': "0000:00:08.0",
409          'driver': 'i40e',
410          'mac': '',
411          'cidr': '152.16.40.10/24',
412          'gateway_ip': '152.16.100.20'}
413     }
414     @mock.patch('yardstick.ssh.SSH')
415     def setUp(self, mock_ssh):
416         self.ovs_deploy = model.OvsDeploy(mock_ssh, '/tmp/dpdk-devbind.py', {})
417
418     def test___init__(self):
419         self.assertIsNotNone(self.ovs_deploy.connection)
420
421     @mock.patch('yardstick.benchmark.contexts.standalone.model.os')
422     def test_prerequisite(self, *args):
423         # NOTE(ralonsoh): this test should check mocked function calls.
424         self.ovs_deploy.helper = mock.Mock()
425         self.assertIsNone(self.ovs_deploy.prerequisite())
426
427     @mock.patch('yardstick.benchmark.contexts.standalone.model.os')
428     def test_prerequisite_2(self, *args):
429         # NOTE(ralonsoh): this test should check mocked function calls. Rename
430         # this test properly.
431         self.ovs_deploy.helper = mock.Mock()
432         self.ovs_deploy.connection.execute = mock.Mock(
433             return_value=(1, '1.2.3.4 00:00:00:00:00:01', ''))
434         self.ovs_deploy.prerequisite = mock.Mock()
435         self.assertIsNone(self.ovs_deploy.ovs_deploy())