|
15 | 15 |
|
16 | 16 | """Tests for PCI request."""
|
17 | 17 |
|
| 18 | +import mock |
| 19 | + |
| 20 | +from oslo_utils.fixture import uuidsentinel |
| 21 | + |
| 22 | +from nova import context |
18 | 23 | from nova import exception
|
| 24 | +from nova.network import model |
| 25 | +from nova import objects |
19 | 26 | from nova.pci import request
|
20 | 27 | from nova import test
|
| 28 | +from nova.tests.unit.api.openstack import fakes |
21 | 29 |
|
22 | 30 |
|
23 | 31 | _fake_alias1 = """{
|
|
62 | 70 | }"""
|
63 | 71 |
|
64 | 72 |
|
65 |
| -class AliasTestCase(test.NoDBTestCase): |
| 73 | +class PciRequestTestCase(test.NoDBTestCase): |
| 74 | + |
| 75 | + @staticmethod |
| 76 | + def _create_fake_inst_with_pci_devs(pci_req_list, pci_dev_list): |
| 77 | + """Create a fake Instance object with the provided InstancePciRequests |
| 78 | + and PciDevices. |
| 79 | +
|
| 80 | + :param pci_req_list: a list of InstancePCIRequest objects. |
| 81 | + :param pci_dev_list: a list of PciDevice objects, each element |
| 82 | + associated (via request_id attribute)with a corresponding |
| 83 | + element from pci_req_list. |
| 84 | + :return: A fake Instance object associated with the provided |
| 85 | + PciRequests and PciDevices. |
| 86 | + """ |
| 87 | + |
| 88 | + inst = objects.Instance() |
| 89 | + inst.uuid = uuidsentinel.instance1 |
| 90 | + inst.pci_requests = objects.InstancePCIRequests( |
| 91 | + requests=pci_req_list) |
| 92 | + inst.pci_devices = objects.PciDeviceList(objects=pci_dev_list) |
| 93 | + inst.host = 'fake-host' |
| 94 | + inst.node = 'fake-node' |
| 95 | + return inst |
| 96 | + |
| 97 | + def setUp(self): |
| 98 | + super(PciRequestTestCase, self).setUp() |
| 99 | + self.context = context.RequestContext(fakes.FAKE_USER_ID, |
| 100 | + fakes.FAKE_PROJECT_ID) |
| 101 | + self.mock_inst_cn = mock.Mock() |
66 | 102 |
|
67 | 103 | def test_valid_alias(self):
|
68 | 104 | self.flags(alias=[_fake_alias1], group='pci')
|
@@ -232,6 +268,99 @@ def test_alias_2_request_invalid(self):
|
232 | 268 | request._translate_alias_to_requests,
|
233 | 269 | "QuicAssistX : 3")
|
234 | 270 |
|
| 271 | + @mock.patch.object(objects.compute_node.ComputeNode, |
| 272 | + 'get_by_host_and_nodename') |
| 273 | + def test_get_instance_pci_request_from_vif_invalid( |
| 274 | + self, |
| 275 | + cn_get_by_host_and_node): |
| 276 | + # Basically make sure we raise an exception if an instance |
| 277 | + # has an allocated PCI device without having the its corresponding |
| 278 | + # PCIRequest object in instance.pci_requests |
| 279 | + self.mock_inst_cn.id = 1 |
| 280 | + cn_get_by_host_and_node.return_value = self.mock_inst_cn |
| 281 | + |
| 282 | + # Create a fake instance with PCI request and allocated PCI devices |
| 283 | + pci_dev1 = objects.PciDevice(request_id=uuidsentinel.pci_req_id1, |
| 284 | + address='0000:04:00.0', |
| 285 | + compute_node_id=1) |
| 286 | + |
| 287 | + pci_req2 = objects.InstancePCIRequest( |
| 288 | + request_id=uuidsentinel.pci_req_id2) |
| 289 | + pci_dev2 = objects.PciDevice(request_id=uuidsentinel.pci_req_id2, |
| 290 | + address='0000:05:00.0', |
| 291 | + compute_node_id=1) |
| 292 | + pci_request_list = [pci_req2] |
| 293 | + pci_device_list = [pci_dev1, pci_dev2] |
| 294 | + inst = PciRequestTestCase._create_fake_inst_with_pci_devs( |
| 295 | + pci_request_list, |
| 296 | + pci_device_list) |
| 297 | + # Create a VIF with pci_dev1 that has no corresponding PCI request |
| 298 | + pci_vif = model.VIF(vnic_type=model.VNIC_TYPE_DIRECT, |
| 299 | + profile={'pci_slot': '0000:04:00.0'}) |
| 300 | + |
| 301 | + self.assertRaises(exception.PciRequestFromVIFNotFound, |
| 302 | + request.get_instance_pci_request_from_vif, |
| 303 | + self.context, |
| 304 | + inst, |
| 305 | + pci_vif) |
| 306 | + |
| 307 | + @mock.patch.object(objects.compute_node.ComputeNode, |
| 308 | + 'get_by_host_and_nodename') |
| 309 | + def test_get_instance_pci_request_from_vif(self, cn_get_by_host_and_node): |
| 310 | + self.mock_inst_cn.id = 1 |
| 311 | + cn_get_by_host_and_node.return_value = self.mock_inst_cn |
| 312 | + |
| 313 | + # Create a fake instance with PCI request and allocated PCI devices |
| 314 | + pci_req1 = objects.InstancePCIRequest( |
| 315 | + request_id=uuidsentinel.pci_req_id1) |
| 316 | + pci_dev1 = objects.PciDevice(request_id=uuidsentinel.pci_req_id1, |
| 317 | + address='0000:04:00.0', |
| 318 | + compute_node_id = 1) |
| 319 | + pci_req2 = objects.InstancePCIRequest( |
| 320 | + request_id=uuidsentinel.pci_req_id2) |
| 321 | + pci_dev2 = objects.PciDevice(request_id=uuidsentinel.pci_req_id2, |
| 322 | + address='0000:05:00.0', |
| 323 | + compute_node_id=1) |
| 324 | + pci_request_list = [pci_req1, pci_req2] |
| 325 | + pci_device_list = [pci_dev1, pci_dev2] |
| 326 | + inst = PciRequestTestCase._create_fake_inst_with_pci_devs( |
| 327 | + pci_request_list, |
| 328 | + pci_device_list) |
| 329 | + |
| 330 | + # Create a vif with normal port and make sure no PCI request returned |
| 331 | + normal_vif = model.VIF(vnic_type=model.VNIC_TYPE_NORMAL) |
| 332 | + self.assertIsNone(request.get_instance_pci_request_from_vif( |
| 333 | + self.context, |
| 334 | + inst, |
| 335 | + normal_vif)) |
| 336 | + |
| 337 | + # Create a vif with PCI address under profile, make sure the correct |
| 338 | + # PCI request is returned |
| 339 | + pci_vif = model.VIF(vnic_type=model.VNIC_TYPE_DIRECT, |
| 340 | + profile={'pci_slot': '0000:05:00.0'}) |
| 341 | + self.assertEqual(uuidsentinel.pci_req_id2, |
| 342 | + request.get_instance_pci_request_from_vif( |
| 343 | + self.context, |
| 344 | + inst, |
| 345 | + pci_vif).request_id) |
| 346 | + |
| 347 | + # Create a vif with PCI under profile which is not claimed |
| 348 | + # for the instance, i.e no matching pci device in instance.pci_devices |
| 349 | + nonclaimed_pci_vif = model.VIF(vnic_type=model.VNIC_TYPE_DIRECT, |
| 350 | + profile={'pci_slot': '0000:08:00.0'}) |
| 351 | + self.assertIsNone(request.get_instance_pci_request_from_vif( |
| 352 | + self.context, |
| 353 | + inst, |
| 354 | + nonclaimed_pci_vif)) |
| 355 | + |
| 356 | + # "Move" the instance to another compute node, make sure that no |
| 357 | + # matching PCI request against the new compute. |
| 358 | + self.mock_inst_cn.id = 2 |
| 359 | + self.assertIsNone(request.get_instance_pci_request_from_vif( |
| 360 | + self.context, |
| 361 | + inst, |
| 362 | + pci_vif)) |
| 363 | + |
235 | 364 | def test_get_pci_requests_from_flavor(self):
|
236 | 365 | self.flags(alias=[_fake_alias1, _fake_alias3], group='pci')
|
237 | 366 | expect_request = [
|
|
0 commit comments