Extends pci devices metrics
Collects PCI class, revision, and bus information for the pci-devices collector, these metrics as well as vendor id and device id are components which can be used to construct device information like lspci output, which is how cyborg agent collects accelerator devices. Accelerator device based scheduling is possible after ironic has such information in place. Change-Id: I6c37c554f37dd5f1d21c8fd4fad2a4f44a3c75d7 Story: 2007971 Task: 40474
This commit is contained in:
parent
a9ed390f08
commit
b424fbfa35
@ -315,17 +315,38 @@ def collect_pci_devices_info(data, failures):
|
||||
with open(os.path.join(pci_devices_path, subdir,
|
||||
'device')) as vendor_device:
|
||||
device = vendor_device.read().strip().split('x')[1]
|
||||
with open(os.path.join(pci_devices_path, subdir,
|
||||
'class')) as vendor_device:
|
||||
pci_class = vendor_device.read().strip().split('x')[1]
|
||||
except IOError as exc:
|
||||
LOG.warning('Failed to gather vendor id or product id '
|
||||
LOG.warning('Failed to gather vendor id, product id or pci class '
|
||||
'from PCI device %s: %s', subdir, exc)
|
||||
continue
|
||||
except IndexError as exc:
|
||||
LOG.warning('Wrong format of vendor id or product id in PCI '
|
||||
'device %s: %s', subdir, exc)
|
||||
LOG.warning('Wrong format of vendor id, product id or pci class '
|
||||
'in PCI device %s: %s', subdir, exc)
|
||||
continue
|
||||
|
||||
pci_revision = None
|
||||
pci_revision_path = os.path.join(pci_devices_path, subdir,
|
||||
'revision')
|
||||
if os.path.isfile(pci_revision_path):
|
||||
try:
|
||||
with open(pci_revision_path) as revision_file:
|
||||
pci_revision = revision_file.read().strip().split('x')[1]
|
||||
except IOError as exc:
|
||||
LOG.warning('Failed to gather PCI revision from PCI '
|
||||
'device %s: %s', subdir, exc)
|
||||
except IndexError as exc:
|
||||
LOG.warning('Wrong format of PCI revision in PCI '
|
||||
'device %s: %s', subdir, exc)
|
||||
|
||||
LOG.debug(
|
||||
'Found a PCI device with vendor id %s and product id %s',
|
||||
vendor, device)
|
||||
'Found a PCI device with vendor id %s, product id %s, class %s '
|
||||
'and revision %s', vendor, device, pci_class, pci_revision)
|
||||
pci_devices_info.append({'vendor_id': vendor,
|
||||
'product_id': device})
|
||||
'product_id': device,
|
||||
'class': pci_class,
|
||||
'revision': pci_revision,
|
||||
'bus': subdir})
|
||||
data['pci_devices'] = pci_devices_info
|
||||
|
@ -361,14 +361,21 @@ class TestCollectPciDevicesInfo(base.IronicAgentTest):
|
||||
self.data = {}
|
||||
self.failures = utils.AccumulatedFailures()
|
||||
|
||||
@mock.patch.object(os.path, 'isfile', autospec=True)
|
||||
@mock.patch.object(os.path, 'isdir', autospec=True)
|
||||
def test_success(self, mock_isdir, mock_listdir):
|
||||
def test_success(self, mock_isdir, mock_isfile, mock_listdir):
|
||||
subdirs = ['foo', 'bar']
|
||||
mock_listdir.return_value = subdirs
|
||||
mock_isfile.return_value = True
|
||||
mock_isdir.return_value = True
|
||||
reads = ['0x1234', '0x5678', '0x9876', '0x5432']
|
||||
expected_pci_devices = [{'vendor_id': '1234', 'product_id': '5678'},
|
||||
{'vendor_id': '9876', 'product_id': '5432'}]
|
||||
reads = ['0x1234', '0x5678', '0x060000', '0x01',
|
||||
'0x9876', '0x5432', '0x030000', '0x00']
|
||||
expected_pci_devices = [{'vendor_id': '1234', 'product_id': '5678',
|
||||
'class': '060000', 'revision': '01',
|
||||
'bus': 'foo'},
|
||||
{'vendor_id': '9876', 'product_id': '5432',
|
||||
'class': '030000', 'revision': '00',
|
||||
'bus': 'bar'}]
|
||||
|
||||
mock_open = mock.mock_open()
|
||||
with mock.patch('builtins.open', mock_open):
|
||||
@ -376,7 +383,7 @@ class TestCollectPciDevicesInfo(base.IronicAgentTest):
|
||||
mock_read.side_effect = reads
|
||||
inspector.collect_pci_devices_info(self.data, self.failures)
|
||||
|
||||
self.assertEqual(2 * len(subdirs), mock_open.call_count)
|
||||
self.assertEqual(4 * len(subdirs), mock_open.call_count)
|
||||
self.assertListEqual(expected_pci_devices, self.data['pci_devices'])
|
||||
|
||||
def test_wrong_path(self, mock_listdir):
|
||||
@ -387,14 +394,18 @@ class TestCollectPciDevicesInfo(base.IronicAgentTest):
|
||||
self.assertNotIn('pci_devices', self.data)
|
||||
self.assertEqual(1, len(self.failures._failures))
|
||||
|
||||
@mock.patch.object(os.path, 'isfile', autospec=True)
|
||||
@mock.patch.object(os.path, 'isdir', autospec=True)
|
||||
def test_bad_pci_device_info(self, mock_isdir, mock_listdir):
|
||||
def test_bad_pci_device_info(self, mock_isdir, mock_isfile, mock_listdir):
|
||||
subdirs = ['foo', 'bar', 'baz']
|
||||
mock_listdir.return_value = subdirs
|
||||
mock_isfile.return_value = False
|
||||
mock_isdir.return_value = True
|
||||
reads = ['0x1234', '0x5678', '0x9876', IOError, IndexError,
|
||||
'0x5432']
|
||||
expected_pci_devices = [{'vendor_id': '1234', 'product_id': '5678'}]
|
||||
reads = ['0x1234', '0x5678', '0x060000', '0x9876',
|
||||
IOError, IndexError]
|
||||
expected_pci_devices = [{'vendor_id': '1234', 'product_id': '5678',
|
||||
'class': '060000', 'revision': None,
|
||||
'bus': 'foo'}]
|
||||
|
||||
mock_open = mock.mock_open()
|
||||
with mock.patch('builtins.open', mock_open):
|
||||
@ -403,8 +414,8 @@ class TestCollectPciDevicesInfo(base.IronicAgentTest):
|
||||
inspector.collect_pci_devices_info(self.data, self.failures)
|
||||
|
||||
# note(sborkows): due to throwing IOError, the corresponding mock_open
|
||||
# will not be called, so there are 5 mock_open calls in total
|
||||
self.assertEqual(5, mock_open.call_count)
|
||||
# will not be called, so there are 6 mock_open calls in total
|
||||
self.assertEqual(6, mock_open.call_count)
|
||||
self.assertListEqual(expected_pci_devices, self.data['pci_devices'])
|
||||
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Introspection of PCI devices now collects PCI class, revision and PCI bus.
|
Loading…
Reference in New Issue
Block a user