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.
20 from xml.etree import ElementTree
22 from yardstick import ssh
23 from yardstick.benchmark.contexts.standalone import model
24 from yardstick import constants
25 from yardstick.network_services import utils
28 XML_SAMPLE = """<?xml version="1.0"?>
35 XML_SAMPLE_INTERFACE = """<?xml version="1.0"?>
45 class ModelLibvirtTestCase(unittest.TestCase):
48 self.xml = ElementTree.ElementTree(
49 element=ElementTree.fromstring(XML_SAMPLE))
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_write_xml = mock.patch.object(ElementTree.ElementTree,
55 self.mock_write_xml = self._mock_write_xml.start()
57 self.addCleanup(self._cleanup)
60 self._mock_write_xml.stop()
62 # TODO: Remove mocking of yardstick.ssh.SSH (here and elsewhere)
63 # In this case, we are mocking a param to be passed into other methods
64 # It can be a generic Mock() with return values set for the right methods
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)
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")
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)
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),
97 self.assertEqual('0x{}'.format(self.pci_address.bus),
99 self.assertEqual('0x{}'.format(self.pci_address.slot),
101 self.assertEqual('0x{}'.format(self.pci_address.function),
102 result.get('function'))
104 def test_add_ovs_interfaces(self):
105 xml_input = mock.Mock()
106 with mock.patch.object(ElementTree, 'parse', return_value=self.xml) \
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',
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 = mock.Mock()
133 with mock.patch.object(ElementTree, 'parse', return_value=self.xml) \
135 xml = copy.deepcopy(self.xml)
136 mock_parse.return_value = xml
137 vm_pci = '0001:05:04.2'
138 model.Libvirt.add_sriov_interfaces(
139 vm_pci, self.pci_address_str, 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 source_address = source.find('address')
149 self.assertIsNotNone(source.find('address'))
151 self.assertEqual('pci', source_address.get('type'))
152 self.assertEqual('0x' + self.pci_address_str.split(':')[0],
153 source_address.get('domain'))
154 self.assertEqual('0x' + self.pci_address_str.split(':')[1],
155 source_address.get('bus'))
156 self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[0],
157 source_address.get('slot'))
158 self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[1],
159 source_address.get('function'))
161 interface_address = interface.find('address')
162 self.assertEqual('pci', interface_address.get('type'))
163 self.assertEqual('0x' + vm_pci.split(':')[0],
164 interface_address.get('domain'))
165 self.assertEqual('0x' + vm_pci.split(':')[1],
166 interface_address.get('bus'))
167 self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[0],
168 interface_address.get('slot'))
169 self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[1],
170 interface_address.get('function'))
172 def test_create_snapshot_qemu(self):
173 result = "/var/lib/libvirt/images/0.qcow2"
174 with mock.patch("yardstick.ssh.SSH") as ssh:
175 ssh_mock = mock.Mock(autospec=ssh.SSH)
177 mock.Mock(return_value=(0, "a", ""))
178 ssh.return_value = ssh_mock
179 image = model.Libvirt.create_snapshot_qemu(ssh_mock, "0", "ubuntu.img")
180 self.assertEqual(image, result)
182 @mock.patch.object(model.Libvirt, 'pin_vcpu_for_perf')
183 @mock.patch.object(model.Libvirt, 'create_snapshot_qemu')
184 def test_build_vm_xml(self, mock_create_snapshot_qemu,
186 # NOTE(ralonsoh): this test doesn't cover function execution. This test
187 # should also check mocked function calls.
188 cfg_file = 'test_config_file.cfg'
189 self.addCleanup(os.remove, cfg_file)
191 with mock.patch("yardstick.ssh.SSH") as ssh:
192 ssh_mock = mock.Mock(autospec=ssh.SSH)
194 mock.Mock(return_value=(0, "a", ""))
195 ssh.return_value = ssh_mock
196 mock_create_snapshot_qemu.return_value = "0.img"
198 status = model.Libvirt.build_vm_xml(ssh_mock, {}, cfg_file, 'vm_0', 0)
199 self.assertEqual(status[0], result[0])
201 # TODO: Edit this test to test state instead of output
202 # update_interrupts_hugepages_perf does not return anything
203 def test_update_interrupts_hugepages_perf(self):
204 with mock.patch("yardstick.ssh.SSH") as ssh:
205 ssh_mock = mock.Mock(autospec=ssh.SSH)
207 mock.Mock(return_value=(0, "a", ""))
208 ssh.return_value = ssh_mock
209 # NOTE(ralonsoh): 'update_interrupts_hugepages_perf' always return
210 # None, this check is trivial.
211 #status = Libvirt.update_interrupts_hugepages_perf(ssh_mock)
212 #self.assertIsNone(status)
213 model.Libvirt.update_interrupts_hugepages_perf(ssh_mock)
215 @mock.patch.object(model, 'CpuSysCores')
216 @mock.patch.object(model.Libvirt, 'update_interrupts_hugepages_perf')
217 def test_pin_vcpu_for_perf(self, *args):
218 # NOTE(ralonsoh): test mocked methods/variables.
219 with mock.patch("yardstick.ssh.SSH") as ssh:
220 ssh_mock = mock.Mock(autospec=ssh.SSH)
222 mock.Mock(return_value=(0, "a", ""))
223 ssh.return_value = ssh_mock
224 status = model.Libvirt.pin_vcpu_for_perf(ssh_mock, 4)
225 self.assertIsNotNone(status)
227 class StandaloneContextHelperTestCase(unittest.TestCase):
229 NODE_SAMPLE = "nodes_sample.yaml"
230 NODE_SRIOV_SAMPLE = "nodes_sriov_sample.yaml"
233 'mgmt': {'cidr': '152.16.100.10/24'},
235 'phy_port': "0000:05:00.0",
236 'vpci': "0000:00:07.0",
237 'cidr': '152.16.100.10/24',
238 'gateway_ip': '152.16.100.20'},
240 'phy_port': "0000:05:00.1",
241 'vpci': "0000:00:08.0",
242 'cidr': '152.16.40.10/24',
243 'gateway_ip': '152.16.100.20'}
247 self.helper = model.StandaloneContextHelper()
249 def test___init__(self):
250 self.assertIsNone(self.helper.file_path)
252 def test_install_req_libs(self):
253 with mock.patch("yardstick.ssh.SSH") as ssh:
254 ssh_mock = mock.Mock(autospec=ssh.SSH)
256 mock.Mock(return_value=(1, "a", ""))
257 ssh.return_value = ssh_mock
258 # NOTE(ralonsoh): this test doesn't cover function execution. This test
259 # should also check mocked function calls.
260 model.StandaloneContextHelper.install_req_libs(ssh_mock)
262 def test_get_kernel_module(self):
263 with mock.patch("yardstick.ssh.SSH") as ssh:
264 ssh_mock = mock.Mock(autospec=ssh.SSH)
266 mock.Mock(return_value=(1, "i40e", ""))
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.get_kernel_module(
271 ssh_mock, "05:00.0", None)
273 @mock.patch.object(model.StandaloneContextHelper, 'get_kernel_module')
274 def test_get_nic_details(self, mock_get_kernel_module):
275 with mock.patch("yardstick.ssh.SSH") as ssh:
276 ssh_mock = mock.Mock(autospec=ssh.SSH)
277 ssh_mock.execute = mock.Mock(return_value=(1, "i40e ixgbe", ""))
278 ssh.return_value = ssh_mock
279 mock_get_kernel_module.return_value = "i40e"
280 # NOTE(ralonsoh): this test doesn't cover function execution. This test
281 # should also check mocked function calls.
282 model.StandaloneContextHelper.get_nic_details(
283 ssh_mock, self.NETWORKS, 'dpdk-devbind.py')
285 def test_get_virtual_devices(self):
286 pattern = "PCI_SLOT_NAME=0000:05:00.0"
287 with mock.patch("yardstick.ssh.SSH") as ssh:
288 ssh_mock = mock.Mock(autospec=ssh.SSH)
290 mock.Mock(return_value=(1, pattern, ""))
291 ssh.return_value = ssh_mock
292 # NOTE(ralonsoh): this test doesn't cover function execution. This test
293 # should also check mocked function calls.
294 model.StandaloneContextHelper.get_virtual_devices(
295 ssh_mock, '0000:00:05.0')
297 def _get_file_abspath(self, filename):
298 curr_path = os.path.dirname(os.path.abspath(__file__))
299 file_path = os.path.join(curr_path, filename)
302 def test_read_config_file(self):
303 self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE)
304 status = self.helper.read_config_file()
305 self.assertIsNotNone(status)
307 def test_parse_pod_file(self):
308 self.helper.file_path = self._get_file_abspath("dummy")
309 self.assertRaises(IOError, self.helper.parse_pod_file,
310 self.helper.file_path)
312 self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE)
313 self.assertRaises(TypeError, self.helper.parse_pod_file,
314 self.helper.file_path)
316 self.helper.file_path = self._get_file_abspath(self.NODE_SRIOV_SAMPLE)
317 self.assertIsNotNone(self.helper.parse_pod_file(self.helper.file_path))
319 def test_get_mac_address(self):
320 status = model.StandaloneContextHelper.get_mac_address()
321 self.assertIsNotNone(status)
323 @mock.patch('yardstick.ssh.SSH')
324 def test_get_mgmt_ip(self, *args):
325 # NOTE(ralonsoh): test mocked methods/variables.
326 with mock.patch("yardstick.ssh.SSH") as ssh:
327 ssh_mock = mock.Mock(autospec=ssh.SSH)
328 ssh_mock.execute = mock.Mock(
329 return_value=(1, "1.2.3.4 00:00:00:00:00:01", ""))
330 ssh.return_value = ssh_mock
331 # NOTE(ralonsoh): this test doesn't cover function execution. This test
332 # should also check mocked function calls.
333 status = model.StandaloneContextHelper.get_mgmt_ip(
334 ssh_mock, "00:00:00:00:00:01", "1.1.1.1/24", {})
335 self.assertIsNotNone(status)
337 @mock.patch('yardstick.ssh.SSH')
338 def test_get_mgmt_ip_no(self, *args):
339 # NOTE(ralonsoh): test mocked methods/variables.
340 with mock.patch("yardstick.ssh.SSH") as ssh:
341 ssh_mock = mock.Mock(autospec=ssh.SSH)
343 mock.Mock(return_value=(1, "", ""))
344 ssh.return_value = ssh_mock
345 # NOTE(ralonsoh): this test doesn't cover function execution. This test
346 # should also check mocked function calls.
347 model.WAIT_FOR_BOOT = 0
348 status = model.StandaloneContextHelper.get_mgmt_ip(
349 ssh_mock, "99", "1.1.1.1/24", {})
350 self.assertIsNone(status)
353 class ServerTestCase(unittest.TestCase):
356 'mgmt': {'cidr': '152.16.100.10/24'},
358 'phy_port': "0000:05:00.0",
359 'vpci': "0000:00:07.0",
362 'cidr': '152.16.100.10/24',
363 'gateway_ip': '152.16.100.20'},
365 'phy_port': "0000:05:00.1",
366 'vpci': "0000:00:08.0",
369 'cidr': '152.16.40.10/24',
370 'gateway_ip': '152.16.100.20'}
374 self.server = model.Server()
376 def test___init__(self):
377 self.assertIsNotNone(self.server)
379 def test_build_vnf_interfaces(self):
382 'mgmt': {'cidr': '152.16.100.10/24'},
383 'xe0': ['private_0'],
387 status = model.Server.build_vnf_interfaces(vnf, self.NETWORKS)
388 self.assertIsNotNone(status)
390 def test_generate_vnf_instance(self):
393 'mgmt': {'cidr': '152.16.100.10/24'},
394 'xe0': ['private_0'],
398 status = self.server.generate_vnf_instance(
399 {}, self.NETWORKS, '1.1.1.1/24', 'vm_0', vnf, '00:00:00:00:00:01')
400 self.assertIsNotNone(status)
403 class OvsDeployTestCase(unittest.TestCase):
405 OVS_DETAILS = {'version': {'ovs': 'ovs_version', 'dpdk': 'dpdk_version'}}
408 self._mock_ssh = mock.patch.object(ssh, 'SSH')
409 self.mock_ssh = self._mock_ssh .start()
410 self.ovs_deploy = model.OvsDeploy(self.mock_ssh,
411 '/tmp/dpdk-devbind.py',
413 self._mock_path_isfile = mock.patch.object(os.path, 'isfile')
414 self._mock_path_join = mock.patch.object(os.path, 'join')
415 self.mock_path_isfile = self._mock_path_isfile.start()
416 self.mock_path_join = self._mock_path_join.start()
418 self.addCleanup(self._stop_mock)
420 def _stop_mock(self):
421 self._mock_ssh.stop()
422 self._mock_path_isfile.stop()
423 self._mock_path_join.stop()
425 @mock.patch.object(model.StandaloneContextHelper, 'install_req_libs')
426 def test_prerequisite(self, mock_install_req_libs):
427 pkgs = ["git", "build-essential", "pkg-config", "automake",
428 "autotools-dev", "libltdl-dev", "cmake", "libnuma-dev",
430 self.ovs_deploy.prerequisite()
431 mock_install_req_libs.assert_called_once_with(
432 self.ovs_deploy.connection, pkgs)
434 def test_ovs_deploy_no_file(self):
435 self.mock_path_isfile.return_value = False
436 mock_file = mock.Mock()
437 self.mock_path_join.return_value = mock_file
439 self.ovs_deploy.ovs_deploy()
440 self.mock_path_isfile.assert_called_once_with(mock_file)
441 self.mock_path_join.assert_called_once_with(
442 constants.YARDSTICK_ROOT_PATH,
443 'yardstick/resources/scripts/install/',
444 self.ovs_deploy.OVS_DEPLOY_SCRIPT)
446 @mock.patch.object(os.environ, 'get', return_value='test_proxy')
447 def test_ovs_deploy(self, mock_env_get):
448 self.mock_path_isfile.return_value = True
449 mock_deploy_file = mock.Mock()
450 mock_remove_ovs_deploy = mock.Mock()
451 self.mock_path_join.side_effect = [mock_deploy_file,
452 mock_remove_ovs_deploy]
453 dpdk_version = self.OVS_DETAILS['version']['dpdk']
454 ovs_version = self.OVS_DETAILS['version']['ovs']
456 with mock.patch.object(self.ovs_deploy.connection, 'put') as \
458 mock.patch.object(self.ovs_deploy.connection, 'execute') as \
460 mock.patch.object(self.ovs_deploy, 'prerequisite'):
461 mock_execute.return_value = (0, 0, 0)
462 self.ovs_deploy.ovs_deploy()
464 self.mock_path_isfile.assert_called_once_with(mock_deploy_file)
465 self.mock_path_join.assert_has_calls([
466 mock.call(constants.YARDSTICK_ROOT_PATH,
467 'yardstick/resources/scripts/install/',
468 self.ovs_deploy.OVS_DEPLOY_SCRIPT),
469 mock.call(self.ovs_deploy.bin_path,
470 self.ovs_deploy.OVS_DEPLOY_SCRIPT)
472 mock_put.assert_called_once_with(mock_deploy_file,
473 mock_remove_ovs_deploy)
474 cmd = ("sudo -E %(remote_ovs_deploy)s --ovs='%(ovs_version)s' "
475 "--dpdk='%(dpdk_version)s' -p='%(proxy)s'" %
476 {'remote_ovs_deploy': mock_remove_ovs_deploy,
477 'ovs_version': ovs_version,
478 'dpdk_version': dpdk_version,
479 'proxy': 'test_proxy'})
480 mock_execute.assert_called_once_with(cmd)
481 mock_env_get.assert_called_once_with('http_proxy', '')