1 # Copyright (c) 2016-2017 Intel Corporation
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
21 from xml.etree import ElementTree
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
30 XML_SAMPLE = """<?xml version="1.0"?>
37 XML_SAMPLE_INTERFACE = """<?xml version="1.0"?>
47 class ModelLibvirtTestCase(unittest.TestCase):
50 self.pci_address_str = '0001:04:03.2'
51 self.pci_address = utils.PciAddress(self.pci_address_str)
52 self.mac = '00:00:00:00:00:01'
53 self._mock_ssh = mock.Mock()
54 self.mock_ssh = self._mock_ssh.start()
55 self.addCleanup(self._cleanup)
60 # TODO: Remove mocking of yardstick.ssh.SSH (here and elsewhere)
61 # In this case, we are mocking a param to be passed into other methods
62 # It can be a generic Mock() with return values set for the right methods
63 def test_check_if_vm_exists_and_delete(self):
64 with mock.patch("yardstick.ssh.SSH") as ssh:
65 ssh_mock = mock.Mock(autospec=ssh.SSH)
66 ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
67 ssh.return_value = ssh_mock
68 # NOTE(ralonsoh): this test doesn't cover function execution.
69 model.Libvirt.check_if_vm_exists_and_delete("vm_0", ssh_mock)
71 def test_virsh_create_vm(self):
72 self.mock_ssh.execute = mock.Mock(return_value=(0, 0, 0))
73 model.Libvirt.virsh_create_vm(self.mock_ssh, 'vm_0')
74 self.mock_ssh.execute.assert_called_once_with('virsh create vm_0')
76 def test_virsh_create_vm_error(self):
77 self.mock_ssh.execute = mock.Mock(return_value=(1, 0, 'error_create'))
78 with self.assertRaises(exceptions.LibvirtCreateError) as exc:
79 model.Libvirt.virsh_create_vm(self.mock_ssh, 'vm_0')
80 self.assertEqual('Error creating the virtual machine. Error: '
81 'error_create.', str(exc.exception))
82 self.mock_ssh.execute.assert_called_once_with('virsh create vm_0')
84 def test_virsh_destroy_vm(self):
85 with mock.patch("yardstick.ssh.SSH") as ssh:
86 ssh_mock = mock.Mock(autospec=ssh.SSH)
87 ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
88 ssh.return_value = ssh_mock
89 # NOTE(ralonsoh): this test doesn't cover function execution.
90 model.Libvirt.virsh_destroy_vm("vm_0", ssh_mock)
92 def test_add_interface_address(self):
93 xml = ElementTree.ElementTree(
94 element=ElementTree.fromstring(XML_SAMPLE_INTERFACE))
95 interface = xml.find('devices').find('interface')
96 result = model.Libvirt._add_interface_address(interface, self.pci_address)
97 self.assertEqual('pci', result.get('type'))
98 self.assertEqual('0x{}'.format(self.pci_address.domain),
100 self.assertEqual('0x{}'.format(self.pci_address.bus),
102 self.assertEqual('0x{}'.format(self.pci_address.slot),
104 self.assertEqual('0x{}'.format(self.pci_address.function),
105 result.get('function'))
107 def test_add_ovs_interfaces(self):
108 xml_input = copy.deepcopy(XML_SAMPLE)
109 xml_output = model.Libvirt.add_ovs_interface(
110 '/usr/local', 0, self.pci_address_str, self.mac, xml_input)
112 root = ElementTree.fromstring(xml_output)
113 et_out = ElementTree.ElementTree(element=root)
114 interface = et_out.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',
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'))
131 def test_add_sriov_interfaces(self):
132 xml_input = copy.deepcopy(XML_SAMPLE)
133 vm_pci = '0001:05:04.2'
134 xml_output = model.Libvirt.add_sriov_interfaces(
135 vm_pci, self.pci_address_str, self.mac, xml_input)
136 root = ElementTree.fromstring(xml_output)
137 et_out = ElementTree.ElementTree(element=root)
138 interface = et_out.find('devices').find('interface')
139 self.assertEqual('yes', interface.get('managed'))
140 self.assertEqual('hostdev', interface.get('type'))
141 mac = interface.find('mac')
142 self.assertEqual(self.mac, mac.get('address'))
143 source = interface.find('source')
144 source_address = source.find('address')
145 self.assertIsNotNone(source.find('address'))
147 self.assertEqual('pci', source_address.get('type'))
148 self.assertEqual('0x' + self.pci_address_str.split(':')[0],
149 source_address.get('domain'))
150 self.assertEqual('0x' + self.pci_address_str.split(':')[1],
151 source_address.get('bus'))
152 self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[0],
153 source_address.get('slot'))
154 self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[1],
155 source_address.get('function'))
157 interface_address = interface.find('address')
158 self.assertEqual('pci', interface_address.get('type'))
159 self.assertEqual('0x' + vm_pci.split(':')[0],
160 interface_address.get('domain'))
161 self.assertEqual('0x' + vm_pci.split(':')[1],
162 interface_address.get('bus'))
163 self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[0],
164 interface_address.get('slot'))
165 self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[1],
166 interface_address.get('function'))
168 def test_create_snapshot_qemu(self):
169 result = "/var/lib/libvirt/images/0.qcow2"
170 with mock.patch("yardstick.ssh.SSH") as ssh:
171 ssh_mock = mock.Mock(autospec=ssh.SSH)
173 mock.Mock(return_value=(0, "a", ""))
174 ssh.return_value = ssh_mock
175 image = model.Libvirt.create_snapshot_qemu(ssh_mock, "0", "ubuntu.img")
176 self.assertEqual(image, result)
178 @mock.patch.object(model.Libvirt, 'pin_vcpu_for_perf', return_value='4,5')
179 @mock.patch.object(model.Libvirt, 'create_snapshot_qemu',
180 return_value='qemu_image')
181 def test_build_vm_xml(self, mock_create_snapshot_qemu,
182 mock_pin_vcpu_for_perf):
183 extra_specs = {'hw:cpu_cores': '4',
184 'hw:cpu_sockets': '3',
185 'hw:cpu_threads': '2',
187 flavor = {'ram': '1024',
188 'extra_specs': extra_specs,
191 mac = model.StandaloneContextHelper.get_mac_address(0x00)
193 connection = mock.Mock()
194 with mock.patch.object(model.StandaloneContextHelper,
195 'get_mac_address', return_value=mac) as \
196 mock_get_mac_address, \
197 mock.patch.object(uuid, 'uuid4', return_value=_uuid):
198 xml_out, mac = model.Libvirt.build_vm_xml(
199 connection, flavor, 'vm_name', 100)
201 xml_ref = model.VM_TEMPLATE.format(vm_name='vm_name',
202 random_uuid=_uuid, mac_addr=mac, memory='1024', vcpu='8', cpu='4',
203 numa_cpus='0-7', socket='3', threads='2',
204 vm_image='qemu_image', cpuset='4,5', cputune='cool')
205 self.assertEqual(xml_ref, xml_out)
206 mock_get_mac_address.assert_called_once_with(0x00)
207 mock_create_snapshot_qemu.assert_called_once_with(
208 connection, 100, 'images')
209 mock_pin_vcpu_for_perf.assert_called_once_with(connection, '1')
211 # TODO: Edit this test to test state instead of output
212 # update_interrupts_hugepages_perf does not return anything
213 def test_update_interrupts_hugepages_perf(self):
214 with mock.patch("yardstick.ssh.SSH") as ssh:
215 ssh_mock = mock.Mock(autospec=ssh.SSH)
217 mock.Mock(return_value=(0, "a", ""))
218 ssh.return_value = ssh_mock
219 # NOTE(ralonsoh): 'update_interrupts_hugepages_perf' always return
220 # None, this check is trivial.
221 #status = Libvirt.update_interrupts_hugepages_perf(ssh_mock)
222 #self.assertIsNone(status)
223 model.Libvirt.update_interrupts_hugepages_perf(ssh_mock)
225 @mock.patch.object(model, 'CpuSysCores')
226 @mock.patch.object(model.Libvirt, 'update_interrupts_hugepages_perf')
227 def test_pin_vcpu_for_perf(self, *args):
228 # NOTE(ralonsoh): test mocked methods/variables.
229 with mock.patch("yardstick.ssh.SSH") as ssh:
230 ssh_mock = mock.Mock(autospec=ssh.SSH)
232 mock.Mock(return_value=(0, "a", ""))
233 ssh.return_value = ssh_mock
234 status = model.Libvirt.pin_vcpu_for_perf(ssh_mock, 4)
235 self.assertIsNotNone(status)
237 class StandaloneContextHelperTestCase(unittest.TestCase):
239 NODE_SAMPLE = "nodes_sample.yaml"
240 NODE_SRIOV_SAMPLE = "nodes_sriov_sample.yaml"
243 'mgmt': {'cidr': '152.16.100.10/24'},
245 'phy_port': "0000:05:00.0",
246 'vpci': "0000:00:07.0",
247 'cidr': '152.16.100.10/24',
248 'gateway_ip': '152.16.100.20'},
250 'phy_port': "0000:05:00.1",
251 'vpci': "0000:00:08.0",
252 'cidr': '152.16.40.10/24',
253 'gateway_ip': '152.16.100.20'}
257 self.helper = model.StandaloneContextHelper()
259 def test___init__(self):
260 self.assertIsNone(self.helper.file_path)
262 def test_install_req_libs(self):
263 with mock.patch("yardstick.ssh.SSH") as ssh:
264 ssh_mock = mock.Mock(autospec=ssh.SSH)
266 mock.Mock(return_value=(1, "a", ""))
267 ssh.return_value = ssh_mock
268 # NOTE(ralonsoh): this test doesn't cover function execution. This test
269 # should also check mocked function calls.
270 model.StandaloneContextHelper.install_req_libs(ssh_mock)
272 def test_get_kernel_module(self):
273 with mock.patch("yardstick.ssh.SSH") as ssh:
274 ssh_mock = mock.Mock(autospec=ssh.SSH)
276 mock.Mock(return_value=(1, "i40e", ""))
277 ssh.return_value = ssh_mock
278 # NOTE(ralonsoh): this test doesn't cover function execution. This test
279 # should also check mocked function calls.
280 model.StandaloneContextHelper.get_kernel_module(
281 ssh_mock, "05:00.0", None)
283 @mock.patch.object(model.StandaloneContextHelper, 'get_kernel_module')
284 def test_get_nic_details(self, mock_get_kernel_module):
285 with mock.patch("yardstick.ssh.SSH") as ssh:
286 ssh_mock = mock.Mock(autospec=ssh.SSH)
287 ssh_mock.execute = mock.Mock(return_value=(1, "i40e ixgbe", ""))
288 ssh.return_value = ssh_mock
289 mock_get_kernel_module.return_value = "i40e"
290 # NOTE(ralonsoh): this test doesn't cover function execution. This test
291 # should also check mocked function calls.
292 model.StandaloneContextHelper.get_nic_details(
293 ssh_mock, self.NETWORKS, 'dpdk-devbind.py')
295 def test_get_virtual_devices(self):
296 pattern = "PCI_SLOT_NAME=0000:05:00.0"
297 with mock.patch("yardstick.ssh.SSH") as ssh:
298 ssh_mock = mock.Mock(autospec=ssh.SSH)
300 mock.Mock(return_value=(1, pattern, ""))
301 ssh.return_value = ssh_mock
302 # NOTE(ralonsoh): this test doesn't cover function execution. This test
303 # should also check mocked function calls.
304 model.StandaloneContextHelper.get_virtual_devices(
305 ssh_mock, '0000:00:05.0')
307 def _get_file_abspath(self, filename):
308 curr_path = os.path.dirname(os.path.abspath(__file__))
309 file_path = os.path.join(curr_path, filename)
312 def test_read_config_file(self):
313 self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE)
314 status = self.helper.read_config_file()
315 self.assertIsNotNone(status)
317 def test_parse_pod_file(self):
318 self.helper.file_path = self._get_file_abspath("dummy")
319 self.assertRaises(IOError, self.helper.parse_pod_file,
320 self.helper.file_path)
322 self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE)
323 self.assertRaises(TypeError, self.helper.parse_pod_file,
324 self.helper.file_path)
326 self.helper.file_path = self._get_file_abspath(self.NODE_SRIOV_SAMPLE)
327 self.assertIsNotNone(self.helper.parse_pod_file(self.helper.file_path))
329 def test_get_mac_address(self):
330 status = model.StandaloneContextHelper.get_mac_address()
331 self.assertIsNotNone(status)
333 @mock.patch('yardstick.ssh.SSH')
334 def test_get_mgmt_ip(self, *args):
335 # NOTE(ralonsoh): test mocked methods/variables.
336 with mock.patch("yardstick.ssh.SSH") as ssh:
337 ssh_mock = mock.Mock(autospec=ssh.SSH)
338 ssh_mock.execute = mock.Mock(
339 return_value=(1, "1.2.3.4 00:00:00:00:00:01", ""))
340 ssh.return_value = ssh_mock
341 # NOTE(ralonsoh): this test doesn't cover function execution. This test
342 # should also check mocked function calls.
343 status = model.StandaloneContextHelper.get_mgmt_ip(
344 ssh_mock, "00:00:00:00:00:01", "1.1.1.1/24", {})
345 self.assertIsNotNone(status)
347 @mock.patch('yardstick.ssh.SSH')
348 def test_get_mgmt_ip_no(self, *args):
349 # NOTE(ralonsoh): test mocked methods/variables.
350 with mock.patch("yardstick.ssh.SSH") as ssh:
351 ssh_mock = mock.Mock(autospec=ssh.SSH)
353 mock.Mock(return_value=(1, "", ""))
354 ssh.return_value = ssh_mock
355 # NOTE(ralonsoh): this test doesn't cover function execution. This test
356 # should also check mocked function calls.
357 model.WAIT_FOR_BOOT = 0
358 status = model.StandaloneContextHelper.get_mgmt_ip(
359 ssh_mock, "99", "1.1.1.1/24", {})
360 self.assertIsNone(status)
363 class ServerTestCase(unittest.TestCase):
366 'mgmt': {'cidr': '152.16.100.10/24'},
368 'phy_port': "0000:05:00.0",
369 'vpci': "0000:00:07.0",
372 'cidr': '152.16.100.10/24',
373 'gateway_ip': '152.16.100.20'},
375 'phy_port': "0000:05:00.1",
376 'vpci': "0000:00:08.0",
379 'cidr': '152.16.40.10/24',
380 'gateway_ip': '152.16.100.20'}
384 self.server = model.Server()
386 def test___init__(self):
387 self.assertIsNotNone(self.server)
389 def test_build_vnf_interfaces(self):
392 'mgmt': {'cidr': '152.16.100.10/24'},
393 'xe0': ['private_0'],
397 status = model.Server.build_vnf_interfaces(vnf, self.NETWORKS)
398 self.assertIsNotNone(status)
400 def test_generate_vnf_instance(self):
403 'mgmt': {'cidr': '152.16.100.10/24'},
404 'xe0': ['private_0'],
408 status = self.server.generate_vnf_instance(
409 {}, self.NETWORKS, '1.1.1.1/24', 'vm_0', vnf, '00:00:00:00:00:01')
410 self.assertIsNotNone(status)
413 class OvsDeployTestCase(unittest.TestCase):
415 OVS_DETAILS = {'version': {'ovs': 'ovs_version', 'dpdk': 'dpdk_version'}}
418 self._mock_ssh = mock.patch.object(ssh, 'SSH')
419 self.mock_ssh = self._mock_ssh .start()
420 self.ovs_deploy = model.OvsDeploy(self.mock_ssh,
421 '/tmp/dpdk-devbind.py',
423 self._mock_path_isfile = mock.patch.object(os.path, 'isfile')
424 self._mock_path_join = mock.patch.object(os.path, 'join')
425 self.mock_path_isfile = self._mock_path_isfile.start()
426 self.mock_path_join = self._mock_path_join.start()
428 self.addCleanup(self._stop_mock)
430 def _stop_mock(self):
431 self._mock_ssh.stop()
432 self._mock_path_isfile.stop()
433 self._mock_path_join.stop()
435 @mock.patch.object(model.StandaloneContextHelper, 'install_req_libs')
436 def test_prerequisite(self, mock_install_req_libs):
437 pkgs = ["git", "build-essential", "pkg-config", "automake",
438 "autotools-dev", "libltdl-dev", "cmake", "libnuma-dev",
440 self.ovs_deploy.prerequisite()
441 mock_install_req_libs.assert_called_once_with(
442 self.ovs_deploy.connection, pkgs)
444 def test_ovs_deploy_no_file(self):
445 self.mock_path_isfile.return_value = False
446 mock_file = mock.Mock()
447 self.mock_path_join.return_value = mock_file
449 self.ovs_deploy.ovs_deploy()
450 self.mock_path_isfile.assert_called_once_with(mock_file)
451 self.mock_path_join.assert_called_once_with(
452 constants.YARDSTICK_ROOT_PATH,
453 'yardstick/resources/scripts/install/',
454 self.ovs_deploy.OVS_DEPLOY_SCRIPT)
456 @mock.patch.object(os.environ, 'get', return_value='test_proxy')
457 def test_ovs_deploy(self, mock_env_get):
458 self.mock_path_isfile.return_value = True
459 mock_deploy_file = mock.Mock()
460 mock_remove_ovs_deploy = mock.Mock()
461 self.mock_path_join.side_effect = [mock_deploy_file,
462 mock_remove_ovs_deploy]
463 dpdk_version = self.OVS_DETAILS['version']['dpdk']
464 ovs_version = self.OVS_DETAILS['version']['ovs']
466 with mock.patch.object(self.ovs_deploy.connection, 'put') as \
468 mock.patch.object(self.ovs_deploy.connection, 'execute') as \
470 mock.patch.object(self.ovs_deploy, 'prerequisite'):
471 mock_execute.return_value = (0, 0, 0)
472 self.ovs_deploy.ovs_deploy()
474 self.mock_path_isfile.assert_called_once_with(mock_deploy_file)
475 self.mock_path_join.assert_has_calls([
476 mock.call(constants.YARDSTICK_ROOT_PATH,
477 'yardstick/resources/scripts/install/',
478 self.ovs_deploy.OVS_DEPLOY_SCRIPT),
479 mock.call(self.ovs_deploy.bin_path,
480 self.ovs_deploy.OVS_DEPLOY_SCRIPT)
482 mock_put.assert_called_once_with(mock_deploy_file,
483 mock_remove_ovs_deploy)
484 cmd = ("sudo -E %(remote_ovs_deploy)s --ovs='%(ovs_version)s' "
485 "--dpdk='%(dpdk_version)s' -p='%(proxy)s'" %
486 {'remote_ovs_deploy': mock_remove_ovs_deploy,
487 'ovs_version': ovs_version,
488 'dpdk_version': dpdk_version,
489 'proxy': 'test_proxy'})
490 mock_execute.assert_called_once_with(cmd)
491 mock_env_get.assert_called_once_with('http_proxy', '')