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