diff options
-rw-r--r-- | src/hardware/test/TestHardware.py | 44 | ||||
-rw-r--r-- | src/hardware/test/TestHardwareBase.py | 147 |
2 files changed, 130 insertions, 61 deletions
diff --git a/src/hardware/test/TestHardware.py b/src/hardware/test/TestHardware.py index 5c72ade..949b6a3 100644 --- a/src/hardware/test/TestHardware.py +++ b/src/hardware/test/TestHardware.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2014 Red Hat, Inc. All rights reserved. +# Copyright (C) 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 @@ -35,34 +35,38 @@ class TestHardwareProcessor(HardwareProcessorTestCase): This test is valid only on x86 architectures. """ - cpu_instances = self.cim_class.instances() - self.assertTrue(cpu_instances) + lmi_cpu_instances = self.cim_class.instances() + self.assertTrue(lmi_cpu_instances) - # same count of cpus? - cpu_info = self.get_cpu_info() - self.assertTrue(cpu_info) + cpus_info = self.get_cpus_info_proc() + self.assertTrue(cpus_info) + cpus_dmi_info = self.get_cpus_info_dmidecode() - self.assertEqual(len(cpu_instances), len(cpu_info)) + # Compare only count of physical cpus. + self.assertEqual(len(lmi_cpu_instances), len(cpus_dmi_info.keys())) - my_arch = self.get_my_arch() + cpu_arch = self.get_my_arch() - cpu_num = 0 - for cpu in cpu_instances: + # Get only one set of cpu flags. + cpu_flags = cpus_info[0]["flags"].split() + # Translate to numeric values. + cpu_flags = sorted(map(lambda f: self.proc_flag_table[f], cpu_flags)) - # same architecture on all cpus? - self.assertEqual(my_arch, cpu.Architecture) + # All architectures of cpus should be same. + # Flags too. But we are good testers right? + # Maybe some memory corruption or failing broker... + # Who knows. We are little paranoid here. + for lmi_cpu in lmi_cpu_instances: - # 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) + # Same architecture on all cpus? + self.assertEqual(cpu_arch, lmi_cpu.Architecture) - lmi_cpu_flags = cpu.Flags + lmi_cpu_flags = lmi_cpu.Flags self.assertTrue (lmi_cpu_flags) - # same flags? - self.assertEqual(sorted(cpu_flags), sorted(lmi_cpu_flags)) - ++cpu_num + # Same cpu flags on both sides? + self.assertEqual(sorted(lmi_cpu_flags), sorted(cpu_flags)) + class TestHardwareMemory(HardwareMemoryTestCase): """ diff --git a/src/hardware/test/TestHardwareBase.py b/src/hardware/test/TestHardwareBase.py index 7519bbb..a3b4083 100644 --- a/src/hardware/test/TestHardwareBase.py +++ b/src/hardware/test/TestHardwareBase.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -# Copyright (C) 2012-2014 Red Hat, Inc. All rights reserved. +# Copyright (C) 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 @@ -28,56 +28,104 @@ import re import subprocess from hwdata import PCI import unittest +from pprint import pprint -class HardwareTestCase(LmiTestCase): - """ - Base class for all LMI Hardware test classes. - """ - USE_EXCEPTIONS = True +def parse_whole_dmi_line(line): + key = line.strip().split(':')[0].strip() + value = line.strip().split(':')[1].strip() + return (key, value) - @classmethod - def setUpClass(cls): - LmiTestCase.setUpClass.im_func(cls) - cls.dmi_output_cached_type = -1 +def parse_flag_lines(flags): + # And god said: We must divide them by the mighty bracket char! + return map(lambda flag: flag.split("(")[0].lower(), flags) - def parse_dmi_output(self, dmioutput): - devices = {} - device = {} +def parse_dmi_output(dmioutput): - r = re.compile('^Handle') - handle = False - skip_line = False - for line in dmioutput.split('\n'): + r = re.compile('^Handle 0x') + + devices = {} + device = {} + + # Feed the hungry machine with states. + handle = False + skip_line = False + key = None + multiline_values = [] + + # Houston. Launch in 4... 3... 2... 1... + for line in dmioutput.split('\n'): + # Are we in handle context? + if handle: # skip line after Handle 0x if skip_line: skip_line = False continue - # next device + # We found blank line. if not line.strip(): - if handle: - devices[handle] = device + # Maybe multiline values ends with new line. + # We must handle it + if len(multiline_values) > 0: + device[key] = multiline_values + + devices[handle] = device + + # Carefully reset all states. device = {} + # Handle context ends here. handle = False skip_line = False + key = None + # reset here if ve are in multiline mode + # and input is damaged + multiline_values = [] continue + if len(multiline_values) > 0 and line.find(":") != -1: + device[key] = multiline_values + multiline_values = [] + + # We have line like: + # Current Speed: 2900 MHz + # I call that whole dmi line. + if len(line.split(":")) == 2: + (key, value) = parse_whole_dmi_line(line) + device[key] = value + continue + # We have line like: + # Flags: + # or line like: + # FXSR (FXSAVE and FXSTOR instructions supported) + if len(line.split(":")) == 1: + if line.find(":") == -1: + multiline_values.append(line.strip()) + else: + # We need to wait for another lines. + key = line.strip().split(":")[0] + continue + else: + # match for Handle 0x + # this starts handle context if r.match(line): handle = line.split()[1][:-1] + # skip one line of dmidecode output skip_line = True continue + pprint (devices) + return devices - if handle: - key = line.strip().split(':')[0].strip() - value = line.strip().split(':')[1].strip() - device[key] = value - return devices +def get_dmi_output(type_p): + return subprocess.check_output("dmidecode -t %d" % type_p, shell=True) + +class HardwareTestCase(LmiTestCase): + """ + Base class for all LMI Hardware test classes. + """ + USE_EXCEPTIONS = True - 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 + @classmethod + def setUpClass(cls): + LmiTestCase.setUpClass.im_func(cls) class HardwareProcessorTestCase(HardwareTestCase): @@ -259,8 +307,24 @@ class HardwareProcessorTestCase(HardwareTestCase): 'smap' : 308 } - # stolen from: http://amitsaha.github.io/site/notes/articles/python_linux/article.html - def get_cpu_info(self): + def get_cpus_info_dmidecode(self): + dmidecode = parse_dmi_output(get_dmi_output(4)) + + if len(dmidecode.keys()) == 0: + return None + + # There are no cpu flags in dmidecoude output in virtual machine + # enviroment. + for handle in dmidecode.keys(): + try: + dmidecode[handle]["Flags"] = parse_flag_lines(dmidecode[handle]["Flags"]) + except KeyError: + dmidecode[handle]["Flags"] = [] + + return dmidecode + + # Get info only for physical processors + def get_cpus_info_proc(self): """ Return the information in /proc/cpuinfo as a dictionary in the following format: @@ -270,6 +334,7 @@ class HardwareProcessorTestCase(HardwareTestCase): cpu_info = OrderedDict() proc_info = OrderedDict() nprocs = 0 + physical_id = -1 with open('/proc/cpuinfo') as f: for line in f: if not line.strip(): @@ -286,7 +351,7 @@ class HardwareProcessorTestCase(HardwareTestCase): return cpu_info def get_my_arch(self): - return os.uname()[4] + return os.uname()[4] class HardwareMemoryTestCase(HardwareTestCase): @@ -362,7 +427,7 @@ class HardwarePhysicalMemoryTestCase(HardwareTestCase): } def get_physical_memory(self): - dmidecode_mem_17 = self.parse_dmi_output(self.get_dmi_output(17)) + dmidecode_mem_17 = parse_dmi_output(get_dmi_output(17)) tuples = [] @@ -383,20 +448,20 @@ class HardwarePhysicalMemoryTestCase(HardwareTestCase): self.memory_type_table[module.get("Type", "Unknown")], module.get("Manufacturer", ""), module.get("Part Number", ""), - int(module.get("Speed", "0 MHz".split(" ")[0])) + 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)) + dmidecode_mem_6 = parse_dmi_output(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 + empty_output = False + c += 1 # on virtual machines is this "normal" state. if empty_output: for c in xrange(0, len(tuples)): @@ -407,7 +472,7 @@ class HardwarePhysicalMemoryTestCase(HardwareTestCase): class HardwareBaseboardTestCase(HardwareTestCase): def get_baseboards(self): - dmidecode_boards = self.parse_dmi_output(self.get_dmi_output(2)) + dmidecode_boards = parse_dmi_output(get_dmi_output(2)) tuples = [] @@ -427,7 +492,7 @@ class HardwareBaseboardTestCase(HardwareTestCase): 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") + f = open ("/sys/bus/pci/devices/%s/%s" % (device, attr_p), "r") attr = f.readline () f.close() return attr @@ -447,8 +512,8 @@ class HardwarePCITestCase(HardwareTestCase): 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 device bridge? Class == 0x06? is_bridge = ((int(device_class, 16) >> 16) == 0x06) device = device.replace("0000:","") |