diff --git a/nova/pci/utils.py b/nova/pci/utils.py index 489853e2c317..a15dc1bfaec5 100644 --- a/nova/pci/utils.py +++ b/nova/pci/utils.py @@ -45,11 +45,19 @@ def pci_device_prop_match(pci_dev, specs): b) Device with vendor_id as 0x10de and product_id as 0x10d8: [{"vendor_id":"8086", "product_id":"8259"}, - {"vendor_id":"10de", "product_id":"10d8"}] + {"vendor_id":"10de", "product_id":"10d8", + "capabilities_network": ["rx", "tx", "tso", "gso"]}] """ def _matching_devices(spec): - return all(pci_dev.get(k) == v for k, v in spec.items()) + for k, v in spec.items(): + pci_dev_v = pci_dev.get(k) + if isinstance(v, list) and isinstance(pci_dev_v, list): + if not all(x in pci_dev.get(k) for x in v): + return False + elif pci_dev_v != v: + return False + return True return any(_matching_devices(spec) for spec in specs) diff --git a/nova/tests/unit/pci/test_utils.py b/nova/tests/unit/pci/test_utils.py index 3c44336f4967..b86f0fab7a8d 100644 --- a/nova/tests/unit/pci/test_utils.py +++ b/nova/tests/unit/pci/test_utils.py @@ -30,7 +30,8 @@ class PciDeviceMatchTestCase(test.NoDBTestCase): def setUp(self): super(PciDeviceMatchTestCase, self).setUp() self.fake_pci_1 = {'vendor_id': 'v1', - 'device_id': 'd1'} + 'device_id': 'd1', + 'capabilities_network': ['cap1', 'cap2', 'cap3']} def test_single_spec_match(self): self.assertTrue(utils.pci_device_prop_match( @@ -53,6 +54,24 @@ class PciDeviceMatchTestCase(test.NoDBTestCase): self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1', 'wrong_key': 'k1'}])) + def test_spec_list(self): + self.assertTrue(utils.pci_device_prop_match( + self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1', + 'capabilities_network': ['cap1', 'cap2', + 'cap3']}])) + self.assertTrue(utils.pci_device_prop_match( + self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1', + 'capabilities_network': ['cap3', 'cap1']}])) + + def test_spec_list_no_matching(self): + self.assertFalse(utils.pci_device_prop_match( + self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': 'd1', + 'capabilities_network': ['cap1', 'cap33']}])) + + def test_spec_list_wrong_type(self): + self.assertFalse(utils.pci_device_prop_match( + self.fake_pci_1, [{'vendor_id': 'v1', 'device_id': ['d1']}])) + class PciDeviceAddressParserTestCase(test.NoDBTestCase): def test_parse_address(self):