summaryrefslogtreecommitdiffstats
path: root/src/hardware
diff options
context:
space:
mode:
authorRobin Hack <rhack@redhat.com>2014-01-23 12:31:23 +0100
committerRobin Hack <rhack@redhat.com>2014-01-31 14:28:04 +0100
commitf5d8f92ea3ca95845642701c02ffc662e754a87f (patch)
treea8c79542753a14399cc08a0a54865b8dfa4a6af0 /src/hardware
parentb0f9df85881e2a3c4024489f4ecb00286296deb1 (diff)
downloadopenlmi-providers-f5d8f92ea3ca95845642701c02ffc662e754a87f.tar.gz
openlmi-providers-f5d8f92ea3ca95845642701c02ffc662e754a87f.tar.xz
openlmi-providers-f5d8f92ea3ca95845642701c02ffc662e754a87f.zip
Hardware: Upstream testsuite from QA.
Diffstat (limited to 'src/hardware')
-rw-r--r--src/hardware/test/README18
-rw-r--r--src/hardware/test/TestHardware.py183
-rw-r--r--src/hardware/test/TestHardwareBase.py506
3 files changed, 707 insertions, 0 deletions
diff --git a/src/hardware/test/README b/src/hardware/test/README
new file mode 100644
index 0000000..a375d9f
--- /dev/null
+++ b/src/hardware/test/README
@@ -0,0 +1,18 @@
+Testing
+=======
+
+Dependencies
+------------
+ * python-hwdata
+
+Preparation
+-----------
+``lmi.test`` module must be on python path. The easiest way to get it there is
+to export ``PYTHONPATH`` environment variable like this: ::
+
+ export PYTHONPATH="${PATH_TO_GIT_ROOT}/src/python"
+
+Running tests
+-------------
+For example: ::
+ nosetests -v ./TestHardware.py
diff --git a/src/hardware/test/TestHardware.py b/src/hardware/test/TestHardware.py
new file mode 100644
index 0000000..5c72ade
--- /dev/null
+++ b/src/hardware/test/TestHardware.py
@@ -0,0 +1,183 @@
+# Copyright (C) 2012-2014 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Robin Hack <rhack@redhat.com>
+#
+
+from TestHardwareBase import *
+from lmi.shell import LMIInstance
+import os
+import unittest
+
+class TestHardwareProcessor(HardwareProcessorTestCase):
+ """
+ Class for testing LMI_Processor class
+ """
+
+ CLASS_NAME = "LMI_Processor"
+
+ def test_processor_flags_x86(self):
+ """
+ Hardware: Test for processor flags.
+ This test is valid only on x86 architectures.
+ """
+
+ cpu_instances = self.cim_class.instances()
+ self.assertTrue(cpu_instances)
+
+ # same count of cpus?
+ cpu_info = self.get_cpu_info()
+ self.assertTrue(cpu_info)
+
+ self.assertEqual(len(cpu_instances), len(cpu_info))
+
+ my_arch = self.get_my_arch()
+
+ cpu_num = 0
+ for cpu in cpu_instances:
+
+ # same architecture on all cpus?
+ self.assertEqual(my_arch, cpu.Architecture)
+
+ # same flags?
+ cpu_flags = cpu_info[cpu_num]["flags"].split()
+ cpu_flags = map (lambda f: self.proc_flag_table[f], cpu_flags)
+ self.assertTrue (cpu_flags)
+
+ lmi_cpu_flags = cpu.Flags
+ self.assertTrue (lmi_cpu_flags)
+
+ # same flags?
+ self.assertEqual(sorted(cpu_flags), sorted(lmi_cpu_flags))
+ ++cpu_num
+
+class TestHardwareMemory(HardwareMemoryTestCase):
+ """
+ Class for testing LMI_Memory class
+ """
+
+ CLASS_NAME = "LMI_Memory"
+
+ def test_huge_page_sizes(self):
+ """ Get supported sizes of hugepages """
+ lmi_mem_instances = self.cim_class.instances()
+ self.assertTrue(lmi_mem_instances)
+
+ huge_pages_sizes = self.get_huge_pages_sizes()
+ self.assertEqual(len(lmi_mem_instances), len(huge_pages_sizes))
+
+ for lmi_mem in lmi_mem_instances:
+ self.assertEqual(lmi_mem.SupportedHugeMemoryPageSizes, huge_pages_sizes)
+
+ def test_memory_page_size(self):
+ lmi_mem_instance = self.cim_class.first_instance()
+ self.assertTrue(lmi_mem_instance)
+
+ page_size = os.sysconf("SC_PAGE_SIZE") / 1024
+ lmi_page_size = lmi_mem_instance.StandardMemoryPageSize
+
+ self.assertEqual (page_size, lmi_page_size)
+
+
+class TestHardwarePhysicalMemory(HardwarePhysicalMemoryTestCase):
+ """
+ Class for testing LMI_PhysicalMemory class
+ """
+
+ CLASS_NAME = "LMI_PhysicalMemory"
+
+ def setUp(self):
+ self.lmi_phymem_instances = self.cim_class.instances()
+ self.assertTrue(self.lmi_phymem_instances)
+
+ def test_physical_memory(self):
+ phymems = self.get_physical_memory()
+ lmi_phymems = map(lambda x: (
+ x.TotalWidth,
+ x.DataWidth,
+ x.Capacity,
+ x.SerialNumber,
+ #x.BankLabel,
+ x.FormFactor,
+ x.MemoryType,
+ x.Manufacturer,
+ x.PartNumber,
+ x.ConfiguredMemoryClockSpeed,
+ x.Speed
+ ), self.lmi_phymem_instances)
+ self.assertEqual(sorted(lmi_phymems), sorted(phymems))
+
+
+class TestHardwareBaseboard(HardwareBaseboardTestCase):
+ """
+ Class for testing LMI_Baseboard class
+ """
+
+ CLASS_NAME = "LMI_Baseboard"
+
+ def setUp(self):
+ self.lmi_baseboard_instances = self.cim_class.instances()
+ # On virtual machines there can be blank
+ #self.assertTrue(self.lmi_baseboard_instances)
+
+ def test_baseboard_basic_info(self):
+ baseboards = self.get_baseboards()
+
+ lmi_baseboards = map(lambda x: (
+ x.SerialNumber,
+ x.Manufacturer,
+ x.Model,
+ x.Version
+ ), self.lmi_baseboard_instances)
+ lmi_serials = map(lambda x: x.SerialNumber, self.lmi_baseboard_instances)
+
+ self.assertEqual(sorted(lmi_baseboards), sorted(baseboards))
+
+
+class TestHardwarePCIDevice(HardwarePCITestCase):
+ """
+ Class for testing LMI_PCIDevice class
+ """
+
+ CLASS_NAME = "LMI_PCIDevice"
+
+ def setUp(self):
+ self.lmi_pci_devices_instances = self.cim_class.instances()
+ self.assertTrue(self.lmi_pci_devices_instances)
+
+ def test_pci_devices(self):
+ lmi_pci_devices = self.get_pci_devices_lmi(self.lmi_pci_devices_instances)
+ pci_devices = self.get_pci_devices(self.IS_DEVICE)
+
+ self.assertEqual(sorted(lmi_pci_devices), sorted(pci_devices))
+
+
+class TestHardwarePCIBridge(HardwarePCITestCase):
+ """
+ Class for testing LMI_PCIBridge class
+ """
+
+ CLASS_NAME = "LMI_PCIBridge"
+
+ def setUp(self):
+ self.lmi_pci_bridges_instances = self.cim_class.instances()
+ self.assertTrue(self.lmi_pci_bridges_instances)
+
+ def test_pci_bridges(self):
+ lmi_pci_bridges = self.get_pci_devices_lmi(self.lmi_pci_bridges_instances)
+ pci_bridges = self.get_pci_devices(self.IS_BRIDGE)
+
+ self.assertEqual(sorted(lmi_pci_bridges), sorted(pci_bridges))
diff --git a/src/hardware/test/TestHardwareBase.py b/src/hardware/test/TestHardwareBase.py
new file mode 100644
index 0000000..7519bbb
--- /dev/null
+++ b/src/hardware/test/TestHardwareBase.py
@@ -0,0 +1,506 @@
+# -*- encoding: utf-8 -*-
+# Copyright (C) 2012-2014 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Robin Hack <rhack@redhat.com>
+#
+"""
+Common utilities and base class for all hardware tests.
+"""
+
+from collections import OrderedDict
+from lmi.test.lmibase import LmiTestCase
+import os
+import re
+import subprocess
+from hwdata import PCI
+import unittest
+
+class HardwareTestCase(LmiTestCase):
+ """
+ Base class for all LMI Hardware test classes.
+ """
+ USE_EXCEPTIONS = True
+
+ @classmethod
+ def setUpClass(cls):
+ LmiTestCase.setUpClass.im_func(cls)
+ cls.dmi_output_cached_type = -1
+
+ def parse_dmi_output(self, dmioutput):
+ devices = {}
+ device = {}
+
+ r = re.compile('^Handle')
+ handle = False
+ skip_line = False
+ for line in dmioutput.split('\n'):
+ # skip line after Handle 0x
+ if skip_line:
+ skip_line = False
+ continue
+
+ # next device
+ if not line.strip():
+ if handle:
+ devices[handle] = device
+ device = {}
+ handle = False
+ skip_line = False
+ continue
+
+ if r.match(line):
+ handle = line.split()[1][:-1]
+ skip_line = True
+ continue
+
+ if handle:
+ key = line.strip().split(':')[0].strip()
+ value = line.strip().split(':')[1].strip()
+ device[key] = value
+ return devices
+
+ def get_dmi_output(self, type_p):
+ if self.dmi_output_cached_type != type_p:
+ self.dmi_output_cache = subprocess.check_output("dmidecode -t %d" % type_p, shell=True)
+ self.dmi_output_cached_type = type_p
+ return self.dmi_output_cache
+
+
+class HardwareProcessorTestCase(HardwareTestCase):
+ """
+ Base class for all LMI ProcessorHardware test classes.
+ """
+ # this is stolen from:
+ # linux/arch/x86/include/asm/cpufeature.h
+ proc_flag_table = {
+ 'fpu' : 0,
+ 'vme' : 1,
+ 'de' : 2,
+ 'pse' : 3,
+ 'tsc' : 4,
+ 'msr' : 5,
+ 'pae' : 6,
+ 'mce' : 7,
+ 'cx8' : 8,
+ 'apic' : 9,
+ 'sep' : 11,
+ 'mtrr' : 12,
+ 'pge' : 13,
+ 'mca' : 14,
+ 'cmov' : 15,
+ 'pat' : 16,
+ 'pse36' : 17,
+ 'pn' : 18,
+ 'clflush' : 19,
+ 'dts' : 21,
+ 'acpi' : 22,
+ 'mmx' : 23,
+ 'fxsr' : 24,
+ 'sse' : 25,
+ 'sse2' : 26,
+ 'ss' : 27,
+ 'ht' : 28,
+ 'tm' : 29,
+ 'ia64' : 30,
+ 'pbe' : 31,
+ 'syscall' : 43,
+ 'mp' : 51,
+ 'nx' : 52,
+ 'mmxext' : 54,
+ 'fxsr_opt' : 57,
+ 'pdpe1gb' : 58,
+ 'rdtscp' : 59,
+ 'lm' : 61,
+ '3dnowext' : 62,
+ '3dnow' : 63,
+ 'recovery' : 64,
+ 'longrun' : 65,
+ 'lrti' : 67,
+ 'cxmmx' : 96,
+ 'k6_mtrr' : 97,
+ 'cyrix_arr' : 98,
+ 'centaur_mcr' : 99,
+ 'k8' : 100,
+ 'k7' : 101,
+ 'p3' : 102,
+ 'p4' : 103,
+ 'constant_tsc' : 104,
+ 'up' : 105,
+ 'fxsave_leak' : 106,
+ 'arch_perfmon' : 107,
+ 'pebs' : 108,
+ 'bts' : 109,
+ 'syscall32' : 110,
+ 'sysenter32' : 111,
+ 'rep_good' : 112,
+ 'mfence_rdtsc' : 113,
+ 'lfence_rdtsc' : 114,
+ '11ap' : 115,
+ 'nopl' : 116,
+ 'xtopology' : 118,
+ 'tsc_reliable' : 119,
+ 'nonstop_tsc' : 120,
+ 'clflush_monitor' : 121,
+ 'extd_apicid' : 122,
+ 'amd_dcm' : 123,
+ 'aperfmperf' : 124,
+ 'eagerfpu' : 125,
+ 'pni' : 128,
+ 'pclmulqdq' : 129,
+ 'dtes64' : 130,
+ 'monitor' : 131,
+ 'ds_cpl' : 132,
+ 'vmx' : 133,
+ 'smx' : 134,
+ 'est' : 135,
+ 'tm2' : 136,
+ 'ssse3' : 137,
+ 'cid' : 138,
+ 'fma' : 140,
+ 'cx16' : 141,
+ 'xtpr' : 142,
+ 'pdcm' : 143,
+ 'pcid' : 145,
+ 'dca' : 146,
+ 'sse4_1' : 147,
+ 'sse4_2' : 148,
+ 'x2apic' : 149,
+ 'movbe' : 150,
+ 'popcnt' : 151,
+ 'tsc_deadline_timer' : 152,
+ 'aes' : 153,
+ 'xsave' : 154,
+ 'osxsave' : 155,
+ 'avx' : 156,
+ 'f16c' : 157,
+ 'rdrand' : 158,
+ 'hypervisor' : 159,
+ 'rng' : 162,
+ 'rng_en' : 163,
+ 'ace' : 166,
+ 'ace_en' : 167,
+ 'ace2' : 168,
+ 'ace2_en' : 169,
+ 'phe' : 170,
+ 'phe_en' : 171,
+ 'pmm' : 172,
+ 'pmm_en' : 173,
+ 'lahf_lm' : 192,
+ 'cmp_legacy' : 193,
+ 'svm' : 194,
+ 'extapic' : 195,
+ 'cr8_legacy' : 196,
+ 'abm' : 197,
+ 'sse4a' : 198,
+ 'misalignsse' : 199,
+ '3dnowprefetch' : 200,
+ 'osvw' : 201,
+ 'ibs' : 202,
+ 'xop' : 203,
+ 'skinit' : 204,
+ 'wdt' : 205,
+ 'lwp' : 207,
+ 'fma4' : 208,
+ 'tce' : 209,
+ 'nodeid_msr' : 211,
+ 'tbm' : 213,
+ 'topoext' : 214,
+ 'perfctr_core' : 215,
+ 'ida' : 224,
+ 'arat' : 225,
+ 'cpb' : 226,
+ 'epb' : 227,
+ 'xsaveopt' : 228,
+ 'pln' : 229,
+ 'pts' : 230,
+ 'dtherm' : 231,
+ 'hw_pstate' : 232,
+ 'tpr_shadow' : 256,
+ 'vnmi' : 257,
+ 'flexpriority' : 258,
+ 'ept' : 259,
+ 'vpid' : 260,
+ 'npt' : 261,
+ 'lbrv' : 262,
+ 'svm_lock' : 263,
+ 'nrip_save' : 264,
+ 'tsc_scale' : 265,
+ 'vmcb_clean' : 266,
+ 'flushbyasid' : 267,
+ 'decodeassists' : 268,
+ 'pausefilter' : 269,
+ 'pfthreshold' : 270,
+ 'fsgsbase' : 288,
+ 'tsc_adjust' : 289,
+ 'bmi1' : 291,
+ 'hle' : 292,
+ 'avx2' : 293,
+ 'smep' : 295,
+ 'bmi2' : 296,
+ 'erms' : 297,
+ 'invpcid' : 298,
+ 'rtm' : 299,
+ 'rdseed' : 306,
+ 'adx' : 307,
+ 'smap' : 308
+ }
+
+ # stolen from: http://amitsaha.github.io/site/notes/articles/python_linux/article.html
+ def get_cpu_info(self):
+ """
+ Return the information in /proc/cpuinfo
+ as a dictionary in the following format:
+ cpu_info[0]={...}
+ cpu_info[1]={...}
+ """
+ cpu_info = OrderedDict()
+ proc_info = OrderedDict()
+ nprocs = 0
+ with open('/proc/cpuinfo') as f:
+ for line in f:
+ if not line.strip():
+ # end of one processor
+ cpu_info[nprocs] = proc_info
+ nprocs = nprocs+1
+ # Reset
+ proc_info = OrderedDict()
+ else:
+ if len(line.split(':')) == 2:
+ proc_info[line.split(':')[0].strip()] = line.split(':')[1].strip()
+ else:
+ proc_info[line.split(':')[0].strip()] = ''
+ return cpu_info
+
+ def get_my_arch(self):
+ return os.uname()[4]
+
+
+class HardwareMemoryTestCase(HardwareTestCase):
+
+ def get_huge_pages_sizes(self):
+ # regexp is perfect because:
+ # ./mm/hugetlb.c: snprintf(h->name, HSTATE_NAME_LEN, "hugepages-%lukB", huge_page_size(h)/1024);
+
+ r = re.compile('hugepages-(\d+)kB')
+ dirs = os.listdir("/sys/kernel/mm/hugepages/")
+ huge_pages_sizes = []
+ for dir in dirs:
+ huge_pages_sizes.append(int(r.findall(dir)[0]))
+ return huge_pages_sizes
+
+
+class HardwarePhysicalMemoryTestCase(HardwareTestCase):
+
+ form_factor_table = {
+ 'Unknown': 0,
+ 'Other': 1,
+ 'SIP': 2,
+ 'DIP': 3,
+ 'ZIP': 4,
+ 'SOJ': 5,
+ 'Proprietary': 6,
+ 'SIMM': 7,
+ 'DIMM': 8,
+ 'TSOP': 9,
+ 'PGA': 10,
+ 'RIMM': 11,
+ 'SODIMM': 12,
+ 'SRIMM': 13,
+ 'SMD': 14,
+ 'SSMP': 15,
+ 'QFP': 16,
+ 'TQFP': 17,
+ 'SOIC': 18,
+ 'LCC': 19,
+ 'PLCC': 20,
+ 'BGA': 21,
+ 'FPBGA': 22,
+ 'LGA': 23
+ }
+
+ memory_type_table = {
+ 'Unknown': 0,
+ 'Other': 1,
+ 'DRAM': 2,
+ 'Synchronous DRAM': 3,
+ 'Cache DRAM': 4,
+ 'EDO': 5,
+ 'EDRAM': 6,
+ 'VRAM': 7,
+ 'SRAM': 8,
+ 'RAM': 9,
+ 'ROM': 10,
+ 'Flash': 11,
+ 'EEPROM': 12,
+ 'FEPROM': 13,
+ 'EPROM': 14,
+ 'CDRAM': 15,
+ '3DRAM': 16,
+ 'SDRAM': 17,
+ 'SGRAM': 18,
+ 'RDRAM': 19,
+ 'DDR': 20,
+ 'DDR-2': 21,
+ 'BRAM': 22,
+ 'FB-DIMM': 23,
+ 'DDR3': 24,
+ 'FBD2': 25
+ }
+
+ def get_physical_memory(self):
+ dmidecode_mem_17 = self.parse_dmi_output(self.get_dmi_output(17))
+
+ tuples = []
+
+ for handle in dmidecode_mem_17.keys():
+ module = dmidecode_mem_17[handle]
+ if module["Size"] == "No Module Installed":
+ continue
+
+ tuples.append((
+ int(module.get("Total Width", "0").split(" ")[0]),
+ int(module.get("Data Width", "0").split(" ")[0]),
+ int(module.get("Size", 0).split(" ")[0]) * 1024 * 1024,
+ module.get("Serial Number", "0"),
+ # skipped for now
+ #module.get("Bank Locator", ""),
+ #module.get("Locator", ""),
+ self.form_factor_table[module.get("Form Factor", "Unknown")],
+ self.memory_type_table[module.get("Type", "Unknown")],
+ module.get("Manufacturer", ""),
+ module.get("Part Number", ""),
+ int(module.get("Speed", "0 MHz".split(" ")[0]))
+ ))
+
+ # I just belive that order is achieved...
+ # I need concate two dmidecode outputs to one.
+ empty_output = True
+ dmidecode_mem_6 = self.parse_dmi_output(self.get_dmi_output(6))
+ c = 0
+ for handle in dmidecode_mem_6:
+ module = dmidecode_mem_6[handle]
+
+ tuples[c] = tuples[c] + (int(module.get("Current Speed", "0 ns").split(" ")[0]))
+ empty_output = False
+ ++c
+ # on virtual machines is this "normal" state.
+ if empty_output:
+ for c in xrange(0, len(tuples)):
+ tuples[c] += (0,)
+
+ return tuples
+
+class HardwareBaseboardTestCase(HardwareTestCase):
+
+ def get_baseboards(self):
+ dmidecode_boards = self.parse_dmi_output(self.get_dmi_output(2))
+
+ tuples = []
+
+ for handle in dmidecode_boards.keys():
+ baseboard = dmidecode_boards[handle]
+
+ tuples.append((
+ baseboard.get("Serial Number", "0"),
+ baseboard.get("Manufacturer", ""),
+ baseboard.get("Product Name", ""),
+ baseboard.get("Version", "")
+ ))
+
+ return tuples
+
+
+class HardwarePCITestCase(HardwareTestCase):
+
+ def get_pci_device_attr(self, device, attr_p):
+ f = open ("%s/%s/%s" % ("/sys/bus/pci/devices/", device, attr_p), "r")
+ attr = f.readline ()
+ f.close()
+ return attr
+
+ IS_BRIDGE = 1 << 0
+ IS_DEVICE = 1 << 1
+ IS_BOTH = (IS_BRIDGE | IS_DEVICE)
+
+ def get_pci_devices(self, mask):
+
+ pci_devices = []
+
+ for device in os.listdir("/sys/bus/pci/devices/"):
+
+ device_class = self.get_pci_device_attr(device, "class")
+ vendor_id = self.get_pci_device_attr(device, "vendor")
+ device_id = self.get_pci_device_attr(device, "device")
+ subsystem_device_id = self.get_pci_device_attr(device, "subsystem_device")
+ subsystem_vendor_id = self.get_pci_device_attr(device, "subsystem_vendor")
+ # Is device bridge?
+
+ is_bridge = ((int(device_class, 16) >> 16) == 0x06)
+ device = device.replace("0000:","")
+
+ add_device = False
+ if (mask & self.IS_BRIDGE) and is_bridge:
+ add_device = True
+
+ if (mask & self.IS_DEVICE) and not is_bridge:
+ add_device = True
+
+ if add_device:
+ add_device = False
+ pci_devices.append((
+ device,
+ int(device_id, 16),
+ int(device_class, 16) >> 16,
+ int(vendor_id, 16),
+ self.lookup_pci_vendor(vendor_id),
+ self.lookup_pci_name(vendor_id, device_id),
+ int(subsystem_device_id, 16),
+ int(subsystem_vendor_id, 16),
+ self.lookup_pci_vendor(subsystem_vendor_id)
+ ))
+ continue
+
+ return pci_devices
+
+ def get_pci_devices_lmi(self, lmi_pci_devices_instances):
+ lmi_pci_devices = map(lambda x: (
+ x.DeviceID,
+ x.PCIDeviceID,
+ x.ClassCode,
+ x.VendorID,
+ x.VendorName,
+ x.PCIDeviceName,
+ x.SubsystemID,
+ x.SubsystemVendorID,
+ x.SubsystemVendorName
+ ), lmi_pci_devices_instances)
+ return lmi_pci_devices
+
+
+ def lookup_pci_vendor(self, vendor_id):
+ pci = PCI()
+ # Convert to string without conversion to decimal.
+ # Achieve format of 4 hex numbers.
+ vendor_id = "%.4x" % int(vendor_id, 16)
+ return pci.get_vendor(vendor_id)
+
+
+ def lookup_pci_name(self, vendor_id, device_id):
+ pci = PCI()
+ vendor_id = "%.4x" % int(vendor_id, 16)
+ device_id = "%.4x" % int(device_id, 16)
+ return pci.get_device(vendor_id, device_id)