From 717b841415d12d749c79ddf5a5fd93672e5f436a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Wed, 8 Feb 2023 08:25:23 +0000 Subject: [PATCH 01/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20co?= =?UTF-8?q?nfig/test=5Fconfig.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/test_config.yaml | 59 ----------------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 config/test_config.yaml diff --git a/config/test_config.yaml b/config/test_config.yaml deleted file mode 100644 index 6107cab..0000000 --- a/config/test_config.yaml +++ /dev/null @@ -1,59 +0,0 @@ -#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: - - -- Gitee From 3683d91765aca73531de2d86a8f55d673d2ae43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Wed, 8 Feb 2023 08:26:19 +0000 Subject: [PATCH 02/23] =?UTF-8?q?corerain=20=E6=98=9F=E7=A9=BAX3=E5=8A=A0?= =?UTF-8?q?=E9=80=9F=E5=8D=A1=E8=B0=83=E7=94=A8=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 黄汉高 --- config/test_config.yaml | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 config/test_config.yaml diff --git a/config/test_config.yaml b/config/test_config.yaml new file mode 100644 index 0000000..5d84e75 --- /dev/null +++ b/config/test_config.yaml @@ -0,0 +1,62 @@ +#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 +aiacc: + aiacc1: + device: '0002:e9:00.0' +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: + + -- Gitee From 09151e6e86ab34093b8cfb3e572f8cee5e507a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:49:25 +0000 Subject: [PATCH 03/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20co?= =?UTF-8?q?nfig/test=5Fconfig.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/test_config.yaml | 62 ----------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 config/test_config.yaml diff --git a/config/test_config.yaml b/config/test_config.yaml deleted file mode 100644 index 5d84e75..0000000 --- a/config/test_config.yaml +++ /dev/null @@ -1,62 +0,0 @@ -#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 -aiacc: - aiacc1: - device: '0002:e9:00.0' -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: - - -- Gitee From 91d2410c041827775c664434ed261a973bfda8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:52:35 +0000 Subject: [PATCH 04/23] =?UTF-8?q?Add=20Corerain=20Nebula=20Accelerator=20X?= =?UTF-8?q?3=20Test=20Case=20=E6=96=B0=E5=A2=9E=E4=BA=86config/test=5Fconf?= =?UTF-8?q?ig.yaml=E4=B8=ADaiacc=E7=9A=84=E7=9B=B8=E5=85=B3=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=8C=E5=A6=82device=E5=AD=97=E6=AE=B5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 黄汉高 --- config/test_config.yaml | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 config/test_config.yaml diff --git a/config/test_config.yaml b/config/test_config.yaml new file mode 100644 index 0000000..5d84e75 --- /dev/null +++ b/config/test_config.yaml @@ -0,0 +1,62 @@ +#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 +aiacc: + aiacc1: + device: '0002:e9:00.0' +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: + + -- Gitee From a5a894d5c25804e21c696e080962f739949e050f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:57:29 +0000 Subject: [PATCH 05/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20hw?= =?UTF-8?q?compatible/compatibility.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwcompatible/compatibility.py | 527 ---------------------------------- 1 file changed, 527 deletions(-) delete mode 100755 hwcompatible/compatibility.py diff --git a/hwcompatible/compatibility.py b/hwcompatible/compatibility.py deleted file mode 100755 index a5ed0fb..0000000 --- a/hwcompatible/compatibility.py +++ /dev/null @@ -1,527 +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 - -import os -import time -import argparse -import shutil -import datetime -import re -from collections import namedtuple - -from .document import CertDocument, DeviceDocument, FactoryDocument -from .env import CertEnv -from .device import CertDevice, Device -from .command import Command -from .command_ui import CommandUI -from .job import Job -from .reboot import Reboot -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 - - -class EulerCertification(): - """ - Main program of oec-hardware - """ - - def __init__(self, logger): - self.certification = None - self.test_factory = list() - self.devices = None - self.ui = CommandUI() - self.client = None - self.dir_name = None - self.logger = logger - self.command = Command(logger) - - def run(self): - """ - Openeuler compatibility verification - :return: - """ - self.logger.info( - "The openEuler Hardware Compatibility Test Suite", log_print=False) - copy_pci() - self.load() - certdevice = CertDevice(self.logger) - - while True: - self.submit() - - if self.check_result(): - 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() - 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) - args = argparse.Namespace( - test_factory=self.test_factory, test_suite=test_suite) - job = Job(args) - job.run() - self.save(job) - - def run_rebootup(self): - """ - rebootup - :return: - """ - try: - if not os.path.exists(CertEnv.rebootfile): - return True - self.load() - test_suite = create_test_suite(self.test_factory, self.logger) - args = argparse.Namespace( - test_factory=self.test_factory, test_suite=test_suite) - job = Job(args) - reboot = Reboot(None, job, None) - if reboot.check(logger=self.logger): - job = reboot.job - job.run() - reboot.clean() - self.save(job) - return True - except Exception as e: - self.logger.error("Run reboot up failed. %s" % e) - return False - - def clean(self): - """ - clean all compatibility test file - :return: - """ - if self.ui.prompt_confirm("Are you sure to clean all " - "compatibility test data?"): - if os.path.exists(CertEnv.certificationfile): - os.remove(CertEnv.certificationfile) - if os.path.exists(CertEnv.factoryfile): - os.remove(CertEnv.factoryfile) - if os.path.exists(CertEnv.devicefile): - os.remove(CertEnv.devicefile) - self.logger.info("Clean compatibility test data succeed.") - return True - - def load(self): - """ - load certification - :return: - """ - os.makedirs(os.path.dirname(CertEnv.datadirectory), exist_ok=True) - if not self.certification: - self.certification = CertDocument( - CertEnv.certificationfile, self.logger) - if not self.certification.document: - self.certification.new() - self.certification.save() - if not self.test_factory: - factory_doc = FactoryDocument(CertEnv.factoryfile, self.logger) - self.test_factory = factory_doc.get_factory() - - oec_id = self.certification.get_certify() - hardware_info = self.certification.get_hardware() - self.client = Client(hardware_info, oec_id, self.logger) - version = self.certification.get_oech_value("VERSION", "version") - name = self.certification.get_oech_value("NAME", "client_name") - 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() - self.logger.info(display_message, log_print=False) - - def save(self, job): - """ - collect Job log - :param job: - :return: - """ - 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() - 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)) - self.dir_name = "oech-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") \ - + "-" + 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) - for sublist in os.walk("./"): - for dirname in sublist[1]: - shutil.rmtree(dirname) - break - os.chdir(cwd) - - def submit(self): - """ - submit last result - :return: - """ - packages = list() - pattern = re.compile("^oech-[0-9]{14}-[0-9a-zA-Z]{10}.tar$") - files = [] - for sublist in os.walk(CertEnv.datadirectory): - files = sublist[2] - break - packages.extend(filter(pattern.search, files)) - if len(packages) == 0: - return - packages.sort() - - if self.ui.prompt_confirm("Do you want to submit last result?"): - server = self.certification.get_server() - path = os.path.join(CertEnv.datadirectory, packages[-1]) - if not self.upload(path, server): - self.logger.error( - "Upload result to server %s failed." % server) - else: - self.logger.info( - "Upload result to server %s succeed." % server) - time.sleep(2) - - for filename in packages: - os.remove(os.path.join(CertEnv.datadirectory, filename)) - - def upload(self, path, server): - """ - uploaded result to server - :param path: - :param server: - :return: - """ - self.logger.info( - "Start to upload result to server %s, please wait." % server, log_print=False) - if not self.client: - oec_id = self.certification.get_certify() - hardware_info = self.certification.get_hardware() - self.client = Client(hardware_info, oec_id, self.logger) - return self.client.upload(path, server) - - def get_tests(self, devices): - """ - get test items - :param devices: - :return: - """ - sort_devices = self.sort_tests(devices) - empty_device = Device(logger=self.logger) - test_factory = list() - casenames = [] - for (_, dirs, filenames) in os.walk(CertEnv.testdirectoy): - 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: - 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"] = empty_device - test["run"] = True - test["status"] = "NotRun" - test["reboot"] = False - test_factory.append(test) - return test_factory - - def sort_tests(self, devices): - """ - sort tests - :param devices: - :return: - """ - sort_devices = dict() - empty_device = Device(logger=self.logger) - for device in devices: - if device.get_property("SUBSYSTEM") == "usb" and \ - device.get_property("ID_VENDOR_FROM_DATABASE") == \ - "Linux Foundation" and \ - ("2." in device.get_property("ID_MODEL_FROM_DATABASE") or - "3." in device.get_property("ID_MODEL_FROM_DATABASE")): - sort_devices["usb"] = [empty_device] - continue - if (device.get_property("DEVTYPE") == "disk" and - not device.get_property("ID_TYPE")) or \ - device.get_property("ID_TYPE") == "disk": - if "nvme" in device.get_property("DEVPATH"): - sort_devices["disk"] = [empty_device] - if "nvme" in sort_devices.keys(): - sort_devices["nvme"].extend([device]) - sort_devices["spdk"].extend([device]) - else: - sort_devices["nvme"] = [device] - sort_devices["spdk"] = [device] - elif "/host" in device.get_property("DEVPATH"): - sort_devices["disk"] = [empty_device] - if "RAID" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") or \ - ("SCSI" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") and - "HBA" not in device.get_property("ID_MODEL_FROM_DATABASE")): - if "raid" in sort_devices.keys(): - sort_devices["raid"].extend([device]) - else: - sort_devices["raid"] = [device] - continue - if "Fibre Channel" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE"): - if "fc" in sort_devices.keys(): - sort_devices["fc"].extend([device]) - else: - sort_devices["fc"] = [device] - continue - driver = device.get_property("DRIVER") - if any([d in driver for d in GPU_DRIVER]): - if "gpu" in sort_devices.keys(): - sort_devices["gpu"].extend([device]) - else: - sort_devices["gpu"] = [device] - if driver == "nvidia": - if "vgpu" in sort_devices.keys(): - sort_devices["vgpu"].extend([device]) - else: - sort_devices["vgpu"] = [device] - continue - if device.get_property("SUBSYSTEM") == "net" and \ - device.get_property("INTERFACE"): - interface = device.get_property("INTERFACE") - cmd_result = self.command.run_cmd("nmcli device") - for line in cmd_result[0].split("\n"): - if interface in line and IB in line: - if IB in sort_devices.keys(): - sort_devices[IB].extend([device]) - else: - sort_devices[IB] = [device] - elif interface in line and "ethernet" in line: - if "ethernet" in sort_devices.keys(): - sort_devices["ethernet"].extend([device]) - else: - sort_devices["ethernet"] = [device] - elif interface in line and "wifi" in line: - if "wlan" in sort_devices.keys(): - sort_devices["wlan"].extend([device]) - else: - sort_devices["wlan"] = [device] - continue - if device.get_property("ID_CDROM") == "1": - for dev_type in CDTYPES: - if device.get_property("ID_CDROM_" + dev_type) == "1": - if "cdrom" in sort_devices.keys(): - sort_devices["cdrom"].extend([device]) - else: - sort_devices["cdrom"] = [device] - break - if device.get_property("SUBSYSTEM") == "ipmi": - sort_devices["ipmi"] = [empty_device] - - id_vendor = device.get_property("ID_VENDOR_FROM_DATABASE") - 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] - - return sort_devices - - def edit_tests(self): - """ - edit test items - :return: - """ - while True: - for test in self.test_factory: - if test["name"] == "system": - test["run"] = True - if test["status"] == "PASS": - test["status"] = "Force" - - self.logger.info('\033c', log_print=False) - self.logger.info("Select tests to run:", log_print=False) - self.show_tests() - reply = self.ui.prompt("Selection (|all|none|quit|run): ") - reply = reply.lower() - if reply in ["r", "run"]: - return True - if reply in ["q", "quit"]: - return False - if reply in ["n", "none"]: - for test in self.test_factory: - test["run"] = False - continue - if reply in ["a", "all"]: - for test in self.test_factory: - test["run"] = True - continue - - num_lst = reply.split(" ") - for num in num_lst: - try: - num = int(num) - except ValueError: - continue - - if 0 < num <= len(self.test_factory): - self.test_factory[num - 1]["run"] = not \ - self.test_factory[num - 1]["run"] - continue - - def show_tests(self): - """ - show test items - :return: - """ - device_info = namedtuple('Device_info', DEVICE_INFO) - self.logger.info("\033[1;35m" + "No.".ljust(4) + "Run-Now?".ljust(10) - + "status".ljust(10) + "Class".ljust(14) + - "device".capitalize().ljust(15) - + DRIVER.ljust(15) + VERSION.ljust(18) + - CHIP.ljust(20) - + "%s\033[0m" % BOARD, log_print=False) - num = 0 - for test in self.test_factory: - name = test["name"] - if name == "system": - test["run"] = True - if test["status"] == "PASS": - test["status"] = "Force" - - status = test["status"] - device = test["device"].get_name() - board = test.get("boardModel", "") - chip = test.get("chipModel", "") - driver = test.get("driverName", "") - version = test.get("driverVersion", "") - 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" - device = device_info(color, status, num, run, name, - device, driver, version, chip, board) - self._print_tests(device) - - def choose_tests(self): - """ - choose test behavior - :return: - """ - for test in self.test_factory: - if test["status"] == "PASS": - test["run"] = False - else: - 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() - action = self.ui.prompt("Ready to begin testing?", - ["run", "edit", "quit"]) - action = action.lower() - if action in ["r", "run"]: - return True - if action in ["q", "quit"]: - return False - if action in ["e", "edit"]: - return self.edit_tests() - self.logger.info("Invalid choice!", log_print=False) - return self.choose_tests() - - def check_result(self): - """ - check test result - :return: - """ - if len(self.test_factory) == 0: - return False - for test in self.test_factory: - if test["status"] != "PASS": - return False - return True - - def update_factory(self, test_factory): - """ - update tese factory - :param test_factory: - :return: - """ - 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())) - self.test_factory.sort(key=lambda k: k["name"]) - FactoryDocument(CertEnv.factoryfile, self.logger, self.test_factory).save() - - def _print_tests(self, device): - """ - print board information - """ - self.logger.info("%-6d" % device.num + device.run.ljust(8) - + "\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) -- Gitee From 126a1c7a8cb9f909193a584109d4b62208ef342f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:58:03 +0000 Subject: [PATCH 06/23] =?UTF-8?q?Add=20Corerain=20Nebula=20Accelerator=20X?= =?UTF-8?q?3=20Test=20Case=20=E6=96=B0=E5=A2=9E=E4=BA=86hwcompatible/compa?= =?UTF-8?q?tibility.py=E4=B8=ADaiacc=E8=AE=BE=E5=A4=87=E7=9A=84=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=B8=BA=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E9=B2=B2=E4=BA=91=E7=9A=84X3A=E5=8A=A0=E9=80=9F=E5=8D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 黄汉高 --- hwcompatible/compatibility.py | 534 ++++++++++++++++++++++++++++++++++ 1 file changed, 534 insertions(+) create mode 100644 hwcompatible/compatibility.py diff --git a/hwcompatible/compatibility.py b/hwcompatible/compatibility.py new file mode 100644 index 0000000..ffe7db5 --- /dev/null +++ b/hwcompatible/compatibility.py @@ -0,0 +1,534 @@ +#!/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 os +import time +import argparse +import shutil +import datetime +import re +from collections import namedtuple + +from .document import CertDocument, DeviceDocument, FactoryDocument +from .env import CertEnv +from .device import CertDevice, Device +from .command import Command +from .command_ui import CommandUI +from .job import Job +from .reboot import Reboot +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 + + +class EulerCertification(): + """ + Main program of oec-hardware + """ + + def __init__(self, logger): + self.certification = None + self.test_factory = list() + self.devices = None + self.ui = CommandUI() + self.client = None + self.dir_name = None + self.logger = logger + self.command = Command(logger) + + def run(self): + """ + Openeuler compatibility verification + :return: + """ + self.logger.info( + "The openEuler Hardware Compatibility Test Suite", log_print=False) + copy_pci() + self.load() + certdevice = CertDevice(self.logger) + + while True: + self.submit() + + if self.check_result(): + 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() + 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) + args = argparse.Namespace( + test_factory=self.test_factory, test_suite=test_suite) + job = Job(args) + job.run() + self.save(job) + + def run_rebootup(self): + """ + rebootup + :return: + """ + try: + if not os.path.exists(CertEnv.rebootfile): + return True + self.load() + test_suite = create_test_suite(self.test_factory, self.logger) + args = argparse.Namespace( + test_factory=self.test_factory, test_suite=test_suite) + job = Job(args) + reboot = Reboot(None, job, None) + if reboot.check(logger=self.logger): + job = reboot.job + job.run() + reboot.clean() + self.save(job) + return True + except Exception as e: + self.logger.error("Run reboot up failed. %s" % e) + return False + + def clean(self): + """ + clean all compatibility test file + :return: + """ + if self.ui.prompt_confirm("Are you sure to clean all " + "compatibility test data?"): + if os.path.exists(CertEnv.certificationfile): + os.remove(CertEnv.certificationfile) + if os.path.exists(CertEnv.factoryfile): + os.remove(CertEnv.factoryfile) + if os.path.exists(CertEnv.devicefile): + os.remove(CertEnv.devicefile) + self.logger.info("Clean compatibility test data succeed.") + return True + + def load(self): + """ + load certification + :return: + """ + os.makedirs(os.path.dirname(CertEnv.datadirectory), exist_ok=True) + if not self.certification: + self.certification = CertDocument( + CertEnv.certificationfile, self.logger) + if not self.certification.document: + self.certification.new() + self.certification.save() + if not self.test_factory: + factory_doc = FactoryDocument(CertEnv.factoryfile, self.logger) + self.test_factory = factory_doc.get_factory() + + oec_id = self.certification.get_certify() + hardware_info = self.certification.get_hardware() + self.client = Client(hardware_info, oec_id, self.logger) + version = self.certification.get_oech_value("VERSION", "version") + name = self.certification.get_oech_value("NAME", "client_name") + 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() + self.logger.info(display_message, log_print=False) + + def save(self, job): + """ + collect Job log + :param job: + :return: + """ + 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() + 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)) + self.dir_name = "oech-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") \ + + "-" + 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) + for sublist in os.walk("./"): + for dirname in sublist[1]: + shutil.rmtree(dirname) + break + os.chdir(cwd) + + def submit(self): + """ + submit last result + :return: + """ + packages = list() + pattern = re.compile("^oech-[0-9]{14}-[0-9a-zA-Z]{10}.tar$") + files = [] + for sublist in os.walk(CertEnv.datadirectory): + files = sublist[2] + break + packages.extend(filter(pattern.search, files)) + if len(packages) == 0: + return + packages.sort() + + if self.ui.prompt_confirm("Do you want to submit last result?"): + server = self.certification.get_server() + path = os.path.join(CertEnv.datadirectory, packages[-1]) + if not self.upload(path, server): + self.logger.error( + "Upload result to server %s failed." % server) + else: + self.logger.info( + "Upload result to server %s succeed." % server) + time.sleep(2) + + for filename in packages: + os.remove(os.path.join(CertEnv.datadirectory, filename)) + + def upload(self, path, server): + """ + uploaded result to server + :param path: + :param server: + :return: + """ + self.logger.info( + "Start to upload result to server %s, please wait." % server, log_print=False) + if not self.client: + oec_id = self.certification.get_certify() + hardware_info = self.certification.get_hardware() + self.client = Client(hardware_info, oec_id, self.logger) + return self.client.upload(path, server) + + def get_tests(self, devices): + """ + get test items + :param devices: + :return: + """ + sort_devices = self.sort_tests(devices) + empty_device = Device(logger=self.logger) + test_factory = list() + casenames = [] + for (_, dirs, filenames) in os.walk(CertEnv.testdirectoy): + 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: + 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"] = empty_device + test["run"] = True + test["status"] = "NotRun" + test["reboot"] = False + test_factory.append(test) + return test_factory + + def sort_tests(self, devices): + """ + sort tests + :param devices: + :return: + """ + sort_devices = dict() + empty_device = Device(logger=self.logger) + for device in devices: + if device.get_property("SUBSYSTEM") == "usb" and \ + device.get_property("ID_VENDOR_FROM_DATABASE") == \ + "Linux Foundation" and \ + ("2." in device.get_property("ID_MODEL_FROM_DATABASE") or + "3." in device.get_property("ID_MODEL_FROM_DATABASE")): + sort_devices["usb"] = [empty_device] + continue + if (device.get_property("DEVTYPE") == "disk" and + not device.get_property("ID_TYPE")) or \ + device.get_property("ID_TYPE") == "disk": + if "nvme" in device.get_property("DEVPATH"): + sort_devices["disk"] = [empty_device] + if "nvme" in sort_devices.keys(): + sort_devices["nvme"].extend([device]) + else: + sort_devices["nvme"] = [device] + elif "/host" in device.get_property("DEVPATH"): + sort_devices["disk"] = [empty_device] + if "RAID" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") or \ + ("SCSI" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") and + "HBA" not in device.get_property("ID_MODEL_FROM_DATABASE")): + if "raid" in sort_devices.keys(): + sort_devices["raid"].extend([device]) + else: + sort_devices["raid"] = [device] + continue + if "Fibre Channel" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE"): + if "fc" in sort_devices.keys(): + sort_devices["fc"].extend([device]) + else: + sort_devices["fc"] = [device] + continue + + # Corerain aiacc device + if device.get_property("PCI_ID") == "1C8C:2432": + if "aiacc" in sort_devices.keys(): + sort_devices["aiacc"].extend([device]) + else: + sort_devices["aiacc"] = [device] + continue + + driver = device.get_property("DRIVER") + if any([d in driver for d in GPU_DRIVER]): + if "gpu" in sort_devices.keys(): + sort_devices["gpu"].extend([device]) + else: + sort_devices["gpu"] = [device] + if driver == "nvidia": + if "vgpu" in sort_devices.keys(): + sort_devices["vgpu"].extend([device]) + else: + sort_devices["vgpu"] = [device] + continue + if device.get_property("SUBSYSTEM") == "net" and \ + device.get_property("INTERFACE"): + interface = device.get_property("INTERFACE") + cmd_result = self.command.run_cmd("nmcli device") + for line in cmd_result[0].split("\n"): + if interface in line and IB in line: + if IB in sort_devices.keys(): + sort_devices[IB].extend([device]) + else: + sort_devices[IB] = [device] + elif interface in line and "ethernet" in line: + if "ethernet" in sort_devices.keys(): + sort_devices["ethernet"].extend([device]) + else: + sort_devices["ethernet"] = [device] + elif interface in line and "wifi" in line: + if "wlan" in sort_devices.keys(): + sort_devices["wlan"].extend([device]) + else: + sort_devices["wlan"] = [device] + continue + if device.get_property("ID_CDROM") == "1": + for dev_type in CDTYPES: + if device.get_property("ID_CDROM_" + dev_type) == "1": + if "cdrom" in sort_devices.keys(): + sort_devices["cdrom"].extend([device]) + else: + sort_devices["cdrom"] = [device] + break + if device.get_property("SUBSYSTEM") == "ipmi": + sort_devices["ipmi"] = [empty_device] + + id_vendor = device.get_property("ID_VENDOR_FROM_DATABASE") + 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] + + return sort_devices + + def edit_tests(self): + """ + edit test items + :return: + """ + while True: + for test in self.test_factory: + if test["name"] == "system": + test["run"] = True + if test["status"] == "PASS": + test["status"] = "Force" + + self.logger.info('\033c', log_print=False) + self.logger.info("Select tests to run:", log_print=False) + self.show_tests() + reply = self.ui.prompt("Selection (|all|none|quit|run): ") + reply = reply.lower() + if reply in ["r", "run"]: + return True + if reply in ["q", "quit"]: + return False + if reply in ["n", "none"]: + for test in self.test_factory: + test["run"] = False + continue + if reply in ["a", "all"]: + for test in self.test_factory: + test["run"] = True + continue + + num_lst = reply.split(" ") + for num in num_lst: + try: + num = int(num) + except ValueError: + continue + + if 0 < num <= len(self.test_factory): + self.test_factory[num - 1]["run"] = not \ + self.test_factory[num - 1]["run"] + continue + + def show_tests(self): + """ + show test items + :return: + """ + device_info = namedtuple('Device_info', DEVICE_INFO) + self.logger.info("\033[1;35m" + "No.".ljust(4) + "Run-Now?".ljust(10) + + "status".ljust(10) + "Class".ljust(14) + + "device".capitalize().ljust(15) + + DRIVER.ljust(15) + VERSION.ljust(18) + + CHIP.ljust(20) + + "%s\033[0m" % BOARD, log_print=False) + num = 0 + for test in self.test_factory: + name = test["name"] + if name == "system": + test["run"] = True + if test["status"] == "PASS": + test["status"] = "Force" + + status = test["status"] + device = test["device"].get_name() + board = test.get("boardModel", "") + chip = test.get("chipModel", "") + driver = test.get("driverName", "") + version = test.get("driverVersion", "") + 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" + device = device_info(color, status, num, run, name, + device, driver, version, chip, board) + self._print_tests(device) + + def choose_tests(self): + """ + choose test behavior + :return: + """ + for test in self.test_factory: + if test["status"] == "PASS": + test["run"] = False + else: + 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() + action = self.ui.prompt("Ready to begin testing?", + ["run", "edit", "quit"]) + action = action.lower() + if action in ["r", "run"]: + return True + if action in ["q", "quit"]: + return False + if action in ["e", "edit"]: + return self.edit_tests() + self.logger.info("Invalid choice!", log_print=False) + return self.choose_tests() + + def check_result(self): + """ + check test result + :return: + """ + if len(self.test_factory) == 0: + return False + for test in self.test_factory: + if test["status"] != "PASS": + return False + return True + + def update_factory(self, test_factory): + """ + update tese factory + :param test_factory: + :return: + """ + 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())) + self.test_factory.sort(key=lambda k: k["name"]) + FactoryDocument(CertEnv.factoryfile, self.logger, self.test_factory).save() + + def _print_tests(self, device): + """ + print board information + """ + self.logger.info("%-6d" % device.num + device.run.ljust(8) + + "\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) -- Gitee From 5d73bceb4c6a137800e03aa3fdeff0247dfab91c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:58:34 +0000 Subject: [PATCH 07/23] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20aiacc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/aiacc/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/aiacc/.keep diff --git a/tests/aiacc/.keep b/tests/aiacc/.keep new file mode 100644 index 0000000..e69de29 -- Gitee From c2fa1af37a189835100b525cfbf975a5e7c33935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:59:18 +0000 Subject: [PATCH 08/23] =?UTF-8?q?Add=20Corerain=20Nebula=20Accelerator=20X?= =?UTF-8?q?3=20Test=20Case=20=E6=96=B0=E5=A2=9E=E4=BA=86tests/aiacc?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 黄汉高 --- tests/aiacc/Makefile | 23 +++++++ tests/aiacc/aiacc.py | 51 ++++++++++++++++ tests/aiacc/cr_aiacc.py | 112 +++++++++++++++++++++++++++++++++++ tests/aiacc/test_cr_aiacc.sh | 65 ++++++++++++++++++++ 4 files changed, 251 insertions(+) create mode 100644 tests/aiacc/Makefile create mode 100644 tests/aiacc/aiacc.py create mode 100644 tests/aiacc/cr_aiacc.py create mode 100644 tests/aiacc/test_cr_aiacc.sh diff --git a/tests/aiacc/Makefile b/tests/aiacc/Makefile new file mode 100644 index 0000000..fca5860 --- /dev/null +++ b/tests/aiacc/Makefile @@ -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: 2023-01-10 + +.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 --git a/tests/aiacc/aiacc.py b/tests/aiacc/aiacc.py new file mode 100644 index 0000000..2c5ac54 --- /dev/null +++ b/tests/aiacc/aiacc.py @@ -0,0 +1,51 @@ +# 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: @quanren +# Create: 2023-01-10 +# Desc: aiacc test, support Corerain series aiacc + +import argparse +from hwcompatible.command import Command +from hwcompatible.test import Test +from cr_aiacc import CRAIaccTest + + +class aiaccTest(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 + """ + result = False + driver = self.device.get_driver() + if driver == "Corerain DMA": + cr_test = CRAIaccTest(self.device, self.logger, self.command) + result = cr_test.test_cr_aiacc_sample() + return result + return result + + diff --git a/tests/aiacc/cr_aiacc.py b/tests/aiacc/cr_aiacc.py new file mode 100644 index 0000000..e9d580b --- /dev/null +++ b/tests/aiacc/cr_aiacc.py @@ -0,0 +1,112 @@ +# 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: @quanren +# Create: 2023-01-10 +# Desc: Corerain aiacc test. + +import os +from subprocess import getstatusoutput + +gpu_dir = os.path.dirname(os.path.realpath(__file__)) + + +class CRAIaccTest(): + def __init__(self, device, logger, command): + self.device = device + self.logger = logger + self.command = command + self.cr_aiacc_driver_log = os.path.join(self.logger.logdir, 'cr_aiacc_driver.log') + self.cr_aiacc_DM_log = os.path.join(self.logger.logdir, 'cr_aiacc_DM.log') + self.cr_aiacc_sample_log = os.path.join(self.logger.logdir, 'cr_aiacc_sample.log') + self.screen_info_log = os.path.join(self.logger.logdir, 'screen_info.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_cr_aiacc_driver(self): + """ + Check corerain aiacc utilization by driver, it can execute multi times and has log file + Returns: + bool: + """ + os.chdir("/opt/cr_aiacc/pcie-driver") + cmd = getstatusoutput( + "echo q | ./load | tee %s" % self.cr_aiacc_dirver_log) + if cmd[0] == 0: + self.logger.info("Check corerain aiacc driver succeed.") + else: + self.logger.error("Check corerain aiacc driver failed.") + return False + + return True + + def test_cr_aiacc_DM(self): + """ + AMD gpu test entry function + Returns: + bool: + """ + result = True + self.get_driver_info() + self.command.run_cmd( + "bash %s/test_cr_aiacc.sh install_cr_aiacc_driver" % gpu_dir) + self.command.run_cmd( + "bash %s/test_cr_aiacc.sh install_cr_aiacc_DM" % gpu_dir) + + self.logger.info("Check corerain aiacc driver.") + try: + if not self.test_cr_aiacc_driver(): + result = False + + if not self.test_cr_aiacc_DM(): + result = False + + except Exception as e: + self.logger.error( + "Failed to run the script because compiling or setting variables: %s" % e) + result = False + + return result + + def test_cr_aiacc_sample(self): + """ + Test screen information for gpu + This test need graphical.target to support + Returns: + bool: + """ + os.chdir("/opt/cr_aiacc/") + cmd = self.command.run_cmd( + "./run > $s " % self.cr_aiacc_sample_log) + if cmd[2] == 0: + self.logger.info("Test corerain aiacc screen information succeed.") + else: + self.logger.error("Test corerain aiacc screen information failed.") + return False + + return True diff --git a/tests/aiacc/test_cr_aiacc.sh b/tests/aiacc/test_cr_aiacc.sh new file mode 100644 index 0000000..ce21631 --- /dev/null +++ b/tests/aiacc/test_cr_aiacc.sh @@ -0,0 +1,65 @@ +#!/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: @quanren +# Create: 2023-01-10 +# Desc: Shell script used for testing Corerain aiacc + +function install_cr_aiacc_driver() { + cd /opt + res_code=0 + if [ ! -d cr_aiacc ]; then + git clone https://gitee.com/qren/cr_aiacc.git + fi + cd cr_aiacc/pcie-driver + ./compile && ./load &>/dev/null || res_code=1 + + return $res_code +} + +function install_cr_aiacc_DM() { + cd /opt + res_code=0 + if [ ! -d cr_aiacc ]; then + git clone https://gitee.com/qren/cr_aiacc.git + fi + cd cr_aiacc/device-manager + ./compile && ./load &>/dev/null || res_code=1 + + return $res_code +} + +function install_cr_aiacc_sample() { + cd /opt + res_code=0 + if [ ! -d cr_aiacc ]; then + git clone https://gitee.com/qren/cr_aiacc.git + fi + cd cr_aiacc + ./compile && ./run &>/dev/null || res_code=1 + return $res_code +} + +function main() { + func_name=$1 + + if [[ $func_name == "install_cr_aiacc_driver" ]]; then + install_cr_aiacc_driver + elif [[ $func_name == "install_cr_aiacc_DM" ]]; then + install_cr_aiacc_DM + elif [[ $func_name == "install_cr_aiacc_sample" ]]; then + install_cr_aiacc_sample + else + echo "The function doesn't exist, please check!" + return 1 + fi +} + +main "$@" -- Gitee From ef20a36e24c43fc656bb2e6d98e13f370029cfa8 Mon Sep 17 00:00:00 2001 From: renquan Date: Mon, 13 Feb 2023 15:22:55 +0800 Subject: [PATCH 09/23] Add corerain X3A aiacc test model and update related documents --- config/test_config.yaml | 3 -- docs/design_docs/dev_design.md | 26 ++++++++++------- hwcompatible/compatibility.py | 6 ++-- hwcompatible/constants.py | 4 +-- hwcompatible/device.py | 22 +++++++++++++++ tests/aiacc/.keep | 0 tests/aiacc/cr_aiacc.py | 51 ++-------------------------------- 7 files changed, 45 insertions(+), 67 deletions(-) delete mode 100644 tests/aiacc/.keep diff --git a/config/test_config.yaml b/config/test_config.yaml index 5d84e75..6107cab 100644 --- a/config/test_config.yaml +++ b/config/test_config.yaml @@ -19,9 +19,6 @@ raid: raid2: device: '0000:0a:00.1' disk: sdb -aiacc: - aiacc1: - device: '0002:e9:00.0' disk: all ethernet: # IP has been manually configured, get server IP. diff --git a/docs/design_docs/dev_design.md b/docs/design_docs/dev_design.md index b3772e5..a7977c2 100644 --- a/docs/design_docs/dev_design.md +++ b/docs/design_docs/dev_design.md @@ -35,7 +35,7 @@ #### 1.2.3 客户端测试项依赖组件 | 测试项 | 组件 | 组件描述 | -| --------- | ------ | --------- | +| --------- | ------ | --------- | | acpi | acpica-tools | acpi 测试 | | cdrom | dvd+rw-tools | cd/dvd 测试 | | | cdrkit | | @@ -89,6 +89,12 @@ | | util-linux | | | | expect | | | system | policycoreutils | system 测试 | +| aiacc | gcc | aiacc 测试 | +| | g++ | | +| | make | | +| | cmake | | + + ### 1.3 License @@ -172,11 +178,11 @@ oec-hardware工具框架有如下特点: - 命令描述: 工具执行入口,用于初始化数据并提供测试项给用户进行选择执行。 - + ##### 3.4.1.2 重启执行 `oech --rebootup` - + - 命令描述: 主要提供给 oech 服务使用,在执行部分需要重启的测试项时,在系统重启完成后服务会自动启动并执行该命令,继续执行指定重启的测试项。 @@ -297,7 +303,7 @@ infiniband: device: ibp1s0 client_ip: server_ip: - ``` +``` ### 3.5 内部模块间接口清单 @@ -352,17 +358,17 @@ oech 服务提供两种日志,操作日志和业务日志。 1. 操作日志 路径:/var/oech/oech.log - + 功能:记录用户操作的信息; - + 权限:路径权限755,日志文件权限644,普通用户可以查看; 2. 业务日志 路径:/usr/share/oech/logs/ - + 功能:即测试日志,主要记录执行的测试结果,并提供问题定位信息; - + 权限:路径权限755,日志文件权限644,普通用户可以查看; ##### 3.7.1.2 日志转储 @@ -401,7 +407,7 @@ oech 服务提供两种日志,操作日志和业务日志。 oech-server 服务端的日志由 `nginx` 提供,记录服务端的所有操作信息和访问的用户ip信息。另外 `nginx` 默认提供日志转储功能。 路径:/var/log/nginx/access.log - + 功能:记录服务端的操作信息,包括用户ip、访问时间、操作方式、访问url、访问结果等信息。 - + 权限:路径权限770,日志文件权限664,所有用户均可查看。 diff --git a/hwcompatible/compatibility.py b/hwcompatible/compatibility.py index ffe7db5..928b92a 100644 --- a/hwcompatible/compatibility.py +++ b/hwcompatible/compatibility.py @@ -298,8 +298,10 @@ class EulerCertification(): sort_devices["disk"] = [empty_device] if "nvme" in sort_devices.keys(): sort_devices["nvme"].extend([device]) + sort_devices["spdk"].extend([device]) else: sort_devices["nvme"] = [device] + sort_devices["spdk"] = [device] elif "/host" in device.get_property("DEVPATH"): sort_devices["disk"] = [empty_device] if "RAID" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") or \ @@ -316,15 +318,13 @@ class EulerCertification(): else: sort_devices["fc"] = [device] continue - # Corerain aiacc device if device.get_property("PCI_ID") == "1C8C:2432": if "aiacc" in sort_devices.keys(): - sort_devices["aiacc"].extend([device]) + sort_devices["aiacc"] = [device] else: sort_devices["aiacc"] = [device] continue - driver = device.get_property("DRIVER") if any([d in driver for d in GPU_DRIVER]): if "gpu" in sort_devices.keys(): diff --git a/hwcompatible/constants.py b/hwcompatible/constants.py index 43c37f4..f65b0ae 100644 --- a/hwcompatible/constants.py +++ b/hwcompatible/constants.py @@ -34,7 +34,7 @@ KEYCARD_VENDORS = ('Xilinx', 'Renesas', 'Texas', 'PLX') IB = "infiniband" DEVICE_INFO = ('color', 'status', 'num', 'run', 'name', 'device', 'driver', 'version', 'chip', 'board') -NO_CONFIG_DEVICES = ("gpu", "vgpu", "nvme", "dpdk", "cdrom", "keycard", "spdk") +NO_CONFIG_DEVICES = ("gpu", "vgpu", "nvme", "dpdk", "cdrom", "keycard", "spdk", "aiacc") # File access control FILE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_TRUNC @@ -48,4 +48,4 @@ SHELL_ENV = { # Log rotate settings MAX_BYTES = 31457280 -MAX_COUNT = 30 \ No newline at end of file +MAX_COUNT = 30 diff --git a/hwcompatible/device.py b/hwcompatible/device.py index e949bfe..dfbf8e8 100755 --- a/hwcompatible/device.py +++ b/hwcompatible/device.py @@ -145,6 +145,9 @@ class Device: # 8088 indicate Netswift if self.quad[0] == "8088": self.get_nic_netswift() + # 1c8c indicate Corerain + if self.quad[0] == "1c8c": + self.get_nic_corerain() except Exception: self.logger.error( "Get board information failed, please check %s!" % CertEnv.pcifile, terminal_print=False) @@ -303,6 +306,25 @@ class Device: self.board = self._search_info(r'(RP\S*)', ln) break + def get_nic_corerain(self): + """ + get the board model and chip model of netswift card + """ + flag = 0 + for ln in self.file.readlines(): + if flag == 0: + if re.match(self.quad[0], ln): + flag += 1 + elif flag == 1: + if re.match("\t" + self.quad[1], ln): + flag += 1 + self.chip = self._search_info(r'(Corerain\S*)', ln) + else: + if re.match("\t\t" + self.quad[2] + " " + self.quad[3], ln): + self.board = self._search_info(r'(Corerain\S*)', ln) + break + + def get_broadcom_card(self): """ get the board model and chip model of broadcom card diff --git a/tests/aiacc/.keep b/tests/aiacc/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/aiacc/cr_aiacc.py b/tests/aiacc/cr_aiacc.py index e9d580b..9ff37b1 100644 --- a/tests/aiacc/cr_aiacc.py +++ b/tests/aiacc/cr_aiacc.py @@ -47,62 +47,15 @@ class CRAIaccTest(): self.logger.warning( "The driver version information cannot be obtained. Please view it manually.") - - def test_cr_aiacc_driver(self): - """ - Check corerain aiacc utilization by driver, it can execute multi times and has log file - Returns: - bool: - """ - os.chdir("/opt/cr_aiacc/pcie-driver") - cmd = getstatusoutput( - "echo q | ./load | tee %s" % self.cr_aiacc_dirver_log) - if cmd[0] == 0: - self.logger.info("Check corerain aiacc driver succeed.") - else: - self.logger.error("Check corerain aiacc driver failed.") - return False - - return True - - def test_cr_aiacc_DM(self): - """ - AMD gpu test entry function - Returns: - bool: - """ - result = True - self.get_driver_info() - self.command.run_cmd( - "bash %s/test_cr_aiacc.sh install_cr_aiacc_driver" % gpu_dir) - self.command.run_cmd( - "bash %s/test_cr_aiacc.sh install_cr_aiacc_DM" % gpu_dir) - - self.logger.info("Check corerain aiacc driver.") - try: - if not self.test_cr_aiacc_driver(): - result = False - - if not self.test_cr_aiacc_DM(): - result = False - - except Exception as e: - self.logger.error( - "Failed to run the script because compiling or setting variables: %s" % e) - result = False - - return result - def test_cr_aiacc_sample(self): """ - Test screen information for gpu - This test need graphical.target to support + Test screen information for corerain x3a Returns: bool: """ os.chdir("/opt/cr_aiacc/") cmd = self.command.run_cmd( - "./run > $s " % self.cr_aiacc_sample_log) + "./run > %s " % self.cr_aiacc_sample_log) if cmd[2] == 0: self.logger.info("Test corerain aiacc screen information succeed.") else: -- Gitee From a6302bf21d0f8ef0d25245977fbfbc3174f1245c Mon Sep 17 00:00:00 2001 From: renquan Date: Mon, 13 Feb 2023 15:28:05 +0800 Subject: [PATCH 10/23] Update README.md about aiacc test --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e168b75..b9e0ac5 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ oec-hardware-1.1.1 版本将不再进行更新维护,请获取最新版本的 | | https://github.com/NVIDIA/cuda-samples/archive/refs/heads/master.zip | `/opt` | | VGPU | NVIDIA vgpu client驱动软件包 | /root | | | 下载对应版本和架构的虚拟机镜像文件,此处以openEuler 22.03LTS、x86_64为例:https://repo.openeuler.org/openEuler-22.03-LTS/virtual_machine_img/x86_64/openEuler-22.03-LTS-x86_64.qcow2.xz | `/opt` | + | aiacc | Corerain X3A 驱动软件包:https://gitee.com/qren/cr_aiacc/archive/refs/tags/v1.zip | `/opt` | # 工具安装 @@ -444,6 +445,12 @@ oec-hardware-1.1.1 版本将不再进行更新维护,请获取最新版本的 - 部署 NVIDIA VGPU 客户端虚拟机,测试驱动安装,测试客户端 VGPU 功能。 - VGPU 服务端监控客户端的运行。 +21. **aiacc** + + - 测试 Corerain X3A aiacc 服务端基本功能。 + - 部署 Corerain X3A aiacc 客户端虚拟机,测试驱动安装,测试客户端 aiacc 功能。 + - aiacc 服务端监控客户端的运行。 + # 社区开发者参与介绍 ## 环境部署 @@ -495,7 +502,7 @@ oec-hardware-1.1.1 版本将不再进行更新维护,请获取最新版本的 # FAQ [鲲鹏小智](https://ic-openlabs.huawei.com/chat/#/) 提供了oec-hardware测试过程中可能遇到的问题的解决方案,用户可以通过检索获取问题的解决方法。另外 [鲲鹏论坛](https://bbs.huaweicloud.com/forum/forum-927-1.html)上提供了完整的[oec-hardware安装使用问题解答](https://bbs.huaweicloud.com/forum/thread-0210979171291590002-1-1.html) ,用户可以根据场景获取解决方案。 - + 如果在适配过程中遇到问题,建议用户优先通过鲲鹏小智或鲲鹏论坛获取支撑。 如果鲲鹏小智无法解决,可在本仓库下提issue反馈或者发邮件至openEuler社区兼容性SIG组邮箱:oecompatibility@openeuler.org。 \ No newline at end of file -- Gitee From a1e5fecd4158ca7c0945c69773b985f514f07ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Wed, 8 Feb 2023 08:25:23 +0000 Subject: [PATCH 11/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20co?= =?UTF-8?q?nfig/test=5Fconfig.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/test_config.yaml | 59 ----------------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 config/test_config.yaml diff --git a/config/test_config.yaml b/config/test_config.yaml deleted file mode 100644 index 6107cab..0000000 --- a/config/test_config.yaml +++ /dev/null @@ -1,59 +0,0 @@ -#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: - - -- Gitee From b72ae731554cbbd738e6a977b1e37a4f185c9431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Wed, 8 Feb 2023 08:26:19 +0000 Subject: [PATCH 12/23] =?UTF-8?q?corerain=20=E6=98=9F=E7=A9=BAX3=E5=8A=A0?= =?UTF-8?q?=E9=80=9F=E5=8D=A1=E8=B0=83=E7=94=A8=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 黄汉高 --- config/test_config.yaml | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 config/test_config.yaml diff --git a/config/test_config.yaml b/config/test_config.yaml new file mode 100644 index 0000000..5d84e75 --- /dev/null +++ b/config/test_config.yaml @@ -0,0 +1,62 @@ +#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 +aiacc: + aiacc1: + device: '0002:e9:00.0' +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: + + -- Gitee From 8901b103ff2c3748691efeaade41754304be0865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:49:25 +0000 Subject: [PATCH 13/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20co?= =?UTF-8?q?nfig/test=5Fconfig.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/test_config.yaml | 62 ----------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 config/test_config.yaml diff --git a/config/test_config.yaml b/config/test_config.yaml deleted file mode 100644 index 5d84e75..0000000 --- a/config/test_config.yaml +++ /dev/null @@ -1,62 +0,0 @@ -#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 -aiacc: - aiacc1: - device: '0002:e9:00.0' -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: - - -- Gitee From a754f2b63a6b571a6d58093ea68d291fde41b3ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:52:35 +0000 Subject: [PATCH 14/23] =?UTF-8?q?Add=20Corerain=20Nebula=20Accelerator=20X?= =?UTF-8?q?3=20Test=20Case=20=E6=96=B0=E5=A2=9E=E4=BA=86config/test=5Fconf?= =?UTF-8?q?ig.yaml=E4=B8=ADaiacc=E7=9A=84=E7=9B=B8=E5=85=B3=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=8C=E5=A6=82device=E5=AD=97=E6=AE=B5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 黄汉高 --- config/test_config.yaml | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 config/test_config.yaml diff --git a/config/test_config.yaml b/config/test_config.yaml new file mode 100644 index 0000000..5d84e75 --- /dev/null +++ b/config/test_config.yaml @@ -0,0 +1,62 @@ +#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 +aiacc: + aiacc1: + device: '0002:e9:00.0' +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: + + -- Gitee From e05a63f4eba89b9cccedccd7ed65b70306c0bbdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:57:29 +0000 Subject: [PATCH 15/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20hw?= =?UTF-8?q?compatible/compatibility.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwcompatible/compatibility.py | 531 ---------------------------------- 1 file changed, 531 deletions(-) delete mode 100755 hwcompatible/compatibility.py diff --git a/hwcompatible/compatibility.py b/hwcompatible/compatibility.py deleted file mode 100755 index dbcacf3..0000000 --- a/hwcompatible/compatibility.py +++ /dev/null @@ -1,531 +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 - -import os -import time -import argparse -import shutil -import datetime -import re -from collections import namedtuple - -from .document import CertDocument, DeviceDocument, FactoryDocument -from .env import CertEnv -from .device import CertDevice, Device -from .command import Command -from .command_ui import CommandUI -from .job import Job -from .reboot import Reboot -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 - - -class EulerCertification(): - """ - Main program of oec-hardware - """ - - def __init__(self, logger): - self.certification = None - self.test_factory = list() - self.devices = None - self.ui = CommandUI() - self.client = None - self.dir_name = None - self.logger = logger - self.command = Command(logger) - - def run(self): - """ - Openeuler compatibility verification - :return: - """ - self.logger.info( - "The openEuler Hardware Compatibility Test Suite", log_print=False) - copy_pci() - self.load() - certdevice = CertDevice(self.logger) - - while True: - self.submit() - - if self.check_result(): - 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() - 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) - args = argparse.Namespace( - test_factory=self.test_factory, test_suite=test_suite) - job = Job(args) - job.run() - self.save(job) - - def run_rebootup(self): - """ - rebootup - :return: - """ - try: - if not os.path.exists(CertEnv.rebootfile): - return True - self.load() - test_suite = create_test_suite(self.test_factory, self.logger) - args = argparse.Namespace( - test_factory=self.test_factory, test_suite=test_suite) - job = Job(args) - reboot = Reboot(None, job, None) - if reboot.check(logger=self.logger): - job = reboot.job - job.run() - reboot.clean() - self.save(job) - return True - except Exception as e: - self.logger.error("Run reboot up failed. %s" % e) - return False - - def clean(self): - """ - clean all compatibility test file - :return: - """ - if self.ui.prompt_confirm("Are you sure to clean all " - "compatibility test data?"): - if os.path.exists(CertEnv.certificationfile): - os.remove(CertEnv.certificationfile) - if os.path.exists(CertEnv.factoryfile): - os.remove(CertEnv.factoryfile) - if os.path.exists(CertEnv.devicefile): - os.remove(CertEnv.devicefile) - self.logger.info("Clean compatibility test data succeed.") - return True - - def load(self): - """ - load certification - :return: - """ - os.makedirs(os.path.dirname(CertEnv.datadirectory), exist_ok=True) - if not self.certification: - self.certification = CertDocument( - CertEnv.certificationfile, self.logger) - if not self.certification.document: - self.certification.new() - self.certification.save() - if not self.test_factory: - factory_doc = FactoryDocument(CertEnv.factoryfile, self.logger) - self.test_factory = factory_doc.get_factory() - - oec_id = self.certification.get_certify() - hardware_info = self.certification.get_hardware() - self.client = Client(hardware_info, oec_id, self.logger) - version = self.certification.get_oech_value("VERSION", "version") - name = self.certification.get_oech_value("NAME", "client_name") - 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() - self.logger.info(display_message, log_print=False) - - def save(self, job): - """ - collect Job log - :param job: - :return: - """ - 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() - 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)) - self.dir_name = "oech-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") \ - + "-" + 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) - for sublist in os.walk("./"): - for dirname in sublist[1]: - shutil.rmtree(dirname) - break - os.chdir(cwd) - - def submit(self): - """ - submit last result - :return: - """ - packages = list() - pattern = re.compile("^oech-[0-9]{14}-[0-9a-zA-Z]{10}.tar$") - files = [] - for sublist in os.walk(CertEnv.datadirectory): - files = sublist[2] - break - packages.extend(filter(pattern.search, files)) - if len(packages) == 0: - return - packages.sort() - - if self.ui.prompt_confirm("Do you want to submit last result?"): - server = self.certification.get_server() - path = os.path.join(CertEnv.datadirectory, packages[-1]) - if not self.upload(path, server): - self.logger.error( - "Upload result to server %s failed." % server) - else: - self.logger.info( - "Upload result to server %s succeed." % server) - time.sleep(2) - - for filename in packages: - os.remove(os.path.join(CertEnv.datadirectory, filename)) - - def upload(self, path, server): - """ - uploaded result to server - :param path: - :param server: - :return: - """ - self.logger.info( - "Start to upload result to server %s, please wait." % server, log_print=False) - if not self.client: - oec_id = self.certification.get_certify() - hardware_info = self.certification.get_hardware() - self.client = Client(hardware_info, oec_id, self.logger) - return self.client.upload(path, server) - - def get_tests(self, devices): - """ - get test items - :param devices: - :return: - """ - sort_devices = self.sort_tests(devices) - empty_device = Device(logger=self.logger) - test_factory = list() - casenames = [] - for (_, dirs, filenames) in os.walk(CertEnv.testdirectoy): - 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: - 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"] = empty_device - test["run"] = True - test["status"] = "NotRun" - test["reboot"] = False - test_factory.append(test) - return test_factory - - def sort_tests(self, devices): - """ - sort tests - :param devices: - :return: - """ - sort_devices = dict() - empty_device = Device(logger=self.logger) - for device in devices: - if device.get_property("SUBSYSTEM") == "usb" and \ - device.get_property("ID_VENDOR_FROM_DATABASE") == \ - "Linux Foundation" and \ - ("2." in device.get_property("ID_MODEL_FROM_DATABASE") or - "3." in device.get_property("ID_MODEL_FROM_DATABASE")): - sort_devices["usb"] = [empty_device] - continue - if (device.get_property("DEVTYPE") == "disk" and - not device.get_property("ID_TYPE")) or \ - device.get_property("ID_TYPE") == "disk": - if "nvme" in device.get_property("DEVPATH"): - sort_devices["disk"] = [empty_device] - if "nvme" in sort_devices.keys(): - sort_devices["nvme"].extend([device]) - sort_devices["spdk"].extend([device]) - else: - sort_devices["nvme"] = [device] - sort_devices["spdk"] = [device] - elif "/host" in device.get_property("DEVPATH"): - sort_devices["disk"] = [empty_device] - if "RAID" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") or \ - ("SCSI" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") and - "HBA" not in device.get_property("ID_MODEL_FROM_DATABASE")): - if "raid" in sort_devices.keys(): - sort_devices["raid"].extend([device]) - else: - sort_devices["raid"] = [device] - continue - if "Fibre Channel" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE"): - if "fc" in sort_devices.keys(): - sort_devices["fc"].extend([device]) - else: - sort_devices["fc"] = [device] - continue - driver = device.get_property("DRIVER") - if any([d in driver for d in GPU_DRIVER]): - if "gpu" in sort_devices.keys(): - sort_devices["gpu"].extend([device]) - else: - sort_devices["gpu"] = [device] - if driver == "nvidia": - if "vgpu" in sort_devices.keys(): - sort_devices["vgpu"].extend([device]) - else: - sort_devices["vgpu"] = [device] - continue - if device.get_property("SUBSYSTEM") == "net" and \ - device.get_property("INTERFACE"): - interface = device.get_property("INTERFACE") - cmd_result = self.command.run_cmd("nmcli device") - for line in cmd_result[0].split("\n"): - if interface in line and IB in line: - if IB in sort_devices.keys(): - sort_devices[IB].extend([device]) - else: - sort_devices[IB] = [device] - elif interface in line and "ethernet" in line: - if "ethernet" in sort_devices.keys(): - sort_devices["ethernet"].extend([device]) - else: - sort_devices["ethernet"] = [device] - if "dpdk" in sort_devices.keys(): - sort_devices["dpdk"].extend([device]) - else: - sort_devices["dpdk"] = [device] - elif interface in line and "wifi" in line: - if "wlan" in sort_devices.keys(): - sort_devices["wlan"].extend([device]) - else: - sort_devices["wlan"] = [device] - continue - if device.get_property("ID_CDROM") == "1": - for dev_type in CDTYPES: - if device.get_property("ID_CDROM_" + dev_type) == "1": - if "cdrom" in sort_devices.keys(): - sort_devices["cdrom"].extend([device]) - else: - sort_devices["cdrom"] = [device] - break - if device.get_property("SUBSYSTEM") == "ipmi": - sort_devices["ipmi"] = [empty_device] - - id_vendor = device.get_property("ID_VENDOR_FROM_DATABASE") - 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] - - return sort_devices - - def edit_tests(self): - """ - edit test items - :return: - """ - while True: - for test in self.test_factory: - if test["name"] == "system": - test["run"] = True - if test["status"] == "PASS": - test["status"] = "Force" - - self.logger.info('\033c', log_print=False) - self.logger.info("Select tests to run:", log_print=False) - self.show_tests() - reply = self.ui.prompt("Selection (|all|none|quit|run): ") - reply = reply.lower() - if reply in ["r", "run"]: - return True - if reply in ["q", "quit"]: - return False - if reply in ["n", "none"]: - for test in self.test_factory: - test["run"] = False - continue - if reply in ["a", "all"]: - for test in self.test_factory: - test["run"] = True - continue - - num_lst = reply.split(" ") - for num in num_lst: - try: - num = int(num) - except ValueError: - continue - - if 0 < num <= len(self.test_factory): - self.test_factory[num - 1]["run"] = not \ - self.test_factory[num - 1]["run"] - continue - - def show_tests(self): - """ - show test items - :return: - """ - device_info = namedtuple('Device_info', DEVICE_INFO) - self.logger.info("\033[1;35m" + "No.".ljust(4) + "Run-Now?".ljust(10) - + "status".ljust(10) + "Class".ljust(14) + - "device".capitalize().ljust(15) - + DRIVER.ljust(15) + VERSION.ljust(18) + - CHIP.ljust(20) - + "%s\033[0m" % BOARD, log_print=False) - num = 0 - for test in self.test_factory: - name = test["name"] - if name == "system": - test["run"] = True - if test["status"] == "PASS": - test["status"] = "Force" - - status = test["status"] - device = test["device"].get_name() - board = test.get("boardModel", "") - chip = test.get("chipModel", "") - driver = test.get("driverName", "") - version = test.get("driverVersion", "") - 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" - device = device_info(color, status, num, run, name, - device, driver, version, chip, board) - self._print_tests(device) - - def choose_tests(self): - """ - choose test behavior - :return: - """ - for test in self.test_factory: - if test["status"] == "PASS": - test["run"] = False - else: - 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() - action = self.ui.prompt("Ready to begin testing?", - ["run", "edit", "quit"]) - action = action.lower() - if action in ["r", "run"]: - return True - if action in ["q", "quit"]: - return False - if action in ["e", "edit"]: - return self.edit_tests() - self.logger.info("Invalid choice!", log_print=False) - return self.choose_tests() - - def check_result(self): - """ - check test result - :return: - """ - if len(self.test_factory) == 0: - return False - for test in self.test_factory: - if test["status"] != "PASS": - return False - return True - - def update_factory(self, test_factory): - """ - update tese factory - :param test_factory: - :return: - """ - 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())) - self.test_factory.sort(key=lambda k: k["name"]) - FactoryDocument(CertEnv.factoryfile, self.logger, self.test_factory).save() - - def _print_tests(self, device): - """ - print board information - """ - self.logger.info("%-6d" % device.num + device.run.ljust(8) - + "\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) -- Gitee From 697f33a5fa235bc55cee7973634d6995e38c81b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:58:03 +0000 Subject: [PATCH 16/23] =?UTF-8?q?Add=20Corerain=20Nebula=20Accelerator=20X?= =?UTF-8?q?3=20Test=20Case=20=E6=96=B0=E5=A2=9E=E4=BA=86hwcompatible/compa?= =?UTF-8?q?tibility.py=E4=B8=ADaiacc=E8=AE=BE=E5=A4=87=E7=9A=84=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=B8=BA=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E9=B2=B2=E4=BA=91=E7=9A=84X3A=E5=8A=A0=E9=80=9F=E5=8D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 黄汉高 --- hwcompatible/compatibility.py | 534 ++++++++++++++++++++++++++++++++++ 1 file changed, 534 insertions(+) create mode 100644 hwcompatible/compatibility.py diff --git a/hwcompatible/compatibility.py b/hwcompatible/compatibility.py new file mode 100644 index 0000000..ffe7db5 --- /dev/null +++ b/hwcompatible/compatibility.py @@ -0,0 +1,534 @@ +#!/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 os +import time +import argparse +import shutil +import datetime +import re +from collections import namedtuple + +from .document import CertDocument, DeviceDocument, FactoryDocument +from .env import CertEnv +from .device import CertDevice, Device +from .command import Command +from .command_ui import CommandUI +from .job import Job +from .reboot import Reboot +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 + + +class EulerCertification(): + """ + Main program of oec-hardware + """ + + def __init__(self, logger): + self.certification = None + self.test_factory = list() + self.devices = None + self.ui = CommandUI() + self.client = None + self.dir_name = None + self.logger = logger + self.command = Command(logger) + + def run(self): + """ + Openeuler compatibility verification + :return: + """ + self.logger.info( + "The openEuler Hardware Compatibility Test Suite", log_print=False) + copy_pci() + self.load() + certdevice = CertDevice(self.logger) + + while True: + self.submit() + + if self.check_result(): + 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() + 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) + args = argparse.Namespace( + test_factory=self.test_factory, test_suite=test_suite) + job = Job(args) + job.run() + self.save(job) + + def run_rebootup(self): + """ + rebootup + :return: + """ + try: + if not os.path.exists(CertEnv.rebootfile): + return True + self.load() + test_suite = create_test_suite(self.test_factory, self.logger) + args = argparse.Namespace( + test_factory=self.test_factory, test_suite=test_suite) + job = Job(args) + reboot = Reboot(None, job, None) + if reboot.check(logger=self.logger): + job = reboot.job + job.run() + reboot.clean() + self.save(job) + return True + except Exception as e: + self.logger.error("Run reboot up failed. %s" % e) + return False + + def clean(self): + """ + clean all compatibility test file + :return: + """ + if self.ui.prompt_confirm("Are you sure to clean all " + "compatibility test data?"): + if os.path.exists(CertEnv.certificationfile): + os.remove(CertEnv.certificationfile) + if os.path.exists(CertEnv.factoryfile): + os.remove(CertEnv.factoryfile) + if os.path.exists(CertEnv.devicefile): + os.remove(CertEnv.devicefile) + self.logger.info("Clean compatibility test data succeed.") + return True + + def load(self): + """ + load certification + :return: + """ + os.makedirs(os.path.dirname(CertEnv.datadirectory), exist_ok=True) + if not self.certification: + self.certification = CertDocument( + CertEnv.certificationfile, self.logger) + if not self.certification.document: + self.certification.new() + self.certification.save() + if not self.test_factory: + factory_doc = FactoryDocument(CertEnv.factoryfile, self.logger) + self.test_factory = factory_doc.get_factory() + + oec_id = self.certification.get_certify() + hardware_info = self.certification.get_hardware() + self.client = Client(hardware_info, oec_id, self.logger) + version = self.certification.get_oech_value("VERSION", "version") + name = self.certification.get_oech_value("NAME", "client_name") + 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() + self.logger.info(display_message, log_print=False) + + def save(self, job): + """ + collect Job log + :param job: + :return: + """ + 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() + 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)) + self.dir_name = "oech-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") \ + + "-" + 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) + for sublist in os.walk("./"): + for dirname in sublist[1]: + shutil.rmtree(dirname) + break + os.chdir(cwd) + + def submit(self): + """ + submit last result + :return: + """ + packages = list() + pattern = re.compile("^oech-[0-9]{14}-[0-9a-zA-Z]{10}.tar$") + files = [] + for sublist in os.walk(CertEnv.datadirectory): + files = sublist[2] + break + packages.extend(filter(pattern.search, files)) + if len(packages) == 0: + return + packages.sort() + + if self.ui.prompt_confirm("Do you want to submit last result?"): + server = self.certification.get_server() + path = os.path.join(CertEnv.datadirectory, packages[-1]) + if not self.upload(path, server): + self.logger.error( + "Upload result to server %s failed." % server) + else: + self.logger.info( + "Upload result to server %s succeed." % server) + time.sleep(2) + + for filename in packages: + os.remove(os.path.join(CertEnv.datadirectory, filename)) + + def upload(self, path, server): + """ + uploaded result to server + :param path: + :param server: + :return: + """ + self.logger.info( + "Start to upload result to server %s, please wait." % server, log_print=False) + if not self.client: + oec_id = self.certification.get_certify() + hardware_info = self.certification.get_hardware() + self.client = Client(hardware_info, oec_id, self.logger) + return self.client.upload(path, server) + + def get_tests(self, devices): + """ + get test items + :param devices: + :return: + """ + sort_devices = self.sort_tests(devices) + empty_device = Device(logger=self.logger) + test_factory = list() + casenames = [] + for (_, dirs, filenames) in os.walk(CertEnv.testdirectoy): + 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: + 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"] = empty_device + test["run"] = True + test["status"] = "NotRun" + test["reboot"] = False + test_factory.append(test) + return test_factory + + def sort_tests(self, devices): + """ + sort tests + :param devices: + :return: + """ + sort_devices = dict() + empty_device = Device(logger=self.logger) + for device in devices: + if device.get_property("SUBSYSTEM") == "usb" and \ + device.get_property("ID_VENDOR_FROM_DATABASE") == \ + "Linux Foundation" and \ + ("2." in device.get_property("ID_MODEL_FROM_DATABASE") or + "3." in device.get_property("ID_MODEL_FROM_DATABASE")): + sort_devices["usb"] = [empty_device] + continue + if (device.get_property("DEVTYPE") == "disk" and + not device.get_property("ID_TYPE")) or \ + device.get_property("ID_TYPE") == "disk": + if "nvme" in device.get_property("DEVPATH"): + sort_devices["disk"] = [empty_device] + if "nvme" in sort_devices.keys(): + sort_devices["nvme"].extend([device]) + else: + sort_devices["nvme"] = [device] + elif "/host" in device.get_property("DEVPATH"): + sort_devices["disk"] = [empty_device] + if "RAID" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") or \ + ("SCSI" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") and + "HBA" not in device.get_property("ID_MODEL_FROM_DATABASE")): + if "raid" in sort_devices.keys(): + sort_devices["raid"].extend([device]) + else: + sort_devices["raid"] = [device] + continue + if "Fibre Channel" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE"): + if "fc" in sort_devices.keys(): + sort_devices["fc"].extend([device]) + else: + sort_devices["fc"] = [device] + continue + + # Corerain aiacc device + if device.get_property("PCI_ID") == "1C8C:2432": + if "aiacc" in sort_devices.keys(): + sort_devices["aiacc"].extend([device]) + else: + sort_devices["aiacc"] = [device] + continue + + driver = device.get_property("DRIVER") + if any([d in driver for d in GPU_DRIVER]): + if "gpu" in sort_devices.keys(): + sort_devices["gpu"].extend([device]) + else: + sort_devices["gpu"] = [device] + if driver == "nvidia": + if "vgpu" in sort_devices.keys(): + sort_devices["vgpu"].extend([device]) + else: + sort_devices["vgpu"] = [device] + continue + if device.get_property("SUBSYSTEM") == "net" and \ + device.get_property("INTERFACE"): + interface = device.get_property("INTERFACE") + cmd_result = self.command.run_cmd("nmcli device") + for line in cmd_result[0].split("\n"): + if interface in line and IB in line: + if IB in sort_devices.keys(): + sort_devices[IB].extend([device]) + else: + sort_devices[IB] = [device] + elif interface in line and "ethernet" in line: + if "ethernet" in sort_devices.keys(): + sort_devices["ethernet"].extend([device]) + else: + sort_devices["ethernet"] = [device] + elif interface in line and "wifi" in line: + if "wlan" in sort_devices.keys(): + sort_devices["wlan"].extend([device]) + else: + sort_devices["wlan"] = [device] + continue + if device.get_property("ID_CDROM") == "1": + for dev_type in CDTYPES: + if device.get_property("ID_CDROM_" + dev_type) == "1": + if "cdrom" in sort_devices.keys(): + sort_devices["cdrom"].extend([device]) + else: + sort_devices["cdrom"] = [device] + break + if device.get_property("SUBSYSTEM") == "ipmi": + sort_devices["ipmi"] = [empty_device] + + id_vendor = device.get_property("ID_VENDOR_FROM_DATABASE") + 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] + + return sort_devices + + def edit_tests(self): + """ + edit test items + :return: + """ + while True: + for test in self.test_factory: + if test["name"] == "system": + test["run"] = True + if test["status"] == "PASS": + test["status"] = "Force" + + self.logger.info('\033c', log_print=False) + self.logger.info("Select tests to run:", log_print=False) + self.show_tests() + reply = self.ui.prompt("Selection (|all|none|quit|run): ") + reply = reply.lower() + if reply in ["r", "run"]: + return True + if reply in ["q", "quit"]: + return False + if reply in ["n", "none"]: + for test in self.test_factory: + test["run"] = False + continue + if reply in ["a", "all"]: + for test in self.test_factory: + test["run"] = True + continue + + num_lst = reply.split(" ") + for num in num_lst: + try: + num = int(num) + except ValueError: + continue + + if 0 < num <= len(self.test_factory): + self.test_factory[num - 1]["run"] = not \ + self.test_factory[num - 1]["run"] + continue + + def show_tests(self): + """ + show test items + :return: + """ + device_info = namedtuple('Device_info', DEVICE_INFO) + self.logger.info("\033[1;35m" + "No.".ljust(4) + "Run-Now?".ljust(10) + + "status".ljust(10) + "Class".ljust(14) + + "device".capitalize().ljust(15) + + DRIVER.ljust(15) + VERSION.ljust(18) + + CHIP.ljust(20) + + "%s\033[0m" % BOARD, log_print=False) + num = 0 + for test in self.test_factory: + name = test["name"] + if name == "system": + test["run"] = True + if test["status"] == "PASS": + test["status"] = "Force" + + status = test["status"] + device = test["device"].get_name() + board = test.get("boardModel", "") + chip = test.get("chipModel", "") + driver = test.get("driverName", "") + version = test.get("driverVersion", "") + 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" + device = device_info(color, status, num, run, name, + device, driver, version, chip, board) + self._print_tests(device) + + def choose_tests(self): + """ + choose test behavior + :return: + """ + for test in self.test_factory: + if test["status"] == "PASS": + test["run"] = False + else: + 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() + action = self.ui.prompt("Ready to begin testing?", + ["run", "edit", "quit"]) + action = action.lower() + if action in ["r", "run"]: + return True + if action in ["q", "quit"]: + return False + if action in ["e", "edit"]: + return self.edit_tests() + self.logger.info("Invalid choice!", log_print=False) + return self.choose_tests() + + def check_result(self): + """ + check test result + :return: + """ + if len(self.test_factory) == 0: + return False + for test in self.test_factory: + if test["status"] != "PASS": + return False + return True + + def update_factory(self, test_factory): + """ + update tese factory + :param test_factory: + :return: + """ + 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())) + self.test_factory.sort(key=lambda k: k["name"]) + FactoryDocument(CertEnv.factoryfile, self.logger, self.test_factory).save() + + def _print_tests(self, device): + """ + print board information + """ + self.logger.info("%-6d" % device.num + device.run.ljust(8) + + "\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) -- Gitee From ecb8c744bb25e4f645edf84abe4a92274b40b354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:58:34 +0000 Subject: [PATCH 17/23] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20aiacc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/aiacc/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/aiacc/.keep diff --git a/tests/aiacc/.keep b/tests/aiacc/.keep new file mode 100644 index 0000000..e69de29 -- Gitee From 1a586f1d82d3d22de14a7057b6bcf82dad424355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B1=89=E9=AB=98?= Date: Thu, 9 Feb 2023 02:59:18 +0000 Subject: [PATCH 18/23] =?UTF-8?q?Add=20Corerain=20Nebula=20Accelerator=20X?= =?UTF-8?q?3=20Test=20Case=20=E6=96=B0=E5=A2=9E=E4=BA=86tests/aiacc?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 黄汉高 --- tests/aiacc/Makefile | 23 +++++++ tests/aiacc/aiacc.py | 51 ++++++++++++++++ tests/aiacc/cr_aiacc.py | 112 +++++++++++++++++++++++++++++++++++ tests/aiacc/test_cr_aiacc.sh | 65 ++++++++++++++++++++ 4 files changed, 251 insertions(+) create mode 100644 tests/aiacc/Makefile create mode 100644 tests/aiacc/aiacc.py create mode 100644 tests/aiacc/cr_aiacc.py create mode 100644 tests/aiacc/test_cr_aiacc.sh diff --git a/tests/aiacc/Makefile b/tests/aiacc/Makefile new file mode 100644 index 0000000..fca5860 --- /dev/null +++ b/tests/aiacc/Makefile @@ -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: 2023-01-10 + +.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 --git a/tests/aiacc/aiacc.py b/tests/aiacc/aiacc.py new file mode 100644 index 0000000..2c5ac54 --- /dev/null +++ b/tests/aiacc/aiacc.py @@ -0,0 +1,51 @@ +# 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: @quanren +# Create: 2023-01-10 +# Desc: aiacc test, support Corerain series aiacc + +import argparse +from hwcompatible.command import Command +from hwcompatible.test import Test +from cr_aiacc import CRAIaccTest + + +class aiaccTest(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 + """ + result = False + driver = self.device.get_driver() + if driver == "Corerain DMA": + cr_test = CRAIaccTest(self.device, self.logger, self.command) + result = cr_test.test_cr_aiacc_sample() + return result + return result + + diff --git a/tests/aiacc/cr_aiacc.py b/tests/aiacc/cr_aiacc.py new file mode 100644 index 0000000..e9d580b --- /dev/null +++ b/tests/aiacc/cr_aiacc.py @@ -0,0 +1,112 @@ +# 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: @quanren +# Create: 2023-01-10 +# Desc: Corerain aiacc test. + +import os +from subprocess import getstatusoutput + +gpu_dir = os.path.dirname(os.path.realpath(__file__)) + + +class CRAIaccTest(): + def __init__(self, device, logger, command): + self.device = device + self.logger = logger + self.command = command + self.cr_aiacc_driver_log = os.path.join(self.logger.logdir, 'cr_aiacc_driver.log') + self.cr_aiacc_DM_log = os.path.join(self.logger.logdir, 'cr_aiacc_DM.log') + self.cr_aiacc_sample_log = os.path.join(self.logger.logdir, 'cr_aiacc_sample.log') + self.screen_info_log = os.path.join(self.logger.logdir, 'screen_info.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_cr_aiacc_driver(self): + """ + Check corerain aiacc utilization by driver, it can execute multi times and has log file + Returns: + bool: + """ + os.chdir("/opt/cr_aiacc/pcie-driver") + cmd = getstatusoutput( + "echo q | ./load | tee %s" % self.cr_aiacc_dirver_log) + if cmd[0] == 0: + self.logger.info("Check corerain aiacc driver succeed.") + else: + self.logger.error("Check corerain aiacc driver failed.") + return False + + return True + + def test_cr_aiacc_DM(self): + """ + AMD gpu test entry function + Returns: + bool: + """ + result = True + self.get_driver_info() + self.command.run_cmd( + "bash %s/test_cr_aiacc.sh install_cr_aiacc_driver" % gpu_dir) + self.command.run_cmd( + "bash %s/test_cr_aiacc.sh install_cr_aiacc_DM" % gpu_dir) + + self.logger.info("Check corerain aiacc driver.") + try: + if not self.test_cr_aiacc_driver(): + result = False + + if not self.test_cr_aiacc_DM(): + result = False + + except Exception as e: + self.logger.error( + "Failed to run the script because compiling or setting variables: %s" % e) + result = False + + return result + + def test_cr_aiacc_sample(self): + """ + Test screen information for gpu + This test need graphical.target to support + Returns: + bool: + """ + os.chdir("/opt/cr_aiacc/") + cmd = self.command.run_cmd( + "./run > $s " % self.cr_aiacc_sample_log) + if cmd[2] == 0: + self.logger.info("Test corerain aiacc screen information succeed.") + else: + self.logger.error("Test corerain aiacc screen information failed.") + return False + + return True diff --git a/tests/aiacc/test_cr_aiacc.sh b/tests/aiacc/test_cr_aiacc.sh new file mode 100644 index 0000000..ce21631 --- /dev/null +++ b/tests/aiacc/test_cr_aiacc.sh @@ -0,0 +1,65 @@ +#!/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: @quanren +# Create: 2023-01-10 +# Desc: Shell script used for testing Corerain aiacc + +function install_cr_aiacc_driver() { + cd /opt + res_code=0 + if [ ! -d cr_aiacc ]; then + git clone https://gitee.com/qren/cr_aiacc.git + fi + cd cr_aiacc/pcie-driver + ./compile && ./load &>/dev/null || res_code=1 + + return $res_code +} + +function install_cr_aiacc_DM() { + cd /opt + res_code=0 + if [ ! -d cr_aiacc ]; then + git clone https://gitee.com/qren/cr_aiacc.git + fi + cd cr_aiacc/device-manager + ./compile && ./load &>/dev/null || res_code=1 + + return $res_code +} + +function install_cr_aiacc_sample() { + cd /opt + res_code=0 + if [ ! -d cr_aiacc ]; then + git clone https://gitee.com/qren/cr_aiacc.git + fi + cd cr_aiacc + ./compile && ./run &>/dev/null || res_code=1 + return $res_code +} + +function main() { + func_name=$1 + + if [[ $func_name == "install_cr_aiacc_driver" ]]; then + install_cr_aiacc_driver + elif [[ $func_name == "install_cr_aiacc_DM" ]]; then + install_cr_aiacc_DM + elif [[ $func_name == "install_cr_aiacc_sample" ]]; then + install_cr_aiacc_sample + else + echo "The function doesn't exist, please check!" + return 1 + fi +} + +main "$@" -- Gitee From 6faa298eb350d2395a0b0be0eb4c49249e9bcda1 Mon Sep 17 00:00:00 2001 From: renquan Date: Mon, 13 Feb 2023 15:22:55 +0800 Subject: [PATCH 19/23] Add corerain X3A aiacc test model and update related documents --- config/test_config.yaml | 3 - docs/design_docs/dev_design.md | 409 --------------------------------- hwcompatible/compatibility.py | 6 +- hwcompatible/constants.py | 4 +- hwcompatible/device.py | 22 ++ tests/aiacc/.keep | 0 tests/aiacc/cr_aiacc.py | 51 +--- 7 files changed, 29 insertions(+), 466 deletions(-) delete mode 100644 docs/design_docs/dev_design.md delete mode 100644 tests/aiacc/.keep diff --git a/config/test_config.yaml b/config/test_config.yaml index 5d84e75..6107cab 100644 --- a/config/test_config.yaml +++ b/config/test_config.yaml @@ -19,9 +19,6 @@ raid: raid2: device: '0000:0a:00.1' disk: sdb -aiacc: - aiacc1: - device: '0002:e9:00.0' disk: all ethernet: # IP has been manually configured, get server IP. diff --git a/docs/design_docs/dev_design.md b/docs/design_docs/dev_design.md deleted file mode 100644 index 57c7456..0000000 --- a/docs/design_docs/dev_design.md +++ /dev/null @@ -1,409 +0,0 @@ -# oec-hardware 开发设计文档 - -## 1 需求描述 - -提供硬件兼容性测试工具套件以及CPU、IPMI等系统重要功能测试,实现服务器整机、板卡与openEuler的兼容性验证测试。 - -### 1.2 依赖组件 - -#### 1.2.1 客户端依赖组件 - -| 组件 | 组件描述 | 可获得性 | -| --------- | ------ | --------- | -| python3 | python3 及以上版本 | 可使用 `dnf/yum` 进行安装 | -| python3-pyyaml | 读取yaml格式的配置文件 | 可使用 `dnf/yum` 进行安装 | -| python3-concurrent-log-handler | logging日志辅助模块,用于日志转储 | 可使用 `dnf/yum` 进行安装 | -| kernel | kernel代码,需要使用系统默认安装完成后的提供kernel | 系统安装完成后默认提供 | -| kernel-devel | 需要和系统默认安装使用的kernel版本保持一致 | 可使用 `dnf/yum` 进行安装 | -| kernel-headers | 需要和系统默认安装使用的kernel版本保持一致 | 可使用 `dnf/yum` 进行安装 | -| dmidecode | 获取服务器硬件信息 | 可使用 `dnf/yum` 进行安装 | -| tar | 打包测试日志 | 可使用 `dnf/yum` 进行安装 | - -#### 1.2.2 服务端依赖组件 - -| 组件 | 组件描述 | 可获得性 | -| --------- | ------- | -------- | -| python3 | python3 及以上版本 | 可使用 `dnf/yum` 进行安装 | -| python3-devel | python3开发模块 | 可使用 `dnf/yum` 进行安装 | -| nginx | 提供web服务器 | 可使用 `dnf/yum` 进行安装 | -| tar | 打包、解压测试日志 | 可使用 `dnf/yum` 进行安装 | -| qperf | 用于服务端网络自测 | 可使用 `dnf/yum` 进行安装 | -| psmisc | 提供进程管理服务 | 可使用 `dnf/yum` 进行安装 | -| python3-flask | 提供web访问的http协议的框架 | 可使用 `dnf/yum` 进行安装 | -| python3-uWSGI | 提供wsgi协议的服务器 | 可使用 `dnf/yum` 进行安装 | - -#### 1.2.3 客户端测试项依赖组件 - -| 测试项 | 组件 | 组件描述 | -| --------- | ------ | --------- | -| acpi | acpica-tools | acpi 测试 | -| cdrom | dvd+rw-tools | cd/dvd 测试 | -| | cdrkit | | -| | genisoimage | | -| | util-linux | | -| disk/fc/raid | fio | 硬盘读写测试 | -| ethernet/infiniband | ethtool | 网卡/IB卡测试 | -| | iproute | | -| | psmisc | | -| | qperf | | -| | perftest | | -| | opensm | | -| | rdma-core | | -| ipmi | OpenIPMI | ipmi 测试 | -| | ipmitool | | -| kabi | gzip | kabi 测试 | -| | rpm-build | | -| kdump | crash | kdump 测试 | -| | kernel-debuginfo | | -| | kexec-tools | | -| memory | memtester | 内存测试 | -| | libhugetlbfs-utils | | -| nvme | nvme-cli | nvme 测试 | -| perf | perf | perf测试 | -| usb | usbutils | usb 测试 | -| gpu (Nvidia) | git | Nvidia GPU测试依赖 | -| | gcc-c++ | | -| | make | | -| gpu (AMD) | 图形桌面 | AMD GPU需要在图形界面测试,桌面类型无限制,需要用户提前安装配置 | -| | git | AMD GPU测试依赖 | -| | gcc-c++ | | -| | make | | -| | libdrm-devel | | -| | ncurses-devel | | -| | ncurses-libs | | -| | libpciaccess-devel | | -| | libxcb-devel | | -| | meson | | -| | libX11-devel | | -| | libpng-devel | | -| | cmake | | -| | pkgconf | | -| | libjpeg | | -| | libjpeg-turbo-devel | | -| | libdrm-devel | | -| | mesa-libgbm-devel | | -| | libgudev-devel | | -| vgpu | qemu | vgpu 测试 | -| | libvirt | | -| | xz | | -| | util-linux | | -| | expect | | -| system | policycoreutils | system 测试 | -| spdk | spdk | spdk 测试 | -| dpdk | dpdk-testpmd | dpdk 测试 | - -### 1.3 License - -Mulan V2 - -## 2 设计概述 - -### 2.1 设计原则 - -- 数据与代码分离: 需要进行配置的测试项参数,通过配置文件进行管理。 - -- 接口与实现分离:外部依赖模块接口而不是依赖模块实现。 - -- 模块划分: 模块之间互相独立,执行互相不影响。 - -## 3 需求分析 - -### 3.1 框架概览 - -``` -. -├── hwcompatible 框架主功能 -│ ├── compatibility.py 框架核心功能 -│ ├── client.py 上传测试结果到服务端 -│ ├── command.py bash命令执行封装 -│ ├── command_ui.py 命令行交互工具 -│ ├── device.py 扫描设备信息 -│ ├── document.py 收集配置信息 -│ ├── env.py 全局变量,主要是各个配置文件或目录的路径 -│ ├── job.py 测试任务管理 -│ ├── log.py 日志模块 -│ ├── reboot.py 重启类任务专用,便于机器重启后仍能继续执行测试 -│ ├── sysinfo.py 收集系统信息 -│ ├── config_ip.py 自动检测并配置网卡IP -│ └── test.py 测试套模板 -├── scripts 工具脚本 -│ ├── oech 工具客户端命令行工具 -│ ├── oech-server 工具服务端命令行工具 -│ ├── oech-server.service 工具服务端 service 文件,用于启动 web 服务器 -│ ├── oech.service 工具客户端 service 文件,用于接管 reboot 用例和日志转储 -│ ├── oech_logrotate.sh 工具客户端日志转储脚本 -│ └── kernelrelease.json 工具支持认证的系统和内核版本 -├── server 服务端 -│ ├── oech-server-pre.sh 服务预执行脚本 -│ ├── results/ 测试结果存放目录 -│ ├── server.py 服务端主程序 -│ ├── static/ 网页图片、样式设计文件存放目录 -│ ├── templates/ 网页模板存放目录 -│ ├── uwsgi.conf nginx 服务配置 -│ └── uwsgi.ini uwsgi 服务配置 -├── config 配置文件 -│ ├── version.config 工具版本配置文件 -│ └── test_config.yaml 工具测试项配置文件 -├── templates 兼容性清单模板存放目录 -├── tests 测试套 -└──vendor_tests 厂商测试工具存放目录 -``` - -### 3.2 框架特点 - -oec-hardware工具框架有如下特点: - -1. 为满足可信要求,必须使用openEuler操作系统,不能随意重编/插入内核模块; - -2. 通过扫描机制自适应发现硬件列表,来确定要运行的测试用例集合; - -3. 面向对象抽象各种硬件类型以及测试用例类,用于扩展开发。 - -### 3.3 运行流程 - -![test-flow](../pictures/test-flow.png) - -### 3.4 外部接口清单 - -#### 3.4.1 命令行接口清单 - -##### 3.4.1.1 工具执行 - -`oech` - -- 命令描述: - - 工具执行入口,用于初始化数据并提供测试项给用户进行选择执行。 - -##### 3.4.1.2 重启执行 - -`oech --rebootup` - -- 命令描述: - - 主要提供给 oech 服务使用,在执行部分需要重启的测试项时,在系统重启完成后服务会自动启动并执行该命令,继续执行指定重启的测试项。 - -##### 3.4.1.3 格式化数据 - -`oech --clean` - -- 命令描述: - - 清除配置信息和测试执行信息,如果系统的硬件配置发生变化,可通过该命令清除旧的配置信息,然后执行 `oech` 命令使工具重新收集硬件配置信息。 - -##### 3.4.1.4 查询版本号 - -`oech --version` - -`oech-server --version` - -- 命令描述: - - oech 客户端、服务端版本号查询。 - -#### 3.4.2 服务启动和停止 - -* 客户端 - - 启动 oech 服务:`systemctl start oech.service` - - 查看 oech 状态:`systemctl status oech.service` - - 停止 oech 服务:`systemctl stop oech.service` - - 重启 oech 服务:`systemctl restart oech.service` - -* 服务端 - - 启动 oech-server 服务:`systemctl start oech-server.service` - - 查看 oech-server 状态:`systemctl status oech-server.service` - - 停止 oech-server 服务:`systemctl stop oech-server.service` - - 重启 oech-server 服务:`systemctl restart oech-server.service` - -#### 3.4.3 配置文件 - -##### 3.4.3.1 版本配置文件 - -本工具通过 `version.config` 配置文件管理工具版本。 - -##### 3.4.3.2 硬件信息配置文件 - -OS 通过 `/usr/share/hwdata/pci.ids` 文件获取环境中所有的硬件信息,OS 中该文件信息显示不全,本工具提供新的 `pci.ids` 文件,补充部分硬件设备信息,后续该文件会推动合入到 `hwdata` 软件包。 - -##### 3.4.3.3 测试项配置文件 - -部分硬件测试项的测试信息通过 `test_config.yaml` 配置文件获取。 - -```test_config.yaml -# FC卡测试项配置信息,指定测试的端口设备号和测试的存储设备硬盘名称 -# device为设备号,可通过oech或lspci查看 -# disk指定为all表示测试所有硬盘,可以指定单独的硬盘或硬盘分区 -fc: - fc1: - device: '0000:03:00.0' - disk: all - fc2: - device: '0000:03:00.1' - disk: sda -# RAID卡测试项配置信息,指定测试的硬件设备号和测试的RAID卡下硬盘名称 -raid: - raid1: - device: '0000:02:00.0' - disk: all - raid2: - device: '0000:0a:00.1' - disk: sdb -# DISK卡测试项配置信息,指定测试的硬盘名称 -disk: all -# 网卡测试项配置信息,指定测试的端口设备号、测试RDMA、服务端IP -# device为网卡端口设备号,可通过oech或ip a查看 -# if_rdma表示是否测试网卡RDMA,默认是N,表示不测试RDMA -# client_ip为客户端测试网卡配置的IP -# server_ip为服务端测试网卡配置的IP -# 服务端的端口默认是80,如果有修改,需要添加上修改后的端口号,如下面的eth2示例。 -# 服务端自动配置的IP,测试完成后,需用户手动删除(ip addr del ip地址 dev 接口)。 -ethernet: - # 已手动配置客户端和服务端测试网卡的IP,这里需要添加上服务端的IP地址。 - eth1: - device: enp125s0f0 - if_rdma: N - client_ip: - server_ip: 2.2.2.4 - # 未手动配置IP,使用这里提供的IP进行客户端和服务端配置。 - eth2: - device: enp125s0f1 - if_rdma: N - client_ip: 2.2.2.3 - server_ip: 2.2.2.4:8090 - # 前面两种情况都没有满足,且客户端和服务端的IP地址未提供,程序会自动生成IP,进行配置。 - eth3: - device: enp125s0f2 - if_rdma: y - client_ip: - server_ip: -# IB卡测试项配置信息,指定测试的端口设备号、服务端IP。 -# IB卡IP的配置原则同普通网卡。 -infiniband: - ib1: - device: ibp1s0 - client_ip: - server_ip: 2.2.2.4 - ib2: - device: ibp1s1 - client_ip: 2.2.2.3 - server_ip: 2.2.2.4:8090 - ib3 - device: ibp1s0 - client_ip: - server_ip: - ``` - -### 3.5 内部模块间接口清单 - -| 序号 | 接口名称 | 所属模块 | 接口描述 | -| --------- | --------- | ------- | -------- | -| 1 | `EulerCertification()` | 执行模块 | 和外部接口交互,提供执行 | -| 2 | `Job()` | 任务管理模块 | 管理执行的测试任务 | -| 3 | `Device()` | 硬件信息模块 | 获取硬件的属性 | -| 4 | `CertDevice()` | 硬件信息模块 | 获取环境上所有硬件信息 | -| 5 | `Client()` | 客户端模块 | 和服务端交互 | -| 6 | `Command()` | 命令执行模块 | 安全执行shell命令 | -| 7 | `Logger()` | 日志模块 | 记录日志信息 | -| 8 | `Reboot()` | 测试项模块 | 重启测试项执行模块 | -| 9 | `Test()` | 测试项模块 | 所有测试项的父类 | -| 10 | `CommandUI()`| 命令行交互模块 | 命令行交互显示,提供用户参数输入 | -| 11 | `Document()` | 文档模块 | 文档信息获取,所有文档模块的父类 | -| 12 | `CertDocument()` | 文档模块 | 服务端信息读取 | -| 13 | `DeviceDocument()` | 文档模块 | 硬件信息读取 | -| 14 | `FactoryDocument()` | 文档模块 | 框架信息读取 | -| 15 | `ConfigFile()` | 文档模块 | 配置信息读取 | -| 16 | `CertEnv()` | 工具环境信息模块 | 提供工具文件环境路径 | -| 17 | `SysInfo()` | 系统信息模块 | 系统信息获取 | -| 18 | `ConfigIP()` | 网卡IP配置模块 | 查询并配置网卡IP | -| 19 | `CertInfo()` | 兼容性信息收集模块 | 自动收集并生成兼容性信息文件 | - -### 3.6 web服务接口清单 - -| 序号 | 接口名称 | 类型 | 说明 | -| --------- | ------- | -------- | -------- | -| 1 | `/results` | | web服务端测试结果 | -| 2 | `/results///` | | 测试报告 | -| 3 | `/results////devices/` | | 查看指定硬件信息 | -| 4 | `/results////devices` | | 查看所有硬件信息 | -| 5 | `/results////attachment` | | 下载测试日志压缩包 | -| 6 | `/results////logs/` | | 查看指定测试项的测试日志 | -| 7 | `/results////submit` | | 上传测试结果 | -| 8 | `/api/job/upload` | GET/POST | 客户端job信息上传 | -| 9 | `/files` | | 获取文件信息,辅助客户端网卡测试 | -| 10 | `/files/` | | 文件下载,辅助客户端网卡测试 | -| 11 | `/api/file/upload` | GET/POST | 文件上传,辅助客户端网卡测试 | -| 12 | `/api/` | GET/POST | 文件读写,辅助客户端网卡测试 | -| 13 | `/api/config/ip`| GET/POST | 配置服务端网卡IP | - -### 3.7 日志查看和转储 - -#### 3.7.1 客户端 - -##### 3.7.1.1 日志查看 - -oech 服务提供两种日志,操作日志和业务日志。 - -1. 操作日志 - - 路径:/var/oech/oech.log - - 功能:记录用户操作的信息; - - 权限:路径权限755,日志文件权限644,普通用户可以查看; - -2. 业务日志 - - 路径:/usr/share/oech/logs/ - - 功能:即测试日志,主要记录执行的测试结果,并提供问题定位信息; - - 权限:路径权限755,日志文件权限644,普通用户可以查看; - -##### 3.7.1.2 日志转储 - -1. 操作日志转储: - -- 转储机制 - - 使用 python logging 模块的转储机制,按照日志大小、日志数量进行备份。 - -- 转储过程 - - 运行程序写入日志时,如果日志文件大小超过配置的最大日志字节 `MAX_BYTES`(默认设置为30M),日志文件会自动进行压缩转储,压缩文件名称为oech.log.1.gz,1为压缩转储序号。 - - 如果转储的日志数量大于配置的备份数量 `MAX_COUNT`(默认设置为30),备份日志会按照备份时间删除,最早的备注日志会被删除掉,然后对当前日志进行压缩备份。 - - -2. 业务日志转储: - -- 转储机制 - - 使用shell脚本进行转储,每天转储一次。 - - > 脚本路径:/usr/share/oech/scripts/oech_logrotate.sh - -- 转储过程 - - oech 服务启动时转储脚本后台运行,每天进行转储压缩,压缩文件名称为oech-logrotate-yymmddhh.zip。 - - 如果业务日志目录下的文件数量大于配置的备份数量 `MAX_COUNT`(默认设置为30),会按照时间顺序删除日志目录下最早的文件。 - - oech 服务停止后转储脚本停止,不再进行转储,再次启动时,转储脚本重新执行。 - -#### 3.7.2 服务端 - - oech-server 服务端的日志由 `nginx` 提供,记录服务端的所有操作信息和访问的用户ip信息。另外 `nginx` 默认提供日志转储功能。 - - 路径:/var/log/nginx/access.log - - 功能:记录服务端的操作信息,包括用户ip、访问时间、操作方式、访问url、访问结果等信息。 - - 权限:路径权限770,日志文件权限664,所有用户均可查看。 diff --git a/hwcompatible/compatibility.py b/hwcompatible/compatibility.py index ffe7db5..928b92a 100644 --- a/hwcompatible/compatibility.py +++ b/hwcompatible/compatibility.py @@ -298,8 +298,10 @@ class EulerCertification(): sort_devices["disk"] = [empty_device] if "nvme" in sort_devices.keys(): sort_devices["nvme"].extend([device]) + sort_devices["spdk"].extend([device]) else: sort_devices["nvme"] = [device] + sort_devices["spdk"] = [device] elif "/host" in device.get_property("DEVPATH"): sort_devices["disk"] = [empty_device] if "RAID" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") or \ @@ -316,15 +318,13 @@ class EulerCertification(): else: sort_devices["fc"] = [device] continue - # Corerain aiacc device if device.get_property("PCI_ID") == "1C8C:2432": if "aiacc" in sort_devices.keys(): - sort_devices["aiacc"].extend([device]) + sort_devices["aiacc"] = [device] else: sort_devices["aiacc"] = [device] continue - driver = device.get_property("DRIVER") if any([d in driver for d in GPU_DRIVER]): if "gpu" in sort_devices.keys(): diff --git a/hwcompatible/constants.py b/hwcompatible/constants.py index 43c37f4..f65b0ae 100644 --- a/hwcompatible/constants.py +++ b/hwcompatible/constants.py @@ -34,7 +34,7 @@ KEYCARD_VENDORS = ('Xilinx', 'Renesas', 'Texas', 'PLX') IB = "infiniband" DEVICE_INFO = ('color', 'status', 'num', 'run', 'name', 'device', 'driver', 'version', 'chip', 'board') -NO_CONFIG_DEVICES = ("gpu", "vgpu", "nvme", "dpdk", "cdrom", "keycard", "spdk") +NO_CONFIG_DEVICES = ("gpu", "vgpu", "nvme", "dpdk", "cdrom", "keycard", "spdk", "aiacc") # File access control FILE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_TRUNC @@ -48,4 +48,4 @@ SHELL_ENV = { # Log rotate settings MAX_BYTES = 31457280 -MAX_COUNT = 30 \ No newline at end of file +MAX_COUNT = 30 diff --git a/hwcompatible/device.py b/hwcompatible/device.py index 2f265c6..84be30d 100755 --- a/hwcompatible/device.py +++ b/hwcompatible/device.py @@ -145,6 +145,9 @@ class Device: # 8088 indicate Netswift if self.quad[0] == "8088": self.get_nic_netswift() + # 1c8c indicate Corerain + if self.quad[0] == "1c8c": + self.get_nic_corerain() except Exception: self.logger.error( "Get board information failed, please check %s!" % CertEnv.pcifile, terminal_print=False) @@ -303,6 +306,25 @@ class Device: self.board = self._search_info(r'(RP\S*)', ln) break + def get_nic_corerain(self): + """ + get the board model and chip model of netswift card + """ + flag = 0 + for ln in self.file.readlines(): + if flag == 0: + if re.match(self.quad[0], ln): + flag += 1 + elif flag == 1: + if re.match("\t" + self.quad[1], ln): + flag += 1 + self.chip = self._search_info(r'(Corerain\S*)', ln) + else: + if re.match("\t\t" + self.quad[2] + " " + self.quad[3], ln): + self.board = self._search_info(r'(Corerain\S*)', ln) + break + + def get_broadcom_card(self): """ get the board model and chip model of broadcom card diff --git a/tests/aiacc/.keep b/tests/aiacc/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/aiacc/cr_aiacc.py b/tests/aiacc/cr_aiacc.py index e9d580b..9ff37b1 100644 --- a/tests/aiacc/cr_aiacc.py +++ b/tests/aiacc/cr_aiacc.py @@ -47,62 +47,15 @@ class CRAIaccTest(): self.logger.warning( "The driver version information cannot be obtained. Please view it manually.") - - def test_cr_aiacc_driver(self): - """ - Check corerain aiacc utilization by driver, it can execute multi times and has log file - Returns: - bool: - """ - os.chdir("/opt/cr_aiacc/pcie-driver") - cmd = getstatusoutput( - "echo q | ./load | tee %s" % self.cr_aiacc_dirver_log) - if cmd[0] == 0: - self.logger.info("Check corerain aiacc driver succeed.") - else: - self.logger.error("Check corerain aiacc driver failed.") - return False - - return True - - def test_cr_aiacc_DM(self): - """ - AMD gpu test entry function - Returns: - bool: - """ - result = True - self.get_driver_info() - self.command.run_cmd( - "bash %s/test_cr_aiacc.sh install_cr_aiacc_driver" % gpu_dir) - self.command.run_cmd( - "bash %s/test_cr_aiacc.sh install_cr_aiacc_DM" % gpu_dir) - - self.logger.info("Check corerain aiacc driver.") - try: - if not self.test_cr_aiacc_driver(): - result = False - - if not self.test_cr_aiacc_DM(): - result = False - - except Exception as e: - self.logger.error( - "Failed to run the script because compiling or setting variables: %s" % e) - result = False - - return result - def test_cr_aiacc_sample(self): """ - Test screen information for gpu - This test need graphical.target to support + Test screen information for corerain x3a Returns: bool: """ os.chdir("/opt/cr_aiacc/") cmd = self.command.run_cmd( - "./run > $s " % self.cr_aiacc_sample_log) + "./run > %s " % self.cr_aiacc_sample_log) if cmd[2] == 0: self.logger.info("Test corerain aiacc screen information succeed.") else: -- Gitee From 11f65596be7388e9724e72748248ca392b893008 Mon Sep 17 00:00:00 2001 From: renquan Date: Mon, 13 Feb 2023 15:28:05 +0800 Subject: [PATCH 20/23] Update README.md about aiacc test --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1637b4f..555955c 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ oec-hardware-1.1.1 版本将不再进行更新维护,请获取最新版本的 | | https://github.com/NVIDIA/cuda-samples/archive/refs/heads/master.zip | `/opt` | | VGPU | NVIDIA vgpu client驱动软件包 | /root | | | 下载对应版本和架构的虚拟机镜像文件,此处以openEuler 22.03LTS、x86_64为例:https://repo.openeuler.org/openEuler-22.03-LTS/virtual_machine_img/x86_64/openEuler-22.03-LTS-x86_64.qcow2.xz | `/opt` | + | aiacc | Corerain X3A 驱动软件包:https://gitee.com/qren/cr_aiacc/archive/refs/tags/v1.zip | `/opt` | # 工具安装 @@ -454,6 +455,12 @@ oec-hardware-1.1.1 版本将不再进行更新维护,请获取最新版本的 客户端使用发包模式(Tx-only mode)作为数据包源,服务端使用收包模式(Rx-only mode) 作为数据包接收器, 测试端口传输速率功能。 +21. **aiacc** + + - 测试 Corerain X3A aiacc 服务端基本功能。 + - 部署 Corerain X3A aiacc 客户端虚拟机,测试驱动安装,测试客户端 aiacc 功能。 + - aiacc 服务端监控客户端的运行。 + # 社区开发者参与介绍 ## 环境部署 @@ -505,7 +512,7 @@ oec-hardware-1.1.1 版本将不再进行更新维护,请获取最新版本的 # FAQ [鲲鹏小智](https://ic-openlabs.huawei.com/chat/#/) 提供了oec-hardware测试过程中可能遇到的问题的解决方案,用户可以通过检索获取问题的解决方法。另外 [鲲鹏论坛](https://bbs.huaweicloud.com/forum/forum-927-1.html)上提供了完整的[oec-hardware安装使用问题解答](https://bbs.huaweicloud.com/forum/thread-0210979171291590002-1-1.html) ,用户可以根据场景获取解决方案。 - + 如果在适配过程中遇到问题,建议用户优先通过鲲鹏小智或鲲鹏论坛获取支撑。 如果鲲鹏小智无法解决,可在本仓库下提issue反馈或者发邮件至openEuler社区兼容性SIG组邮箱:oecompatibility@openeuler.org。 -- Gitee From 55bf42958c74155035036ecd36ac47a5aa320b32 Mon Sep 17 00:00:00 2001 From: 15945813141 Date: Thu, 2 Mar 2023 10:21:06 +0800 Subject: [PATCH 21/23] update --- README.md | 7 +++++++ docs/design_docs/dev_design.md | 4 ++++ hwcompatible/compatibility.py | 7 +++++++ hwcompatible/constants.py | 4 ++-- hwcompatible/device.py | 7 +++++-- tests/aiacc/aiacc.py | 11 ++++++----- tests/aiacc/cr_aiacc.py | 10 +++------- tests/aiacc/test_cr_aiacc.sh | 36 ++++++++-------------------------- 8 files changed, 42 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 1637b4f..244007c 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ oec-hardware-1.1.1 版本将不再进行更新维护,请获取最新版本的 | | https://github.com/NVIDIA/cuda-samples/archive/refs/heads/master.zip | `/opt` | | VGPU | NVIDIA vgpu client驱动软件包 | /root | | | 下载对应版本和架构的虚拟机镜像文件,此处以openEuler 22.03LTS、x86_64为例:https://repo.openeuler.org/openEuler-22.03-LTS/virtual_machine_img/x86_64/openEuler-22.03-LTS-x86_64.qcow2.xz | `/opt` | + | aiacc | Corerain X3A 驱动软件包:https://gitee.com/qren/cr_aiacc/archive/refs/tags/v1.zip | `/opt` | # 工具安装 @@ -454,6 +455,12 @@ oec-hardware-1.1.1 版本将不再进行更新维护,请获取最新版本的 客户端使用发包模式(Tx-only mode)作为数据包源,服务端使用收包模式(Rx-only mode) 作为数据包接收器, 测试端口传输速率功能。 +21. **aiacc** + + - 测试 Corerain X3A aiacc 服务端基本功能。 + - 部署 Corerain X3A aiacc 客户端虚拟机,测试驱动安装,测试客户端 aiacc 功能。 + - aiacc 服务端监控客户端的运行。 + # 社区开发者参与介绍 ## 环境部署 diff --git a/docs/design_docs/dev_design.md b/docs/design_docs/dev_design.md index 57c7456..b08f6cc 100644 --- a/docs/design_docs/dev_design.md +++ b/docs/design_docs/dev_design.md @@ -91,6 +91,10 @@ | system | policycoreutils | system 测试 | | spdk | spdk | spdk 测试 | | dpdk | dpdk-testpmd | dpdk 测试 | +| aiacc | gcc | aiacc 测试 | +| | g++ | | +| | make | | +| | cmake | | ### 1.3 License diff --git a/hwcompatible/compatibility.py b/hwcompatible/compatibility.py index dbcacf3..2d7e61e 100644 --- a/hwcompatible/compatibility.py +++ b/hwcompatible/compatibility.py @@ -318,6 +318,13 @@ class EulerCertification(): else: sort_devices["fc"] = [device] continue + # Corerain aiacc device + if device.get_property("PCI_ID") == "1C8C:2432": + if "aiacc" in sort_devices.keys(): + sort_devices["aiacc"].extend([device]) + else: + sort_devices["aiacc"] = [device] + continue driver = device.get_property("DRIVER") if any([d in driver for d in GPU_DRIVER]): if "gpu" in sort_devices.keys(): diff --git a/hwcompatible/constants.py b/hwcompatible/constants.py index 43c37f4..f65b0ae 100644 --- a/hwcompatible/constants.py +++ b/hwcompatible/constants.py @@ -34,7 +34,7 @@ KEYCARD_VENDORS = ('Xilinx', 'Renesas', 'Texas', 'PLX') IB = "infiniband" DEVICE_INFO = ('color', 'status', 'num', 'run', 'name', 'device', 'driver', 'version', 'chip', 'board') -NO_CONFIG_DEVICES = ("gpu", "vgpu", "nvme", "dpdk", "cdrom", "keycard", "spdk") +NO_CONFIG_DEVICES = ("gpu", "vgpu", "nvme", "dpdk", "cdrom", "keycard", "spdk", "aiacc") # File access control FILE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_TRUNC @@ -48,4 +48,4 @@ SHELL_ENV = { # Log rotate settings MAX_BYTES = 31457280 -MAX_COUNT = 30 \ No newline at end of file +MAX_COUNT = 30 diff --git a/hwcompatible/device.py b/hwcompatible/device.py index 2f265c6..104302e 100755 --- a/hwcompatible/device.py +++ b/hwcompatible/device.py @@ -145,6 +145,9 @@ class Device: # 8088 indicate Netswift if self.quad[0] == "8088": self.get_nic_netswift() + # 1c8c indicate Corerain + if self.quad[0] == "1c8c": + self.get_nic_netswift() except Exception: self.logger.error( "Get board information failed, please check %s!" % CertEnv.pcifile, terminal_print=False) @@ -297,10 +300,10 @@ class Device: elif flag == 1: if re.match("\t" + self.quad[1], ln): flag += 1 - self.chip = self._search_info(r'(RP\S*)', ln) + self.chip = self._search_info(r'((Corerain|RP)\S*)', ln) else: if re.match("\t\t" + self.quad[2] + " " + self.quad[3], ln): - self.board = self._search_info(r'(RP\S*)', ln) + self.board = self._search_info(r'((Corerain|RP)\S*)', ln) break def get_broadcom_card(self): diff --git a/tests/aiacc/aiacc.py b/tests/aiacc/aiacc.py index 2c5ac54..959d920 100644 --- a/tests/aiacc/aiacc.py +++ b/tests/aiacc/aiacc.py @@ -1,6 +1,6 @@ # coding: utf-8 -# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. +# Copyright (c) 2020-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: @@ -29,10 +29,8 @@ class aiaccTest(Test): """ Initialization before test """ - self.args = args or argparse.Namespace() - self.logger = getattr(args, "test_logger", None) + super().setup(args) self.device = getattr(args, 'device', None) - self.command = Command(self.logger) def test(self): """ @@ -44,8 +42,11 @@ class aiaccTest(Test): driver = self.device.get_driver() if driver == "Corerain DMA": cr_test = CRAIaccTest(self.device, self.logger, self.command) + cr_test.get_driver_info() result = cr_test.test_cr_aiacc_sample() return result - return result + else: + self.logger.info("No driver named Corerain DMA was found ! ", terminal_print=True) + return result diff --git a/tests/aiacc/cr_aiacc.py b/tests/aiacc/cr_aiacc.py index 9ff37b1..5d85719 100644 --- a/tests/aiacc/cr_aiacc.py +++ b/tests/aiacc/cr_aiacc.py @@ -1,6 +1,6 @@ # coding: utf-8 -# Copyright (c) 2020-2022 Huawei Technologies Co., Ltd. +# Copyright (c) 2020-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: @@ -14,10 +14,6 @@ # Desc: Corerain aiacc test. import os -from subprocess import getstatusoutput - -gpu_dir = os.path.dirname(os.path.realpath(__file__)) - class CRAIaccTest(): def __init__(self, device, logger, command): @@ -33,10 +29,10 @@ class CRAIaccTest(): """ Get driver info, includings name, version """ - self.logger.info("Vendor Info:", terminal_print=False) + self.logger.info("Vendor Info:", terminal_print=True) self.command.run_cmd('lspci -vs %s' % self.device.pci) - self.logger.info("Driver Info:", terminal_print=False) + self.logger.info("Driver Info:", terminal_print=True) driver = self.device.driver self.logger.info("Driver Name: %s" % driver) diff --git a/tests/aiacc/test_cr_aiacc.sh b/tests/aiacc/test_cr_aiacc.sh index ce21631..2c98cb3 100644 --- a/tests/aiacc/test_cr_aiacc.sh +++ b/tests/aiacc/test_cr_aiacc.sh @@ -1,5 +1,5 @@ #!/usr/bin/bash -# Copyright (c) 2022 Huawei Technologies Co., Ltd. +# Copyright (c) 2021-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: @@ -12,36 +12,20 @@ # Create: 2023-01-10 # Desc: Shell script used for testing Corerain aiacc -function install_cr_aiacc_driver() { +cr_aiacc_url=https://gitee.com/qren/cr_aiacc.git + +function install_cr_aiacc_sample() { cd /opt res_code=0 if [ ! -d cr_aiacc ]; then - git clone https://gitee.com/qren/cr_aiacc.git + git clone $cr_aiacc_url || return 1 fi cd cr_aiacc/pcie-driver ./compile && ./load &>/dev/null || res_code=1 - - return $res_code -} - -function install_cr_aiacc_DM() { - cd /opt - res_code=0 - if [ ! -d cr_aiacc ]; then - git clone https://gitee.com/qren/cr_aiacc.git - fi + cd - cd cr_aiacc/device-manager ./compile && ./load &>/dev/null || res_code=1 - - return $res_code -} - -function install_cr_aiacc_sample() { - cd /opt - res_code=0 - if [ ! -d cr_aiacc ]; then - git clone https://gitee.com/qren/cr_aiacc.git - fi + cd - cd cr_aiacc ./compile && ./run &>/dev/null || res_code=1 return $res_code @@ -50,11 +34,7 @@ function install_cr_aiacc_sample() { function main() { func_name=$1 - if [[ $func_name == "install_cr_aiacc_driver" ]]; then - install_cr_aiacc_driver - elif [[ $func_name == "install_cr_aiacc_DM" ]]; then - install_cr_aiacc_DM - elif [[ $func_name == "install_cr_aiacc_sample" ]]; then + if [[ $func_name == "install_cr_aiacc_sample" ]]; then install_cr_aiacc_sample else echo "The function doesn't exist, please check!" -- Gitee From 0d4b80e6b8f8ee34e9da4f14b822410131439c1b Mon Sep 17 00:00:00 2001 From: 15945813141 Date: Thu, 2 Mar 2023 10:31:56 +0800 Subject: [PATCH 22/23] update --- tests/aiacc/test_cr_aiacc.sh | 45 ------------------------------------ 1 file changed, 45 deletions(-) delete mode 100644 tests/aiacc/test_cr_aiacc.sh diff --git a/tests/aiacc/test_cr_aiacc.sh b/tests/aiacc/test_cr_aiacc.sh deleted file mode 100644 index 2c98cb3..0000000 --- a/tests/aiacc/test_cr_aiacc.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/bash -# Copyright (c) 2021-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: @quanren -# Create: 2023-01-10 -# Desc: Shell script used for testing Corerain aiacc - -cr_aiacc_url=https://gitee.com/qren/cr_aiacc.git - -function install_cr_aiacc_sample() { - cd /opt - res_code=0 - if [ ! -d cr_aiacc ]; then - git clone $cr_aiacc_url || return 1 - fi - cd cr_aiacc/pcie-driver - ./compile && ./load &>/dev/null || res_code=1 - cd - - cd cr_aiacc/device-manager - ./compile && ./load &>/dev/null || res_code=1 - cd - - cd cr_aiacc - ./compile && ./run &>/dev/null || res_code=1 - return $res_code -} - -function main() { - func_name=$1 - - if [[ $func_name == "install_cr_aiacc_sample" ]]; then - install_cr_aiacc_sample - else - echo "The function doesn't exist, please check!" - return 1 - fi -} - -main "$@" -- Gitee From 855137fd3755052f4209fd5d9826453820711ce8 Mon Sep 17 00:00:00 2001 From: 15945813141 Date: Thu, 2 Mar 2023 11:16:02 +0800 Subject: [PATCH 23/23] update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 244007c..9258d61 100644 --- a/README.md +++ b/README.md @@ -455,7 +455,7 @@ oec-hardware-1.1.1 版本将不再进行更新维护,请获取最新版本的 客户端使用发包模式(Tx-only mode)作为数据包源,服务端使用收包模式(Rx-only mode) 作为数据包接收器, 测试端口传输速率功能。 -21. **aiacc** +23. **aiacc** - 测试 Corerain X3A aiacc 服务端基本功能。 - 部署 Corerain X3A aiacc 客户端虚拟机,测试驱动安装,测试客户端 aiacc 功能。 -- Gitee