diff --git a/oec-hardware-1.1.5-1-add-virtual-branch-fix-bug.patch b/oec-hardware-1.1.5-1-add-virtual-branch-fix-bug.patch deleted file mode 100644 index e2b5a7ec76fe23335d7790ef9e53e59f89a72884..0000000000000000000000000000000000000000 --- a/oec-hardware-1.1.5-1-add-virtual-branch-fix-bug.patch +++ /dev/null @@ -1,29904 +0,0 @@ -diff -Naur rpm/config/test_config.yaml oech/config/test_config.yaml ---- rpm/config/test_config.yaml 2023-10-24 22:25:50.000000000 +0800 -+++ oech/config/test_config.yaml 2023-12-07 15:01:42.217942181 +0800 -@@ -1,75 +1,75 @@ --# Copyright (c) 2023 Huawei Technologies Co., Ltd. --# # oec-hardware is licensed under the Mulan PSL v2.gica's --# # You can use this software according to the terms and conditions of the Mulan PSL v2. --# # You may obtain a copy of Mulan PSL v2 at: --# # http://license.coscl.org.cn/MulanPSL2 --# # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR --# # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR --# # PURPOSE. --# # See the Mulan PSL v2 for more details. --# # Author: --# # # Create: 2023-09-11 --# #device: fc\raid\ethernet\infiniband testcase need configuration, It is obtained from the OECH command line interface and --# needs to be enclosed in single quotation marks --#disk: fc\raid\disk testcase need configuration, The disk to be tested, such as sda; Or all, test all qualified disks. --#if_rdma: ethernet testcase need configuration, N means to test according to ordinary network card, y means to test according to RDMA card --#server_ip: ethernet\infiniband testcase need configuration. If the server port is modified, need to add the port number after the IP address. eg: 2.2.2.4:8090. --# User need to delete the ip manually which are configured by tool after testing. --#clent_ip: ethernet\infiniband testcase need configuration. IP to be configured for the client port --fc: -- fc1: -- device: '0000:03:00.0' -- disk: all -- fc2: -- device: '0000:03:00.1' -- disk: sda --raid: -- raid1: -- device: '0000:02:00.0' -- disk: all -- raid2: -- device: '0000:0a:00.1' -- disk: sdb --disk: all --ethernet: -- # IP has been manually configured, get server IP. -- eth1: -- device: enp125s0f0 -- if_rdma: N -- client_ip: -- server_ip: 2.2.2.4 -- # Configure the IP obtained here. -- eth2: -- device: enp125s0f1 -- if_rdma: N -- client_ip: 2.2.2.3 -- server_ip: 2.2.2.4 -- # The program automatically generates an IP address for IP configuration -- eth3: -- device: enp125s0f2 -- if_rdma: y -- client_ip: -- server_ip: --infiniband: -- # IP has been manually configured, get server IP. -- ib1: -- device: ibp1s0 -- client_ip: -- server_ip: 2.2.2.4 -- # Configure the IP obtained here. -- ib2: -- device: ibp1s0 -- client_ip: 2.2.2.3 -- server_ip: 2.2.2.4:8090 -- # The program automatically generates an IP address for IP configuration -- ib3: -- device: ibp1s0 -- client_ip: -- server_ip: --kabiwhitelist: -- ko1: -- ko_name: '' -- ko2: -- ko_name: '' -- rpm: -- rpm_name: '' -+# Copyright (c) 2023 Huawei Technologies Co., Ltd. -+# # oec-hardware is licensed under the Mulan PSL v2.gica's -+# # You can use this software according to the terms and conditions of the Mulan PSL v2. -+# # You may obtain a copy of Mulan PSL v2 at: -+# # http://license.coscl.org.cn/MulanPSL2 -+# # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# # IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# # PURPOSE. -+# # See the Mulan PSL v2 for more details. -+# # Author: -+# # # Create: 2023-09-11 -+# #device: fc\raid\ethernet\infiniband testcase need configuration, It is obtained from the OECH command line interface and -+# needs to be enclosed in single quotation marks -+#disk: fc\raid\disk testcase need configuration, The disk to be tested, such as sda; Or all, test all qualified disks. -+#if_rdma: ethernet testcase need configuration, N means to test according to ordinary network card, y means to test according to RDMA card -+#server_ip: ethernet\infiniband testcase need configuration. If the server port is modified, need to add the port number after the IP address. eg: 2.2.2.4:8090. -+# User need to delete the ip manually which are configured by virtualization after testing. -+#clent_ip: ethernet\infiniband testcase need configuration. IP to be configured for the client port -+fc: -+ fc1: -+ device: '0000:03:00.0' -+ disk: all -+ fc2: -+ device: '0000:03:00.1' -+ disk: sda -+raid: -+ raid1: -+ device: '0000:02:00.0' -+ disk: all -+ raid2: -+ device: '0000:0a:00.1' -+ disk: sdb -+disk: all -+ethernet: -+ # IP has been manually configured, get server IP. -+ eth1: -+ device: enp125s0f0 -+ if_rdma: N -+ client_ip: -+ server_ip: 2.2.2.4 -+ # Configure the IP obtained here. -+ eth2: -+ device: enp125s0f1 -+ if_rdma: N -+ client_ip: 2.2.2.3 -+ server_ip: 2.2.2.4 -+ # The program automatically generates an IP address for IP configuration -+ eth3: -+ device: enp125s0f2 -+ if_rdma: y -+ client_ip: -+ server_ip: -+infiniband: -+ # IP has been manually configured, get server IP. -+ ib1: -+ device: ibp1s0 -+ client_ip: -+ server_ip: 2.2.2.4 -+ # Configure the IP obtained here. -+ ib2: -+ device: ibp1s0 -+ client_ip: 2.2.2.3 -+ server_ip: 2.2.2.4:8090 -+ # The program automatically generates an IP address for IP configuration -+ ib3: -+ device: ibp1s0 -+ client_ip: -+ server_ip: -+kabiwhitelist: -+ ko1: -+ ko_name: '' -+ ko2: -+ ko_name: '' -+ rpm: -+ rpm_name: '' -diff -Naur rpm/hwcompatible/cert_info.py oech/hwcompatible/cert_info.py ---- rpm/hwcompatible/cert_info.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/hwcompatible/cert_info.py 2023-12-07 15:01:42.221942234 +0800 -@@ -28,16 +28,17 @@ - self.logger = logger - self.command = command - -- def create_json(self, device): -+ def create_json(self, device_name, device): - """ - Create hardware information json - Args: -+ device_name: device name - device: hardware device - Returns: True/False - """ - if not device or not device.quad: - self.logger.warning( -- "The %s doesn't have quadruple information, couldn't get hardware." % device.name) -+ "The %s doesn't have quadruple information, couldn't get hardware." % device_name) - return False - - if device.quad in self.cert_quads: -@@ -49,7 +50,7 @@ - - self.logger.info( - "Please input sha256, driverSize, downloadLink for %s manually " -- "if you use outbox driver." % device.name) -+ "if you use outbox driver." % device_name) - - oec_json["vendorID"] = device.quad[0] - oec_json["deviceID"] = device.quad[1] -@@ -62,7 +63,7 @@ - oec_json["chipVendor"] = chip_vendor[0].strip("\n") - oec_json["boardModel"] = device.board - oec_json["chipModel"] = device.chip -- oec_json["type"] = device.name.upper() -+ oec_json["type"] = device_name.upper() - arch = self.command.run_cmd("uname -m", log_print=False) - oec_json["architecture"] = arch[0].strip("\n") - os_cmd = self.command.run_cmd( -diff -Naur rpm/hwcompatible/common.py oech/hwcompatible/common.py ---- rpm/hwcompatible/common.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/hwcompatible/common.py 2023-12-07 15:01:42.221942234 +0800 -@@ -25,12 +25,13 @@ - from .command import Command - - --def create_test_suite(test_factory, logger, subtests_filter=None): -+def create_test_suite(test_factory, logger, category="compatible", subtests_filter=None): - """ - Create test suites for job testing - Args: - test_factory (list): total test factory - logger (Logger): logger object to record -+ category (str): test category - subtests_filter (list, optional): filter object. Defaults to None. - - Returns: -@@ -47,7 +48,7 @@ - test_suite.append(testcase) - test_name.append(test["name"]) - -- if test["name"] not in NODEVICE: -+ if category == "compatible" and test["name"] not in NODEVICE: - kabi_select = 1 - if "kabi" in test_name: - kabi_select = 0 -diff -Naur rpm/hwcompatible/compatibility.py oech/hwcompatible/compatibility.py ---- rpm/hwcompatible/compatibility.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/hwcompatible/compatibility.py 2023-12-07 15:01:42.221942234 +0800 -@@ -30,7 +30,7 @@ - from .client import Client - from .common import create_test_suite, copy_pci, search_factory - from .constants import NODEVICE, GPU_DRIVER, IB, CDTYPES, KEYCARD_VENDORS, \ -- BOARD, VERSION, DRIVER, CHIP, DEVICE_INFO -+ BOARD, VERSION, DRIVER, CHIP, DEVICE_INFO, TEST_CATEGORY - - - class EulerCertification(): -@@ -47,17 +47,24 @@ - self.dir_name = None - self.logger = logger - self.command = Command(logger) -+ self.category = '' - - def run(self): - """ - Openeuler compatibility verification - :return: - """ -- self.logger.info( -- "The openEuler Hardware Compatibility Test Suite", log_print=False) -- copy_pci() -+ self._select_category() -+ if self.category == "virtualization": -+ self.logger.info( -+ "The openEuler Virtualization Test Suite") -+ elif self.category == "compatible": -+ self.logger.info( -+ "The openEuler Hardware Compatibility Test Suite") -+ copy_pci() -+ certdevice = CertDevice(self.logger) -+ - self.load() -- certdevice = CertDevice(self.logger) - - while True: - self.submit() -@@ -66,15 +73,17 @@ - self.logger.info("All cases are passed, test end.") - return True - -- oec_devices = certdevice.get_devices() -- self.devices = DeviceDocument(CertEnv.devicefile, self.logger, oec_devices) -- self.devices.save() -+ oec_devices = list() -+ if self.category == "compatible": -+ oec_devices = certdevice.get_devices() -+ self.devices = DeviceDocument(CertEnv.devicefile, self.logger, oec_devices) -+ self.devices.save() - test_factory = self.get_tests(oec_devices) - self.update_factory(test_factory) - if not self.choose_tests(): - return True - -- test_suite = create_test_suite(self.test_factory, self.logger) -+ test_suite = create_test_suite(self.test_factory, self.logger, self.category) - args = argparse.Namespace( - test_factory=self.test_factory, test_suite=test_suite) - job = Job(args) -@@ -116,6 +125,8 @@ - os.remove(CertEnv.certificationfile) - if os.path.exists(CertEnv.factoryfile): - os.remove(CertEnv.factoryfile) -+ if os.path.exists(CertEnv.virtfactoryfile): -+ os.remove(CertEnv.virtfactoryfile) - if os.path.exists(CertEnv.devicefile): - os.remove(CertEnv.devicefile) - self.logger.info("Clean compatibility test data succeed.") -@@ -134,7 +145,10 @@ - self.certification.new() - self.certification.save() - if not self.test_factory: -- factory_doc = FactoryDocument(CertEnv.factoryfile, self.logger) -+ if self.category == "virtualization": -+ factory_doc = FactoryDocument(CertEnv.virtfactoryfile, self.logger) -+ elif self.category == "compatible": -+ factory_doc = FactoryDocument(CertEnv.factoryfile, self.logger) - self.test_factory = factory_doc.get_factory() - - oec_id = self.certification.get_certify() -@@ -145,12 +159,12 @@ - self.certification.save() - - display_message = " %s: ".ljust(20) % name + version + "\n" \ -- " Compatibility Test ID: ".ljust(30) + oec_id + "\n" \ -- " Hardware Info: ".ljust(30) + hardware_info + "\n" \ -- " Product URL: ".ljust(30) + self.certification.get_url() + "\n" \ -- " OS Info: ".ljust(30) + self.certification.get_os() + "\n" \ -- " Kernel Info: ".ljust(30) + self.certification.get_kernel() + "\n" \ -- " Test Server: ".ljust(30) + self.certification.get_server() -+ " Compatibility Test ID: ".ljust(30) + oec_id + "\n" \ -+ " Hardware Info: ".ljust(30) + hardware_info + "\n" \ -+ " Product URL: ".ljust(30) + self.certification.get_url() + "\n" \ -+ " OS Info: ".ljust(30) + self.certification.get_os() + "\n" \ -+ " Kernel Info: ".ljust(30) + self.certification.get_kernel() + "\n" \ -+ " Test Server: ".ljust(30) + self.certification.get_server() - self.logger.info(display_message, log_print=False) - - def save(self, job): -@@ -162,10 +176,14 @@ - doc_dir = os.path.join(CertEnv.logdirectoy, job.job_id) - if not os.path.exists(doc_dir): - return -- FactoryDocument(CertEnv.factoryfile, self.logger, self.test_factory).save() -+ if self.category == "virtualization": -+ FactoryDocument(CertEnv.virtfactoryfile, self.logger, self.test_factory).save() -+ shutil.copy(CertEnv.virtfactoryfile, doc_dir) -+ else: -+ FactoryDocument(CertEnv.factoryfile, self.logger, self.test_factory).save() -+ shutil.copy(CertEnv.factoryfile, doc_dir) -+ shutil.copy(CertEnv.devicefile, doc_dir) - shutil.copy(CertEnv.certificationfile, doc_dir) -- shutil.copy(CertEnv.devicefile, doc_dir) -- shutil.copy(CertEnv.factoryfile, doc_dir) - - cwd = os.getcwd() - os.chdir(os.path.dirname(doc_dir)) -@@ -173,13 +191,13 @@ - + "-" + job.job_id - pack_name = self.dir_name + ".tar" - os.rename(job.job_id, self.dir_name) -- -+ - cmd_result = self.command.run_cmd( - "tar -cf %s --exclude '*.lock' %s" % (pack_name, self.dir_name), log_print=False) - if cmd_result[2] != 0: - self.logger.error("Collect job log failed.") - return -- -+ - self.logger.info("Log saved to file: %s succeed." % - os.path.join(os.getcwd(), pack_name)) - shutil.copy(pack_name, CertEnv.datadirectory) -@@ -234,45 +252,58 @@ - self.client = Client(hardware_info, oec_id, self.logger) - return self.client.upload(path, server) - -- def get_tests(self, devices): -+ def get_tests(self, devices=None): - """ - get test items - :param devices: - :return: - """ -+ if devices is None: -+ devices = list() - sort_devices = self.sort_tests(devices) - empty_device = Device(logger=self.logger) - test_factory = list() - casenames = [] -- for (_, dirs, filenames) in os.walk(CertEnv.testdirectoy): -+ test_path = os.path.join(CertEnv.testdirectoy, self.category) -+ for (_, dirs, filenames) in os.walk(test_path): - dirs.sort() - for filename in filenames: - if filename.endswith(".py") and \ - not filename.startswith("__init__"): - casenames.append(filename.split(".")[0]) - -- with open(CertEnv.pcifile) as file: -+ if self.category == "virtualization": - for testname in casenames: -- if sort_devices.get(testname): -- for device in sort_devices[testname]: -+ test = dict() -+ test["name"] = testname -+ test["device"] = empty_device -+ test["run"] = True -+ test["status"] = "NotRun" -+ test["reboot"] = False -+ test_factory.append(test) -+ else: -+ with open(CertEnv.pcifile) as file: -+ for testname in casenames: -+ if sort_devices.get(testname): -+ for device in sort_devices[testname]: -+ test = dict() -+ test["name"] = testname -+ test["device"] = device -+ test["run"] = True -+ test["status"] = "NotRun" -+ test["reboot"] = False -+ test["driverName"] = test.get("device", "").get_driver() -+ test["driverVersion"] = test.get("device", "").get_driver_version() -+ test["boardModel"], test["chipModel"] = test.get("device", "").get_model(testname, file) -+ test_factory.append(test) -+ elif testname in NODEVICE: - test = dict() - test["name"] = testname -- test["device"] = device -+ test["device"] = empty_device - test["run"] = True - test["status"] = "NotRun" - test["reboot"] = False -- test["driverName"] = test.get("device", "").get_driver() -- test["driverVersion"] = test.get("device", "").get_driver_version() -- test["boardModel"], test["chipModel"] = test.get("device", "").get_model(testname, file) - test_factory.append(test) -- elif testname in NODEVICE: -- test = dict() -- test["name"] = testname -- test["device"] = empty_device -- test["run"] = True -- test["status"] = "NotRun" -- test["reboot"] = False -- test_factory.append(test) - return test_factory - - def sort_tests(self, devices): -@@ -370,7 +401,7 @@ - if any([k in id_vendor for k in KEYCARD_VENDORS]): - sort_devices["keycard"] = [device] - continue -- -+ - cmd_result = self.command.run_cmd("dmidecode | grep 'IPMI Device Information'") - if cmd_result[2] == 0: - sort_devices["ipmi"] = [empty_device] -@@ -391,7 +422,10 @@ - - self.logger.info('\033c', log_print=False) - self.logger.info("Select tests to run:", log_print=False) -- self.show_tests() -+ if self.category == "virtualization": -+ self.show_virt_tests() -+ else: -+ self.show_tests() - reply = self.ui.prompt("Selection (|all|none|quit|run): ") - reply = reply.lower() - if reply in ["r", "run"]: -@@ -461,6 +495,33 @@ - device, driver, version, chip, board) - self._print_tests(device) - -+ def show_virt_tests(self): -+ """ -+ show virtualization test items -+ :return: -+ """ -+ self.logger.info("\033[1;35m" + "No.".ljust(4) + "Run-Now?".ljust(10) -+ + "status".ljust(10) + "%s\033[0m" % "Class".ljust(14), log_print=False) -+ num = 0 -+ for test in self.test_factory: -+ name = test["name"] -+ status = test["status"] -+ run = "no" -+ if test["run"] is True: -+ run = "yes" -+ num = num + 1 -+ if status == "PASS": -+ color = "2" -+ elif status == "FAIL": -+ color = "1" -+ elif status == "Force": -+ color = "3" -+ else: -+ color = "4" -+ self.logger.info("%-6d" % num + run.ljust(8) -+ + "\033[0;3%sm%s \033[0m" % (color, status.ljust(8)) -+ + name.ljust(14), log_print=False) -+ - def choose_tests(self): - """ - choose test behavior -@@ -473,8 +534,11 @@ - test["run"] = True - self.logger.info('\033c', log_print=False) - self.logger.info("These tests are recommended to " -- "complete the compatibility test: ", log_print=False) -- self.show_tests() -+ "complete the %s test: " % self.category, log_print=False) -+ if self.category == "virtualization": -+ self.show_virt_tests() -+ else: -+ self.show_tests() - action = self.ui.prompt("Ready to begin testing?", - ["run", "edit", "quit"]) - action = action.lower() -@@ -508,29 +572,33 @@ - if not self.test_factory: - self.test_factory = test_factory - else: -- for test in self.test_factory: -- if not search_factory(test, test_factory): -- self.test_factory.remove(test) -- self.logger.info("delete %s test %s" % (test["name"], -- test["device"].get_name())) -- for test in test_factory: -- if not search_factory(test, self.test_factory): -- self.test_factory.append(test) -- self.logger.info("add %s test %s" % (test["name"], -- test["device"].get_name())) -- for index, test in enumerate(self.test_factory): -- for test_new in test_factory: -- if test["name"] != test_new["name"]: -- continue -- self_test_path = test["device"].path -- new_test_path = test_new["device"].path -- if not self_test_path and not new_test_path: -- continue -- if self_test_path == new_test_path: -- self.test_factory[index]['device'] = test_new['device'] -- -+ if self.category == 'compatible': -+ for test in self.test_factory: -+ if not search_factory(test, test_factory): -+ self.test_factory.remove(test) -+ self.logger.info("delete %s test %s" % (test["name"], -+ test["device"].get_name())) -+ for test in test_factory: -+ if not search_factory(test, self.test_factory): -+ self.test_factory.append(test) -+ self.logger.info("add %s test %s" % (test["name"], -+ test["device"].get_name())) -+ for index, test in enumerate(self.test_factory): -+ for test_new in test_factory: -+ if test["name"] != test_new["name"]: -+ continue -+ self_test_path = test["device"].path -+ new_test_path = test_new["device"].path -+ if not self_test_path and not new_test_path: -+ continue -+ if self_test_path == new_test_path: -+ self.test_factory[index]['device'] = test_new['device'] -+ if self.category == "virtualization": -+ factoryfile_path = CertEnv.virtfactoryfile -+ else: -+ factoryfile_path = CertEnv.factoryfile - self.test_factory.sort(key=lambda k: k["name"]) -- FactoryDocument(CertEnv.factoryfile, self.logger, self.test_factory).save() -+ FactoryDocument(factoryfile_path, self.logger, self.test_factory).save() - - def _print_tests(self, device): - """ -@@ -540,3 +608,17 @@ - + "\033[0;3%sm%s \033[0m" % (device.color, device.status.ljust(8)) - + device.name.ljust(14) + device.device.ljust(15) + device.driver.ljust(15) - + device.version.ljust(18) + device.chip.ljust(20) + device.board, log_print=False) -+ -+ def _select_category(self): -+ self.logger.info("Please select test category.", log_print=False) -+ self.logger.info("\033[1;35m" + "No.".ljust(6) + "category".ljust(35) + "\033[0m", log_print=False) -+ categories = dict(enumerate(TEST_CATEGORY)) -+ for num, category in categories.items(): -+ self.logger.info("%-6d" % (num + 1) + category.ljust(4)) -+ no = self.ui.prompt("Please select test category No:") -+ if no.isdigit(): -+ no = int(no) -+ if 1 <= no <= len(categories): -+ self.category = categories[no - 1] -+ return -+ self._select_category() -diff -Naur rpm/hwcompatible/constants.py oech/hwcompatible/constants.py ---- rpm/hwcompatible/constants.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/hwcompatible/constants.py 2023-12-07 15:01:42.221942234 +0800 -@@ -25,7 +25,7 @@ - DRIVER = "driverName" - VERSION = "driverVersion" - NODEVICE = ("cpufreq", "memory", "clock", "profiler", "system", -- "stress", "kdump", "perf", "acpi", "watchdog", "kabi", "kabiwhitelist") -+ "stress", "kdump", "perf", "acpi", "watchdog", "kabi", "kabiwhitelist", "longtermstability") - TEST_KABI_ARCH = ("aarch64", "x86_64") - CDTYPES = ("DVD_RW", "DVD_PLUS_RW", "DVD_R", "DVD_PLUS_R", "DVD", - "BD_RE", "BD_R", "BD", "CD_RW", "CD_R", "CD") -@@ -35,6 +35,7 @@ - DEVICE_INFO = ('color', 'status', 'num', 'run', 'name', - 'device', 'driver', 'version', 'chip', 'board') - NO_CONFIG_DEVICES = ("gpu", "vgpu", "nvme", "dpdk", "cdrom", "keycard", "spdk") -+TEST_CATEGORY = ("compatible", "virtualization") - - # File access control - FILE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_TRUNC -diff -Naur rpm/hwcompatible/env.py oech/hwcompatible/env.py ---- rpm/hwcompatible/env.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/hwcompatible/env.py 2023-12-07 15:01:42.221942234 +0800 -@@ -26,6 +26,7 @@ - certificationfile = os.path.join(datadirectory, "compatibility.json") - devicefile = os.path.join(datadirectory, "device.json") - factoryfile = os.path.join(datadirectory, "factory.json") -+ virtfactoryfile = os.path.join(datadirectory, "virtfactory.json") - rebootfile = os.path.join(datadirectory, "reboot.json") - testdirectoy = "/usr/share/oech/lib/tests" - logdirectoy = "/usr/share/oech/logs" -diff -Naur rpm/hwcompatible/job.py oech/hwcompatible/job.py ---- rpm/hwcompatible/job.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/hwcompatible/job.py 2023-12-07 15:01:42.221942234 +0800 -@@ -101,7 +101,7 @@ - testcase["name"], terminal_print=False) - - if testcase["name"] not in NODEVICE: -- cert_infos.create_json(testcase["device"]) -+ cert_infos.create_json(testcase["name"], testcase["device"]) - else: - testcase["status"] = "FAIL" - self.logger.error("Test %s failed." % -diff -Naur rpm/hwcompatible/sysinfo.py oech/hwcompatible/sysinfo.py ---- rpm/hwcompatible/sysinfo.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/hwcompatible/sysinfo.py 2023-12-07 15:01:42.221942234 +0800 -@@ -12,7 +12,6 @@ - # See the Mulan PSL v2 for more details. - # Create: 2020-04-01 - --import os - import re - from subprocess import getoutput - -diff -Naur rpm/oec-hardware.spec oech/oec-hardware.spec ---- rpm/oec-hardware.spec 2023-10-24 22:25:50.000000000 +0800 -+++ oech/oec-hardware.spec 2023-12-07 15:01:42.221942234 +0800 -@@ -25,7 +25,7 @@ - Summary: openEuler Hardware Compatibility Test Server - Group: Development/Tools - Requires: python3, python3-devel, python3-flask, python3-uWSGI, python3-werkzeug --Requires: nginx, tar, qperf, psmisc, dpdk, dpdk-tools, dpdk-devel, net-tools -+Requires: nginx, tar, qperf, psmisc, dpdk, dpdk-tools, dpdk-devel, net-tools, perftest - - %description - openEuler Hardware Compatibility Test Suite -@@ -38,7 +38,7 @@ - - %build - %ifarch x86_64 aarch64 --strip tests/keycard/libswsds_%{_arch}.so -+strip tests/compatible/keycard/libswsds_%{_arch}.so - %endif - [ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT; - DESTDIR=$RPM_BUILD_ROOT VERSION_RELEASE=%{version} make -diff -Naur rpm/server/server.py oech/server/server.py ---- rpm/server/server.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/server/server.py 2023-12-07 15:01:42.225942288 +0800 -@@ -97,7 +97,10 @@ - job = secure_filename(job) - dir_job = os.path.join(dir_results, host, oec_id, job) - json_info = os.path.join(dir_job, 'compatibility.json') -- json_results = os.path.join(dir_job, 'factory.json') -+ files = os.listdir(dir_job) -+ for file in files: -+ if "factory.json" in file: -+ json_results = os.path.join(dir_job, file) - if not os.path.exists(json_info) or not os.path.exists(json_results): - abort(404) - -@@ -110,7 +113,8 @@ - sys.stderr.write("The file %s is not json file.\n") - return False - -- return render_template('job.html', host=host, id=oec_id, job=job, info=info, results=results) -+ return render_template('job.html', host=host, id=oec_id, job=job, info=info, results=results, -+ json_results=json_results) - - - @app.route('/results////devices/') -@@ -127,7 +131,10 @@ - oec_id = secure_filename(oec_id) - job = secure_filename(job) - dir_job = os.path.join(dir_results, host, oec_id, job) -- json_results = os.path.join(dir_job, 'factory.json') -+ files = os.listdir(dir_job) -+ for file in files: -+ if "factory.json" in file: -+ json_results = os.path.join(dir_job, file) - if not os.path.exists(json_results): - abort(404) - -@@ -159,7 +166,10 @@ - oec_id = secure_filename(oec_id) - job = secure_filename(job) - dir_job = os.path.join(dir_results, host, oec_id, job) -- json_devices = os.path.join(dir_job, 'device.json') -+ files = os.listdir(dir_job) -+ for file in files: -+ if "factory.json" in file: -+ json_devices = os.path.join(dir_job, file) - if not os.path.exists(json_devices): - abort(404) - -diff -Naur rpm/server/templates/job.html oech/server/templates/job.html ---- rpm/server/templates/job.html 2023-10-24 22:25:50.000000000 +0800 -+++ oech/server/templates/job.html 2023-12-07 15:01:42.225942288 +0800 -@@ -41,6 +41,7 @@ - -

Testcase

- -+ {% if json_results == "factory.json" %} - -

Device

- -@@ -56,6 +57,7 @@ - -

boardModel

- -+ {% endif %} - -

Result

- -@@ -78,6 +80,7 @@ - {% endif %} - - {{ testcase }} -+ {% if json_results == "factory.json" %} - - {{ int }} - -@@ -85,6 +88,7 @@ - {{ d.get('driverVersion', '') }} - {{ d.get('chipModel', '') }} - {{ d.get('boardModel', '') }} -+ {% endif %} - - {{ result }} - -diff -Naur rpm/tests/acpi/acpi.py oech/tests/acpi/acpi.py ---- rpm/tests/acpi/acpi.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/tests/acpi/acpi.py 1970-01-01 08:00:00.000000000 +0800 -@@ -1,38 +0,0 @@ --#!/usr/bin/env python3 --# coding: utf-8 -- --# Copyright (c) 2020 Huawei Technologies Co., Ltd. --# oec-hardware is licensed under the Mulan PSL v2. --# You can use this software according to the terms and conditions of the Mulan PSL v2. --# You may obtain a copy of Mulan PSL v2 at: --# http://license.coscl.org.cn/MulanPSL2 --# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR --# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR --# PURPOSE. --# See the Mulan PSL v2 for more details. --# Create: 2020-04-01 -- --from hwcompatible.test import Test -- -- --class AcpiTest(Test): -- """ -- acpi test -- """ -- -- def __init__(self): -- Test.__init__(self) -- self.requirements = ["acpica-tools"] -- -- def test(self): -- """ -- Test case -- :return: -- """ -- result = self.command.run_cmd("acpidump") -- if result[2] == 0: -- self.logger.info("Test acpi succeed.") -- return True -- -- self.logger.error("Test acpi failed.\n%s" % result[1]) -- return False -diff -Naur rpm/tests/acpi/Makefile oech/tests/acpi/Makefile ---- rpm/tests/acpi/Makefile 2023-10-24 22:25:50.000000000 +0800 -+++ oech/tests/acpi/Makefile 1970-01-01 08:00:00.000000000 +0800 -@@ -1,22 +0,0 @@ --# Copyright (c) 2020 Huawei Technologies Co., Ltd. --# oec-hardware is licensed under the Mulan PSL v2. --# You can use this software according to the terms and conditions of the Mulan PSL v2. --# You may obtain a copy of Mulan PSL v2 at: --# http://license.coscl.org.cn/MulanPSL2 --# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR --# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR --# PURPOSE. --# See the Mulan PSL v2 for more details. --# Create: 2020-04-01 -- --.PHONY: install clean -- --all: ; -- --install: -- mkdir -p $(DEST) -- cp -a *.py $(DEST) -- chmod a+x $(DEST)/*.py -- --clean: -- rm -rf $(DEST) -diff -Naur rpm/tests/cdrom/cdrom.py oech/tests/cdrom/cdrom.py ---- rpm/tests/cdrom/cdrom.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/tests/cdrom/cdrom.py 1970-01-01 08:00:00.000000000 +0800 -@@ -1,271 +0,0 @@ --#!/usr/bin/env python3 --# coding: utf-8 -- --# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. --# oec-hardware is licensed under the Mulan PSL v2. --# You can use this software according to the terms and conditions of the Mulan PSL v2. --# You may obtain a copy of Mulan PSL v2 at: --# http://license.coscl.org.cn/MulanPSL2 --# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR --# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR --# PURPOSE. --# See the Mulan PSL v2 for more details. --# Create: 2020-04-01 --# Desc: CDRom test -- --import os --import shutil --import argparse --from time import sleep --from hwcompatible.test import Test --from hwcompatible.command_ui import CommandUI --from hwcompatible.command import Command -- -- --class CDRomTest(Test): -- def __init__(self): -- Test.__init__(self) -- self.requirements = ["dvd+rw-tools", -- "cdrkit", "genisoimage", "util-linux"] -- self.method = None -- self.device = None -- self.type = None -- self.com_ui = CommandUI() -- self.test_dir = "/usr/share/doc" -- read_dir = os.getcwd() -- self.mnt_dir = os.path.join(read_dir, "mnt_cdrom") -- self.device_dir = os.path.join(read_dir, "device_dir") -- -- def setup(self, args=None): -- """ -- The Setup before testing -- :param args: -- :return: -- """ -- self.args = args or argparse.Namespace() -- self.logger = getattr(args, "test_logger", None) -- self.device = getattr(args, "device", None) -- self.type = self.get_type(self.device) -- self.command = Command(self.logger) -- self.get_mode(self.type) -- -- def test(self): -- """ -- Test case -- :return: -- """ -- if not (self.method and self.device and self.type): -- return False -- -- if self.method not in dir(self): -- return False -- -- devname = self.device.get_property("DEVNAME") -- self.command.run_cmd("eject %s" % devname, ignore_errors=True) -- while True: -- self.logger.info("Please insert %s disc into %s, then close the tray manually." % ( -- self.type.lower(), devname)) -- if self.method == "write_test": -- self.logger.info("Tips: disc should be new.") -- elif self.method == "read_test": -- self.logger.info("Tips: disc should not be blank.") -- if self.com_ui.prompt_confirm("Done well?"): -- break -- self.command.run_cmd("eject -t %s" % devname, ignore_errors=True) -- self.logger.info( -- "Please wait seconds for media to be inserted.", terminal_print=True) -- sleep(20) -- -- if not getattr(self, self.method)(): -- return False -- return True -- -- def get_type(self, device): -- """ -- Get the type of CDROM -- :param device: -- :return: -- """ -- if not device: -- return None -- -- bd_types = ["BD_RE", "BD_R", "BD"] -- dvd_types = ["DVD_RW", "DVD_PLUS_RW", "DVD_R", "DVD_PLUS_R", "DVD"] -- cd_types = ["CD_RW", "CD_R", "CD"] -- for bd_type in bd_types: -- if device.get_property("ID_CDROM_" + bd_type) == "1": -- return bd_type -- for dvd_type in dvd_types: -- if device.get_property("ID_CDROM_" + dvd_type) == "1": -- return dvd_type -- for cd_type in cd_types: -- if device.get_property("ID_CDROM_" + cd_type) == "1": -- return cd_type -- -- self.logger.error("Find proper test-type for %s failed." % -- device.get_name()) -- return None -- -- def get_mode(self, device_type): -- """ -- Get the read-write mode of CDROM -- :param device_type: -- :return: -- """ -- if not device_type: -- return -- -- if "RW" in device_type or "RE" in device_type: -- self.method = "rw_test" -- elif "_R" in device_type: -- self.method = "write_test" -- else: -- self.method = "read_test" -- -- def rw_test(self): -- """ -- RW mode test of CDROM -- :return: -- """ -- devname = self.device.get_property("DEVNAME") -- self.command.run_cmd("umount %s" % devname, ignore_errors=True) -- if "BD" in self.type: -- self.logger.info("It will format the cdrom.", terminal_print=True) -- self.command.run_cmd("dvd+rw-format -format=full %s" % devname) -- self.reload_disc(devname) -- return self.write_test() -- elif "DVD_PLUS" in self.type: -- self.logger.info("It will format the cdrom.", terminal_print=True) -- self.command.run_cmd("dvd+rw-format -force %s" % devname) -- self.reload_disc(devname) -- return self.write_test() -- else: -- self.logger.info("It will clear data in cdrom.", -- terminal_print=True) -- self.command.run_cmd("cdrecord -v dev=%s blank=fast" % devname) -- self.reload_disc(devname) -- return self.write_test() -- -- def write_test(self): -- """ -- Write mode test of CDROM -- :return: -- """ -- devname = self.device.get_property("DEVNAME") -- self.command.run_cmd("umount %s" % devname, ignore_errors=True) -- if "BD" in self.type or "DVD_PLUS" in self.type: -- grow_cmd = self.command.run_cmd( -- "growisofs -Z %s --quiet -R %s " % (devname, self.test_dir)) -- reload_flag = self.reload_disc(devname) -- if grow_cmd[2] == 0 and reload_flag: -- return True -- return False -- -- write_opts = "-sao" -- cmd_result = self.command.run_cmd( -- "cdrecord dev=%s -checkdrive | grep 'Supported modes'" % devname, ignore_errors=True) -- modes = cmd_result[0] -- if "TAO" in modes: -- write_opts = "-tao" -- if "SAO" in modes: -- write_opts = "-sao" -- cmd_result = self.command.run_cmd( -- "cdrecord dev=%s -checkdrive | grep 'Driver flags'" % devname, ignore_errors=True) -- if "BURNFREE" in cmd_result[0]: -- write_opts += " driveropts=burnfree" -- -- size = self.command.run_cmd( -- "mkisofs -quiet -R -print-size %s" % self.test_dir) -- blocks = int(size[0]) -- -- self.command.run_cmd( -- "mkisofs -o test_cdrom.iso --quiet -r %s" % self.test_dir) -- mkisofs_cmd = self.command.run_cmd( -- "cdrecord -v %s dev=%s fs=32M test_cdrom.iso" % (write_opts, devname)) -- reload_flag = self.reload_disc(devname) -- os.remove("test_cdrom.iso") -- if mkisofs_cmd[2] == 0 and reload_flag: -- return True -- return False -- -- def read_test(self): -- """ -- Read mode test of CDROM -- :return: -- """ -- devname = self.device.get_property("DEVNAME") -- if os.path.exists(self.mnt_dir): -- shutil.rmtree(self.mnt_dir) -- os.mkdir(self.mnt_dir) -- self.logger.info("Check to mount media.", terminal_print=True) -- self.command.run_cmd("umount %s" % devname, ignore_errors=True) -- self.command.run_cmd("mount -o ro %s %s" % (devname, self.mnt_dir)) -- -- cmd_result = self.command.run_cmd( -- "df %s | tail -n1 | awk '{print $3}'" % devname) -- size = int(cmd_result[0]) -- if size == 0: -- self.logger.error("This is a blank disc.") -- self.command.run_cmd("umount %s" % self.mnt_dir) -- shutil.rmtree(self.mnt_dir) -- return False -- -- if os.path.exists(self.device_dir): -- shutil.rmtree(self.device_dir) -- os.mkdir(self.device_dir) -- self.logger.info("Check to copy files.", terminal_print=True) -- self.command.run_cmd("cp -dprf %s/. %s" % (self.mnt_dir, self.device_dir)) -- -- self.logger.info( -- "Check to compare files in directory.", terminal_print=True) -- return_code = self.cmp_tree(self.mnt_dir, self.device_dir) -- self.command.run_cmd("umount %s" % self.mnt_dir) -- if return_code: -- self.logger.info("Compare directory succeed.") -- else: -- self.logger.error("Compare directory failed.") -- -- return return_code -- -- def cmp_tree(self, dir1, dir2): -- """ -- Compare the differences between the two directories -- :param dir1: -- :param dir2: -- :return: -- """ -- if not (dir1 and dir2): -- self.logger.error("Invalid input directory.") -- return False -- -- cmd_result = self.command.run_cmd("diff -r %s %s" % (dir1, dir2)) -- return cmd_result[2] == 0 -- -- def reload_disc(self, device): -- """ -- Reloading the media -- :param device: -- :return: -- """ -- if not device: -- return False -- -- self.logger.info("Check to reload the media.") -- self.command.run_cmd("eject %s" % device) -- self.logger.info("Tray ejected.") -- -- cmd = self.command.run_cmd("eject -t %s" % device) -- if cmd[2] != 0: -- self.logger.error( -- "Could not auto-close the tray, please close the tray manually.") -- self.com_ui.prompt_confirm("Done well?") -- -- sleep(20) -- self.logger.info("Tray auto-closed.\n") -- return True -- -- def teardown(self): -- if os.path.exists(self.mnt_dir): -- shutil.rmtree(self.mnt_dir) -- if os.path.exists(self.device_dir): -- shutil.rmtree(self.device_dir) -diff -Naur rpm/tests/cdrom/Makefile oech/tests/cdrom/Makefile ---- rpm/tests/cdrom/Makefile 2023-10-24 22:25:50.000000000 +0800 -+++ oech/tests/cdrom/Makefile 1970-01-01 08:00:00.000000000 +0800 -@@ -1,22 +0,0 @@ --# Copyright (c) 2020 Huawei Technologies Co., Ltd. --# oec-hardware is licensed under the Mulan PSL v2. --# You can use this software according to the terms and conditions of the Mulan PSL v2. --# You may obtain a copy of Mulan PSL v2 at: --# http://license.coscl.org.cn/MulanPSL2 --# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR --# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR --# PURPOSE. --# See the Mulan PSL v2 for more details. --# Create: 2020-04-01 -- --.PHONY: install clean -- --all: ; -- --install: -- mkdir -p $(DEST) -- cp -a *.py $(DEST) -- chmod a+x $(DEST)/*.py -- --clean: -- rm -rf $(DEST) -diff -Naur rpm/tests/clock/clock.c oech/tests/clock/clock.c ---- rpm/tests/clock/clock.c 2023-10-24 22:25:50.000000000 +0800 -+++ oech/tests/clock/clock.c 1970-01-01 08:00:00.000000000 +0800 -@@ -1,94 +0,0 @@ --/* -- * Copyright (c) 2020 Huawei Technologies Co., Ltd. -- * -- * This program is free software; you can redistribute it and/or -- * modify it under the terms of version 2 of the GNU General Public -- * License as published by the Free Software Foundation. -- * -- * This program 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 -- * General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -- * 02110-1301, USA -- */ -- --#define _GNU_SOURCE 1 -- --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --int test_clock_direction() --{ -- time_t starttime = 0; -- time_t stoptime = 0; -- int sleeptime = 60; -- int delta = 0; -- -- printf("clock direction test start\n"); -- time(&starttime); -- sleep(sleeptime); -- time(&stoptime); -- -- delta = (int)stoptime - (int)starttime - sleeptime; -- if (delta != 0) { -- printf("clock direction test fail\n"); -- return 1; -- } else { -- printf("clock direction test complete\n"); -- return 0; -- } --} -- --int test_rtc_clock() --{ -- int rtc, delta; -- struct tm rtc_tm1, rtc_tm2; -- int sleeptime = 120; -- -- printf("rtc_clock test start\n"); -- if ((rtc = open("/dev/rtc", O_WRONLY)) < 0) { -- perror("could not open RTC device"); -- return 1; -- } -- -- if (ioctl(rtc, RTC_RD_TIME, &rtc_tm1) < 0) { -- perror("could not get the RTC time"); -- close(rtc); -- return 1; -- } -- sleep(sleeptime); -- if (ioctl(rtc, RTC_RD_TIME, &rtc_tm2) < 0) { -- perror("could not get the RTC time"); -- close(rtc); -- return 1; -- } -- -- close(rtc); -- delta = (int)mktime(&rtc_tm2) - (int)mktime(&rtc_tm1) - sleeptime; -- if (delta != 0) { -- printf("rtc_clock test fail\n"); -- return 1; -- } else { -- printf("rtc_clock test complete\n"); -- return 0; -- } --} -- --int main() --{ -- int ret = 0; -- ret += test_clock_direction(); -- ret += test_rtc_clock(); -- return ret; --} -diff -Naur rpm/tests/clock/clock.py oech/tests/clock/clock.py ---- rpm/tests/clock/clock.py 2023-10-24 22:25:50.000000000 +0800 -+++ oech/tests/clock/clock.py 1970-01-01 08:00:00.000000000 +0800 -@@ -1,37 +0,0 @@ --#!/usr/bin/env python3 --# coding: utf-8 -- --# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. --# oec-hardware is licensed under the Mulan PSL v2. --# You can use this software according to the terms and conditions of the Mulan PSL v2. --# You may obtain a copy of Mulan PSL v2 at: --# http://license.coscl.org.cn/MulanPSL2 --# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR --# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR --# PURPOSE. --# See the Mulan PSL v2 for more details. --# Create: 2020-04-01 --# Desc: Clock test -- --import os --from hwcompatible.test import Test -- --clock_dir = os.path.dirname(os.path.realpath(__file__)) -- -- --class ClockTest(Test): -- def __init__(self): -- Test.__init__(self) -- -- def test(self): -- """ -- Clock test case -- :return: -- """ -- result = self.command.run_cmd("%s/clock" % clock_dir) -- if result[2] == 0: -- self.logger.info("Test clock succeed.") -- return True -- -- self.logger.error("Test clock failed.\n %s" % result[1]) -- return False -diff -Naur rpm/tests/clock/Makefile oech/tests/clock/Makefile ---- rpm/tests/clock/Makefile 2023-10-24 22:25:50.000000000 +0800 -+++ oech/tests/clock/Makefile 1970-01-01 08:00:00.000000000 +0800 -@@ -1,34 +0,0 @@ --# Copyright (c) 2020 Huawei Technologies Co., Ltd. --# oec-hardware is licensed under the Mulan PSL v2. --# You can use this software according to the terms and conditions of the Mulan PSL v2. --# You may obtain a copy of Mulan PSL v2 at: --# http://license.coscl.org.cn/MulanPSL2 --# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR --# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR --# PURPOSE. --# See the Mulan PSL v2 for more details. --# Create: 2020-04-01 -- --.PHONY: all install clean -- --all: clock -- --CFLAGS+=-Wall --CFLAGS+=-DCPU_ALLOC --# sched_setaffinity has no size_t argument on older systems. --ifeq ($(shell grep 'sched_setaffinity.*size_t' /usr/include/sched.h),) --CFLAGS+=-DOLD_SCHED_SETAFFINITY --endif -- --clock: clock.c -- $(CC) $(CFLAGS) -lrt $< -o $@ -- --install: -- mkdir -p $(DEST) -- cp -a clock *.py $(DEST) -- chmod a+x $(DEST)/*.py -- --clean: -- rm -rf $(DEST) -- rm -rf clock -- -diff -Naur rpm/tests/compatible/acpi/acpi.py oech/tests/compatible/acpi/acpi.py ---- rpm/tests/compatible/acpi/acpi.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/acpi/acpi.py 2023-12-07 15:01:42.225942288 +0800 -@@ -0,0 +1,38 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+ -+from hwcompatible.test import Test -+ -+ -+class AcpiTest(Test): -+ """ -+ acpi test -+ """ -+ -+ def __init__(self): -+ Test.__init__(self) -+ self.requirements = ["acpica-tools"] -+ -+ def test(self): -+ """ -+ Test case -+ :return: -+ """ -+ result = self.command.run_cmd("acpidump") -+ if result[2] == 0: -+ self.logger.info("Test acpi succeed.") -+ return True -+ -+ self.logger.error("Test acpi failed.\n%s" % result[1]) -+ return False -diff -Naur rpm/tests/compatible/acpi/Makefile oech/tests/compatible/acpi/Makefile ---- rpm/tests/compatible/acpi/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/acpi/Makefile 2023-12-07 15:01:42.225942288 +0800 -@@ -0,0 +1,22 @@ -+# Copyright (c) 2020 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/cdrom/cdrom.py oech/tests/compatible/cdrom/cdrom.py ---- rpm/tests/compatible/cdrom/cdrom.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/cdrom/cdrom.py 2023-12-07 15:01:42.225942288 +0800 -@@ -0,0 +1,271 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+# Desc: CDRom test -+ -+import os -+import shutil -+import argparse -+from time import sleep -+from hwcompatible.test import Test -+from hwcompatible.command_ui import CommandUI -+from hwcompatible.command import Command -+ -+ -+class CDRomTest(Test): -+ def __init__(self): -+ Test.__init__(self) -+ self.requirements = ["dvd+rw-tools", -+ "cdrkit", "genisoimage", "util-linux"] -+ self.method = None -+ self.device = None -+ self.type = None -+ self.com_ui = CommandUI() -+ self.test_dir = "/usr/share/doc" -+ read_dir = os.getcwd() -+ self.mnt_dir = os.path.join(read_dir, "mnt_cdrom") -+ self.device_dir = os.path.join(read_dir, "device_dir") -+ -+ def setup(self, args=None): -+ """ -+ The Setup before testing -+ :param args: -+ :return: -+ """ -+ self.args = args or argparse.Namespace() -+ self.logger = getattr(args, "test_logger", None) -+ self.device = getattr(args, "device", None) -+ self.type = self.get_type(self.device) -+ self.command = Command(self.logger) -+ self.get_mode(self.type) -+ -+ def test(self): -+ """ -+ Test case -+ :return: -+ """ -+ if not (self.method and self.device and self.type): -+ return False -+ -+ if self.method not in dir(self): -+ return False -+ -+ devname = self.device.get_property("DEVNAME") -+ self.command.run_cmd("eject %s" % devname, ignore_errors=True) -+ while True: -+ self.logger.info("Please insert %s disc into %s, then close the tray manually." % ( -+ self.type.lower(), devname)) -+ if self.method == "write_test": -+ self.logger.info("Tips: disc should be new.") -+ elif self.method == "read_test": -+ self.logger.info("Tips: disc should not be blank.") -+ if self.com_ui.prompt_confirm("Done well?"): -+ break -+ self.command.run_cmd("eject -t %s" % devname, ignore_errors=True) -+ self.logger.info( -+ "Please wait seconds for media to be inserted.", terminal_print=True) -+ sleep(20) -+ -+ if not getattr(self, self.method)(): -+ return False -+ return True -+ -+ def get_type(self, device): -+ """ -+ Get the type of CDROM -+ :param device: -+ :return: -+ """ -+ if not device: -+ return None -+ -+ bd_types = ["BD_RE", "BD_R", "BD"] -+ dvd_types = ["DVD_RW", "DVD_PLUS_RW", "DVD_R", "DVD_PLUS_R", "DVD"] -+ cd_types = ["CD_RW", "CD_R", "CD"] -+ for bd_type in bd_types: -+ if device.get_property("ID_CDROM_" + bd_type) == "1": -+ return bd_type -+ for dvd_type in dvd_types: -+ if device.get_property("ID_CDROM_" + dvd_type) == "1": -+ return dvd_type -+ for cd_type in cd_types: -+ if device.get_property("ID_CDROM_" + cd_type) == "1": -+ return cd_type -+ -+ self.logger.error("Find proper test-type for %s failed." % -+ device.get_name()) -+ return None -+ -+ def get_mode(self, device_type): -+ """ -+ Get the read-write mode of CDROM -+ :param device_type: -+ :return: -+ """ -+ if not device_type: -+ return -+ -+ if "RW" in device_type or "RE" in device_type: -+ self.method = "rw_test" -+ elif "_R" in device_type: -+ self.method = "write_test" -+ else: -+ self.method = "read_test" -+ -+ def rw_test(self): -+ """ -+ RW mode test of CDROM -+ :return: -+ """ -+ devname = self.device.get_property("DEVNAME") -+ self.command.run_cmd("umount %s" % devname, ignore_errors=True) -+ if "BD" in self.type: -+ self.logger.info("It will format the cdrom.", terminal_print=True) -+ self.command.run_cmd("dvd+rw-format -format=full %s" % devname) -+ self.reload_disc(devname) -+ return self.write_test() -+ elif "DVD_PLUS" in self.type: -+ self.logger.info("It will format the cdrom.", terminal_print=True) -+ self.command.run_cmd("dvd+rw-format -force %s" % devname) -+ self.reload_disc(devname) -+ return self.write_test() -+ else: -+ self.logger.info("It will clear data in cdrom.", -+ terminal_print=True) -+ self.command.run_cmd("cdrecord -v dev=%s blank=fast" % devname) -+ self.reload_disc(devname) -+ return self.write_test() -+ -+ def write_test(self): -+ """ -+ Write mode test of CDROM -+ :return: -+ """ -+ devname = self.device.get_property("DEVNAME") -+ self.command.run_cmd("umount %s" % devname, ignore_errors=True) -+ if "BD" in self.type or "DVD_PLUS" in self.type: -+ grow_cmd = self.command.run_cmd( -+ "growisofs -Z %s --quiet -R %s " % (devname, self.test_dir)) -+ reload_flag = self.reload_disc(devname) -+ if grow_cmd[2] == 0 and reload_flag: -+ return True -+ return False -+ -+ write_opts = "-sao" -+ cmd_result = self.command.run_cmd( -+ "cdrecord dev=%s -checkdrive | grep 'Supported modes'" % devname, ignore_errors=True) -+ modes = cmd_result[0] -+ if "TAO" in modes: -+ write_opts = "-tao" -+ if "SAO" in modes: -+ write_opts = "-sao" -+ cmd_result = self.command.run_cmd( -+ "cdrecord dev=%s -checkdrive | grep 'Driver flags'" % devname, ignore_errors=True) -+ if "BURNFREE" in cmd_result[0]: -+ write_opts += " driveropts=burnfree" -+ -+ size = self.command.run_cmd( -+ "mkisofs -quiet -R -print-size %s" % self.test_dir) -+ blocks = int(size[0]) -+ -+ self.command.run_cmd( -+ "mkisofs -o test_cdrom.iso --quiet -r %s" % self.test_dir) -+ mkisofs_cmd = self.command.run_cmd( -+ "cdrecord -v %s dev=%s fs=32M test_cdrom.iso" % (write_opts, devname)) -+ reload_flag = self.reload_disc(devname) -+ os.remove("test_cdrom.iso") -+ if mkisofs_cmd[2] == 0 and reload_flag: -+ return True -+ return False -+ -+ def read_test(self): -+ """ -+ Read mode test of CDROM -+ :return: -+ """ -+ devname = self.device.get_property("DEVNAME") -+ if os.path.exists(self.mnt_dir): -+ shutil.rmtree(self.mnt_dir) -+ os.mkdir(self.mnt_dir) -+ self.logger.info("Check to mount media.", terminal_print=True) -+ self.command.run_cmd("umount %s" % devname, ignore_errors=True) -+ self.command.run_cmd("mount -o ro %s %s" % (devname, self.mnt_dir)) -+ -+ cmd_result = self.command.run_cmd( -+ "df %s | tail -n1 | awk '{print $3}'" % devname) -+ size = int(cmd_result[0]) -+ if size == 0: -+ self.logger.error("This is a blank disc.") -+ self.command.run_cmd("umount %s" % self.mnt_dir) -+ shutil.rmtree(self.mnt_dir) -+ return False -+ -+ if os.path.exists(self.device_dir): -+ shutil.rmtree(self.device_dir) -+ os.mkdir(self.device_dir) -+ self.logger.info("Check to copy files.", terminal_print=True) -+ self.command.run_cmd("cp -dprf %s/. %s" % (self.mnt_dir, self.device_dir)) -+ -+ self.logger.info( -+ "Check to compare files in directory.", terminal_print=True) -+ return_code = self.cmp_tree(self.mnt_dir, self.device_dir) -+ self.command.run_cmd("umount %s" % self.mnt_dir) -+ if return_code: -+ self.logger.info("Compare directory succeed.") -+ else: -+ self.logger.error("Compare directory failed.") -+ -+ return return_code -+ -+ def cmp_tree(self, dir1, dir2): -+ """ -+ Compare the differences between the two directories -+ :param dir1: -+ :param dir2: -+ :return: -+ """ -+ if not (dir1 and dir2): -+ self.logger.error("Invalid input directory.") -+ return False -+ -+ cmd_result = self.command.run_cmd("diff -r %s %s" % (dir1, dir2)) -+ return cmd_result[2] == 0 -+ -+ def reload_disc(self, device): -+ """ -+ Reloading the media -+ :param device: -+ :return: -+ """ -+ if not device: -+ return False -+ -+ self.logger.info("Check to reload the media.") -+ self.command.run_cmd("eject %s" % device) -+ self.logger.info("Tray ejected.") -+ -+ cmd = self.command.run_cmd("eject -t %s" % device) -+ if cmd[2] != 0: -+ self.logger.error( -+ "Could not auto-close the tray, please close the tray manually.") -+ self.com_ui.prompt_confirm("Done well?") -+ -+ sleep(20) -+ self.logger.info("Tray auto-closed.\n") -+ return True -+ -+ def teardown(self): -+ if os.path.exists(self.mnt_dir): -+ shutil.rmtree(self.mnt_dir) -+ if os.path.exists(self.device_dir): -+ shutil.rmtree(self.device_dir) -diff -Naur rpm/tests/compatible/cdrom/Makefile oech/tests/compatible/cdrom/Makefile ---- rpm/tests/compatible/cdrom/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/cdrom/Makefile 2023-12-07 15:01:42.225942288 +0800 -@@ -0,0 +1,22 @@ -+# Copyright (c) 2020 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/clock/clock.c oech/tests/compatible/clock/clock.c ---- rpm/tests/compatible/clock/clock.c 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/clock/clock.c 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,94 @@ -+/* -+ * Copyright (c) 2020 Huawei Technologies Co., Ltd. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of version 2 of the GNU General Public -+ * License as published by the Free Software Foundation. -+ * -+ * This program 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 -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#define _GNU_SOURCE 1 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+int test_clock_direction() -+{ -+ time_t starttime = 0; -+ time_t stoptime = 0; -+ int sleeptime = 60; -+ int delta = 0; -+ -+ printf("clock direction test start\n"); -+ time(&starttime); -+ sleep(sleeptime); -+ time(&stoptime); -+ -+ delta = (int)stoptime - (int)starttime - sleeptime; -+ if (delta != 0) { -+ printf("clock direction test fail\n"); -+ return 1; -+ } else { -+ printf("clock direction test complete\n"); -+ return 0; -+ } -+} -+ -+int test_rtc_clock() -+{ -+ int rtc, delta; -+ struct tm rtc_tm1, rtc_tm2; -+ int sleeptime = 120; -+ -+ printf("rtc_clock test start\n"); -+ if ((rtc = open("/dev/rtc", O_WRONLY)) < 0) { -+ perror("could not open RTC device"); -+ return 1; -+ } -+ -+ if (ioctl(rtc, RTC_RD_TIME, &rtc_tm1) < 0) { -+ perror("could not get the RTC time"); -+ close(rtc); -+ return 1; -+ } -+ sleep(sleeptime); -+ if (ioctl(rtc, RTC_RD_TIME, &rtc_tm2) < 0) { -+ perror("could not get the RTC time"); -+ close(rtc); -+ return 1; -+ } -+ -+ close(rtc); -+ delta = (int)mktime(&rtc_tm2) - (int)mktime(&rtc_tm1) - sleeptime; -+ if (delta != 0) { -+ printf("rtc_clock test fail\n"); -+ return 1; -+ } else { -+ printf("rtc_clock test complete\n"); -+ return 0; -+ } -+} -+ -+int main() -+{ -+ int ret = 0; -+ ret += test_clock_direction(); -+ ret += test_rtc_clock(); -+ return ret; -+} -diff -Naur rpm/tests/compatible/clock/clock.py oech/tests/compatible/clock/clock.py ---- rpm/tests/compatible/clock/clock.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/clock/clock.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,37 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+# Desc: Clock test -+ -+import os -+from hwcompatible.test import Test -+ -+clock_dir = os.path.dirname(os.path.realpath(__file__)) -+ -+ -+class ClockTest(Test): -+ def __init__(self): -+ Test.__init__(self) -+ -+ def test(self): -+ """ -+ Clock test case -+ :return: -+ """ -+ result = self.command.run_cmd("%s/clock" % clock_dir) -+ if result[2] == 0: -+ self.logger.info("Test clock succeed.") -+ return True -+ -+ self.logger.error("Test clock failed.\n %s" % result[1]) -+ return False -diff -Naur rpm/tests/compatible/clock/Makefile oech/tests/compatible/clock/Makefile ---- rpm/tests/compatible/clock/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/clock/Makefile 2023-12-07 15:01:42.225942288 +0800 -@@ -0,0 +1,34 @@ -+# Copyright (c) 2020 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+ -+.PHONY: all install clean -+ -+all: clock -+ -+CFLAGS+=-Wall -+CFLAGS+=-DCPU_ALLOC -+# sched_setaffinity has no size_t argument on older systems. -+ifeq ($(shell grep 'sched_setaffinity.*size_t' /usr/include/sched.h),) -+CFLAGS+=-DOLD_SCHED_SETAFFINITY -+endif -+ -+clock: clock.c -+ $(CC) $(CFLAGS) -lrt $< -o $@ -+ -+install: -+ mkdir -p $(DEST) -+ cp -a clock *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -+ rm -rf clock -+ -diff -Naur rpm/tests/compatible/cpufreq/cal.py oech/tests/compatible/cpufreq/cal.py ---- rpm/tests/compatible/cpufreq/cal.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/cpufreq/cal.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,34 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+ -+import decimal -+import time -+ -+ -+def cal(): -+ """Call test_case""" -+ decimal.getcontext().prec = 1000 -+ one = decimal.Decimal(1) -+ for i in range(1000): -+ (i * one).sqrt() -+ -+ -+if __name__ == '__main__': -+ time_start = time.time() -+ while 1: -+ cal() -+ time_delta = time.time() - time_start -+ if time_delta >= 2: -+ print(time_delta) -+ break -diff -Naur rpm/tests/compatible/cpufreq/cpufreq.py oech/tests/compatible/cpufreq/cpufreq.py ---- rpm/tests/compatible/cpufreq/cpufreq.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/cpufreq/cpufreq.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,460 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+# Desc: cpufreq test -+ -+import argparse -+from random import randint -+from time import sleep -+from threading import Thread -+from hwcompatible.env import CertEnv -+from hwcompatible.test import Test -+from hwcompatible.command import Command -+ -+ -+class CPU: -+ """ -+ cpufreq test -+ """ -+ -+ def __init__(self, logger, command): -+ self.cpu = None -+ self.nums = 0 -+ self.list = None -+ self.original_governor = None -+ self.max_freq = 0 -+ self.min_freq = 0 -+ self.logger = logger -+ self.command = command -+ -+ def get_info(self): -+ """ -+ Get CPU info -+ :return: -+ """ -+ cmd_result = self.command.run_cmd( -+ "lscpu | grep '^CPU(s):' | awk '{print $2}'") -+ self.logger.info("Get the CPU(s) succeed.") -+ self.nums = int(cmd_result[0]) -+ self.list = range(self.nums) -+ -+ cmd = self.command.run_cmd( -+ "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq") -+ if cmd[2] != 0: -+ self.logger.error("Get the scaling_max_freq of cpu failed.") -+ return False -+ self.max_freq = int(cmd[0]) -+ -+ cmd = self.command.run_cmd( -+ "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq") -+ if cmd[2] != 0: -+ self.logger.error("Get the scaling_min_freq of cpu failed.") -+ return False -+ self.min_freq = int(cmd[0]) -+ -+ return True -+ -+ def set_freq(self, freq, cpu='all'): -+ """ -+ Set CPU frequency -+ :param freq: -+ :param cpu: -+ :return: -+ """ -+ cmd = self.command.run_cmd( -+ "cpupower -c %s frequency-set --freq %s" % (cpu, freq), log_print=False) -+ return cmd[2] == 0 -+ -+ def get_freq(self, cpu): -+ """ -+ Get CPU frequency -+ :param cpu: -+ :return: -+ """ -+ cmd = self.command.run_cmd( -+ "cpupower -c %s frequency-info -w | grep 'frequency' | cut -d ' ' -f 6" % cpu) -+ try: -+ if int(cmd[0]) and cmd[2] == 0: -+ self.logger.info("Get cpu frequency succeed.") -+ except ValueError as e: -+ self.logger.error("Get cpu frequency failed, %s" % e) -+ self.logger.info("Please use 'cpupower frequency-info' to check current frequency manually.") -+ return False -+ return int(cmd[0]) -+ -+ def set_governor(self, governor, cpu='all'): -+ """ -+ Set the frequency governor mode of CPU -+ :param governor: -+ :param cpu: -+ :return: -+ """ -+ cmd = self.command.run_cmd( -+ "cpupower -c %s frequency-set --governor %s" % (cpu, governor), log_print=False) -+ return cmd[2] == 0 -+ -+ def get_governor(self, cpu): -+ """ -+ Get cpu governor -+ :param cpu: -+ :return: -+ """ -+ cmd = self.command.run_cmd( -+ "cpupower -c %s frequency-info -p | grep governor | cut -d '\"' -f 2" % cpu) -+ if cmd[2] != 0: -+ self.logger.error("Get cpu governor failed.") -+ return False -+ self.logger.info("Get cpu governor succeed.") -+ return cmd[0].strip() -+ -+ -+class Load(Thread): -+ """ -+ Let a program run on a specific CPU -+ """ -+ -+ def __init__(self, cpu, command): -+ Thread.__init__(self) -+ self.cpu = cpu -+ self.command = command -+ self.process = None -+ self.returncode = None -+ -+ def run(self): -+ """ -+ Process started -+ :return: -+ """ -+ self.process = self.command.run_cmd( -+ "taskset -c %s python -u %s/cpufreq/cal.py" % (self.cpu, CertEnv.testdirectoy), log_print=False) -+ -+ def get_runtime(self): -+ """ -+ Get the running time of the process -+ :return: -+ """ -+ while self.is_alive(): -+ sleep(0.02) -+ -+ self.returncode = self.process[2] -+ if self.returncode == 0: -+ line = self.process[0] -+ return float(line) -+ return 0 -+ -+ -+class CPUFreqTest(Test): -+ """ -+ CPU frequency test -+ """ -+ -+ def __init__(self): -+ Test.__init__(self) -+ self.requirements = ['util-linux', 'kernel-tools'] -+ self.cpu = None -+ self.original_governor = None -+ -+ def setup(self, args=None): -+ """ -+ Initialization before test -+ :param args: -+ :return: -+ """ -+ self.args = args or argparse.Namespace() -+ self.logger = getattr(self.args, "test_logger", None) -+ self.command = Command(self.logger) -+ self.cpu = CPU(self.logger, self.command) -+ self.original_governor = self.cpu.get_governor(0) -+ -+ def test_userspace(self): -+ """ -+ userspace mode of testing CPU frequency -+ :return: -+ """ -+ target_cpu = randint(0, self.cpu.nums-1) -+ target_freq = randint(self.cpu.min_freq, self.cpu.max_freq) -+ if not self.cpu.set_freq(target_freq, cpu=target_cpu): -+ self.logger.error("Set CPU%s to freq %d failed." % -+ (target_cpu, target_freq)) -+ return False -+ self.logger.info("Set CPU%s to freq %d." % (target_cpu, target_freq)) -+ target_cpu_freq = self.cpu.get_freq(target_cpu) -+ self.logger.info("Current freq of CPU%s is %d." % -+ (target_cpu, target_cpu_freq)) -+ -+ target_cpu_governor = self.cpu.get_governor(target_cpu) -+ if target_cpu_governor != 'userspace': -+ self.logger.error("The governor of CPU%s(%s) is not userspace." % -+ (target_cpu, target_cpu_governor)) -+ return False -+ self.logger.info("The governor of CPU%s is %s." % -+ (target_cpu, target_cpu_governor)) -+ -+ # min_freq -> max_runtime -+ self.cpu.set_freq(self.cpu.min_freq) -+ load_list = [] -+ runtime_list = [] -+ for cpu in self.cpu.list: -+ load_test = Load(cpu, self.command) -+ load_test.start() -+ load_list.append(load_test) -+ for cpu in self.cpu.list: -+ runtime = load_list[cpu].get_runtime() -+ runtime_list.append(runtime) -+ max_average_runtime = 1.0 * sum(runtime_list) / len(runtime_list) -+ if max_average_runtime == 0: -+ self.logger.error("Max average time is 0.") -+ return False -+ self.logger.info( -+ "Max average time of all CPUs userspace load test: %.2f" % max_average_runtime) -+ -+ # max_freq -> min_runtime -+ self.cpu.set_freq(self.cpu.max_freq) -+ load_list = [] -+ runtime_list = [] -+ for cpu in self.cpu.list: -+ load_test = Load(cpu, self.command) -+ load_test.start() -+ load_list.append(load_test) -+ for cpu in self.cpu.list: -+ runtime = load_list[cpu].get_runtime() -+ runtime_list.append(runtime) -+ min_average_runtime = 1.0 * sum(runtime_list) / len(runtime_list) -+ if min_average_runtime == 0: -+ self.logger.info("Min average time is 0.") -+ return False -+ self.logger.info( -+ "Min average time of all CPUs userspace load test: %.2f" % min_average_runtime) -+ -+ measured_speedup = 1.0 * max_average_runtime / min_average_runtime -+ expected_speedup = 1.0 * self.cpu.max_freq / self.cpu.min_freq -+ tolerance = 1.0 -+ min_speedup = expected_speedup - (expected_speedup - 1.0) * tolerance -+ max_speedup = expected_speedup + (expected_speedup - 1.0) * tolerance -+ if not min_speedup <= measured_speedup <= max_speedup: -+ self.logger.error("The speedup(%.2f) is not between %.2f and %.2f" % ( -+ measured_speedup, min_speedup, max_speedup)) -+ return False -+ self.logger.info("The speedup(%.2f) is between %.2f and %.2f" % -+ (measured_speedup, min_speedup, max_speedup)) -+ -+ return True -+ -+ def test_ondemand(self): -+ """ -+ ondemand mode of testing CPU frequency -+ :return: -+ """ -+ if not self.cpu.set_governor('powersave'): -+ self.logger.error("Set governor of all CPUs to powersave failed.") -+ return False -+ self.logger.info("Set governor of all CPUs to powersave succeed.") -+ -+ if not self.cpu.set_governor('ondemand'): -+ self.logger.error("Set governor of all CPUs to ondemand failed.") -+ return False -+ self.logger.info("Set governor of all CPUs to ondemand succeed.") -+ -+ target_cpu = randint(0, self.cpu.nums-1) -+ target_cpu_governor = self.cpu.get_governor(target_cpu) -+ if target_cpu_governor != 'ondemand': -+ self.logger.error("The governor of CPU%s(%s) is not ondemand." % ( -+ target_cpu, target_cpu_governor)) -+ return False -+ self.logger.info("The governor of CPU%s is %s." % -+ (target_cpu, target_cpu_governor)) -+ -+ load_test = Load(target_cpu, self.command) -+ load_test.start() -+ sleep(1) -+ target_cpu_freq = self.cpu.get_freq(target_cpu) -+ if target_cpu_freq != self.cpu.max_freq: -+ self.logger.error("The freq of CPU%s(%d) is not scaling_max_freq(%d)." % ( -+ target_cpu, target_cpu_freq, self.cpu.max_freq)) -+ return False -+ self.logger.info("The freq of CPU%s is scaling_max_freq(%d)." % -+ (target_cpu, target_cpu_freq)) -+ -+ load_test_time = load_test.get_runtime() -+ self.logger.info("Time of CPU%s ondemand load test: %.2f" % -+ (target_cpu, load_test_time)) -+ target_cpu_freq = self.cpu.get_freq(target_cpu) -+ if not target_cpu_freq <= self.cpu.max_freq: -+ self.logger.error("The freq of CPU%s(%d) is not less equal than %d." % ( -+ target_cpu, target_cpu_freq, self.cpu.max_freq)) -+ return False -+ self.logger.info("The freq of CPU%s(%d) is less equal than %d." % ( -+ target_cpu, target_cpu_freq, self.cpu.max_freq)) -+ -+ return True -+ -+ def test_conservative(self): -+ """ -+ conservative mode of testing CPU frequency -+ :return: -+ """ -+ if not self.cpu.set_governor('powersave'): -+ self.logger.error("Set governor of all CPUs to powersave failed.") -+ return False -+ self.logger.info("Set governor of all CPUs to powersave.") -+ -+ if not self.cpu.set_governor('conservative'): -+ self.logger.error( -+ "Set governor of all CPUs to conservative failed.") -+ return False -+ self.logger.info("Set governor of all CPUs to conservative.") -+ -+ target_cpu = randint(0, self.cpu.nums-1) -+ target_cpu_governor = self.cpu.get_governor(target_cpu) -+ if target_cpu_governor != 'conservative': -+ self.logger.error("The governor of CPU%s(%s) is not conservative." % -+ (target_cpu, target_cpu_governor)) -+ return False -+ self.logger.info("The governor of CPU%s is %s." % -+ (target_cpu, target_cpu_governor)) -+ -+ load_test = Load(target_cpu, self.command) -+ load_test.start() -+ sleep(1) -+ target_cpu_freq = self.cpu.get_freq(target_cpu) -+ if not self.cpu.min_freq <= target_cpu_freq <= self.cpu.max_freq: -+ self.logger.error("The freq of CPU%s(%d) is not between %d~%d." % -+ (target_cpu, target_cpu_freq, self.cpu.min_freq, self.cpu.max_freq)) -+ return False -+ self.logger.info("The freq of CPU%s(%d) is between %d~%d." % -+ (target_cpu, target_cpu_freq, self.cpu.min_freq, self.cpu.max_freq)) -+ -+ load_test_time = load_test.get_runtime() -+ self.logger.info("Time of CPU%s conservative load test: %.2f" % -+ (target_cpu, load_test_time)) -+ target_cpu_freq = self.cpu.get_freq(target_cpu) -+ self.logger.info("Current freq of CPU%s is %d." % -+ (target_cpu, target_cpu_freq)) -+ -+ return True -+ -+ def test_powersave(self): -+ """ -+ Powersave mode of testing CPU frequency -+ :return: -+ """ -+ if not self.cpu.set_governor('powersave'): -+ self.logger.error("Set governor of all CPUs to powersave failed.") -+ return False -+ self.logger.info("Set governor of all CPUs to powersave.") -+ -+ target_cpu = randint(0, self.cpu.nums-1) -+ target_cpu_governor = self.cpu.get_governor(target_cpu) -+ if target_cpu_governor != 'powersave': -+ self.logger.error("The governor of CPU%s(%s) is not powersave." % -+ (target_cpu, target_cpu_governor)) -+ return False -+ self.logger.info("The governor of CPU%s is %s." % -+ (target_cpu, target_cpu_governor)) -+ -+ target_cpu_freq = self.cpu.get_freq(target_cpu) -+ if target_cpu_freq != self.cpu.min_freq: -+ self.logger.error("The freq of CPU%s(%d) is not scaling_min_freq(%d)." % -+ (target_cpu, target_cpu_freq, self.cpu.min_freq)) -+ return False -+ self.logger.info("The freq of CPU%s is %d." % -+ (target_cpu, target_cpu_freq)) -+ -+ load_test = Load(target_cpu, self.command) -+ load_test.start() -+ load_test_time = load_test.get_runtime() -+ self.logger.info("Time of CPU%s powersave load test: %.2f" % -+ (target_cpu, load_test_time)) -+ target_cpu_freq = self.cpu.get_freq(target_cpu) -+ self.logger.info("Current freq of CPU%s is %d." % -+ (target_cpu, target_cpu_freq)) -+ -+ return True -+ -+ def test_performance(self): -+ """ -+ Performance mode of testing CPU frequency -+ :return: -+ """ -+ if not self.cpu.set_governor('performance'): -+ self.logger.error( -+ "Set governor of all CPUs to performance failed.") -+ return False -+ self.logger.info("Set governor of all CPUs to performance.") -+ -+ target_cpu = randint(0, self.cpu.nums-1) -+ target_cpu_governor = self.cpu.get_governor(target_cpu) -+ if target_cpu_governor != 'performance': -+ self.logger.error("The governor of CPU%s(%s) is not performance." % -+ (target_cpu, target_cpu_governor)) -+ return False -+ self.logger.info("The governor of CPU%s is %s." % -+ (target_cpu, target_cpu_governor)) -+ -+ target_cpu_freq = self.cpu.get_freq(target_cpu) -+ if target_cpu_freq != self.cpu.max_freq: -+ self.logger.error("The freq of CPU%s(%d) is not scaling_max_freq(%d)." % -+ (target_cpu, target_cpu_freq, self.cpu.max_freq)) -+ return False -+ self.logger.info("The freq of CPU%s is %d." % -+ (target_cpu, target_cpu_freq)) -+ -+ load_test = Load(target_cpu, self.command) -+ load_test.start() -+ load_test_time = load_test.get_runtime() -+ self.logger.info("Time of CPU%s performance load test: %.2f" % -+ (target_cpu, load_test_time)) -+ target_cpu_freq = self.cpu.get_freq(target_cpu) -+ self.logger.info("Current freq of CPU%s is %d." % -+ (target_cpu, target_cpu_freq)) -+ -+ return True -+ -+ def test(self): -+ """ -+ Test case -+ :return: -+ """ -+ if not self.cpu.get_info(): -+ self.logger.error( -+ "Fail to get CPU info.\n Please check if the CPU supports cpufreq.") -+ return False -+ -+ ret = True -+ self.logger.info("Test userspace.") -+ if not self.test_userspace(): -+ self.logger.error("Test userspace failed.") -+ ret = False -+ -+ self.logger.info("Test ondemand.") -+ if not self.test_ondemand(): -+ self.logger.error("Test ondemand failed.") -+ ret = False -+ -+ self.logger.info("Test conservative.") -+ if not self.test_conservative(): -+ self.logger.error("Test conservative failed.") -+ ret = False -+ -+ self.logger.info("Test powersave.") -+ if not self.test_powersave(): -+ self.logger.error("Test powersave failed.") -+ ret = False -+ -+ self.logger.info("Test performance.") -+ if not self.test_performance(): -+ self.logger.error("Test performance failed.") -+ ret = False -+ -+ self.cpu.set_governor(self.original_governor) -+ return ret -diff -Naur rpm/tests/compatible/cpufreq/Makefile oech/tests/compatible/cpufreq/Makefile ---- rpm/tests/compatible/cpufreq/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/cpufreq/Makefile 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,22 @@ -+# Copyright (c) 2020 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/disk/common.py oech/tests/compatible/disk/common.py ---- rpm/tests/compatible/disk/common.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/disk/common.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,208 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @cuixucui -+# Create: 2022-09-23 -+ -+import os -+import shutil -+from subprocess import getoutput -+from hwcompatible.device import CertDevice -+ -+ -+def query_disk(logger, command): -+ """ -+ query disk info -+ """ -+ logger.info("Disk Info:", terminal_print=False) -+ command.run_cmd("fdisk -l") -+ logger.info("Partition Info:", terminal_print=False) -+ command.run_cmd("df -h") -+ logger.info("Mount Info:", terminal_print=False) -+ command.run_cmd("mount") -+ logger.info("Swap Info:", terminal_print=False) -+ command.run_cmd("cat /proc/swaps") -+ logger.info("LVM Info:", terminal_print=False) -+ command.run_cmd("pvdisplay") -+ command.run_cmd("vgdisplay") -+ command.run_cmd("lvdisplay") -+ logger.info("Md Info:", terminal_print=False) -+ command.run_cmd("cat /proc/mdstat") -+ -+ -+def get_disk(logger, command, config_data, pci_num=""): -+ """ -+ Get disk info -+ """ -+ disks = list() -+ test_disks = [] -+ devices = CertDevice(logger).get_devices() -+ for device in devices: -+ if (device.get_property("DEVTYPE") == "disk" and not device.get_property("ID_TYPE")) or\ -+ device.get_property("ID_TYPE") == "disk": -+ if "/host" in device.get_property("DEVPATH"): -+ if isinstance(config_data, str): -+ disks.append(device.get_name()) -+ elif pci_num in device.get_property("DEVPATH"): -+ disks.append(device.get_name()) -+ -+ command.run_cmd("/usr/sbin/swapon -a") -+ with open("/proc/partitions", "r") as partition_file: -+ partition = partition_file.read() -+ -+ with open("/proc/swaps", "r") as swap_file: -+ swap = swap_file.read() -+ -+ with open("/proc/mdstat", "r") as mdstat_file: -+ mdstat = mdstat_file.read() -+ -+ with open("/proc/mounts", "r") as mount_file: -+ mounts = mount_file.read() -+ -+ for disk in disks: -+ if disk not in partition or ("/dev/%s" % disk) in swap: -+ continue -+ if ("/dev/%s" % disk) in mounts or disk in mdstat: -+ continue -+ result = command.run_cmd("pvs | grep -q '/dev/%s'" % disk) -+ if result[2] == 0: -+ continue -+ test_disks.append(disk) -+ -+ un_suitable = list(set(disks).difference(set(test_disks))) -+ if len(un_suitable) > 0: -+ logger.info("These disks %s are in use now, skip them." % "|".join(un_suitable)) -+ return test_disks -+ -+ -+def raw_test(logger, command, disk): -+ """ -+ Raw test -+ """ -+ logger.info("%s raw IO test" % disk) -+ device = os.path.join("/dev", disk) -+ if not os.path.exists(device): -+ logger.error("Device %s doesn't exist." % device) -+ return False -+ proc_path = os.path.join("/sys/block/", disk) -+ if not os.path.exists(proc_path): -+ proc_path = os.path.join("/sys/block/*/", disk) -+ size = getoutput("cat %s/size" % proc_path) -+ size = int(size) / 2 -+ if size <= 0: -+ logger.error( -+ "Device %s size is not suitable for testing." % device) -+ return False -+ elif size > 1048576: -+ size = 1048576 -+ -+ logger.info("Starting sequential raw IO test...") -+ opts = "-direct=1 -iodepth 4 -rw=rw -rwmixread=50 -group_reporting -name=file -runtime=300" -+ if not do_fio(logger, command, device, size, opts): -+ logger.error("%s sequential raw IO test failed." % device) -+ return False -+ -+ logger.info("Starting rand raw IO test...") -+ opts = "-direct=1 -iodepth 4 -rw=randrw -rwmixread=50 " \ -+ "-group_reporting -name=file -runtime=300" -+ if not do_fio(logger, command, device, size, opts): -+ logger.error("%s rand raw IO test failed." % device) -+ return False -+ -+ return True -+ -+ -+def vfs_test(logger, command, disk, filesystems): -+ """ -+ Vfs test -+ """ -+ logger.info("%s vfs test" % disk) -+ device = os.path.join("/dev/", disk) -+ if not os.path.exists(device): -+ logger.error("Device %s doesn't exist." % device) -+ return False -+ proc_path = os.path.join("/sys/block/", disk) -+ if not os.path.exists(proc_path): -+ proc_path = os.path.join("/sys/block/*/", disk) -+ size = getoutput("cat %s/size" % proc_path) -+ size = int(size) / 2 / 2 -+ if size <= 0: -+ logger.error( -+ "Device %s size is not suitable for testing." % device) -+ return False -+ elif size > 1048576: -+ size = 1048576 -+ -+ if os.path.exists("vfs_test"): -+ shutil.rmtree("vfs_test") -+ os.mkdir("vfs_test") -+ path = os.path.join(os.getcwd(), "vfs_test") -+ -+ return_code = True -+ for file_sys in filesystems: -+ logger.info("Formatting %s to %s ..." % -+ (device, file_sys), terminal_print=False) -+ command.run_cmd("umount %s" % device, ignore_errors=True) -+ command.run_cmd("mkfs -t %s -F %s" % (file_sys, device)) -+ command.run_cmd("mount -t %s %s %s" % -+ (file_sys, device, "vfs_test")) -+ logger.info("Starting sequential vfs IO test...") -+ opts = "-direct=1 -iodepth 4 -rw=rw -rwmixread=50 -name=directoy -runtime=300" -+ if not do_fio(logger, command, path, size, opts): -+ return_code = False -+ break -+ -+ logger.info("Starting rand vfs IO test...") -+ opts = "-direct=1 -iodepth 4 -rw=randrw -rwmixread=50 -name=directoy -runtime=300" -+ if not do_fio(logger, command, path, size, opts): -+ return_code = False -+ break -+ -+ command.run_cmd("umount %s" % device) -+ shutil.rmtree("vfs_test") -+ return return_code -+ -+ -+def do_fio(logger, command, filepath, size, option): -+ """ -+ Fio test -+ """ -+ if os.path.isdir(filepath): -+ file_opt = "-directory=%s" % filepath -+ else: -+ file_opt = "-filename=%s" % filepath -+ max_bs = 64 -+ a_bs = 4 -+ while a_bs <= max_bs: -+ cmd_result = command.run_cmd( -+ "fio %s -size=%dK -bs=%dK %s" % (file_opt, size, a_bs, option)) -+ if cmd_result[2] != 0: -+ logger.error("%s fio failed." % filepath) -+ return False -+ a_bs = a_bs * 2 -+ logger.info("%s fio succeed." % filepath) -+ return True -+ -+ -+def valid_disk(logger, disk, disks): -+ """ -+ Is the disk valid -+ """ -+ result = True -+ if disk: -+ if disk != "all" and disk not in disks: -+ logger.error("%s is in use or disk does not exist." % disk) -+ result = False -+ else: -+ logger.error("Failed to get disk information.") -+ result = False -+ return result -diff -Naur rpm/tests/compatible/disk/disk.py oech/tests/compatible/disk/disk.py ---- rpm/tests/compatible/disk/disk.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/disk/disk.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,66 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+# Desc: Disk test -+ -+import argparse -+from hwcompatible.test import Test -+from hwcompatible.command import Command -+from common import query_disk, get_disk, raw_test, vfs_test, valid_disk -+ -+ -+class DiskTest(Test): -+ def __init__(self): -+ Test.__init__(self) -+ self.disks = list() -+ self.requirements = ["fio"] -+ self.filesystems = ["ext4"] -+ self.config_data = "" -+ -+ def setup(self, args=None): -+ """ -+ The Setup before testing -+ :return: -+ """ -+ self.args = args or argparse.Namespace() -+ self.logger = getattr(self.args, "test_logger", None) -+ self.command = Command(self.logger) -+ self.config_data = getattr(self.args, "config_data", None) -+ query_disk(self.logger, self.command) -+ -+ def test(self): -+ """ -+ Start test -+ """ -+ self.disks = get_disk(self.logger, self.command, self.config_data) -+ if len(self.disks) == 0: -+ self.logger.error("No suite disk found to test.") -+ return False -+ -+ if not self.config_data: -+ self.logger.error("Failed to get disk from configuration file.") -+ return False -+ disk = self.config_data -+ result = valid_disk(self.logger, disk, self.disks) -+ if not result: -+ return False -+ -+ return_code = True -+ if disk != "all": -+ self.disks = [disk] -+ for disk in self.disks: -+ if not raw_test(self.logger, self.command, disk): -+ return_code = False -+ if not vfs_test(self.logger, self.command, disk, self.filesystems): -+ return_code = False -+ return return_code -diff -Naur rpm/tests/compatible/disk/Makefile oech/tests/compatible/disk/Makefile ---- rpm/tests/compatible/disk/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/disk/Makefile 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,22 @@ -+# Copyright (c) 2020 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/dpdk/dpdk.py oech/tests/compatible/dpdk/dpdk.py ---- rpm/tests/compatible/dpdk/dpdk.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/dpdk/dpdk.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,439 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+# Author: @ylzhangah -+# Create: 2022-12-01 -+# Desc: DPDK test -+ -+ -+import os -+import argparse -+import json -+import time -+import subprocess -+ -+from urllib.parse import urlencode -+from urllib.request import urlopen, Request -+ -+from hwcompatible.test import Test -+from hwcompatible.command import Command -+from hwcompatible.document import CertDocument -+from hwcompatible.env import CertEnv -+from hwcompatible.constants import FILE_FLAGS, FILE_MODES -+from hugepages import ShowHugepages -+ -+ -+class DPDKTest(Test): -+ """ -+ DPDK test -+ """ -+ -+ def __init__(self): -+ Test.__init__(self) -+ self.requirements = ["dpdk", "dpdk-tools", "dpdk-devel"] -+ self.config_data = dict() -+ self.interface = None -+ self.server_ip = "" -+ self.server_port = 80 -+ self.portmask = "0xffff" -+ self.packet_size = 1514 -+ self.support_driver = ['mlx4_core', 'mlx5_core', 'ixgbe', 'ice', 'hinic', 'igc'] -+ self.dpdk_driver = 'uio_pci_generic' -+ self.kernel_driver = None -+ self.retries = 3 -+ self.speed = 0 # Mb/s -+ self.target_bandwidth_percent = 0.8 -+ self.device = "" -+ self.pci = "" -+ self.card_id = None -+ self.ethpeer = None -+ self.test_dpdk_file = "" -+ -+ def setup(self, args=None): -+ """ -+ Initialization before test -+ :return: -+ """ -+ self.args = args or argparse.Namespace() -+ self.logger = getattr(self.args, "test_logger", None) -+ self.command = Command(self.logger) -+ self.hugepage = ShowHugepages(self.logger, self.command) -+ self.test_dpdk_file = os.path.join(self.logger.logdir, 'test_dpdk.log') -+ self.device = getattr(self.args, 'device', None) -+ self.interface = self.device.get_property("INTERFACE") -+ self.show_driver_info() -+ self.pci = self.device.get_pci() -+ self.kernel_driver = self.device.get_driver() -+ self.card_id = self.device.get_quadruple() -+ self.command.run_cmd("dpdk-hugepages.py -u", terminal_print=False) -+ self.command.run_cmd("dpdk-hugepages.py -c", terminal_print=False) -+ self.command.run_cmd("dpdk-hugepages.py --setup 2G", terminal_print=True) -+ self.config_data = getattr(args, "config_data", None) -+ self.server_ip = CertDocument(CertEnv.certificationfile, self.logger).get_server() -+ self.test_prepare() -+ -+ def get_interface_speed(self): -+ """ -+ Get speed on the interface -+ :return: -+ """ -+ speed = self.command.run_cmd( -+ "ethtool %s | grep Speed | awk '{print $2}'" % self.interface) -+ if speed[2] != 0: -+ self.logger.error("No speed found on the interface.") -+ return 0 -+ -+ return int(speed[0][:-5]) -+ -+ def check_bind(self): -+ """ -+ Check whether binding card is required -+ :return: -+ """ -+ # set interface down so that bind the dpdk driver. -+ if self.kernel_driver not in self.support_driver: -+ self.logger.error("The card driver %s doesn't support dpdk test, Supported drivers are %s." -+ % (self.kernel_driver, self.support_driver)) -+ return False -+ else: -+ self.logger.info("DPDK driver is loading...") -+ subprocess.getoutput("modprobe uio; modprobe %s" % self.dpdk_driver) -+ if self.command.run_cmd("lsmod | grep %s" % self.dpdk_driver, terminal_print=True)[2] != 0: -+ self.logger.error("DPDK driver is loaded failed!") -+ return False -+ else: -+ self.logger.info("Get server card's ethpeer...") -+ if not self.get_ethpeer(): -+ return False -+ if self.kernel_driver == "mlx4_core" or self.kernel_driver == "mlx5_core": -+ self.logger.info("The mellanox network card does not need to be bound.") -+ self.command.run_cmd("modprobe -a ib_uverbs mlx5_core mlx5_ib mlx4_core", terminal_print=True) -+ else: -+ self.logger.info("Server dpdk is binding...") -+ if not self.server_dpdk_bind(): -+ return False -+ self.logger.info("Client dpdk is binding...") -+ if not self.client_dpdk_bind(): -+ return False -+ return True -+ -+ def get_ethpeer(self): -+ """ -+ Get ethpeer. -+ :return: -+ """ -+ form = {'serverip': self.server_ip, 'cardid': self.card_id} -+ url = 'http://{}:%s/api/get/ethpeer'.format(self.server_ip) % self.server_port -+ data = urlencode(form).encode('utf8') -+ headers = { -+ 'Content-type': 'application/x-www-form-urlencoded', -+ 'Accept': 'text/plain' -+ } -+ request = Request(url, data=data, headers=headers) -+ try: -+ response = urlopen(request) -+ except Exception: -+ self.logger.error("Call remote server url %s failed." % url) -+ return False -+ self.logger.info(str(response.headers), terminal_print=False) -+ self.ethpeer = json.loads(response.read())['ethpeer'] -+ self.logger.info("The mac of the server card is %s" % self.ethpeer) -+ self.logger.info("Status: %u %s" % (response.code, response.msg)) -+ if response.code != 200: -+ return False -+ return True -+ -+ def client_dpdk_bind(self): -+ """ -+ Bind client card with dpdk driver -+ :return: -+ """ -+ self.logger.info("Setting client interface %s down." % self.interface) -+ if not self.ifdown(self.interface): -+ self.logger.error("Setting client interface down failed!") -+ return False -+ else: -+ self.logger.info("Client dpdk is binding...") -+ cmd = self.command.run_cmd("dpdk-devbind.py -b %s %s" % (self.dpdk_driver, self.interface)) -+ if cmd[2] == 0: -+ self.logger.info("Client dpdk is bound successfully!") -+ self.command.run_cmd("dpdk-devbind.py -s") -+ return True -+ else: -+ self.logger.error("Bind card with dpdk driver failed!") -+ return False -+ -+ def server_dpdk_bind(self): -+ """ -+ Bind the server card. -+ :return: -+ """ -+ form = {'serverip': self.server_ip, 'cardid': self.card_id} -+ url = 'http://{}:%s/api/bind/server'.format(self.server_ip) % self.server_port -+ data = urlencode(form).encode('utf8') -+ headers = { -+ 'Content-type': 'application/x-www-form-urlencoded', -+ 'Accept': 'text/plain' -+ } -+ request = Request(url, data=data, headers=headers) -+ try: -+ response = urlopen(request) -+ except Exception: -+ self.logger.error("Call remote server url %s failed." % url) -+ return False -+ self.logger.info(str(response.headers), terminal_print=False) -+ self.logger.info("Status: %u %s" % (response.code, response.msg)) -+ if response.code != 200: -+ return False -+ return True -+ -+ def test(self): -+ """ -+ Test case -+ :return: -+ """ -+ if not self.test_icmp(): -+ return False -+ -+ if not self.check_bind(): -+ return False -+ -+ self.logger.info("Start dpdk-testpmd server...") -+ if not self.call_remote_server('dpdk-testpmd', 'start'): -+ self.logger.error("[X] start dpdk-testpmd server failed.") -+ return False -+ -+ self.logger.info("Test dpdk speed...") -+ if not self.test_speed(): -+ self.logger.error("Test dpdk speed failed.") -+ return False -+ -+ self.logger.info("Stop dpdk-testpmd server...") -+ if not self.call_remote_server('dpdk-testpmd', 'stop'): -+ self.logger.error("[X] Stop dpdk-testpmd server failed.") -+ return False -+ -+ return True -+ -+ def show_hugepage(self): -+ """ -+ Show Hugepages on system. -+ :return: -+ """ -+ if self.hugepage.is_numa(): -+ self.hugepage.show_numa_pages() -+ else: -+ self.hugepage.show_non_numa_pages() -+ -+ def test_prepare(self): -+ """ -+ Preparation before test -+ :return: -+ """ -+ if not self.hugepage.check_hugepage_allocate(self.hugepage.is_numa()): -+ self.logger.error("No hugepage allocated.") -+ return False -+ -+ if not self.hugepage.get_mountpoints(): -+ self.logger.error("No hugepage mounted.") -+ return False -+ -+ self.logger.info("Hugepage successfully configured.") -+ self.show_hugepage() -+ -+ return True -+ -+ def test_speed(self): -+ """ -+ Test speed -+ :return: -+ """ -+ command = [ -+ 'dpdk-testpmd', -+ '-l', '0-1', -+ '-n', '1', -+ '-a', self.pci, -+ '--', -+ '--portmask=0x1', -+ '--txpkts=%d' % self.packet_size, -+ '--rxq=4', -+ '--txq=4', -+ '--forward-mode=txonly', -+ '--eth-peer=0,%s' % self.ethpeer, -+ '--stats-period=2' -+ ] -+ res = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ self.logger.info("Please wait 30 seconds.") -+ time.sleep(30) -+ res.terminate() -+ with os.fdopen(os.open(self.test_dpdk_file, FILE_FLAGS, FILE_MODES), "w") as log: -+ log.write(str(res.stdout.read(), 'UTF-8')) -+ time.sleep(30) -+ res = self.command.run_cmd("grep Tx-bps %s | awk '{print $4}'" % self.test_dpdk_file) -+ if res[2] != 0: -+ self.logger.error("The test data result is empty, Please check if the server is configured properly!") -+ res_list = res[0].split("\n")[-10:-1] -+ int_list = [int(x) for x in res_list] -+ number = len(int_list) -+ if number != 0: -+ bandwidth = float(sum(int_list) / number / 1e6) -+ # 1e6 = 1000000.0 -+ target_bandwidth = self.target_bandwidth_percent * self.speed -+ self.logger.info("Current bandwidth is around %.2f Mb/s, target is %.2fMb/s" % -+ (bandwidth, target_bandwidth)) -+ if bandwidth > target_bandwidth: -+ self.logger.info("Test dpdk bandwidth successfully.") -+ return True -+ self.logger.error("Test dpdk bandwidth failed!") -+ return False -+ else: -+ self.logger.error("No data obtained for testing dpdk, Please manually check!") -+ return False -+ -+ def ifdown(self, interface): -+ """ -+ Judge whether the specified interface is closed successfully -+ :param interface: -+ :return: -+ """ -+ self.command.run_cmd("ip link set down %s" % interface) -+ for _ in range(10): -+ result = self.command.run_cmd( -+ "ip link show %s | grep 'state DOWN'" % interface, ignore_errors=True) -+ if result[2] == 0: -+ self.logger.info("Set interface %s down succeed." % self.interface) -+ return True -+ time.sleep(1) -+ -+ self.logger.error("Set interface %s down failed." % self.interface) -+ return False -+ -+ def ifup(self, interface): -+ """ -+ Judge whether the specified interface is enabled successfully -+ :param interface: -+ :return: -+ """ -+ self.command.run_cmd("ip link set up %s" % interface) -+ for _ in range(10): -+ result = self.command.run_cmd( -+ "ip link show %s | grep 'state UP'" % interface, ignore_errors=True) -+ if result[2] == 0: -+ self.logger.info("Set interface %s up succeed." % self.interface) -+ return True -+ time.sleep(1) -+ -+ self.logger.error("Set interface %s up failed." % self.interface) -+ return False -+ -+ def test_icmp(self): -+ """ -+ Test ICMP -+ :return: -+ """ -+ self.speed = self.get_interface_speed() -+ if self.speed: -+ self.logger.info("The speed of %s is %sMb/s." % -+ (self.interface, self.speed)) -+ else: -+ self.logger.error("Set speed of %s failed." % self.interface) -+ -+ count = 500 -+ cmd = "ping -q -c %d -i 0 %s | grep 'packet loss' | awk '{print $6}'" % ( -+ count, self.server_ip) -+ for _ in range(self.retries): -+ result = self.command.run_cmd(cmd, ignore_errors=True) -+ if result[0].strip() == "0%": -+ self.logger.info("Test icmp succeed.") -+ return True -+ self.logger.error("Test icmp failed.") -+ return False -+ -+ def call_remote_server(self, cmd, act='start'): -+ """ -+ Connect to the server somehow. -+ :param cmd: -+ :param act: -+ :return: -+ """ -+ form = dict() -+ form = {'cmd': cmd, 'serverip': self.server_ip, 'cardid': self.card_id} -+ url = 'http://%s/api/%s' % (self.server_ip, act) -+ data = urlencode(form).encode('utf8') -+ headers = { -+ 'Content-type': 'application/x-www-form-urlencoded', -+ 'Accept': 'text/plain' -+ } -+ request = Request(url, data=data, headers=headers) -+ try: -+ response = urlopen(request) -+ except Exception: -+ self.logger.error("Call remote dpdk server url %s failed." % url) -+ return False -+ self.logger.info("Status: %u %s" % (response.code, response.msg)) -+ return int(response.code) == 200 -+ -+ def server_dpdk_unbind(self): -+ """ -+ Unbind the server card. -+ :return: -+ """ -+ form = {'serverip': self.server_ip, 'cardid': self.card_id} -+ url = 'http://{}/api/unbind/server'.format(self.server_ip) -+ data = urlencode(form).encode('utf8') -+ headers = { -+ 'Content-type': 'application/x-www-form-urlencoded', -+ 'Accept': 'text/plain' -+ } -+ request = Request(url, data=data, headers=headers) -+ try: -+ response = urlopen(request) -+ except Exception: -+ self.logger.error("Call remote server url %s failed." % url) -+ return False -+ -+ self.logger.info("Status: %u %s" % (response.code, response.msg)) -+ if response.code != 200: -+ return False -+ return True -+ -+ def dev_unbind(self): -+ """ -+ dpdk unbind -+ :return: -+ """ -+ self.logger.info("Unbinding server card...") -+ if self.server_dpdk_unbind(): -+ self.logger.info("Unbind server card successfully!") -+ -+ self.logger.info("Unbinding client card...") -+ self.command.run_cmd("dpdk-devbind.py -u %s" % self.pci) -+ cmd = self.command.run_cmd("dpdk-devbind.py -b %s %s" % (self.kernel_driver, self.pci)) -+ if cmd[0] == "": -+ self.logger.info("Unbinding client card successfully!") -+ -+ self.logger.info("Setting client interface %s up..." % self.interface) -+ if not self.ifup(self.interface): -+ return False -+ return True -+ -+ def teardown(self): -+ """ -+ Environment recovery after test -+ :return: -+ """ -+ if self.kernel_driver == "mlx4_core" or self.kernel_driver == "mlx5_core": -+ self.logger.info("The Mellanox card need not unbind!") -+ else: -+ self.dev_unbind() -+ self.call_remote_server('all', 'stop') -+ self.logger.info("Stop all test servers.") -diff -Naur rpm/tests/compatible/dpdk/hugepages.py oech/tests/compatible/dpdk/hugepages.py ---- rpm/tests/compatible/dpdk/hugepages.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/dpdk/hugepages.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,106 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @ylzhangah -+# Create: 2022-12-01 -+# Desc: DPDK test -+ -+ -+import os -+import glob -+from math import log2 -+ -+ -+class ShowHugepages: -+ """ -+ Format memsize, get moutpoint, show hugepages -+ """ -+ -+ def __init__(self, logger, command): -+ self.logger = logger -+ self.command = command -+ -+ def format_memsize(self, kb): -+ """" -+ format memsize. this is a code snippit from dpdk repo -+ """ -+ binary_prefix = "KMG" -+ logk = int(log2(kb) / 10) -+ suffix = binary_prefix[logk] -+ unit = 2 ** (logk * 10) -+ if unit != 0: -+ return '{}{}b'.format(int(kb / unit), suffix) -+ else: -+ return False -+ -+ def get_mountpoints(self): -+ """ -+ Get list of where hugepage filesystem is mounted -+ """ -+ mounted = self.command.run_cmd("mount | grep hugetlbfs | awk '{print $2}'")[0].strip('\n') -+ return mounted -+ -+ def is_numa(self): -+ """ -+ Test if numa is used on this system -+ """ -+ return os.path.exists('/sys/devices/system/node') -+ -+ def show_numa_pages(self): -+ """ -+ Show huge page reservations on numa system -+ """ -+ self.logger.info('Node Pages Size Total') -+ for numa_path in glob.glob('/sys/devices/system/node/node*'): -+ node = numa_path[29:] # slice after /sys/devices/system/node/node -+ path = os.path.join(numa_path, 'hugepages') -+ for hdir in os.listdir(path): -+ comm = self.command.run_cmd("cat %s/%s/nr_hugepages" % (path, hdir)) -+ pages = int(comm[0].strip('\n')) -+ if pages > 0: -+ kb = int(hdir[10:-2]) # slice out of hugepages-NNNkB -+ self.logger.info('{:<4} {:<5} {:<6} {}'.format(node, pages, -+ self.format_memsize(kb), self.format_memsize(pages * kb))) -+ -+ def show_non_numa_pages(self): -+ """ -+ Show huge page reservations on non numa system -+ """ -+ self.logger.info('Pages Size Total') -+ hugepagedir = '/sys/kernel/mm/hugepages/' -+ for hdir in os.listdir(hugepagedir): -+ comm = self.command.run_cmd("cat %s/%s/nr_hugepages" % (hugepagedir, hdir)) -+ pages = int(comm[0].strip('\n')) -+ if pages > 0: -+ kb = int(hdir[10:-2]) -+ -+ self.logger.info('{:<5} {:<6} {}'.format(pages, self.format_memsize(kb), -+ self.format_memsize(pages * kb))) -+ -+ def check_hugepage_allocate(self, isnuma): -+ if not isnuma: -+ hugepagedir = '/sys/kernel/mm/hugepages/' -+ else: -+ numaid = 0 -+ hugepagedir = '/sys/devices/system/node/node%d/hugepages/' % numaid -+ -+ for (_, dirs, _) in os.walk(hugepagedir): -+ for directory in dirs: -+ comm = self.command.run_cmd("cat %s/%s/nr_hugepages" % (hugepagedir, directory)) -+ if comm[0] != 0: -+ return True -+ break -+ -+ return False -+ -+ # return false when -+ # 1. no files in hugepagedir; -+ # 2. no non-zero entry was found; -diff -Naur rpm/tests/compatible/dpdk/Makefile oech/tests/compatible/dpdk/Makefile ---- rpm/tests/compatible/dpdk/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/dpdk/Makefile 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,24 @@ -+# Copyright (c) 2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @ylzhangah -+# Create: 2022-12-01 -+# Desc: DPDK test -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a $(SUBDIR)/build *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/fc/fc.py oech/tests/compatible/fc/fc.py ---- rpm/tests/compatible/fc/fc.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/fc/fc.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,96 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2022-04-09 -+# Desc: Fibre channel test -+ -+import argparse -+from hwcompatible.test import Test -+from hwcompatible.command import Command -+from tests.compatible.disk.common import query_disk, get_disk, raw_test, vfs_test, valid_disk -+ -+ -+class FCTest(Test): -+ def __init__(self): -+ Test.__init__(self) -+ self.disks = list() -+ self.requirements = ["fio"] -+ self.filesystems = ["ext4"] -+ self.device = "" -+ self.pci_num = "" -+ self.config_data = dict() -+ -+ def setup(self, args=None): -+ """ -+ The Setup before testing -+ :return: -+ """ -+ self.args = args or argparse.Namespace() -+ self.logger = getattr(self.args, "test_logger", None) -+ self.command = Command(self.logger) -+ self.config_data = getattr(self.args, "config_data", None) -+ -+ self.device = getattr(self.args, 'device', None) -+ self.pci_num = self.device.get_property("DEVPATH").split('/')[-1] -+ self.show_driver_info() -+ self.logger.info("Vendor Info:", terminal_print=False) -+ self.command.run_cmd("lspci -s %s -v" % self.pci_num) -+ query_disk(self.logger, self.command) -+ -+ def test(self): -+ """ -+ Start test -+ """ -+ pci_num = self.check_link_state() -+ if not pci_num: -+ return False -+ self.disks = get_disk(self.logger, self.command, self.config_data, pci_num) -+ if len(self.disks) == 0: -+ self.logger.error("No suite disk found to test.") -+ return False -+ -+ if not self.config_data: -+ self.logger.error("Failed to get disk from configuration file.") -+ return False -+ -+ disk = self.config_data.get('disk', '') -+ if not valid_disk(self.logger, disk, self.disks): -+ return False -+ -+ return_code = True -+ if disk != "all": -+ self.disks = [disk] -+ for disk in self.disks: -+ if not raw_test(self.logger, self.command, disk): -+ return_code = False -+ if not vfs_test(self.logger, self.command, disk, self.filesystems): -+ return_code = False -+ return return_code -+ -+ def check_link_state(self): -+ """ -+ check HBA link state -+ """ -+ host_name = self.command.run_cmd("ls -l /sys/class/fc_host | grep %s | awk '{print $9}'" -+ % self.pci_num)[0].strip('\n') -+ port_state = self.command.run_cmd("cat /sys/class/fc_host/%s/port_state" % host_name)[0].strip('\n') -+ if port_state == "Linkdown": -+ self.logger.error("The HBA's port_state is linkdown, Please check the connection state!") -+ return "" -+ elif port_state == "Online": -+ pci_num = self.pci_num -+ self.logger.info("The HBA's port_state is Online, start testing...") -+ return pci_num -+ else: -+ self.logger.info("The HBA's port_state can't be viewed") -+ return False -+ -diff -Naur rpm/tests/compatible/fc/Makefile oech/tests/compatible/fc/Makefile ---- rpm/tests/compatible/fc/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/fc/Makefile 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,22 @@ -+# Copyright (c) 2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2022-04-09 -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/gpu/amd_gpu.py oech/tests/compatible/gpu/amd_gpu.py ---- rpm/tests/compatible/gpu/amd_gpu.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/gpu/amd_gpu.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,141 @@ -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @meitingli -+# Create: 2022-10-15 -+# Desc: AMD GPU test (This test could only execute on graphical.target) -+ -+import os -+from subprocess import getstatusoutput -+ -+gpu_dir = os.path.dirname(os.path.realpath(__file__)) -+ -+ -+class AMDGpuTest(): -+ def __init__(self, device, logger, command): -+ self.device = device -+ self.logger = logger -+ self.command = command -+ self.radeontop_log = os.path.join(self.logger.logdir, 'radeontop.log') -+ self.screen_info_log = os.path.join( -+ self.logger.logdir, 'screen_info.log') -+ self.glmark_log = os.path.join(self.logger.logdir, 'glmark2.log') -+ -+ def get_driver_info(self): -+ """ -+ Get driver info, includings name, version -+ """ -+ self.logger.info("Vendor Info:", terminal_print=False) -+ self.command.run_cmd('lspci -vs %s' % self.device.pci) -+ -+ self.logger.info("Driver Info:", terminal_print=False) -+ driver = self.device.driver -+ self.logger.info("Driver Name: %s" % driver) -+ -+ driver_version = self.device.get_driver_version() -+ if driver_version: -+ self.logger.info("Driver Version: %s" % driver_version) -+ else: -+ self.logger.warning( -+ "The driver version information cannot be obtained. Please view it manually.") -+ -+ def test_pressure(self): -+ """ -+ Set pressure for gpu to test -+ This test need graphical.target to support -+ Returns: -+ bool: -+ """ -+ os.chdir("/opt/glmark2/build/src") -+ cmd = getstatusoutput( -+ './glmark2 --off-screen | tee %s' % self.glmark_log) -+ if cmd[0] != 0: -+ self.logger.error("Test gpu pressure failed.") -+ return False -+ self.logger.info("Test gpu pressure succeed.") -+ -+ cmd = self.command.run_cmd( -+ "grep 'glmark2 Score' %s" % self.glmark_log) -+ if cmd[2] == 0: -+ self.logger.info("Check gpu glmark2 score succeed.") -+ else: -+ self.logger.error("Check gpu glmark2 score failed.") -+ return False -+ -+ return True -+ -+ def test_screen_info(self): -+ """ -+ Test screen information for gpu -+ This test need graphical.target to support -+ Returns: -+ bool: -+ """ -+ os.chdir("/opt/glmark2/build/src") -+ cmd = self.command.run_cmd( -+ "./glmark2 -l | tee %s " % self.screen_info_log) -+ if cmd[2] == 0: -+ self.logger.info("Test gpu screen information succeed.") -+ else: -+ self.logger.error("Test gpu screen information failed.") -+ return False -+ -+ return True -+ -+ def test_radeontop(self): -+ """ -+ Check gpu utilization by radeontop, it can execute multi times and has log file -+ Returns: -+ bool: -+ """ -+ os.chdir("/opt/radeontop") -+ cmd = getstatusoutput( -+ "echo q | ./radeontop | tee %s" % self.radeontop_log) -+ if cmd[0] == 0: -+ self.logger.info("Check gpu radeontop succeed.") -+ else: -+ self.logger.error("Check gpu radeontop failed.") -+ return False -+ -+ return True -+ -+ def test_amd_gpu(self): -+ """ -+ AMD gpu test entry function -+ Returns: -+ bool: -+ """ -+ result = True -+ self.get_driver_info() -+ self.command.run_cmd( -+ "bash %s/test_amd_gpu.sh install_readontop" % gpu_dir) -+ self.command.run_cmd( -+ "bash %s/test_amd_gpu.sh install_glmark2" % gpu_dir) -+ -+ self.logger.info("Check gpu radeontop.") -+ try: -+ if not self.test_radeontop(): -+ result = False -+ -+ if not self.test_screen_info(): -+ result = False -+ -+ self.logger.info("Start to test gpu pressure.") -+ if not self.test_pressure(): -+ result = False -+ self.logger.info("End to test gpu pressure.") -+ -+ except Exception as e: -+ self.logger.error( -+ "Failed to run the script because compiling or setting variables: %s" % e) -+ result = False -+ -+ return result -diff -Naur rpm/tests/compatible/gpu/gpu.py oech/tests/compatible/gpu/gpu.py ---- rpm/tests/compatible/gpu/gpu.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/gpu/gpu.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,54 @@ -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @meitingli -+# Create: 2022-04-13 -+# Desc: GPU test, support AMD/NVIDIA series gpu -+ -+import argparse -+from hwcompatible.command import Command -+from hwcompatible.test import Test -+from nvidia_gpu import NvidiaGpuTest -+from amd_gpu import AMDGpuTest -+ -+ -+class GpuTest(Test): -+ def __init__(self): -+ Test.__init__(self) -+ self.requirements = ["gcc-c++", "make", "git"] -+ self.device = None -+ -+ def setup(self, args=None): -+ """ -+ Initialization before test -+ """ -+ self.args = args or argparse.Namespace() -+ self.logger = getattr(args, "test_logger", None) -+ self.device = getattr(args, 'device', None) -+ self.command = Command(self.logger) -+ -+ def test(self): -+ """ -+ Test case -+ Returns: -+ bool: Execution result -+ """ -+ driver = self.device.driver -+ if driver == "amdgpu": -+ amd_test = AMDGpuTest(self.device, self.logger, self.command) -+ result = amd_test.test_amd_gpu() -+ else: -+ nvidia_test = NvidiaGpuTest(self.device, self.logger, self.command) -+ result = nvidia_test.test_nvidia_gpu() -+ -+ return result -+ -+ -\ No newline at end of file -diff -Naur rpm/tests/compatible/gpu/Makefile oech/tests/compatible/gpu/Makefile ---- rpm/tests/compatible/gpu/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/gpu/Makefile 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,23 @@ -+# Copyright (c) 2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2022-04-13 -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a *.py $(DEST) -+ cp -a *.sh $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/gpu/nvidia_gpu.py oech/tests/compatible/gpu/nvidia_gpu.py ---- rpm/tests/compatible/gpu/nvidia_gpu.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/gpu/nvidia_gpu.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,154 @@ -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2022-10-14 -+# Desc: Nvidia GPU test -+ -+import os -+import re -+import time -+from subprocess import getstatusoutput -+gpu_dir = os.path.dirname(os.path.realpath(__file__)) -+ -+ -+class NvidiaGpuTest(): -+ def __init__(self, device, logger, command): -+ self.device = device -+ self.logger = logger -+ self.command = command -+ self.cuda_samples_log = os.path.join( -+ self.logger.logdir, 'cuda_samples.log') -+ self.gpu_burn = os.path.join(self.logger.logdir, 'gpu_burn.log') -+ self.smi_name = "nvidia-smi" -+ -+ def get_driver_info(self): -+ """ -+ Get driver info, includings name, version -+ """ -+ self.logger.info("Vendor Info:", terminal_print=False) -+ self.command.run_cmd('lspci -vs %s' % self.device.pci) -+ -+ self.logger.info("Driver Info:", terminal_print=False) -+ driver = self.device.driver -+ if driver == "iluvatar-itr": -+ self.smi_name = "ixsmi" -+ driver = "bi_driver" -+ self.device.set_driver(driver) -+ self.logger.info("Driver Name: %s" % driver) -+ -+ driver_version = self.device.get_driver_version() -+ if driver_version: -+ self.logger.info("Driver Version: %s" % driver_version) -+ else: -+ self.logger.warning( -+ "The driver version information cannot be obtained. Please view it manually.") -+ -+ def set_default_gpu(self): -+ pci = [] -+ num = [] -+ pci_key = "GPU 0000" + self.device.get_pci() -+ gpu = self.command.run_cmd('%s -q' % self.smi_name, log_print=False) -+ for line in gpu[0].split("\n"): -+ if "GPU 0000" in line: -+ pci.append(line) -+ if "Minor Number" in line: -+ num.append(line) -+ id_num = 0 -+ output = dict(zip(pci, num)) -+ if pci_key in output.keys(): -+ id_num = str(re.findall("\d+", output[pci_key])).strip("['']") -+ os.environ['CUDA_VISIBLE_DEVICES'] = id_num -+ -+ self.logger.info("Set default test gpu as %s." % id_num) -+ -+ def test_pressure(self): -+ """ -+ Set pressure for gpu to test -+ Returns: -+ bool: -+ """ -+ self.logger.info("Monitor GPU temperature and utilization rate.") -+ pci_num = self.device.get_pci() -+ self.command.run_cmd(self.smi_name) -+ self.command.run_cmd( -+ "bash %s/test_nvidia_gpu.sh install_gpu_burn" % gpu_dir) -+ -+ os.chdir("/opt/gpu-burn") -+ cmd = self.command.run_cmd( -+ "nvidia-smi -q | grep -i -A1 '%s' | grep 'Product Name' | cut -d ':' -f 2" % pci_num) -+ device_name = cmd[0].strip() -+ cmd = self.command.run_cmd( -+ "./gpu_burn -l | grep -i '%s' | cut -d ':' -f 1 | awk '{print $2}'" % device_name) -+ run_id = cmd[0].strip() -+ cmd = getstatusoutput( -+ 'nohup ./gpu_burn -i%s 10 &> %s &' % (run_id, self.gpu_burn)) -+ if cmd[0] != 0: -+ self.logger.error("Execute gpu_burn failed.") -+ return False -+ self.logger.info("Execute gpu_burn succeed.") -+ -+ time_start = time.time() -+ while 1: -+ cmd = self.command.run_cmd( -+ "ps -ef | grep 'gpu_burn' | grep -v grep", ignore_errors=True) -+ if cmd[2] != 0: -+ break -+ time_delta = time.time() - time_start -+ if time_delta >= 500: -+ break -+ self.command.run_cmd(self.smi_name) -+ time.sleep(5) -+ -+ return True -+ -+ def test_nvidia_gpu(self): -+ """ -+ Nvidia gpu test entry function -+ Returns: -+ bool: -+ """ -+ result = True -+ self.get_driver_info() -+ -+ self.logger.info("Check gpu information.") -+ self.command.run_cmd('%s -q' % self.smi_name) -+ self.logger.info("Check cuda version.") -+ self.command.run_cmd('/usr/local/cuda/bin/nvcc --version') -+ -+ self.logger.info("Start to test gpu pressure.") -+ try: -+ if not self.test_pressure(): -+ result = False -+ -+ check_result = self.command.run_cmd( -+ "grep 'GPU 0: OK' %s" % self.gpu_burn) -+ if os.path.exists(self.gpu_burn) and check_result[2] == 0: -+ self.logger.info("Test gpu pressure succeed.") -+ else: -+ self.logger.error("Test gpu pressure failed.") -+ result = False -+ -+ self.logger.info("Start to test cuda samples.") -+ self.set_default_gpu() -+ sample_case = "simpleOccupancy,bandwidthTest,p2pBandwidthLatencyTest,deviceQuery,clock" -+ code = self.command.run_cmd( -+ "bash %s/test_nvidia_gpu.sh test_cuda_samples '%s %s'" % (gpu_dir, self.cuda_samples_log, sample_case)) -+ if code[2] == 0: -+ self.logger.info("Test cuda samples succeed.") -+ else: -+ result = False -+ self.logger.error("Test cuda samples failed.") -+ except Exception as e: -+ self.logger.error( -+ "Failed to run the script because compiling or setting variables: %s" % e) -+ result = False -+ -+ return result -diff -Naur rpm/tests/compatible/gpu/test_amd_gpu.sh oech/tests/compatible/gpu/test_amd_gpu.sh ---- rpm/tests/compatible/gpu/test_amd_gpu.sh 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/gpu/test_amd_gpu.sh 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,56 @@ -+#!/usr/bin/bash -+# Copyright (c) 2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @meitingli -+# Create: 2022-10-13 -+# Desc: Shell script used for testing AMD gpu -+ -+function install_readontop() { -+ cd /opt -+ res_code=0 -+ if [ ! -d radeontop ]; then -+ git clone https://github.com/clbr/radeontop.git -+ dnf install -y libdrm-devel ncurses-devel ncurses-libs libpciaccess-devel libxcb-devel -+ fi -+ cd radeontop -+ make &>/dev/null || res_code=1 -+ -+ return $res_code -+} -+ -+function install_glmark2() { -+ cd /opt -+ res_code=0 -+ if [ ! -d glmark2 ]; then -+ git clone https://github.com/glmark2/glmark2.git -+ dnf install -y meson libX11-devel libpng-devel cmake pkgconf libjpeg libjpeg-turbo-devel libdrm-devel mesa-libgbm-devel libgudev-devel -+ fi -+ cd glmark2 -+ meson setup build -Dflavors=drm-gl,drm-glesv2,wayland-gl,wayland-glesv2,x11-gl,x11-glesv2 -+ ninja -C build &>/dev/null -+ ninja -C build install &>/dev/null || res_code=1 -+ -+ return $res_code -+} -+ -+function main() { -+ func_name=$1 -+ -+ if [[ $func_name == "install_readontop" ]]; then -+ install_readontop -+ elif [[ $func_name == "install_glmark2" ]]; then -+ install_glmark2 -+ else -+ echo "The function doesn't exist, please check!" -+ return 1 -+ fi -+} -+ -+main "$@" -diff -Naur rpm/tests/compatible/gpu/test_nvidia_gpu.sh oech/tests/compatible/gpu/test_nvidia_gpu.sh ---- rpm/tests/compatible/gpu/test_nvidia_gpu.sh 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/gpu/test_nvidia_gpu.sh 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,135 @@ -+#!/usr/bin/bash -+# Copyright (c) 2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @meitingli -+# Create: 2022-05-05 -+# Desc: Shell script used for testing nvidia gpu -+ -+cuda_version=$(nvidia-smi -q | grep "CUDA Version" | awk '{print $4}') -+cuda_name="cuda-samples-${cuda_version}" -+ -+function install_gpu_burn() { -+ cd /opt -+ res_code=0 -+ if [ ! -d gpu-burn ]; then -+ git clone https://github.com/wilicc/gpu-burn.git -+ fi -+ cd gpu-burn -+ lsmod | grep bi_driver >/dev/null -+ if [ $? -eq 0 ]; then -+ COREX_PATH=${COREX_PATH:-/usr/local/corex} -+ clang++ compare.cu -o compare.ll -I${COREX_PATH}/include --cuda-gpu-arch=ivcore10 --cuda-path=${COREX_PATH} --cuda-device-only -S -x cuda || res_code=1 -+ llc -mcpu=ivcore10 -mtriple=bi-iluvatar-ilurt -show-mc-encoding -filetype=obj compare.ll -o compare.o || res_code=1 -+ lld -flavor ld.lld --no-undefined compare.o -o compare.ptx || res_code=1 -+ rm compare.ll compare.o -+ sed -i '/cuFuncSet/d' gpu_burn-drv.cpp -+ sed -i '/cuParamSet/d' gpu_burn-drv.cpp -+ sed -i 's/nvidia-smi/ixsmi/g' gpu_burn-drv.cpp -+ sed -i 's/.*cuLaunchGridAsync.*/void\* kargs[] = {\&d_Cdata, \&d_faultyElemData, \&d_iters};checkError(cuLaunchKernel(d_function, SIZE\/g_blockSize, SIZE\/g_blockSize, 1, g_blockSize, g_blockSize, 1, 0, 0, kargs, nullptr));/g' gpu_burn-drv.cpp -+ clang++ -std=c++11 -I${COREX_PATH}/include -L${COREX_PATH}/lib64 -lcudart -lcuda -lcublas -o gpu_burn ./gpu_burn-drv.cpp || res_code=1 -+ else -+ make &>/dev/null || res_code=1 -+ fi -+ return $res_code -+} -+ -+function install_cuda_samples() { -+ cd /opt -+ if [ ! -d ${cuda_name} ]; then -+ wget https://github.com/NVIDIA/cuda-samples/archive/refs/tags/v${cuda_version}.zip -+ unzip v${cuda_version}.zip >/dev/null -+ rm -rf v${cuda_version}.zip -+ fi -+ return 0 -+} -+ -+function test_nvidia_case() { -+ casename=$1 -+ logfile=$2 -+ res_code=0 -+ cd /opt/${cuda_name} -+ path=$(find ./ -name $casename -type d) -+ cd $path -+ make &>/dev/null -+ ./$casename &>>$logfile -+ if [[ $? -eq 0 ]]; then -+ echo "Test $casename succeed." >>$logfile -+ else -+ echo "Test $casename failed." >>$logfile -+ res_code=1 -+ fi -+ return $res_code -+} -+ -+function test_iluvatar_case() { -+ casename=$1 -+ logfile=$2 -+ res_code=0 -+ CUDA_PATH=${CUDA_PATH:-/usr/local/corex} -+ cd /opt/${cuda_name} -+ path=$(find ./ -name $casename) -+ cd $path -+ src_file=${casename}.cu -+ if [ ! -f ./$src_file ] && [ -f ./${casename}.cpp ]; then -+ src_file=${casename}.cpp -+ fi -+ clang++ -std=c++11 -I../../../Common -I${CUDA_PATH}/include --cuda-path=${CUDA_PATH} -L${CUDA_PATH}/lib64 -lcudart -lixlogger -lcuda -lixthunk -o ${casename} ./${src_file} -+ ./$casename &>>$logfile -+ if [[ $? -eq 0 ]]; then -+ echo "Test $casename succeed." -+ else -+ echo "Test $casename failed." -+ res_code=1 -+ fi -+ return $res_code -+} -+ -+function test_cuda_samples() { -+ logfile=$1 -+ allcases=(${2//,/ }) -+ res_code=0 -+ install_cuda_samples -+ cd /opt/${cuda_name} -+ lsmod | grep bi_driver -+ if [[ $? -eq 0 ]]; then -+ for casename in ${allcases[@]}; do -+ test_iluvatar_case $casename $logfile -+ if [[ $? -eq 1 ]]; then -+ res_code=1 -+ fi -+ done -+ else -+ for casename in ${allcases[@]}; do -+ test_nvidia_case $casename $logfile -+ if [[ $? -eq 1 ]]; then -+ res_code=1 -+ fi -+ done -+ fi -+ return $res_code -+} -+ -+function main() { -+ func_name=$1 -+ param_list=$2 -+ -+ if [[ $func_name == "install_gpu_burn" ]]; then -+ install_gpu_burn -+ elif [[ $func_name == "install_cuda_samples" ]]; then -+ install_cuda_samples -+ elif [[ $func_name == "test_cuda_samples" ]]; then -+ test_cuda_samples $param_list -+ else -+ echo "The function doesn't exist, please check!" -+ return 1 -+ fi -+} -+ -+main "$@" -diff -Naur rpm/tests/compatible/infiniband/infiniband.py oech/tests/compatible/infiniband/infiniband.py ---- rpm/tests/compatible/infiniband/infiniband.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/infiniband/infiniband.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,47 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2022-05-24 -+# Desc: InfiniBand Test -+ -+from tests.compatible.network.rdma import RDMATest -+ -+ -+class InfiniBandTest(RDMATest): -+ def __init__(self): -+ RDMATest.__init__(self) -+ self.subtests = [self.test_ip_info, self.test_ibstatus, -+ self.test_ib_link, self.test_icmp, self.test_rdma] -+ -+ def test_ib_link(self): -+ """ -+ IB Link test -+ :return: -+ """ -+ if 'LinkUp' not in self.phys_state: -+ self.logger.error("Device is not LinkUp.") -+ -+ if 'ACTIVE' not in self.state: -+ self.logger.error("Link is not ACTIVE.") -+ -+ if self.base_lid == 0x0: -+ self.logger.error("Fail to get base lid of %s." % self.interface) -+ return False -+ self.logger.info("The base lid is %s." % self.base_lid) -+ -+ if self.sm_lid == 0x0: -+ self.logger.error( -+ "Fail to get subnet manager lid of %s." % self.interface) -+ return False -+ self.logger.info("The subnet manager lid is %s." % self.sm_lid) -+ -+ return True -diff -Naur rpm/tests/compatible/infiniband/Makefile oech/tests/compatible/infiniband/Makefile ---- rpm/tests/compatible/infiniband/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/infiniband/Makefile 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,22 @@ -+# Copyright (c) 2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2022-05-23 -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/__init__.py oech/tests/compatible/__init__.py ---- rpm/tests/compatible/__init__.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/__init__.py 2023-12-07 15:01:42.225942288 +0800 -@@ -0,0 +1,10 @@ -+# Copyright (c) 2020 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -diff -Naur rpm/tests/compatible/ipmi/ipmi.py oech/tests/compatible/ipmi/ipmi.py ---- rpm/tests/compatible/ipmi/ipmi.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/ipmi/ipmi.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,60 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+# Desc: Intelligent Platform Management Interface test -+ -+from hwcompatible.test import Test -+ -+ -+class IpmiTest(Test): -+ def __init__(self): -+ Test.__init__(self) -+ self.requirements = ["OpenIPMI", "ipmitool"] -+ -+ def start_ipmi(self): -+ """ -+ Start IPMI test -+ :return: -+ """ -+ self.command.run_cmd("systemctl start ipmi") -+ result = self.command.run_cmd("systemctl status ipmi.service | grep 'Active: active'" ) -+ if result[2] != 0: -+ self.logger.error("Ipmi service start failed.") -+ return False -+ self.logger.info("Ipmi service start succeed.") -+ return True -+ -+ def ipmitool(self): -+ """ -+ Testing with iptool tools -+ :return: -+ """ -+ cmd_list = ["ipmitool fru", "ipmitool sensor"] -+ for cmd in cmd_list: -+ result = self.command.run_cmd(cmd) -+ if result[2] != 0: -+ self.logger.error("%s execute failed." % cmd) -+ return False -+ self.logger.info("%s execute successfully." % cmd) -+ return True -+ -+ def test(self): -+ """ -+ Test case -+ :return: -+ """ -+ if not self.start_ipmi(): -+ return False -+ if not self.ipmitool(): -+ return False -+ return True -diff -Naur rpm/tests/compatible/ipmi/Makefile oech/tests/compatible/ipmi/Makefile ---- rpm/tests/compatible/ipmi/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/ipmi/Makefile 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,22 @@ -+# Copyright (c) 2020 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/kabi/kabi.py oech/tests/compatible/kabi/kabi.py ---- rpm/tests/compatible/kabi/kabi.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/kabi/kabi.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,144 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+# Copyright (c) 2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2.gica's -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @meitingli -+# Create: 2022-05-30 -+# Desc: Public kabi test -+ -+import os -+import argparse -+from subprocess import getoutput -+from hwcompatible.command import Command -+from hwcompatible.test import Test -+from hwcompatible.constants import TEST_KABI_ARCH -+from hwcompatible.sysinfo import SysInfo -+from hwcompatible.env import CertEnv -+from hwcompatible.document import Document -+ -+kabi_dir = os.path.dirname(os.path.realpath(__file__)) -+ -+ -+class KabiTest(Test): -+ def __init__(self): -+ Test.__init__(self) -+ self.kernel_version = getoutput("uname -r") -+ self.requirements = ["gzip", "rpm-build"] -+ self.symvers = None -+ self.wl_logpath = "" -+ self.miss_logpath = "" -+ self.changed_logpath = "" -+ self.sysinfo = SysInfo(CertEnv.releasefile) -+ -+ def setup(self, args=None): -+ """ -+ Initialization before test -+ """ -+ self.args = args or argparse.Namespace() -+ self.logger = getattr(self.args, "test_logger", None) -+ self.command = Command(self.logger) -+ self.wl_logpath = os.path.join( -+ self.logger.logdir, "kabi-whitelist.log") -+ self.miss_logpath = os.path.join( -+ self.logger.logdir, "kabi-missing.log") -+ self.changed_logpath = os.path.join( -+ self.logger.logdir, "kabi-changed.log") -+ self.symvers = os.path.join( -+ CertEnv.datadirectory, "symvers-" + self.kernel_version) -+ -+ def test(self): -+ """ -+ Run kabi test case -+ return: result -+ """ -+ arch = self.command.run_cmd("uname -m")[0].strip() -+ if arch not in TEST_KABI_ARCH: -+ self.logger.info(" %s architecture does not support kabi testing." % arch) -+ return True -+ -+ result = True -+ self.logger.info("Start to test, please wait...") -+ if not os.path.exists(self.symvers): -+ symvers_gz = "symvers-" + self.kernel_version + ".gz" -+ self.command.run_cmd("cp /boot/%s %s" % -+ (symvers_gz, CertEnv.datadirectory)) -+ self.command.run_cmd("gzip -d %s/%s" % -+ (CertEnv.datadirectory, symvers_gz)) -+ -+ standard_symvers = self._get_kernel_source_rpm(arch) -+ with open(standard_symvers, "r") as f: -+ for line in f.readlines(): -+ line = line.strip().replace("\n", "") -+ if line == "": -+ continue -+ -+ hsdp = line.split() -+ if len(hsdp) < 4 : -+ continue -+ -+ result = self.command.run_cmd("grep %s %s" % ( -+ hsdp[1], self.symvers), log_print=False) -+ data = result[0] -+ if data and hsdp[0] in data: -+ continue -+ elif data and hsdp[0] not in data: -+ if not os.path.exists(self.changed_logpath): -+ self.command.run_cmd("echo 'standard_symvers cur_symvers' | tee %s" % ( -+ self.changed_logpath), log_print=False) -+ -+ self.command.run_cmd("echo '{%s} {%s}' | tee %s" % ( -+ line, data, self.changed_logpath), log_print=False) -+ result = False -+ else: -+ self.command.run_cmd("echo '%s' | tee %s" % ( -+ line, self.miss_logpath), log_print=False) -+ result = False -+ -+ if result: -+ self.logger.info("Test kabi succeed.") -+ else: -+ self.logger.error("Test kabi failed.") -+ -+ return result -+ -+ def _get_kernel_source_rpm(self, arch): -+ """ -+ get the path of kernel source rpm -+ """ -+ rpmpath = "/root/rpmbuild/SOURCES" -+ standard_symvers = os.path.join(rpmpath, "Module.kabi_" + arch) -+ if os.path.exists(standard_symvers): -+ return standard_symvers -+ -+ product = self.sysinfo.product.split(" ")[0] -+ if product == "openEuler": -+ standard_kernel_version = getoutput( -+ "dnf list --repo=source | grep '^kernel.src' | awk '{print $2}'") -+ self.command.run_cmd("dnf download --source kernel-%s" -+ % standard_kernel_version) -+ elif product == "KylinSec": -+ kylinsec_version = getoutput("cat /etc/dnf/vars/osversion | sed 's/[^0-9]//g'") -+ kernel_dict = Document(CertEnv.kernelinfo, self.logger) -+ if not kernel_dict.load(): -+ self.logger.error("Failed to get kernel info.") -+ return False -+ openeuler_version = kernel_dict.document[product][kylinsec_version].split('/')[0] -+ standard_kernel_version = kernel_dict.document[product][kylinsec_version].split('/')[1] -+ url = "https://repo.openeuler.org/%s/source/Packages/kernel-%s.src.rpm" \ -+ % (openeuler_version, standard_kernel_version) -+ self.command.run_cmd("wget %s -P %s" % (url, rpmpath)) -+ else: -+ self.logger.info("Currently, this system is not supported to test kabi," -+ " Please add the corresponding system in kernelrelease.json.") -+ -+ rpm = os.path.join("kernel-" + standard_kernel_version + ".src.rpm") -+ getoutput("rpm -ivh %s" % rpm) -+ os.remove(rpm) -+ return standard_symvers -diff -Naur rpm/tests/compatible/kabi/Makefile oech/tests/compatible/kabi/Makefile ---- rpm/tests/compatible/kabi/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/kabi/Makefile 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,23 @@ -+# Copyright (c) 2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2.gica's -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @meitingli -+# Create: 2022-05-30 -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a *.py $(DEST) -+ chmod a+x $(DEST)/*.py -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/kabiwhitelist/kabi_check.sh oech/tests/compatible/kabiwhitelist/kabi_check.sh ---- rpm/tests/compatible/kabiwhitelist/kabi_check.sh 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/kabiwhitelist/kabi_check.sh 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,179 @@ -+#!/usr/bin/bash -+# Copyright (c) 2023 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @liqiang1118 -+# Create: 2023-05-15 -+ -+mkdir /usr/share/oech/lib/tests/kabiwhitelist/test_log -+testdir="/usr/share/oech/lib/tests/kabiwhitelist/test_log" -+cd $testdir -+ -+os_version=`cat /etc/openEuler-latest|grep openeulerversion |awk -F = '{print $2}'` -+arch=`uname -m` -+url="https://gitee.com/src-openeuler/kernel/raw/$os_version/kabi_whitelist_$arch" -+wget $url -+kernel_version=`uname -r` -+symvers_gz="symvers-"$kernel_version".gz" -+cp /boot/$symvers_gz /usr/share/oech/lib/tests/kabiwhitelist/test_log -+gunzip /usr/share/oech/lib/tests/kabiwhitelist/test_log/$symvers_gz -+ -+# Desc: Test kabi -+# Input: xxx.ko or xxx.rpm -+function test_kabi() { -+ cat $kabi.kabi |while read line; -+ do -+ kabiname=`echo $line |awk '{print $2}'` -+ filename=`echo $line |awk '{print $1}'` -+ cat kabi_whitelist_$arch|grep "$kabiname" >> $filename.txt -+ have=`cat $filename.txt|wc -l` -+ if [ $have == 0 ]; then -+ echo $line >> $kabi"_change_"$arch -+ fi -+ done -+ cat $kabi.kabi |while read line; -+ do -+ real=`echo $line|awk '{print $2}'` -+ if [ -f $kabi"_change_"$arch ]; then -+ white_list=`cat $kabi"_change_"$arch|grep "$real" |wc -l` -+ if [ $white_list == 0 ]; then -+ echo $line >> $kabi"_white_"$arch -+ fi -+ else -+ echo $line >> $kabi"_white_"$arch -+ fi -+ done -+} -+ -+ -+function test_inlist(){ -+ if [ -f $kabi"_change_"$arch ]; then -+ cat $kabi"_change_"$arch |while read line; -+ do -+ changekb=`echo $line |awk '{print $2}'` -+ inos=`cat symvers-"$kernel_version" |grep $changekb|wc -l` -+ if [ $inos == 0 ]; then -+ echo $changekb >> $kabi"_changeos" -+ else -+ echo $changekb >> $kabi"_inlist" -+ fi -+ done -+ fi -+} -+ -+ -+function real_result(){ -+ if [ -f $kabi"_change_"$arch ]; then -+ cat $kabi"_change_"$arch|while read line; -+ do -+ inlist=`echo $line|awk '{print $2}'` -+ noin=`cat $kabi"_changeos" |grep $inlist|wc -l` -+ if [ $noin == 0 ]; then -+ echo $line >> $kabi"_change" -+ -+ fi -+ -+ done -+ fi -+} -+ -+echo "####################KABI TEST START####################" -+cat /usr/share/oech/lib/config/test_config.yaml|grep name|awk -F "'" '{print $2}' >> dir.txt -+if_test=`cat dir.txt|wc -w` -+if [ $if_test == 0 ]; then -+ echo "Please configure the board information in the configuration file" > change.txt -+ echo "no ko or rpm" >> nokorpm.txt -+ cat change.txt -+fi -+cat dir.txt|while read line; -+do -+ lineword=`echo $line |wc -w` -+ if [ "$lineword" -gt 0 ]; then -+ echo $line >> dirt.txt -+ fi -+done -+cat dirt.txt |while read line; -+do -+ if [ -f /root/$line ]; then -+ cp /root/$line ./ -+ echo $line >> dirth -+ fi -+done -+cat dirth|while read line; -+do -+ for i in $line -+ do -+ class=`echo $i|awk -F . '{print $NF}'` -+ if [ $class == ko ]; then -+ kabi=`echo $i|awk -F . '{print $1}'` -+ modprobe --dump $i > $kabi.kabi -+ test_kabi -+ test_inlist -+ real_result -+ elif [ $class == rpm ]; then -+ echo "this is a rpm please wait" > /dev/null -+ rpm2cpio $i |cpio -div -+ find ./ -name "*.ko*" |grep module >> rpmko -+ ifrpm=`cat rpmko|wc -l` -+ if [ $ifrpm == 0 ]; then -+ echo "Please check rpm" > rpmchange -+ echo "Please check rpm" -+ exit 0 -+ else -+ echo "$i rpm decompression completed" -+ fi -+ cat rpmko|while read line; -+ do -+ cp $line ./ -+ koname=`echo $line |awk -F "/" '{print $NF}'` -+ kabi=`echo $koname|awk -F . '{print $1}' ` -+ modprobe --dump $koname > $kabi.kabi -+ echo $koname >> realname -+ test_kabi -+ test_inlist -+ real_result -+ done -+ fi -+ done -+done -+ -+ -+# save test log -+cat dirth |grep ko >> realname -+cat realname |while read line; -+do -+ kabi=`echo $line |awk -F . '{print $1}'` -+ if [ ! -f $kabi"_change_"$arch ]; then -+ echo "$kabi kabi $arch test pass" >> result -+ else -+ echo "$kabi kabi $arch test fail" >> result -+ fi -+done -+echo "Test results are as follows" -+cat result -+cat realname|grep ko |awk -F . '{print $1}' > res.txt -+cat res.txt |while read line; -+do -+ if [ -f $line"_change" ] || [ -f $line"_white_"$arch ]; then -+ if [ -f $line"_change" ]; then -+ whitenum=`cat $line"_change" |wc -l` -+ echo "Here are $line.ko KABI not in whitelist count=$whitenum" -+ cat $line"_change" -+ fi -+ if [ -f $line"_white_"$arch ]; then -+ notnum=`cat $line"_white_"$arch |wc -l` -+ echo "Here are $line.ko KABI in whitelist count=$notnum" -+ cat $line"_white_"$arch -+ fi -+ fi -+ if [ -f $line"_changeos" ]; then -+ echo "Here are $line.ko KABI not in OS KABI list" -+ cat $line"_changeos" -+ fi -+done -diff -Naur rpm/tests/compatible/kabiwhitelist/kabiwhitelist.py oech/tests/compatible/kabiwhitelist/kabiwhitelist.py ---- rpm/tests/compatible/kabiwhitelist/kabiwhitelist.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/kabiwhitelist/kabiwhitelist.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,64 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+# Copyright (c) 2023 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2.gica's -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @liqiang1118 -+# Create: 2023-05-15 -+# Desc: Public kabi test -+ -+import os -+import shutil -+import argparse -+from subprocess import getoutput -+from hwcompatible.command import Command -+from hwcompatible.test import Test -+ -+kabi_whitelist_dir = os.path.dirname(os.path.realpath(__file__)) -+ -+ -+class KabiWhiteListTest(Test): -+ def __init__(self): -+ Test.__init__(self) -+ self.requirements = ["gzip", "rpm-build"] -+ -+ def setup(self, args=None): -+ """ -+ Initialization before test -+ """ -+ self.args = args or argparse.Namespace() -+ self.logger = getattr(self.args, "test_logger", None) -+ self.command = Command(self.logger) -+ -+ def test(self): -+ """ -+ Run kabi test case -+ return: result -+ """ -+ self.command.run_cmd("bash %s/kabi_check.sh" % kabi_whitelist_dir) -+ ko_result = self.command.run_cmd("ls %s/test_log/ | grep noko" % kabi_whitelist_dir) -+ if ko_result[2] == 0: -+ self.logger.error("Please configure the board information in the configuration file") -+ return False -+ self.logger.info("Ko or rpm check complete") -+ -+ test_result = self.command.run_cmd("ls %s/test_log | grep change" % kabi_whitelist_dir) -+ if test_result[2] == 0: -+ self.logger.error("Kabiwhitelist test fail") -+ return False -+ return True -+ -+ def teardown(self): -+ """ -+ Clear temporary files -+ """ -+ file_name = "/usr/share/oech/lib/tests/kabiwhitelist/test_log" -+ if os.path.exists(file_name): -+ shutil.rmtree(file_name) -+ self.logger.info("Clearing temporary files is complete") -diff -Naur rpm/tests/compatible/kabiwhitelist/Makefile oech/tests/compatible/kabiwhitelist/Makefile ---- rpm/tests/compatible/kabiwhitelist/Makefile 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/kabiwhitelist/Makefile 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,26 @@ -+# Copyright (c) 2023 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Author: @liqiang1118 -+# Create: 2023-05-15 -+# Desc: KabiWhitelist test -+ -+.PHONY: install clean -+ -+all: ; -+ -+install: -+ mkdir -p $(DEST) -+ cp -a $(SUBDIR)/build *.py $(DEST) -+ cp -a $(SUBDIR)/build *.sh $(DEST) -+ chmod a+x $(DEST)/*.py -+ chmod a+x $(DEST)/*.sh -+ -+clean: -+ rm -rf $(DEST) -diff -Naur rpm/tests/compatible/kdump/kdump.py oech/tests/compatible/kdump/kdump.py ---- rpm/tests/compatible/kdump/kdump.py 1970-01-01 08:00:00.000000000 +0800 -+++ oech/tests/compatible/kdump/kdump.py 2023-12-07 15:01:42.229942342 +0800 -@@ -0,0 +1,119 @@ -+#!/usr/bin/env python3 -+# coding: utf-8 -+ -+# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. -+# oec-hardware is licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# Create: 2020-04-01 -+# Desc: Kdump Test -+ -+import os -+import re -+from time import sleep -+from subprocess import getoutput -+from hwcompatible.test import Test -+from hwcompatible.command import Command -+from hwcompatible.command_ui import CommandUI -+from hwcompatible.document import ConfigFile -+ -+ -+class KdumpTest(Test): -+ def __init__(self): -+ Test.__init__(self) -+ self.pri = 9 -+ self.reboot = True -+ self.kernel_version = getoutput("uname -r") -+ self.rebootup = "verify_vmcore" -+ self.kdump_conf = "/etc/kdump.conf" -+ self.vmcore_path = "/var/crash" -+ self.requirements = ["crash", "kexec-tools"] -+ -+ def test(self): -+ """ -+ Test case -+ :return: -+ """ -+ cmd_result = self.command.run_cmd("yum install -y kernel-debuginfo-%s" % self.kernel_version) -+ if len(cmd_result[1]) != 0 and cmd_result[2] != 0: -+ self.logger.error( -+ "Fail to install required packages.\n %s" % cmd_result[1]) -+ return False -+ -+ cmd_result = self.command.run_cmd("grep crashkernel /proc/cmdline") -+ if cmd_result[2] != 0: -+ self.logger.error( -+ "The /proc/cmdline file cannot find crashkernel.") -+ return False -+ crash_kernel = cmd_result[0].split(" ") -+ crash_size = "" -+ for line in crash_kernel: -+ if "crashkernel" in line: -+ crash_size = line.split("=")[1] -+ break -+ self.logger.info("The value of crashkernel is %s" % crash_size) -+ -+ config = ConfigFile(self.kdump_conf) -+ if not config.get_parameter("path"): -+ config.add_parameter("path", self.vmcore_path) -+ else: -+ self.vmcore_path = config.get_parameter("path") -+ -+ if config.get_parameter("kdump_obj") == "kbox": -+ config.remove_parameter("kdump_obj") -+ config.add_parameter("kdump_obj", "all") -+ -+ self.command.run_cmd("systemctl restart kdump") -+ cmd = self.command.run_cmd( -+ "systemctl status kdump | grep 'Active: active'") -+ if cmd[2] != 0: -+ self.logger.error("Kdump service is not active.") -+ return False -+ self.logger.info("Start kdump service succeed.") -+ -+ self.logger.info("kdump config.") -+ config.dump() -+ -+ com_ui = CommandUI() -+ if com_ui.prompt_confirm("System will reboot, are you ready?"): -+ self.logger.info("Trigger crash, please wait seconds.") -+ self.command.run_cmd("sync", log_print=False) -+ self.command.run_cmd("echo 'c' | tee /proc/sysrq-trigger") -+ sleep(30) -+ return False -+ -+ return False -+ -+ def verify_vmcore(self, logger): -+ """ -+ Verify vmcore -+ :return: -+ """ -+ config = ConfigFile(self.kdump_conf) -+ if config.get_parameter("path"): -+ self.vmcore_path = config.get_parameter("path") -+ -+ dir_pattern = re.compile( -+ r'(?P[0-9]+\.[0-9]+\.[0-9]+)-(?P[0-9]+[-.][0-9]+[-.][0-9]+)-' -+ r'(?P