98d2b1836d6f3bf37fea03766bb7618f057651b4
[yardstick.git] / yardstick / 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 uuid
18
19 import mock
20 import unittest
21 from xml.etree import ElementTree
22
23 from yardstick import ssh
24 from yardstick.benchmark.contexts.standalone import model
25 from yardstick.common import exceptions
26 from yardstick import constants
27 from yardstick.network_services import utils
28
29
30 XML_SAMPLE = """<?xml version="1.0"?>
31 <domain type="kvm">
32     <devices>
33     </devices>
34 </domain>
35 """
36
37 XML_SAMPLE_INTERFACE = """<?xml version="1.0"?>
38 <domain type="kvm">
39     <devices>
40         <interface>
41         </interface>
42     </devices>
43 </domain>
44 """
45
46
47 class ModelLibvirtTestCase(unittest.TestCase):
48
49     XML_STR = model.VM_TEMPLATE.format(
50         vm_name="vm_name",
51         random_uuid=uuid.uuid4(),
52         mac_addr="00:01:02:03:04:05",
53         memory=2048, vcpu=2, cpu=2,
54         numa_cpus=0 - 10,
55         socket=1, threads=1,
56         vm_image="/var/lib/libvirt/images/yardstick-nsb-image.img",
57         cpuset=2 - 10, cputune='')
58
59     def setUp(self):
60         self.pci_address_str = '0001:04:03.2'
61         self.pci_address = utils.PciAddress(self.pci_address_str)
62         self.mac = '00:00:00:00:00:01'
63         self._mock_ssh = mock.Mock()
64         self.mock_ssh = self._mock_ssh.start()
65         self.addCleanup(self._cleanup)
66
67     def _cleanup(self):
68         self._mock_ssh.stop()
69
70     # TODO: Remove mocking of yardstick.ssh.SSH (here and elsewhere)
71     # In this case, we are mocking a param to be passed into other methods
72     # It can be a generic Mock() with return values set for the right methods
73     def test_check_if_vm_exists_and_delete(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.check_if_vm_exists_and_delete('vm-0', ssh_mock)
80
81     def test_virsh_create_vm(self):
82         self.mock_ssh.execute = mock.Mock(return_value=(0, 0, 0))
83         model.Libvirt.virsh_create_vm(self.mock_ssh, 'vm-0')
84         self.mock_ssh.execute.assert_called_once_with('virsh create vm-0')
85
86     def test_virsh_create_vm_error(self):
87         self.mock_ssh.execute = mock.Mock(return_value=(1, 0, 'error_create'))
88         with self.assertRaises(exceptions.LibvirtCreateError) as exc:
89             model.Libvirt.virsh_create_vm(self.mock_ssh, 'vm-0')
90         self.assertEqual('Error creating the virtual machine. Error: '
91                          'error_create.', str(exc.exception))
92         self.mock_ssh.execute.assert_called_once_with('virsh create vm-0')
93
94     def test_virsh_destroy_vm(self):
95         self.mock_ssh.execute = mock.Mock(return_value=(0, 0, 0))
96         model.Libvirt.virsh_destroy_vm('vm-0', self.mock_ssh)
97         self.mock_ssh.execute.assert_called_once_with('virsh destroy vm-0')
98
99     @mock.patch.object(model, 'LOG')
100     def test_virsh_destroy_vm_error(self, mock_logger):
101         self.mock_ssh.execute = mock.Mock(return_value=(1, 0, 'error_destroy'))
102         mock_logger.warning = mock.Mock()
103         model.Libvirt.virsh_destroy_vm('vm-0', self.mock_ssh)
104         mock_logger.warning.assert_called_once_with(
105             'Error destroying VM %s. Error: %s', 'vm-0', 'error_destroy')
106         self.mock_ssh.execute.assert_called_once_with('virsh destroy vm-0')
107
108     def test_add_interface_address(self):
109         xml = ElementTree.ElementTree(
110             element=ElementTree.fromstring(XML_SAMPLE_INTERFACE))
111         interface = xml.find('devices').find('interface')
112         result = model.Libvirt._add_interface_address(interface, self.pci_address)
113         self.assertEqual('pci', result.get('type'))
114         self.assertEqual('0x{}'.format(self.pci_address.domain),
115                          result.get('domain'))
116         self.assertEqual('0x{}'.format(self.pci_address.bus),
117                          result.get('bus'))
118         self.assertEqual('0x{}'.format(self.pci_address.slot),
119                          result.get('slot'))
120         self.assertEqual('0x{}'.format(self.pci_address.function),
121                          result.get('function'))
122
123     def test_add_ovs_interfaces(self):
124         xml_input = copy.deepcopy(XML_SAMPLE)
125         xml_output = model.Libvirt.add_ovs_interface(
126             '/usr/local', 0, self.pci_address_str, self.mac, xml_input)
127
128         root = ElementTree.fromstring(xml_output)
129         et_out = ElementTree.ElementTree(element=root)
130         interface = et_out.find('devices').find('interface')
131         self.assertEqual('vhostuser', interface.get('type'))
132         mac = interface.find('mac')
133         self.assertEqual(self.mac, mac.get('address'))
134         source = interface.find('source')
135         self.assertEqual('unix', source.get('type'))
136         self.assertEqual('/usr/local/var/run/openvswitch/dpdkvhostuser0',
137                          source.get('path'))
138         self.assertEqual('client', source.get('mode'))
139         _model = interface.find('model')
140         self.assertEqual('virtio', _model.get('type'))
141         driver = interface.find('driver')
142         self.assertEqual('4', driver.get('queues'))
143         host = driver.find('host')
144         self.assertEqual('off', host.get('mrg_rxbuf'))
145         self.assertIsNotNone(interface.find('address'))
146
147     def test_add_sriov_interfaces(self):
148         xml_input = copy.deepcopy(XML_SAMPLE)
149         vm_pci = '0001:05:04.2'
150         xml_output = model.Libvirt.add_sriov_interfaces(
151             vm_pci, self.pci_address_str, self.mac, xml_input)
152         root = ElementTree.fromstring(xml_output)
153         et_out = ElementTree.ElementTree(element=root)
154         interface = et_out.find('devices').find('interface')
155         self.assertEqual('yes', interface.get('managed'))
156         self.assertEqual('hostdev', interface.get('type'))
157         mac = interface.find('mac')
158         self.assertEqual(self.mac, mac.get('address'))
159         source = interface.find('source')
160         source_address = source.find('address')
161         self.assertIsNotNone(source.find('address'))
162
163         self.assertEqual('pci', source_address.get('type'))
164         self.assertEqual('0x' + self.pci_address_str.split(':')[0],
165                          source_address.get('domain'))
166         self.assertEqual('0x' + self.pci_address_str.split(':')[1],
167                          source_address.get('bus'))
168         self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[0],
169                          source_address.get('slot'))
170         self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[1],
171                          source_address.get('function'))
172
173         interface_address = interface.find('address')
174         self.assertEqual('pci', interface_address.get('type'))
175         self.assertEqual('0x' + vm_pci.split(':')[0],
176                          interface_address.get('domain'))
177         self.assertEqual('0x' + vm_pci.split(':')[1],
178                          interface_address.get('bus'))
179         self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[0],
180                          interface_address.get('slot'))
181         self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[1],
182                          interface_address.get('function'))
183
184     def test_add_cdrom(self):
185         xml_input = copy.deepcopy(XML_SAMPLE)
186         xml_output = model.Libvirt.add_cdrom('/var/lib/libvirt/images/data.img', xml_input)
187
188         root = ElementTree.fromstring(xml_output)
189         et_out = ElementTree.ElementTree(element=root)
190         disk = et_out.find('devices').find('disk')
191         self.assertEqual('file', disk.get('type'))
192         self.assertEqual('cdrom', disk.get('device'))
193         driver = disk.find('driver')
194         self.assertEqual('qemu', driver.get('name'))
195         self.assertEqual('raw', driver.get('type'))
196         source = disk.find('source')
197         self.assertEqual('/var/lib/libvirt/images/data.img', source.get('file'))
198         target = disk.find('target')
199         self.assertEqual('hdb', target.get('dev'))
200         self.assertIsNotNone(disk.find('readonly'))
201
202     def test_gen_cdrom_image(self):
203         self.mock_ssh.execute = mock.Mock(return_value=(0, 0, 0))
204         root = ElementTree.fromstring(self.XML_STR)
205         hostname = root.find('name').text
206         meta_data = "/tmp/meta-data"
207         user_data = "/tmp/user-data"
208         network_data = "/tmp/network-config"
209         file_path = "/tmp/cdrom-0.img"
210         key_filename = "id_rsa"
211         pub_key_str = "KEY"
212         user = 'root'
213         mac = "00:11:22:33:44:55"
214         ip = "1.1.1.7/24"
215         user_config = ["    - name: {user_name}",
216                        "      ssh_authorized_keys:",
217                        "        - {pub_key_str}"]
218
219         user_conf = os.linesep.join(user_config).format(pub_key_str=pub_key_str, user_name=user)
220         with mock.patch('six.moves.builtins.open', mock.mock_open(read_data=pub_key_str),
221                         create=True) as mock_file:
222             with open(key_filename, "r") as h:
223                 result = h.read()
224             model.Libvirt.gen_cdrom_image(self.mock_ssh, file_path, hostname, user, key_filename,
225                                           mac, ip)
226             mock_file.assert_called_with(".".join([key_filename, "pub"]), "r")
227         self.assertEqual(result, pub_key_str)
228
229         self.mock_ssh.execute.assert_has_calls([
230             mock.call("touch %s" % meta_data),
231             mock.call(model.USER_DATA_TEMPLATE.format(user_file=user_data, host=hostname,
232                                                       user_config=user_conf)),
233             mock.call(model.NETWORK_DATA_TEMPLATE.format(network_file=network_data,
234                                                          mac_address=mac, ip_address=ip)),
235             mock.call("genisoimage -output {0} -volid cidata"
236                       " -joliet -r {1} {2} {3}".format(file_path, meta_data, user_data,
237                                                        network_data)),
238             mock.call("rm {0} {1} {2}".format(meta_data, user_data, network_data))
239         ])
240
241     def test_create_snapshot_qemu(self):
242         self.mock_ssh.execute = mock.Mock(return_value=(0, 0, 0))
243         index = 1
244         vm_image = '/var/lib/libvirt/images/%s.qcow2' % index
245         base_image = '/tmp/base_image'
246
247         model.Libvirt.create_snapshot_qemu(self.mock_ssh, index, base_image)
248         self.mock_ssh.execute.assert_has_calls([
249             mock.call('rm -- "%s"' % vm_image),
250             mock.call('test -r %s' % base_image),
251             mock.call('qemu-img create -f qcow2 -o backing_file=%s %s' %
252                       (base_image, vm_image))
253         ])
254
255     @mock.patch.object(os.path, 'basename', return_value='base_image')
256     @mock.patch.object(os.path, 'normpath')
257     @mock.patch.object(os, 'access', return_value=True)
258     def test_create_snapshot_qemu_no_image_remote(self,
259             mock_os_access, mock_normpath, mock_basename):
260         self.mock_ssh.execute = mock.Mock(
261             side_effect=[(0, 0, 0), (1, 0, 0), (0, 0, 0), (0, 0, 0)])
262         index = 1
263         vm_image = '/var/lib/libvirt/images/%s.qcow2' % index
264         base_image = '/tmp/base_image'
265         mock_normpath.return_value = base_image
266
267         model.Libvirt.create_snapshot_qemu(self.mock_ssh, index, base_image)
268         self.mock_ssh.execute.assert_has_calls([
269             mock.call('rm -- "%s"' % vm_image),
270             mock.call('test -r %s' % base_image),
271             mock.call('mv -- "/tmp/%s" "%s"' % ('base_image', base_image)),
272             mock.call('qemu-img create -f qcow2 -o backing_file=%s %s' %
273                       (base_image, vm_image))
274         ])
275         mock_os_access.assert_called_once_with(base_image, os.R_OK)
276         mock_normpath.assert_called_once_with(base_image)
277         mock_basename.assert_has_calls([mock.call(base_image)])
278         self.mock_ssh.put_file.assert_called_once_with(base_image,
279                                                        '/tmp/base_image')
280
281     @mock.patch.object(model.Libvirt, 'gen_cdrom_image')
282     def test_check_update_key(self, mock_gen_cdrom_image):
283         node = {
284             'user': 'defuser',
285             'key_filename': '/home/ubuntu/id_rsa',
286             'ip': '1.1.1.7',
287             'netmask': '255.255.255.0'}
288         cdrom_img = "/var/lib/libvirt/images/data.img"
289         id_name = 'fake_name'
290         key_filename = node.get('key_filename')
291         root = ElementTree.fromstring(self.XML_STR)
292         hostname = root.find('name').text
293         mac = "00:11:22:33:44:55"
294         ip = "{0}/{1}".format(node.get('ip'), node.get('netmask'))
295         model.StandaloneContextHelper.check_update_key(self.mock_ssh, node, hostname, id_name,
296                                                        cdrom_img, mac)
297         mock_gen_cdrom_image.assert_called_once_with(self.mock_ssh, cdrom_img, hostname,
298                                                      node.get('user'), key_filename, mac, ip)
299
300     @mock.patch.object(os, 'access', return_value=False)
301     def test_create_snapshot_qemu_no_image_local(self, mock_os_access):
302         self.mock_ssh.execute = mock.Mock(side_effect=[(0, 0, 0), (1, 0, 0)])
303         base_image = '/tmp/base_image'
304
305         with self.assertRaises(exceptions.LibvirtQemuImageBaseImageNotPresent):
306             model.Libvirt.create_snapshot_qemu(self.mock_ssh, 3, base_image)
307         mock_os_access.assert_called_once_with(base_image, os.R_OK)
308
309     def test_create_snapshot_qemu_error_qemuimg_command(self):
310         self.mock_ssh.execute = mock.Mock(
311             side_effect=[(0, 0, 0), (0, 0, 0), (1, 0, 0)])
312         index = 1
313         vm_image = '/var/lib/libvirt/images/%s.qcow2' % index
314         base_image = '/tmp/base_image'
315
316         with self.assertRaises(exceptions.LibvirtQemuImageCreateError):
317             model.Libvirt.create_snapshot_qemu(self.mock_ssh, index,
318                                                base_image)
319         self.mock_ssh.execute.assert_has_calls([
320             mock.call('rm -- "%s"' % vm_image),
321             mock.call('test -r %s' % base_image),
322             mock.call('qemu-img create -f qcow2 -o backing_file=%s %s' %
323                       (base_image, vm_image))
324         ])
325
326     @mock.patch.object(model.Libvirt, 'pin_vcpu_for_perf', return_value='4,5')
327     @mock.patch.object(model.Libvirt, 'create_snapshot_qemu',
328                        return_value='qemu_image')
329     def test_build_vm_xml(self, mock_create_snapshot_qemu,
330                           mock_pin_vcpu_for_perf):
331         extra_specs = {'hw:cpu_cores': '4',
332                        'hw:cpu_sockets': '3',
333                        'hw:cpu_threads': '2',
334                        'cputune': 'cool'}
335         flavor = {'ram': '1024',
336                   'extra_specs': extra_specs,
337                   'hw_socket': '1',
338                   'images': 'images'}
339         mac = model.StandaloneContextHelper.get_mac_address(0x00)
340         _uuid = uuid.uuid4()
341         connection = mock.Mock()
342         cdrom_img = '/tmp/cdrom-0.img'
343         with mock.patch.object(model.StandaloneContextHelper,
344                                'get_mac_address', return_value=mac) as \
345                 mock_get_mac_address, \
346                 mock.patch.object(uuid, 'uuid4', return_value=_uuid):
347             xml_out, mac = model.Libvirt.build_vm_xml(
348                 connection, flavor, 'vm_name', 100, cdrom_img)
349
350         xml_ref = model.VM_TEMPLATE.format(vm_name='vm_name',
351             random_uuid=_uuid, mac_addr=mac, memory='1024', vcpu='8', cpu='4',
352             numa_cpus='0-7', socket='3', threads='2',
353             vm_image='qemu_image', cpuset='4,5', cputune='cool')
354         xml_ref = model.Libvirt.add_cdrom(cdrom_img, xml_ref)
355         self.assertEqual(xml_out, xml_ref)
356         mock_get_mac_address.assert_called_once_with(0x00)
357         mock_create_snapshot_qemu.assert_called_once_with(
358             connection, 100, 'images')
359         mock_pin_vcpu_for_perf.assert_called_once_with(connection, '1')
360
361     # TODO: Edit this test to test state instead of output
362     # update_interrupts_hugepages_perf does not return anything
363     def test_update_interrupts_hugepages_perf(self):
364         with mock.patch("yardstick.ssh.SSH") as ssh:
365             ssh_mock = mock.Mock(autospec=ssh.SSH)
366             ssh_mock.execute = \
367                 mock.Mock(return_value=(0, "a", ""))
368             ssh.return_value = ssh_mock
369         # NOTE(ralonsoh): 'update_interrupts_hugepages_perf' always return
370         # None, this check is trivial.
371         #status = Libvirt.update_interrupts_hugepages_perf(ssh_mock)
372         #self.assertIsNone(status)
373         model.Libvirt.update_interrupts_hugepages_perf(ssh_mock)
374
375     @mock.patch.object(model, 'CpuSysCores')
376     @mock.patch.object(model.Libvirt, 'update_interrupts_hugepages_perf')
377     def test_pin_vcpu_for_perf(self, *args):
378         # NOTE(ralonsoh): test mocked methods/variables.
379         with mock.patch("yardstick.ssh.SSH") as ssh:
380             ssh_mock = mock.Mock(autospec=ssh.SSH)
381             ssh_mock.execute = \
382                 mock.Mock(return_value=(0, "a", ""))
383             ssh.return_value = ssh_mock
384         status = model.Libvirt.pin_vcpu_for_perf(ssh_mock, 4)
385         self.assertIsNotNone(status)
386
387
388 class StandaloneContextHelperTestCase(unittest.TestCase):
389
390     NODE_SAMPLE = "nodes_sample.yaml"
391     NODE_SRIOV_SAMPLE = "nodes_sriov_sample.yaml"
392
393     NETWORKS = {
394         'mgmt': {'cidr': '152.16.100.10/24'},
395         'private_0': {
396             'phy_port': "0000:05:00.0",
397             'vpci': "0000:00:07.0",
398             'cidr': '152.16.100.10/24',
399             'gateway_ip': '152.16.100.20'},
400         'public_0': {
401             'phy_port': "0000:05:00.1",
402             'vpci': "0000:00:08.0",
403             'cidr': '152.16.40.10/24',
404             'gateway_ip': '152.16.100.20'}
405     }
406
407     def setUp(self):
408         self.helper = model.StandaloneContextHelper()
409
410     def test___init__(self):
411         self.assertIsNone(self.helper.file_path)
412
413     def test_install_req_libs(self):
414         with mock.patch("yardstick.ssh.SSH") as ssh:
415             ssh_mock = mock.Mock(autospec=ssh.SSH)
416             ssh_mock.execute = \
417                 mock.Mock(return_value=(1, "a", ""))
418             ssh.return_value = ssh_mock
419         # NOTE(ralonsoh): this test doesn't cover function execution. This test
420         # should also check mocked function calls.
421         model.StandaloneContextHelper.install_req_libs(ssh_mock)
422
423     def test_get_kernel_module(self):
424         with mock.patch("yardstick.ssh.SSH") as ssh:
425             ssh_mock = mock.Mock(autospec=ssh.SSH)
426             ssh_mock.execute = \
427                 mock.Mock(return_value=(1, "i40e", ""))
428             ssh.return_value = ssh_mock
429         # NOTE(ralonsoh): this test doesn't cover function execution. This test
430         # should also check mocked function calls.
431         model.StandaloneContextHelper.get_kernel_module(
432             ssh_mock, "05:00.0", None)
433
434     @mock.patch.object(model.StandaloneContextHelper, 'get_kernel_module')
435     def test_get_nic_details(self, mock_get_kernel_module):
436         with mock.patch("yardstick.ssh.SSH") as ssh:
437             ssh_mock = mock.Mock(autospec=ssh.SSH)
438             ssh_mock.execute = mock.Mock(return_value=(1, "i40e ixgbe", ""))
439             ssh.return_value = ssh_mock
440         mock_get_kernel_module.return_value = "i40e"
441         # NOTE(ralonsoh): this test doesn't cover function execution. This test
442         # should also check mocked function calls.
443         model.StandaloneContextHelper.get_nic_details(
444             ssh_mock, self.NETWORKS, 'dpdk-devbind.py')
445
446     def test_get_virtual_devices(self):
447         pattern = "PCI_SLOT_NAME=0000:05:00.0"
448         with mock.patch("yardstick.ssh.SSH") as ssh:
449             ssh_mock = mock.Mock(autospec=ssh.SSH)
450             ssh_mock.execute = \
451                 mock.Mock(return_value=(1, pattern, ""))
452             ssh.return_value = ssh_mock
453         # NOTE(ralonsoh): this test doesn't cover function execution. This test
454         # should also check mocked function calls.
455         model.StandaloneContextHelper.get_virtual_devices(
456             ssh_mock, '0000:00:05.0')
457
458     def _get_file_abspath(self, filename):
459         curr_path = os.path.dirname(os.path.abspath(__file__))
460         file_path = os.path.join(curr_path, filename)
461         return file_path
462
463     def test_parse_pod_file(self):
464         self.helper.file_path = self._get_file_abspath("dummy")
465         self.assertRaises(IOError, self.helper.parse_pod_file,
466                           self.helper.file_path)
467
468         self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE)
469         self.assertRaises(TypeError, self.helper.parse_pod_file,
470                           self.helper.file_path)
471
472         self.helper.file_path = self._get_file_abspath(self.NODE_SRIOV_SAMPLE)
473         self.assertIsNotNone(self.helper.parse_pod_file(self.helper.file_path))
474
475     def test_get_mac_address(self):
476         status = model.StandaloneContextHelper.get_mac_address()
477         self.assertIsNotNone(status)
478
479     @mock.patch('yardstick.ssh.SSH')
480     def test_get_mgmt_ip(self, *args):
481         # NOTE(ralonsoh): test mocked methods/variables.
482         with mock.patch("yardstick.ssh.SSH") as ssh:
483             ssh_mock = mock.Mock(autospec=ssh.SSH)
484             ssh_mock.execute = mock.Mock(
485                 return_value=(1, "1.2.3.4 00:00:00:00:00:01", ""))
486             ssh.return_value = ssh_mock
487         # NOTE(ralonsoh): this test doesn't cover function execution. This test
488         # should also check mocked function calls.
489         status = model.StandaloneContextHelper.get_mgmt_ip(
490             ssh_mock, "00:00:00:00:00:01", "1.1.1.1/24", {})
491         self.assertIsNotNone(status)
492
493     @mock.patch('yardstick.ssh.SSH')
494     def test_get_mgmt_ip_no(self, *args):
495         # NOTE(ralonsoh): test mocked methods/variables.
496         with mock.patch("yardstick.ssh.SSH") as ssh:
497             ssh_mock = mock.Mock(autospec=ssh.SSH)
498             ssh_mock.execute = \
499                 mock.Mock(return_value=(1, "", ""))
500             ssh.return_value = ssh_mock
501         # NOTE(ralonsoh): this test doesn't cover function execution. This test
502         # should also check mocked function calls.
503         model.WAIT_FOR_BOOT = 0
504         status = model.StandaloneContextHelper.get_mgmt_ip(
505             ssh_mock, "99", "1.1.1.1/24", {})
506         self.assertIsNone(status)
507
508
509 class ServerTestCase(unittest.TestCase):
510
511     NETWORKS = {
512         'mgmt': {'cidr': '152.16.100.10/24'},
513         'private_0': {
514             'phy_port': "0000:05:00.0",
515             'vpci': "0000:00:07.0",
516             'driver': 'i40e',
517             'mac': '',
518             'cidr': '152.16.100.10/24',
519             'gateway_ip': '152.16.100.20'},
520         'public_0': {
521             'phy_port': "0000:05:00.1",
522             'vpci': "0000:00:08.0",
523             'driver': 'i40e',
524             'mac': '',
525             'cidr': '152.16.40.10/24',
526             'gateway_ip': '152.16.100.20'}
527     }
528
529     def setUp(self):
530         self.server = model.Server()
531
532     def test___init__(self):
533         self.assertIsNotNone(self.server)
534
535     def test_build_vnf_interfaces(self):
536         vnf = {
537             "network_ports": {
538                 'mgmt': {'cidr': '152.16.100.10/24'},
539                 'xe0': ['private_0'],
540                 'xe1': ['public_0'],
541             }
542         }
543         status = model.Server.build_vnf_interfaces(vnf, self.NETWORKS)
544         self.assertIsNotNone(status)
545
546     def test_generate_vnf_instance(self):
547         vnf = {
548             "network_ports": {
549                 'mgmt': {'cidr': '152.16.100.10/24'},
550                 'xe0': ['private_0'],
551                 'xe1': ['public_0'],
552             }
553         }
554         status = self.server.generate_vnf_instance(
555             {}, self.NETWORKS, '1.1.1.1/24', 'vm-0', vnf, '00:00:00:00:00:01')
556         self.assertIsNotNone(status)
557
558
559 class OvsDeployTestCase(unittest.TestCase):
560
561     OVS_DETAILS = {'version': {'ovs': 'ovs_version', 'dpdk': 'dpdk_version'}}
562
563     def setUp(self):
564         self._mock_ssh = mock.patch.object(ssh, 'SSH')
565         self.mock_ssh = self._mock_ssh.start()
566         self.ovs_deploy = model.OvsDeploy(self.mock_ssh,
567                                           '/tmp/dpdk-devbind.py',
568                                           self.OVS_DETAILS)
569         self._mock_path_isfile = mock.patch.object(os.path, 'isfile')
570         self._mock_path_join = mock.patch.object(os.path, 'join')
571         self.mock_path_isfile = self._mock_path_isfile.start()
572         self.mock_path_join = self._mock_path_join.start()
573
574         self.addCleanup(self._stop_mock)
575
576     def _stop_mock(self):
577         self._mock_ssh.stop()
578         self._mock_path_isfile.stop()
579         self._mock_path_join.stop()
580
581     @mock.patch.object(model.StandaloneContextHelper, 'install_req_libs')
582     def test_prerequisite(self, mock_install_req_libs):
583         pkgs = ["git", "build-essential", "pkg-config", "automake",
584                 "autotools-dev", "libltdl-dev", "cmake", "libnuma-dev",
585                 "libpcap-dev"]
586         self.ovs_deploy.prerequisite()
587         mock_install_req_libs.assert_called_once_with(
588             self.ovs_deploy.connection, pkgs)
589
590     def test_ovs_deploy_no_file(self):
591         self.mock_path_isfile.return_value = False
592         mock_file = mock.Mock()
593         self.mock_path_join.return_value = mock_file
594
595         self.ovs_deploy.ovs_deploy()
596         self.mock_path_isfile.assert_called_once_with(mock_file)
597         self.mock_path_join.assert_called_once_with(
598             constants.YARDSTICK_ROOT_PATH,
599             'yardstick/resources/scripts/install/',
600             self.ovs_deploy.OVS_DEPLOY_SCRIPT)
601
602     @mock.patch.object(os.environ, 'get', return_value='test_proxy')
603     def test_ovs_deploy(self, mock_env_get):
604         self.mock_path_isfile.return_value = True
605         mock_deploy_file = mock.Mock()
606         mock_remove_ovs_deploy = mock.Mock()
607         self.mock_path_join.side_effect = [mock_deploy_file,
608                                            mock_remove_ovs_deploy]
609         dpdk_version = self.OVS_DETAILS['version']['dpdk']
610         ovs_version = self.OVS_DETAILS['version']['ovs']
611
612         with mock.patch.object(self.ovs_deploy.connection, 'put') as \
613                 mock_put, \
614                 mock.patch.object(self.ovs_deploy.connection, 'execute') as \
615                 mock_execute, \
616                 mock.patch.object(self.ovs_deploy, 'prerequisite'):
617             mock_execute.return_value = (0, 0, 0)
618             self.ovs_deploy.ovs_deploy()
619
620             self.mock_path_isfile.assert_called_once_with(mock_deploy_file)
621             self.mock_path_join.assert_has_calls([
622                 mock.call(constants.YARDSTICK_ROOT_PATH,
623                           'yardstick/resources/scripts/install/',
624                           self.ovs_deploy.OVS_DEPLOY_SCRIPT),
625                 mock.call(self.ovs_deploy.bin_path,
626                           self.ovs_deploy.OVS_DEPLOY_SCRIPT)
627             ])
628             mock_put.assert_called_once_with(mock_deploy_file,
629                                              mock_remove_ovs_deploy)
630             cmd = ("sudo -E %(remote_ovs_deploy)s --ovs='%(ovs_version)s' "
631                    "--dpdk='%(dpdk_version)s' -p='%(proxy)s'" %
632                    {'remote_ovs_deploy': mock_remove_ovs_deploy,
633                     'ovs_version': ovs_version,
634                     'dpdk_version': dpdk_version,
635                     'proxy': 'test_proxy'})
636             mock_execute.assert_called_once_with(cmd)
637             mock_env_get.assert_has_calls([mock.call('http_proxy', '')])