From 9c621a91199c093f603ef30ba3daf59010c20e47 Mon Sep 17 00:00:00 2001 From: karolinku Date: Thu, 10 Apr 2025 09:14:51 +0200 Subject: [PATCH 26/37] Add handling of shorten PCI ID and lowercases HW data file is inconsistent and sometimes contains both upper/lower cases so this patch is unifying it. Also PCI ID can be passed as full ID: Vendor:Device:SVendor:SDevice, but also in shorten version: Vendor:Device. This patch introduce handling of both cases. The data comming from DDDD file was sanitised. JIRA: RHEL-72544 --- .../deviceanddriverdeprecationdataload.py | 9 +++ .../libraries/pcidevicesscanner.py | 19 ++++-- .../tests/test_pcidevicesscanner.py | 64 +++++++++++++++++-- 3 files changed, 81 insertions(+), 11 deletions(-) diff --git a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py index b12e77c9..acea583d 100644 --- a/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py +++ b/repos/system_upgrade/common/actors/loaddevicedriverdeprecationdata/libraries/deviceanddriverdeprecationdataload.py @@ -25,6 +25,15 @@ def process(): docs_url='', docs_title='') + # Unify all device ids to lowercase + try: + for entry in deprecation_data['data']: + if "device_id" in entry.keys(): + entry["device_id"] = entry.get("device_id").lower() + except (KeyError, AttributeError, TypeError): + # this may happen if receiving invalid data + pass + try: api.produce( DeviceDriverDeprecationData( diff --git a/repos/system_upgrade/common/actors/pcidevicesscanner/libraries/pcidevicesscanner.py b/repos/system_upgrade/common/actors/pcidevicesscanner/libraries/pcidevicesscanner.py index eb063abb..285a8a21 100644 --- a/repos/system_upgrade/common/actors/pcidevicesscanner/libraries/pcidevicesscanner.py +++ b/repos/system_upgrade/common/actors/pcidevicesscanner/libraries/pcidevicesscanner.py @@ -60,7 +60,7 @@ def parse_pci_device(textual_block, numeric_block): driver=device['Driver'], modules=device['Module'], numa_node=device['NUMANode'], - pci_id=":".join(PCI_ID_REG.findall(numeric_block)) + pci_id=(":".join(PCI_ID_REG.findall(numeric_block)).lower()) ) @@ -78,14 +78,19 @@ def parse_pci_devices(pci_textual, pci_numeric): def produce_detected_devices(devices): prefix_re = re.compile('0x') entry_lookup = { - prefix_re.sub('', entry.device_id): entry + prefix_re.sub('', entry.device_id.lower()): entry for message in api.consume(DeviceDriverDeprecationData) for entry in message.entries } - api.produce(*[ - DetectedDeviceOrDriver(**entry_lookup[device.pci_id].dump()) - for device in devices - if device.pci_id in entry_lookup - ]) + + device_list = [] + for device in devices: + shorten_pci_id = ":".join(device.pci_id.split(':')[:-2]) + if device.pci_id in entry_lookup: + device_list.append(DetectedDeviceOrDriver(**entry_lookup[device.pci_id].dump())) + elif shorten_pci_id in entry_lookup: + device_list.append(DetectedDeviceOrDriver(**entry_lookup[shorten_pci_id].dump())) + + api.produce(*device_list) def produce_detected_drivers(devices): diff --git a/repos/system_upgrade/common/actors/pcidevicesscanner/tests/test_pcidevicesscanner.py b/repos/system_upgrade/common/actors/pcidevicesscanner/tests/test_pcidevicesscanner.py index 4bd545ba..2bfde232 100644 --- a/repos/system_upgrade/common/actors/pcidevicesscanner/tests/test_pcidevicesscanner.py +++ b/repos/system_upgrade/common/actors/pcidevicesscanner/tests/test_pcidevicesscanner.py @@ -2,8 +2,16 @@ import os import pytest -from leapp.libraries.actor.pcidevicesscanner import parse_pci_devices, produce_pci_devices -from leapp.models import PCIDevice, PCIDevices +from leapp.libraries.actor.pcidevicesscanner import parse_pci_devices, produce_detected_devices, produce_pci_devices +from leapp.libraries.common.testutils import CurrentActorMocked, produce_mocked +from leapp.libraries.stdlib import api +from leapp.models import ( + DetectedDeviceOrDriver, + DeviceDriverDeprecationData, + DeviceDriverDeprecationEntry, + PCIDevice, + PCIDevices +) def test_parse_pci_devices(): @@ -37,9 +45,9 @@ Module: ata_generic ''' devices_numeric = '''Slot: 00:00.0 Class: Host bridge -Vendor: 15b45 +Vendor: 15B45 Device: 0724 -SVendor: 15b46 +SVendor: 15B46 SDevice: 0725 PhySlot: 3 Rev: 02 @@ -76,6 +84,7 @@ Module: ata_generic assert dev.progif == '80' assert dev.driver == 'ata_piix' assert dev.pci_id == '15b43:0722' + assert dev.pci_id.islower() is True assert len(dev.modules) == 3 assert 'ata_piix' in dev.modules assert 'pata_acpi' in dev.modules @@ -206,6 +215,53 @@ def test_produce_no_devices(): assert not output[0].devices +def test_shorten_id(monkeypatch): + + input_data = [PCIDevice( + slot='b765:00:02.0', + dev_cls='Ethernet controller', + vendor='Mellanox Technologies', + name='MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]', + subsystem_vendor='Mellanox Technologies', + subsystem_name='Device 61b0', + physical_slot='2', + rev='', + progif='', + driver='mlx4_core', + modules=['mlx4_core'], + numa_node='0', + pci_id='15b3:1004:15b3:61b0' + )] + + messages = [DeviceDriverDeprecationData(entries=[DeviceDriverDeprecationEntry( + available_in_rhel=[7, 8, 9], + deprecation_announced="", + device_id="0x15B3:0x1004", + device_name="Mellanox Technologies: MT27500 Family [ConnectX-3 Virtual Function]", + device_type="pci", + driver_name="mlx4_core", + maintained_in_rhel=[7, 8] + )])] + + expected_output = DetectedDeviceOrDriver( + available_in_rhel=[7, 8, 9], + deprecation_announced="", + device_id="0x15B3:0x1004", + device_name="Mellanox Technologies: MT27500 Family [ConnectX-3 Virtual Function]", + device_type="pci", + driver_name="mlx4_core", + maintained_in_rhel=[7, 8] + ) + + current_actor = CurrentActorMocked(msgs=messages, src_ver='8.10', dst_ver='9.6') + monkeypatch.setattr(api, 'current_actor', current_actor) + monkeypatch.setattr(api, 'produce', produce_mocked()) + + produce_detected_devices(input_data) + assert api.produce.model_instances + assert expected_output == api.produce.model_instances[0] + + # TODO(pstodulk): update the test - drop current_actor_context and use monkeypatch @pytest.mark.skipif(not os.path.exists('/usr/sbin/lspci'), reason='lspci not installed on the system') def test_actor_execution(current_actor_context): -- 2.49.0