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 import constants
26 from yardstick.network_services import utils
29 XML_SAMPLE = """<?xml version="1.0"?>
36 XML_SAMPLE_INTERFACE = """<?xml version="1.0"?>
46 class ModelLibvirtTestCase(unittest.TestCase):
49 self.pci_address_str = '0001:04:03.2'
50 self.pci_address = utils.PciAddress(self.pci_address_str)
51 self.mac = '00:00:00:00:00:01'
53 # TODO: Remove mocking of yardstick.ssh.SSH (here and elsewhere)
54 # In this case, we are mocking a param to be passed into other methods
55 # It can be a generic Mock() with return values set for the right methods
56 def test_check_if_vm_exists_and_delete(self):
57 with mock.patch("yardstick.ssh.SSH") as ssh:
58 ssh_mock = mock.Mock(autospec=ssh.SSH)
59 ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
60 ssh.return_value = ssh_mock
61 # NOTE(ralonsoh): this test doesn't cover function execution.
62 model.Libvirt.check_if_vm_exists_and_delete("vm_0", ssh_mock)
64 def test_virsh_create_vm(self):
65 with mock.patch("yardstick.ssh.SSH") as ssh:
66 ssh_mock = mock.Mock(autospec=ssh.SSH)
67 ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
68 ssh.return_value = ssh_mock
69 # NOTE(ralonsoh): this test doesn't cover function execution.
70 model.Libvirt.virsh_create_vm(ssh_mock, "vm_0")
72 def test_virsh_destroy_vm(self):
73 with mock.patch("yardstick.ssh.SSH") as ssh:
74 ssh_mock = mock.Mock(autospec=ssh.SSH)
75 ssh_mock.execute = mock.Mock(return_value=(0, "a", ""))
76 ssh.return_value = ssh_mock
77 # NOTE(ralonsoh): this test doesn't cover function execution.
78 model.Libvirt.virsh_destroy_vm("vm_0", ssh_mock)
80 def test_add_interface_address(self):
81 xml = ElementTree.ElementTree(
82 element=ElementTree.fromstring(XML_SAMPLE_INTERFACE))
83 interface = xml.find('devices').find('interface')
84 result = model.Libvirt._add_interface_address(interface, self.pci_address)
85 self.assertEqual('pci', result.get('type'))
86 self.assertEqual('0x{}'.format(self.pci_address.domain),
88 self.assertEqual('0x{}'.format(self.pci_address.bus),
90 self.assertEqual('0x{}'.format(self.pci_address.slot),
92 self.assertEqual('0x{}'.format(self.pci_address.function),
93 result.get('function'))
95 def test_add_ovs_interfaces(self):
96 xml_input = copy.deepcopy(XML_SAMPLE)
97 xml_output = model.Libvirt.add_ovs_interface(
98 '/usr/local', 0, self.pci_address_str, self.mac, xml_input)
100 root = ElementTree.fromstring(xml_output)
101 et_out = ElementTree.ElementTree(element=root)
102 interface = et_out.find('devices').find('interface')
103 self.assertEqual('vhostuser', interface.get('type'))
104 mac = interface.find('mac')
105 self.assertEqual(self.mac, mac.get('address'))
106 source = interface.find('source')
107 self.assertEqual('unix', source.get('type'))
108 self.assertEqual('/usr/local/var/run/openvswitch/dpdkvhostuser0',
110 self.assertEqual('client', source.get('mode'))
111 _model = interface.find('model')
112 self.assertEqual('virtio', _model.get('type'))
113 driver = interface.find('driver')
114 self.assertEqual('4', driver.get('queues'))
115 host = driver.find('host')
116 self.assertEqual('off', host.get('mrg_rxbuf'))
117 self.assertIsNotNone(interface.find('address'))
119 def test_add_sriov_interfaces(self):
120 xml_input = copy.deepcopy(XML_SAMPLE)
121 vm_pci = '0001:05:04.2'
122 xml_output = model.Libvirt.add_sriov_interfaces(
123 vm_pci, self.pci_address_str, self.mac, xml_input)
124 root = ElementTree.fromstring(xml_output)
125 et_out = ElementTree.ElementTree(element=root)
126 interface = et_out.find('devices').find('interface')
127 self.assertEqual('yes', interface.get('managed'))
128 self.assertEqual('hostdev', interface.get('type'))
129 mac = interface.find('mac')
130 self.assertEqual(self.mac, mac.get('address'))
131 source = interface.find('source')
132 source_address = source.find('address')
133 self.assertIsNotNone(source.find('address'))
135 self.assertEqual('pci', source_address.get('type'))
136 self.assertEqual('0x' + self.pci_address_str.split(':')[0],
137 source_address.get('domain'))
138 self.assertEqual('0x' + self.pci_address_str.split(':')[1],
139 source_address.get('bus'))
140 self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[0],
141 source_address.get('slot'))
142 self.assertEqual('0x' + self.pci_address_str.split(':')[2].split('.')[1],
143 source_address.get('function'))
145 interface_address = interface.find('address')
146 self.assertEqual('pci', interface_address.get('type'))
147 self.assertEqual('0x' + vm_pci.split(':')[0],
148 interface_address.get('domain'))
149 self.assertEqual('0x' + vm_pci.split(':')[1],
150 interface_address.get('bus'))
151 self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[0],
152 interface_address.get('slot'))
153 self.assertEqual('0x' + vm_pci.split(':')[2].split('.')[1],
154 interface_address.get('function'))
156 def test_create_snapshot_qemu(self):
157 result = "/var/lib/libvirt/images/0.qcow2"
158 with mock.patch("yardstick.ssh.SSH") as ssh:
159 ssh_mock = mock.Mock(autospec=ssh.SSH)
161 mock.Mock(return_value=(0, "a", ""))
162 ssh.return_value = ssh_mock
163 image = model.Libvirt.create_snapshot_qemu(ssh_mock, "0", "ubuntu.img")
164 self.assertEqual(image, result)
166 @mock.patch.object(model.Libvirt, 'pin_vcpu_for_perf', return_value='4,5')
167 @mock.patch.object(model.Libvirt, 'create_snapshot_qemu',
168 return_value='qemu_image')
169 def test_build_vm_xml(self, mock_create_snapshot_qemu,
170 mock_pin_vcpu_for_perf):
171 extra_specs = {'hw:cpu_cores': '4',
172 'hw:cpu_sockets': '3',
173 'hw:cpu_threads': '2',
175 flavor = {'ram': '1024',
176 'extra_specs': extra_specs,
179 mac = model.StandaloneContextHelper.get_mac_address(0x00)
181 connection = mock.Mock()
182 with mock.patch.object(model.StandaloneContextHelper,
183 'get_mac_address', return_value=mac) as \
184 mock_get_mac_address, \
185 mock.patch.object(uuid, 'uuid4', return_value=_uuid):
186 xml_out, mac = model.Libvirt.build_vm_xml(
187 connection, flavor, 'vm_name', 100)
189 xml_ref = model.VM_TEMPLATE.format(vm_name='vm_name',
190 random_uuid=_uuid, mac_addr=mac, memory='1024', vcpu='8', cpu='4',
191 numa_cpus='0-7', socket='3', threads='2',
192 vm_image='qemu_image', cpuset='4,5', cputune='cool')
193 self.assertEqual(xml_ref, xml_out)
194 mock_get_mac_address.assert_called_once_with(0x00)
195 mock_create_snapshot_qemu.assert_called_once_with(
196 connection, 100, 'images')
197 mock_pin_vcpu_for_perf.assert_called_once_with(connection, '1')
199 # TODO: Edit this test to test state instead of output
200 # update_interrupts_hugepages_perf does not return anything
201 def test_update_interrupts_hugepages_perf(self):
202 with mock.patch("yardstick.ssh.SSH") as ssh:
203 ssh_mock = mock.Mock(autospec=ssh.SSH)
205 mock.Mock(return_value=(0, "a", ""))
206 ssh.return_value = ssh_mock
207 # NOTE(ralonsoh): 'update_interrupts_hugepages_perf' always return
208 # None, this check is trivial.
209 #status = Libvirt.update_interrupts_hugepages_perf(ssh_mock)
210 #self.assertIsNone(status)
211 model.Libvirt.update_interrupts_hugepages_perf(ssh_mock)
213 @mock.patch.object(model, 'CpuSysCores')
214 @mock.patch.object(model.Libvirt, 'update_interrupts_hugepages_perf')
215 def test_pin_vcpu_for_perf(self, *args):
216 # NOTE(ralonsoh): test mocked methods/variables.
217 with mock.patch("yardstick.ssh.SSH") as ssh:
218 ssh_mock = mock.Mock(autospec=ssh.SSH)
220 mock.Mock(return_value=(0, "a", ""))
221 ssh.return_value = ssh_mock
222 status = model.Libvirt.pin_vcpu_for_perf(ssh_mock, 4)
223 self.assertIsNotNone(status)
225 class StandaloneContextHelperTestCase(unittest.TestCase):
227 NODE_SAMPLE = "nodes_sample.yaml"
228 NODE_SRIOV_SAMPLE = "nodes_sriov_sample.yaml"
231 'mgmt': {'cidr': '152.16.100.10/24'},
233 'phy_port': "0000:05:00.0",
234 'vpci': "0000:00:07.0",
235 'cidr': '152.16.100.10/24',
236 'gateway_ip': '152.16.100.20'},
238 'phy_port': "0000:05:00.1",
239 'vpci': "0000:00:08.0",
240 'cidr': '152.16.40.10/24',
241 'gateway_ip': '152.16.100.20'}
245 self.helper = model.StandaloneContextHelper()
247 def test___init__(self):
248 self.assertIsNone(self.helper.file_path)
250 def test_install_req_libs(self):
251 with mock.patch("yardstick.ssh.SSH") as ssh:
252 ssh_mock = mock.Mock(autospec=ssh.SSH)
254 mock.Mock(return_value=(1, "a", ""))
255 ssh.return_value = ssh_mock
256 # NOTE(ralonsoh): this test doesn't cover function execution. This test
257 # should also check mocked function calls.
258 model.StandaloneContextHelper.install_req_libs(ssh_mock)
260 def test_get_kernel_module(self):
261 with mock.patch("yardstick.ssh.SSH") as ssh:
262 ssh_mock = mock.Mock(autospec=ssh.SSH)
264 mock.Mock(return_value=(1, "i40e", ""))
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_kernel_module(
269 ssh_mock, "05:00.0", None)
271 @mock.patch.object(model.StandaloneContextHelper, 'get_kernel_module')
272 def test_get_nic_details(self, mock_get_kernel_module):
273 with mock.patch("yardstick.ssh.SSH") as ssh:
274 ssh_mock = mock.Mock(autospec=ssh.SSH)
275 ssh_mock.execute = mock.Mock(return_value=(1, "i40e ixgbe", ""))
276 ssh.return_value = ssh_mock
277 mock_get_kernel_module.return_value = "i40e"
278 # NOTE(ralonsoh): this test doesn't cover function execution. This test
279 # should also check mocked function calls.
280 model.StandaloneContextHelper.get_nic_details(
281 ssh_mock, self.NETWORKS, 'dpdk-devbind.py')
283 def test_get_virtual_devices(self):
284 pattern = "PCI_SLOT_NAME=0000:05:00.0"
285 with mock.patch("yardstick.ssh.SSH") as ssh:
286 ssh_mock = mock.Mock(autospec=ssh.SSH)
288 mock.Mock(return_value=(1, pattern, ""))
289 ssh.return_value = ssh_mock
290 # NOTE(ralonsoh): this test doesn't cover function execution. This test
291 # should also check mocked function calls.
292 model.StandaloneContextHelper.get_virtual_devices(
293 ssh_mock, '0000:00:05.0')
295 def _get_file_abspath(self, filename):
296 curr_path = os.path.dirname(os.path.abspath(__file__))
297 file_path = os.path.join(curr_path, filename)
300 def test_read_config_file(self):
301 self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE)
302 status = self.helper.read_config_file()
303 self.assertIsNotNone(status)
305 def test_parse_pod_file(self):
306 self.helper.file_path = self._get_file_abspath("dummy")
307 self.assertRaises(IOError, self.helper.parse_pod_file,
308 self.helper.file_path)
310 self.helper.file_path = self._get_file_abspath(self.NODE_SAMPLE)
311 self.assertRaises(TypeError, self.helper.parse_pod_file,
312 self.helper.file_path)
314 self.helper.file_path = self._get_file_abspath(self.NODE_SRIOV_SAMPLE)
315 self.assertIsNotNone(self.helper.parse_pod_file(self.helper.file_path))
317 def test_get_mac_address(self):
318 status = model.StandaloneContextHelper.get_mac_address()
319 self.assertIsNotNone(status)
321 @mock.patch('yardstick.ssh.SSH')
322 def test_get_mgmt_ip(self, *args):
323 # NOTE(ralonsoh): test mocked methods/variables.
324 with mock.patch("yardstick.ssh.SSH") as ssh:
325 ssh_mock = mock.Mock(autospec=ssh.SSH)
326 ssh_mock.execute = mock.Mock(
327 return_value=(1, "1.2.3.4 00:00:00:00:00:01", ""))
328 ssh.return_value = ssh_mock
329 # NOTE(ralonsoh): this test doesn't cover function execution. This test
330 # should also check mocked function calls.
331 status = model.StandaloneContextHelper.get_mgmt_ip(
332 ssh_mock, "00:00:00:00:00:01", "1.1.1.1/24", {})
333 self.assertIsNotNone(status)
335 @mock.patch('yardstick.ssh.SSH')
336 def test_get_mgmt_ip_no(self, *args):
337 # NOTE(ralonsoh): test mocked methods/variables.
338 with mock.patch("yardstick.ssh.SSH") as ssh:
339 ssh_mock = mock.Mock(autospec=ssh.SSH)
341 mock.Mock(return_value=(1, "", ""))
342 ssh.return_value = ssh_mock
343 # NOTE(ralonsoh): this test doesn't cover function execution. This test
344 # should also check mocked function calls.
345 model.WAIT_FOR_BOOT = 0
346 status = model.StandaloneContextHelper.get_mgmt_ip(
347 ssh_mock, "99", "1.1.1.1/24", {})
348 self.assertIsNone(status)
351 class ServerTestCase(unittest.TestCase):
354 'mgmt': {'cidr': '152.16.100.10/24'},
356 'phy_port': "0000:05:00.0",
357 'vpci': "0000:00:07.0",
360 'cidr': '152.16.100.10/24',
361 'gateway_ip': '152.16.100.20'},
363 'phy_port': "0000:05:00.1",
364 'vpci': "0000:00:08.0",
367 'cidr': '152.16.40.10/24',
368 'gateway_ip': '152.16.100.20'}
372 self.server = model.Server()
374 def test___init__(self):
375 self.assertIsNotNone(self.server)
377 def test_build_vnf_interfaces(self):
380 'mgmt': {'cidr': '152.16.100.10/24'},
381 'xe0': ['private_0'],
385 status = model.Server.build_vnf_interfaces(vnf, self.NETWORKS)
386 self.assertIsNotNone(status)
388 def test_generate_vnf_instance(self):
391 'mgmt': {'cidr': '152.16.100.10/24'},
392 'xe0': ['private_0'],
396 status = self.server.generate_vnf_instance(
397 {}, self.NETWORKS, '1.1.1.1/24', 'vm_0', vnf, '00:00:00:00:00:01')
398 self.assertIsNotNone(status)
401 class OvsDeployTestCase(unittest.TestCase):
403 OVS_DETAILS = {'version': {'ovs': 'ovs_version', 'dpdk': 'dpdk_version'}}
406 self._mock_ssh = mock.patch.object(ssh, 'SSH')
407 self.mock_ssh = self._mock_ssh .start()
408 self.ovs_deploy = model.OvsDeploy(self.mock_ssh,
409 '/tmp/dpdk-devbind.py',
411 self._mock_path_isfile = mock.patch.object(os.path, 'isfile')
412 self._mock_path_join = mock.patch.object(os.path, 'join')
413 self.mock_path_isfile = self._mock_path_isfile.start()
414 self.mock_path_join = self._mock_path_join.start()
416 self.addCleanup(self._stop_mock)
418 def _stop_mock(self):
419 self._mock_ssh.stop()
420 self._mock_path_isfile.stop()
421 self._mock_path_join.stop()
423 @mock.patch.object(model.StandaloneContextHelper, 'install_req_libs')
424 def test_prerequisite(self, mock_install_req_libs):
425 pkgs = ["git", "build-essential", "pkg-config", "automake",
426 "autotools-dev", "libltdl-dev", "cmake", "libnuma-dev",
428 self.ovs_deploy.prerequisite()
429 mock_install_req_libs.assert_called_once_with(
430 self.ovs_deploy.connection, pkgs)
432 def test_ovs_deploy_no_file(self):
433 self.mock_path_isfile.return_value = False
434 mock_file = mock.Mock()
435 self.mock_path_join.return_value = mock_file
437 self.ovs_deploy.ovs_deploy()
438 self.mock_path_isfile.assert_called_once_with(mock_file)
439 self.mock_path_join.assert_called_once_with(
440 constants.YARDSTICK_ROOT_PATH,
441 'yardstick/resources/scripts/install/',
442 self.ovs_deploy.OVS_DEPLOY_SCRIPT)
444 @mock.patch.object(os.environ, 'get', return_value='test_proxy')
445 def test_ovs_deploy(self, mock_env_get):
446 self.mock_path_isfile.return_value = True
447 mock_deploy_file = mock.Mock()
448 mock_remove_ovs_deploy = mock.Mock()
449 self.mock_path_join.side_effect = [mock_deploy_file,
450 mock_remove_ovs_deploy]
451 dpdk_version = self.OVS_DETAILS['version']['dpdk']
452 ovs_version = self.OVS_DETAILS['version']['ovs']
454 with mock.patch.object(self.ovs_deploy.connection, 'put') as \
456 mock.patch.object(self.ovs_deploy.connection, 'execute') as \
458 mock.patch.object(self.ovs_deploy, 'prerequisite'):
459 mock_execute.return_value = (0, 0, 0)
460 self.ovs_deploy.ovs_deploy()
462 self.mock_path_isfile.assert_called_once_with(mock_deploy_file)
463 self.mock_path_join.assert_has_calls([
464 mock.call(constants.YARDSTICK_ROOT_PATH,
465 'yardstick/resources/scripts/install/',
466 self.ovs_deploy.OVS_DEPLOY_SCRIPT),
467 mock.call(self.ovs_deploy.bin_path,
468 self.ovs_deploy.OVS_DEPLOY_SCRIPT)
470 mock_put.assert_called_once_with(mock_deploy_file,
471 mock_remove_ovs_deploy)
472 cmd = ("sudo -E %(remote_ovs_deploy)s --ovs='%(ovs_version)s' "
473 "--dpdk='%(dpdk_version)s' -p='%(proxy)s'" %
474 {'remote_ovs_deploy': mock_remove_ovs_deploy,
475 'ovs_version': ovs_version,
476 'dpdk_version': dpdk_version,
477 'proxy': 'test_proxy'})
478 mock_execute.assert_called_once_with(cmd)
479 mock_env_get.assert_called_once_with('http_proxy', '')