diff --git a/oec-hardware-1.1.0-add-cases.patch b/oec-hardware-1.1.0-add-cases.patch new file mode 100644 index 0000000000000000000000000000000000000000..ca9eeeb109b3ab7fd85eef2010c929f806c80d1b --- /dev/null +++ b/oec-hardware-1.1.0-add-cases.patch @@ -0,0 +1,6836 @@ +diff -urN oec-hardware-1.0.0/docs/KABI/KABI_list.md oec-hardware/docs/KABI/KABI_list.md +--- oec-hardware-1.0.0/docs/KABI/KABI_list.md 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/docs/KABI/KABI_list.md 2022-05-31 22:01:38.363872295 +0800 +@@ -0,0 +1,3 @@ ++# KABI Compatibility List For Arm64 ++ ++For details,see [https://gitee.com/openeuler/kernel/tree/kernel-4.19/kabi/2019-V1](https://gitee.com/openeuler/kernel/tree/kernel-4.19/kabi/2019-V1). +\ No newline at end of file +Binary files oec-hardware-1.0.0/docs/test-flow.png and oec-hardware/docs/test-flow.png differ +diff -urN oec-hardware-1.0.0/hwcompatible/client.py oec-hardware/hwcompatible/client.py +--- oec-hardware-1.0.0/hwcompatible/client.py 2022-05-31 22:00:43.440655579 +0800 ++++ oec-hardware/hwcompatible/client.py 2022-05-31 22:01:38.372872494 +0800 +@@ -64,7 +64,6 @@ + 'Accept': 'text/plain' + } + try: +- # print(url) + req = Request(url, data=data, headers=headers) + res = urlopen(req) + if res.code != 200: +@@ -81,3 +80,4 @@ + import sys + file_name = sys.argv[1] + c.upload(file_name) ++ +diff -urN oec-hardware-1.0.0/hwcompatible/command.py oec-hardware/hwcompatible/command.py +--- oec-hardware-1.0.0/hwcompatible/command.py 2022-05-31 22:00:43.440655579 +0800 ++++ oec-hardware/hwcompatible/command.py 2022-05-31 22:01:38.372872494 +0800 +@@ -4,7 +4,7 @@ + # Copyright (c) 2020 Huawei Technologies Co., Ltd. + # oec-hardware is licensed under the Mulan PSL v2. + # You can use this software according to the terms and conditions of the Mulan PSL v2. +-# You may obtain a copy of Mulan PSL v2 at: ++# You may ob tain 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 +@@ -80,7 +80,6 @@ + + if self.errors and len(self.errors) > 0: + self.print_errors() +- # raise CertCommandError(self, "has output on stderr") + + def run_quiet(self): + """quiet after running command""" +@@ -95,7 +94,7 @@ + + def print_output(self): + """ +- 结果显示 ++ Result display + :return: + """ + if self.output: +@@ -106,7 +105,7 @@ + + def print_errors(self): + """ +- 页面显示错误信息 ++ Print error messages on model + :return: + """ + if self.errors: +@@ -117,7 +116,7 @@ + + def pid(self): + """ +- 获取管道pid值 ++ Get pipe pid + :return: + """ + if self.pipe: +@@ -125,7 +124,7 @@ + + def readline(self): + """ +- 按行读取输出信息 ++ Read line to get messages + :return + """ + if self.pipe: +@@ -133,7 +132,7 @@ + + def read(self): + """ +- 执行命令,并读取结果 ++ Execute command and get results + :return: + """ + self.pipe = subprocess.Popen(self.command, shell=True, +@@ -173,28 +172,30 @@ + + # otherwise + raise CertCommandError(self, "no match for regular " +- "expression %s" % self.regex) ++ "expression %s" % self.regex) + + def _get_str_multi_line(self, result, pattern, return_list): +- if self.output: +- for line in self.output: +- if self.regex_group: +- match = pattern.match(line) +- if match: +- if self.regex_group: +- if return_list: +- result.append(match.group(self.regex_group)) +- else: +- return match.group(self.regex_group) ++ if self.output == None: ++ return None ++ ++ for line in self.output: ++ if self.regex_group: ++ match = pattern.match(line) ++ if match and self.regex_group: ++ if return_list: ++ result.append(match.group(self.regex_group)) ++ else: ++ return match.group(self.regex_group) ++ else: ++ # otherwise, return the matching line ++ match = pattern.search(line) ++ if match == None: ++ continue ++ if return_list: ++ result.append(match.group()) + else: +- # otherwise, return the matching line +- match = pattern.search(line) +- if match: +- if return_list: +- result.append(match.group()) +- else: +- return match.group() +- return result ++ return match.group() ++ return result + + def _get_str(self, regex=None, regex_group=None, + single_line=True, return_list=False): +@@ -219,23 +220,19 @@ + + def get_str(self, regex=None, regex_group=None, single_line=True, + return_list=False, ignore_errors=False): +- """获取命令执行结果中匹配的值""" ++ """Get matching value in results""" + result = self._get_str(regex, regex_group, single_line, return_list) + if not ignore_errors: + if self.returncode != 0: + self.print_output() + self.print_errors() + raise CertCommandError(self, "returned %d" % self.returncode) +- +- # if self.errors and len(self.errors) > 0: +- # raise CertCommandError(self, "has output on stderr") +- + return result + + + class CertCommandError(Exception): + """ +- Cert command error handling ++ Cert command error handling + """ + def __init__(self, command, message): + Exception.__init__(self) +@@ -252,3 +249,4 @@ + def _set_message(self, value): + self.__message = value + message = property(_get_message, _set_message) ++ +diff -urN oec-hardware-1.0.0/hwcompatible/commandUI.py oec-hardware/hwcompatible/commandUI.py +--- oec-hardware-1.0.0/hwcompatible/commandUI.py 2022-05-31 22:00:43.441655601 +0800 ++++ oec-hardware/hwcompatible/commandUI.py 2022-05-31 22:01:38.373872516 +0800 +@@ -14,12 +14,13 @@ + + import sys + import readline +- ++from .constants import SAMEASYES, YES, SAMEASNO, NO + + class CommandUI: + """ + Command user interface selection + """ ++ + def __init__(self, echoResponses=False): + self.echo = echoResponses + +@@ -86,10 +87,6 @@ + :param question: + :return: + """ +- YES = "y" +- SAMEASYES = ["y", "yes"] +- NO = "n" +- SAMEASNO = ["n", "no"] + while True: + reply = self.prompt(question, (YES, NO)) + if reply.lower() in SAMEASYES: +@@ -127,3 +124,4 @@ + "following: %s" % " | ".join(choices)) + finally: + readline.set_startup_hook() ++ +diff -urN oec-hardware-1.0.0/hwcompatible/compatibility.py oec-hardware/hwcompatible/compatibility.py +--- oec-hardware-1.0.0/hwcompatible/compatibility.py 2022-05-31 22:00:43.441655601 +0800 ++++ oec-hardware/hwcompatible/compatibility.py 2022-05-31 22:01:38.373872516 +0800 +@@ -27,18 +27,21 @@ + from .job import Job + from .reboot import Reboot + from .client import Client ++from .constants import * + + + class EulerCertification(): + """ + Main program of oec-hardware + """ ++ + def __init__(self): + self.certification = None + self.test_factory = list() + self.devices = None + self.ui = CommandUI() + self.client = None ++ self.dir_name = None + + def run(self): + """ +@@ -59,9 +62,6 @@ + oec_devices = certdevice.get_devices() + self.devices = DeviceDocument(CertEnv.devicefile, oec_devices) + self.devices.save() +- +- # test_factory format example: [{"name":"nvme", "device":device, +- # "run":True, "status":"PASS", "reboot":False}] + test_factory = self.get_tests(oec_devices) + self.update_factory(test_factory) + if not self.choose_tests(): +@@ -99,11 +99,11 @@ + if self.ui.prompt_confirm("Are you sure to clean all " + "compatibility test data?"): + try: +- Command("rm -rf %s" % CertEnv.certificationfile).run() +- Command("rm -rf %s" % CertEnv.factoryfile).run() +- Command("rm -rf %s" % CertEnv.devicefile).run() ++ Command("rm -rf %s" % CertEnv.certificationfile).run_quiet() ++ Command("rm -rf %s" % CertEnv.factoryfile).run_quiet() ++ Command("rm -rf %s" % CertEnv.devicefile).run_quiet() + except Exception as e: +- print(e) ++ print("Clean compatibility test data failed. \n", e) + return False + return True + +@@ -112,9 +112,7 @@ + load certification + :return: + """ +- if not os.path.exists(CertEnv.datadirectory): +- os.mkdir(CertEnv.datadirectory) +- ++ os.makedirs(os.path.dirname(CertEnv.datadirectory), exist_ok=True) + if not self.certification: + self.certification = CertDocument(CertEnv.certificationfile) + if not self.certification.document: +@@ -151,17 +149,18 @@ + + cwd = os.getcwd() + os.chdir(os.path.dirname(doc_dir)) +- dir_name = "oech-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S")\ +- + "-" + job.job_id +- pack_name = dir_name + ".tar" +- cmd = Command("tar -cf %s %s" % (pack_name, dir_name)) ++ self.dir_name = "oech-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S")\ ++ + "-" + job.job_id ++ pack_name = self.dir_name + ".tar" ++ cmd = Command("tar -cf %s %s" % (pack_name, self.dir_name)) + try: +- os.rename(job.job_id, dir_name) +- cmd.run() ++ os.rename(job.job_id, self.dir_name) ++ cmd.run_quiet() + except CertCommandError: +- print("Error:Job log collect failed.") ++ print("Error: Job log collect failed.") + return +- print("Log saved to %s succ." % os.path.join(os.getcwd(), pack_name)) ++ print("Log saved to file: %s succeed." % ++ os.path.join(os.getcwd(), pack_name)) + shutil.copy(pack_name, CertEnv.datadirectory) + for (rootdir, dirs, filenams) in os.walk("./"): + for dirname in dirs: +@@ -216,8 +215,6 @@ + :param devices: + :return: + """ +- nodevice = ["cpufreq", "memory", "clock", "profiler", "system", +- "stress", "kdump", "perf", "acpi", "watchdog"] + sort_devices = self.sort_tests(devices) + empty_device = Device() + test_factory = list() +@@ -233,19 +230,19 @@ + 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[NAME] = testname ++ test[DEVICE] = device ++ test[RUN] = True ++ test[STATUS] = NOTRUN ++ test[REBOOT] = False + test_factory.append(test) +- elif testname in nodevice: ++ elif testname in NODEVICE: + test = dict() +- test["name"] = testname +- test["device"] = empty_device +- test["run"] = True +- test["status"] = "NotRun" +- test["reboot"] = False ++ test[NAME] = testname ++ test[DEVICE] = empty_device ++ test[RUN] = True ++ test[STATUS] = NOTRUN ++ test[REBOOT] = False + test_factory.append(test) + return test_factory + +@@ -258,28 +255,47 @@ + sort_devices = dict() + empty_device = Device() + for device in devices: +- if device.get_property("SUBSYSTEM") == "usb" and \ ++ 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] ++ sort_devices[USB] = [empty_device] + continue + if device.get_property("PCI_CLASS") == "30000" or \ + device.get_property("PCI_CLASS") == "38000": +- sort_devices["video"] = [device] ++ sort_devices[VIDEO] = [device] + continue +- if (device.get_property("DEVTYPE") == "disk" and ++ 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] +- try: +- sort_devices["nvme"].extend([device]) +- except KeyError: +- sort_devices["nvme"] = [device] ++ 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] ++ sort_devices[DISK] = [empty_device] ++ if "RAID" in device.get_property("ID_PCI_SUBCLASS_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 ++ if device.get_property("PCI_CLASS") == "30200" or \ ++ device.get_property("PCI_CLASS") == "120000": ++ if GPU in sort_devices.keys(): ++ sort_devices[GPU].extend([device]) ++ else: ++ sort_devices[GPU] = [device] ++ continue + if device.get_property("SUBSYSTEM") == "net" and \ + device.get_property("INTERFACE"): + interface = device.get_property("INTERFACE") +@@ -288,40 +304,43 @@ + while True: + line = nmcli.readline() + if line: +- if interface in line and "infiniband" in line: +- try: +- sort_devices["infiniband"].extend([device]) +- except KeyError: +- sort_devices["infiniband"] = [device] +- elif interface in line and "ethernet" in line: +- try: +- sort_devices["ethernet"].extend([device]) +- except KeyError: +- sort_devices["ethernet"] = [device] +- elif interface in line and "wifi" in line: +- try: +- sort_devices["wlan"].extend([device]) +- except KeyError: +- sort_devices["wlan"] = [device] ++ 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] + else: + break + continue + if device.get_property("ID_CDROM") == "1": +- types = ["DVD_RW", "DVD_PLUS_RW", "DVD_R", "DVD_PLUS_R", "DVD", +- "BD_RE", "BD_R", "BD", "CD_RW", "CD_R", "CD"] +- for dev_type in types: ++ for dev_type in CDTYPES: + if device.get_property("ID_CDROM_" + dev_type) == "1": +- try: +- sort_devices["cdrom"].extend([device]) +- except KeyError: +- sort_devices["cdrom"] = [device] ++ 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] ++ 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 + try: + Command("dmidecode").get_str("IPMI Device Information", + single_line=False) +- sort_devices["ipmi"] = [empty_device] ++ sort_devices[IPMI] = [empty_device] + except: + pass + +@@ -334,10 +353,10 @@ + """ + while True: + for test in self.test_factory: +- if test["name"] == "system": +- test["run"] = True +- if test["status"] == "PASS": +- test["status"] = "Force" ++ if test[NAME] == SYSTEM: ++ test[RUN] = True ++ if test[STATUS] == PASS: ++ test[STATUS] = FORCE + + os.system("clear") + print("Select tests to run:") +@@ -350,11 +369,11 @@ + return False + if reply in ["n", "none"]: + for test in self.test_factory: +- test["run"] = False ++ test[RUN] = False + continue + if reply in ["a", "all"]: + for test in self.test_factory: +- test["run"] = True ++ test[RUN] = True + continue + + num_lst = reply.split(" ") +@@ -365,8 +384,8 @@ + continue + + if 0 < num <= len(self.test_factory): +- self.test_factory[num - 1]["run"] = not \ +- self.test_factory[num - 1]["run"] ++ self.test_factory[num - 1][RUN] = not \ ++ self.test_factory[num - 1][RUN] + continue + + def show_tests(self): +@@ -375,29 +394,29 @@ + :return: + """ + print("\033[1;35m" + "No.".ljust(4) + "Run-Now?".ljust(10) +- + "Status".ljust(8) + "Class".ljust(14) + "Device\033[0m") ++ + STATUS.ljust(8) + "Class".ljust(14) + "Device\033[0m") + num = 0 + for test in self.test_factory: +- name = test["name"] +- if name == "system": +- test["run"] = True +- if test["status"] == "PASS": +- test["status"] = "Force" ++ name = test[NAME] ++ if name == SYSTEM: ++ test[RUN] = True ++ if test[STATUS] == PASS: ++ test[STATUS] = FORCE + +- status = test["status"] +- device = test["device"].get_name() ++ status = test[STATUS] ++ device = test[DEVICE].get_name() + run = "no" +- if test["run"] is True: ++ if test[RUN] is True: + run = "yes" + + num = num + 1 +- if status == "PASS": ++ if status == PASS: + print("%-6d" % num + run.ljust(8) + "\033[0;32mPASS \033[0m" + + name.ljust(14) + "%s" % device) + elif status == "FAIL": + print("%-6d" % num + run.ljust(8) + "\033[0;31mFAIL \033[0m" + + name.ljust(14) + "%s" % device) +- elif status == "Force": ++ elif status == FORCE: + print("%-6d" % num + run.ljust(8) + "\033[0;33mForce \033[0m" + + name.ljust(14) + "%s" % device) + else: +@@ -410,10 +429,10 @@ + :return: + """ + for test in self.test_factory: +- if test["status"] == "PASS": +- test["run"] = False ++ if test[STATUS] == PASS: ++ test[RUN] = False + else: +- test["run"] = True ++ test[RUN] = True + os.system("clear") + print("These tests are recommended to " + "complete the compatibility test:") +@@ -438,7 +457,7 @@ + if len(self.test_factory) == 0: + return False + for test in self.test_factory: +- if test["status"] != "PASS": ++ if test[STATUS] != PASS: + return False + return True + +@@ -454,14 +473,14 @@ + for test in self.test_factory: + if not self.search_factory(test, test_factory): + self.test_factory.remove(test) +- print("delete %s test %s" % (test["name"], +- test["device"].get_name())) ++ print("delete %s test %s" % (test[NAME], ++ test[DEVICE].get_name())) + for test in test_factory: + if not self.search_factory(test, self.test_factory): + self.test_factory.append(test) +- print("add %s test %s" % (test["name"], +- test["device"].get_name())) +- self.test_factory.sort(key=lambda k: k["name"]) ++ print("add %s test %s" % (test[NAME], ++ test[DEVICE].get_name())) ++ self.test_factory.sort(key=lambda k: k[NAME]) + FactoryDocument(CertEnv.factoryfile, self.test_factory).save() + + def search_factory(self, obj_test, test_factory): +@@ -472,7 +491,7 @@ + :return: + """ + for test in test_factory: +- if test["name"] == obj_test["name"] and \ +- test["device"].path == obj_test["device"].path: ++ if test[NAME] == obj_test[NAME] and \ ++ test[DEVICE].path == obj_test[DEVICE].path: + return True + return False +diff -urN oec-hardware-1.0.0/hwcompatible/constants.py oec-hardware/hwcompatible/constants.py +--- oec-hardware-1.0.0/hwcompatible/constants.py 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/hwcompatible/constants.py 2022-05-31 22:01:38.374872538 +0800 +@@ -0,0 +1,63 @@ ++# -*- encoding=utf-8 -*- ++""" ++# ********************************************************************************** ++# Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. ++# [oecp] is licensed under the Mulan PSL v1. ++# You can use this software according to the terms and conditions of the Mulan PSL v1. ++# You may obtain a copy of Mulan PSL v1 at: ++# http://license.coscl.org.cn/MulanPSL ++# 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 v1 for more details. ++# Author: meitingli ++# Create: 2021-03-01 ++# Description: save constants objects ++# ********************************************************************************** ++""" ++ ++TOTAL_COUNT = 0 ++CURRENT_NUM = 0 ++YES = "y" ++SAMEASYES = ["y", "yes"] ++NO = "n" ++SAMEASNO = ["n", "no"] ++TEST = "test" ++PASS = "PASS" ++FAIL = "FAIL" ++FORCE = "Force" ++RUN = "run" ++NOTRUN = "NotRun" ++ ++OS = "OS" ++KERNEL = "kernel" ++ID = "ID" ++PRODUCTURL = "Product URL" ++SERVER = "server" ++NAME = "name" ++DEVICE = "device" ++STATUS = "status" ++REBOOT = "reboot" ++SYSTEM = "system" ++ ++NODEVICE = ["cpufreq", "memory", "clock", "profiler", "system", ++ "stress", "kdump", "perf", "acpi", "watchdog"] ++CDTYPES = ["DVD_RW", "DVD_PLUS_RW", "DVD_R", "DVD_PLUS_R", "DVD", ++ "BD_RE", "BD_R", "BD", "CD_RW", "CD_R", "CD"] ++SUBSYSTEM = "SUBSYSTEM" ++PCI_CLASS = "PCI_CLASS" ++USB = "usb" ++VIDEO = "video" ++DISK = "disk" ++NVME = "nvme" ++ETHERNET = "ethernet" ++WIFI = "wifi" ++WLAN = "wlan" ++CDROM = "cdrom" ++IPMI = "ipmi" ++FC = "fibrechannel" ++RAID = "raid" ++GPU = "gpu" ++KEYCARD = "keycard" ++KEYCARD_VENDORS = ['Xilinx', 'Renesas', 'Texas', 'PLX'] ++IB = "infiniband" +diff -urN oec-hardware-1.0.0/hwcompatible/device.py oec-hardware/hwcompatible/device.py +--- oec-hardware-1.0.0/hwcompatible/device.py 2022-05-31 22:00:43.442655623 +0800 ++++ oec-hardware/hwcompatible/device.py 2022-05-31 22:01:38.374872538 +0800 +@@ -11,6 +11,7 @@ + # PURPOSE. + # See the Mulan PSL v2 for more details. + # Create: 2020-04-01 ++import re + + from .command import Command + +@@ -38,6 +39,7 @@ + """ + Certified device + """ ++ + def __init__(self): + self.devices = None + +@@ -53,29 +55,26 @@ + properties = dict() + while True: + line = pipe.readline() +- if line: +- if line == "\n": +- if len(properties) > 0: +- device = Device(properties) +- if device.path != "": +- self.devices.append(device) +- properties = dict() +- else: +- prop = line.split(":", 1) +- if len(prop) == 2: +- tp = prop[0].strip('\ \'\n') +- attribute = prop[1].strip('\ \'\n') +- if tp == "E": +- keyvalue = attribute.split("=", 1) +- if len(keyvalue) == 2: +- properties[keyvalue[0]] = keyvalue[1] +- elif tp == "P": +- properties["INFO"] = attribute +- else: ++ if not line: + break ++ if line == "\n" and len(properties) > 0: ++ device = Device(properties) ++ if device.path != "": ++ self.devices.append(device) ++ properties = dict() ++ else: ++ prop = line.split(":", 1) ++ if len(prop) == 2: ++ tp = prop[0].strip('\ \'\n') ++ attribute = prop[1].strip('\ \'\n') ++ if tp == "E": ++ keyvalue = attribute.split("=", 1) ++ if len(keyvalue) == 2: ++ properties[keyvalue[0]] = keyvalue[1] ++ elif tp == "P": ++ properties["INFO"] = attribute + except Exception as e: +- print("Warning: get devices fail") +- print(e) ++ print("Warning: get devices fail.\n", e) + self.devices.sort(key=lambda k: k.path) + return self.devices + +@@ -84,6 +83,7 @@ + """ + get device properties + """ ++ + def __init__(self, properties=None): + self.path = "" + if properties: +@@ -98,10 +98,7 @@ + :param prop: + :return: + """ +- try: +- return self.properties[prop] +- except KeyError: +- return "" ++ return self.properties.get(prop, "") + + def get_name(self): + """ +@@ -112,6 +109,15 @@ + return self.properties["INTERFACE"] + if "DEVNAME" in self.properties.keys(): + return self.properties["DEVNAME"].split("/")[-1] ++ if "ID_PCI_SUBCLASS_FROM_DATABASE" in self.properties.keys() and \ ++ self.properties["ID_PCI_SUBCLASS_FROM_DATABASE"] == "Fibre Channel": ++ return re.search(r'.*\((\S+)', self.properties["ID_MODEL_FROM_DATABASE"]).group(1) ++ if "ID_PCI_SUBCLASS_FROM_DATABASE" in self.properties.keys() and \ ++ self.properties["ID_PCI_SUBCLASS_FROM_DATABASE"] == "RAID bus controller": ++ return '-'.join(self.properties["ID_MODEL_FROM_DATABASE"].split(" ")) ++ if "PCI_CLASS" in self.properties.keys() and \ ++ self.properties["PCI_CLASS"] == "30200": ++ return self.properties["ID_MODEL_FROM_DATABASE"].split(" ")[0] + if self.path: + return self.path.split("/")[-1] + return "" +diff -urN oec-hardware-1.0.0/hwcompatible/document.py oec-hardware/hwcompatible/document.py +--- oec-hardware-1.0.0/hwcompatible/document.py 2022-05-31 22:00:43.442655623 +0800 ++++ oec-hardware/hwcompatible/document.py 2022-05-31 22:01:38.375872561 +0800 +@@ -20,12 +20,14 @@ + from .device import Device + from .sysinfo import SysInfo + from .env import CertEnv ++from .constants import * + + + class Document(): + """ + Read and write documents + """ ++ + def __init__(self, filename, document=''): + self.document = document + self.filename = filename +@@ -40,8 +42,7 @@ + json.dump(self.document, save_f, indent=4) + save_f.close() + except Exception as concrete_error: +- print("Error: doc save fail.") +- print(concrete_error) ++ print("Error: doc save fail.\n", concrete_error) + return False + return True + +@@ -51,17 +52,17 @@ + with open(self.filename, "r") as load_f: + self.document = json.load(load_f) + load_f.close() +- return True + except Exception: + return False ++ return True + + + class CertDocument(Document): + """ + get hardware and release information + """ ++ + def __init__(self, filename, document=''): +- # super(CertDocument, self).__init__(filename, document) + self.document = dict() + self.filename = filename + if not document: +@@ -72,7 +73,6 @@ + def new(self): + """ + new document object +- :return: + """ + try: + pipe = Command("/usr/sbin/dmidecode -t 1") +@@ -80,71 +80,72 @@ + self.document = dict() + while True: + line = pipe.readline() +- if line: +- property_right = line.split(":", 1) +- if len(property_right) == 2: +- key = property_right[0].strip() +- value = property_right[1].strip() +- if key in ["Manufacturer", "Product Name", "Version"]: +- self.document[key] = value +- else: ++ if not line: + break ++ property_right = line.split(":", 1) ++ if len(property_right) != 2: ++ continue ++ key = property_right[0].strip() ++ value = property_right[1].strip() ++ if key in ["Manufacturer", "Product Name", "Version"]: ++ self.document[key] = value + except Exception as concrete_error: +- print("Error: get hardware info fail.") +- print(concrete_error) ++ print("Error: get hardware info fail.\n", concrete_error) + + sysinfo = SysInfo(CertEnv.releasefile) +- self.document["OS"] = sysinfo.product + " " + sysinfo.get_version() +- self.document["kernel"] = sysinfo.kernel +- self.document["ID"] = CommandUI().prompt("Please provide your Compatibility Test ID:") +- self.document["Product URL"] = CommandUI().prompt("Please provide your Product URL:") +- self.document["server"] = CommandUI().prompt("Please provide the Compatibility Test " +- "Server (Hostname or Ipaddr):") ++ self.document[OS] = sysinfo.product + " " + sysinfo.get_version() ++ self.document[KERNEL] = sysinfo.kernel ++ self.document[ID] = CommandUI().prompt( ++ "Please provide your Compatibility Test ID:") ++ self.document[PRODUCTURL] = CommandUI().prompt( ++ "Please provide your Product URL:") ++ self.document[SERVER] = CommandUI().prompt("Please provide the Compatibility Test " ++ "Server (Hostname or Ipaddr):") + + def get_hardware(self): + """ + Get hardware information + """ + return self.document["Manufacturer"] + " " + self.document["Product Name"] + " " \ +- + self.document["Version"] ++ + self.document["Version"] + + def get_os(self): + """ + Get os information + """ +- return self.document["OS"] ++ return self.document[OS] + + def get_server(self): + """ + Get server information + """ +- return self.document["server"] ++ return self.document[SERVER] + + def get_url(self): + """ + Get url + """ +- return self.document["Product URL"] ++ return self.document[PRODUCTURL] + + def get_certify(self): + """ + Get certify + """ +- return self.document["ID"] ++ return self.document[ID] + + def get_kernel(self): + """ + Get kernel information + """ +- return self.document["kernel"] ++ return self.document[KERNEL] + + + class DeviceDocument(Document): + """ + get device document + """ ++ + def __init__(self, filename, devices=''): +- # super(DeviceDocument, self).__init__(filename, devices) + self.filename = filename + self.document = list() + if not devices: +@@ -160,19 +161,18 @@ + """ + + def __init__(self, filename, factory=''): +- # super(FactoryDocument, self).__init__(filename, factory) + self.document = list() + self.filename = filename + if not factory: + self.load() +- else: +- for member in factory: +- element = dict() +- element["name"] = member["name"] +- element["device"] = member["device"].properties +- element["run"] = member["run"] +- element["status"] = member["status"] +- self.document.append(element) ++ return ++ for member in factory: ++ element = dict() ++ element[NAME] = member[NAME] ++ element[DEVICE] = member[DEVICE].properties ++ element[RUN] = member[RUN] ++ element[STATUS] = member[STATUS] ++ self.document.append(element) + + def get_factory(self): + """ +@@ -182,11 +182,11 @@ + factory = list() + for element in self.document: + test = dict() +- device = Device(element["device"]) +- test["device"] = device +- test["name"] = element["name"] +- test["run"] = element["run"] +- test["status"] = element["status"] ++ device = Device(element[DEVICE]) ++ test[DEVICE] = device ++ test[NAME] = element[NAME] ++ test[RUN] = element[RUN] ++ test[STATUS] = element[STATUS] + factory.append(test) + return factory + +@@ -195,6 +195,7 @@ + """ + Get parameters from configuration file + """ ++ + def __init__(self, filename): + self.filename = filename + self.parameters = dict() +@@ -219,12 +220,7 @@ + """ + Get parameter + """ +- if self.parameters: +- try: +- return self.parameters[name] +- except KeyError: +- pass +- return None ++ return self.parameters.get(name, None) + + def dump(self): + """ +@@ -240,12 +236,12 @@ + """ + add parameter + """ +- if not self.getParameter(name): +- self.parameters[name] = value +- self.config.append("%s %s\n" % (name, value)) +- self.save() +- return True +- return False ++ if self.get_parameter(name): ++ return False ++ self.parameters[name] = value ++ self.config.append("%s %s\n" % (name, value)) ++ self.save() ++ return True + + def remove_parameter(self, name): + """ +@@ -253,20 +249,21 @@ + :param name: + :return: + """ +- if self.getParameter(name): +- del self.parameters[name] +- newconfig = list() +- for line in self.config: +- if line.strip() and line.strip()[0] == "#": +- newconfig.append(line) +- continue +- words = line.strip().split(" ") +- if words and words[0] == name: +- continue +- else: +- newconfig.append(line) +- self.config = newconfig +- self.save() ++ if not self.get_parameter(name): ++ return ++ del self.parameters[name] ++ newconfig = list() ++ for line in self.config: ++ if line.strip() and line.strip()[0] == "#": ++ newconfig.append(line) ++ continue ++ words = line.strip().split(" ") ++ if words and words[0] == name: ++ continue ++ else: ++ newconfig.append(line) ++ self.config = newconfig ++ self.save() + + def save(self): + """ +diff -urN oec-hardware-1.0.0/hwcompatible/job.py oec-hardware/hwcompatible/job.py +--- oec-hardware-1.0.0/hwcompatible/job.py 2022-05-31 22:00:43.443655645 +0800 ++++ oec-hardware/hwcompatible/job.py 2022-05-31 22:01:38.376872583 +0800 +@@ -26,12 +26,13 @@ + from .commandUI import CommandUI + from .log import Logger + from .reboot import Reboot +- ++from .constants import * + + class Job(): + """ + Test task management + """ ++ + def __init__(self, args=None): + """ + Creates an instance of Job class. +@@ -43,10 +44,11 @@ + self.args = args or argparse.Namespace() + self.test_factory = getattr(args, "test_factory", []) + self.test_suite = [] +- self.job_id = ''.join(random.sample(string.ascii_letters + string.digits, 10)) ++ self.job_id = ''.join(random.sample( ++ string.ascii_letters + string.digits, 10)) + self.com_ui = CommandUI() + self.subtests_filter = getattr(args, "subtests_filter", None) +- ++ self.logpath = CertEnv.logdirectoy +"/" + self.job_id+"/job.log" + self.test_parameters = None + if "test_parameters" in self.args: + self.test_parameters = {} +@@ -77,18 +79,13 @@ + try: + module = __import__(testname, globals(), locals()) + except Exception as concrete_error: +- print("Error: module import failed for %s" % testname) +- print(concrete_error) ++ print("Error: module import failed for %s" % testname, concrete_error) + return None +- ++ ct = type + for thing in dir(module): + test_class = getattr(module, thing) +- try: +- from types import ClassType as ct +- except ImportError: +- ct = type + if isinstance(test_class, ct) and issubclass(test_class, Test): +- if "test" not in dir(test_class): ++ if TEST not in dir(test_class): + continue + if (subtests_filter and not subtests_filter in dir(test_class)): + continue +@@ -110,23 +107,29 @@ + + self.test_suite = [] + for test in self.test_factory: +- if test["run"]: +- testclass = self.discover(test["name"], subtests_filter) +- if testclass: +- testcase = dict() +- testcase["test"] = testclass +- testcase["name"] = test["name"] +- testcase["device"] = test["device"] +- testcase["status"] = "FAIL" +- self.test_suite.append(testcase) +- else: ++ if test[RUN]: ++ testclass = self.discover(test[NAME], subtests_filter) ++ if not testclass: + if not subtests_filter: +- test["status"] = "FAIL" +- print("not found %s" % test["name"]) ++ test[STATUS] = FAIL ++ print("not found %s" % test[NAME]) ++ continue ++ testcase = dict() ++ testcase[TEST] = testclass ++ testcase[NAME] = test[NAME] ++ testcase[DEVICE] = test[DEVICE] ++ testcase[STATUS] = FAIL ++ self.test_suite.append(testcase) + + if not len(self.test_suite): + print("No test found") + ++ global TOTAL_COUNT ++ global CURRENT_NUM ++ CURRENT_NUM = 0 ++ TOTAL_COUNT = len(self.test_suite) ++ print("There are %s selected test suites." % TOTAL_COUNT) ++ + def check_test_depends(self): + """ + Install dependency packages +@@ -134,21 +137,21 @@ + """ + required_rpms = [] + for tests in self.test_suite: +- for pkg in tests["test"].requirements: ++ for pkg in tests[TEST].requirements: + try: +- Command("rpm -q " + pkg).run_quiet() ++ Command("rpm -q %s &>> %s"%(pkg, self.logpath)).run_quiet() + except CertCommandError: + if not pkg in required_rpms: + required_rpms.append(pkg) + + if len(required_rpms): +- print("Installing required packages: %s" % ", ".join(required_rpms)) ++ print("Installing required packages: %s" % ++ ", ".join(required_rpms)) + try: +- cmd = Command("yum install -y " + " ".join(required_rpms)) ++ cmd = Command("yum install -y %s &>> %s"%(" ".join(required_rpms), self.logpath)) + cmd.echo() + except CertCommandError as concrete_error: +- print(concrete_error) +- print("Fail to install required packages.") ++ print("Fail to install required packages. ", concrete_error) + return False + + return True +@@ -160,25 +163,29 @@ + :param subtests_filter: + :return: + """ +- name = testcase["name"] +- if testcase["device"].get_name(): +- name = testcase["name"] + "-" + testcase["device"].get_name() ++ name = testcase[NAME] ++ if testcase[DEVICE].get_name(): ++ name = testcase[NAME] + "-" + testcase[DEVICE].get_name() + logname = name + ".log" + reboot = None + test = None + logger = None ++ global CURRENT_NUM + try: +- test = testcase["test"] ++ test = testcase[TEST] + logger = Logger(logname, self.job_id, sys.stdout, sys.stderr) + logger.start() + if subtests_filter: + return_code = getattr(test, subtests_filter)() + else: +- print("---- start to run test %s ----" % name) +- args = argparse.Namespace(device=testcase["device"], logdir=logger.log.dir) ++ CURRENT_NUM += 1 ++ print("Start to run %s/%s test suite: %s." % ++ (CURRENT_NUM, TOTAL_COUNT, name)) ++ args = argparse.Namespace( ++ device=testcase[DEVICE], logdir=logger.log.dir, testname=name) + test.setup(args) + if test.reboot: +- reboot = Reboot(testcase["name"], self, test.rebootup) ++ reboot = Reboot(testcase[NAME], self, test.rebootup) + return_code = False + if reboot.setup(): + return_code = test.test() +@@ -193,7 +200,8 @@ + if not subtests_filter: + test.teardown() + logger.stop() +- print("") ++ print("End to run %s/%s test suite: %s." % ++ (CURRENT_NUM, TOTAL_COUNT, name)) + return return_code + + def run_tests(self, subtests_filter=None): +@@ -206,12 +214,12 @@ + print("No test to run.") + return + +- self.test_suite.sort(key=lambda k: k["test"].pri) ++ self.test_suite.sort(key=lambda k: k[TEST].pri) + for testcase in self.test_suite: + if self._run_test(testcase, subtests_filter): +- testcase["status"] = "PASS" ++ testcase[STATUS] = PASS + else: +- testcase["status"] = "FAIL" ++ testcase[STATUS] = FAIL + + def run(self): + """ +@@ -234,17 +242,17 @@ + Command line interface display summary + :return: + """ +- print("------------- Summary -------------") ++ print("----------------- Summary -----------------") + for test in self.test_factory: +- if test["run"]: +- name = test["name"] +- if test["device"].get_name(): +- name = test["name"] + "-" + test["device"].get_name() +- if test["status"] == "PASS": +- print(name.ljust(33) + "\033[0;32mPASS\033[0m") ++ if test[RUN]: ++ name = test[NAME] ++ if test[DEVICE].get_name(): ++ name = test[NAME] + "-" + test[DEVICE].get_name() ++ if test[STATUS] == PASS: ++ print(name.ljust(40) + "\033[0;32mPASS\033[0m") + else: +- print(name.ljust(33) + "\033[0;31mFAIL\033[0m") +- print("") ++ print(name.ljust(40) + "\033[0;31mFAIL\033[0m") ++ print("\n") + + def save_result(self): + """ +@@ -253,6 +261,6 @@ + """ + for test in self.test_factory: + for testcase in self.test_suite: +- if test["name"] == testcase["name"] and test["device"].path == \ +- testcase["device"].path: +- test["status"] = testcase["status"] ++ if test[NAME] == testcase[NAME] and test[DEVICE].path == \ ++ testcase[DEVICE].path: ++ test[STATUS] = testcase[STATUS] +diff -urN oec-hardware-1.0.0/hwcompatible/log.py oec-hardware/hwcompatible/log.py +--- oec-hardware-1.0.0/hwcompatible/log.py 2022-05-31 22:00:43.443655645 +0800 ++++ oec-hardware/hwcompatible/log.py 2022-05-31 22:01:38.377872605 +0800 +@@ -25,6 +25,7 @@ + """ + Read and write log + """ ++ + def __init__(self, logname='oech.log', logdir='__temp__'): + if not logdir: + curtime = datetime.datetime.now().isoformat() +@@ -72,6 +73,7 @@ + """ + Output results to file + """ ++ + def __init__(self, logname, logdir, out, err): + self.log = Log(logname, logdir) + self.stdout = out +diff -urN oec-hardware-1.0.0/hwcompatible/reboot.py oec-hardware/hwcompatible/reboot.py +--- oec-hardware-1.0.0/hwcompatible/reboot.py 2022-05-31 22:00:43.444655667 +0800 ++++ oec-hardware/hwcompatible/reboot.py 2022-05-31 22:01:38.377872605 +0800 +@@ -15,17 +15,18 @@ + """Special for restart tasks, so that the test can be continued after the machine is restarted""" + + import datetime +-import os + + from .document import Document, FactoryDocument + from .env import CertEnv + from .command import Command, CertCommandError ++from .constants import * + + + class Reboot: + """ + Special for restart tasks, so that the test can be continued after the machine is restarted + """ ++ + def __init__(self, testname, job, rebootup): + self.testname = testname + self.rebootup = rebootup +@@ -41,8 +42,8 @@ + return + + for test in self.job.test_factory: +- if test["run"] and self.testname == test["name"]: +- test["reboot"] = False ++ if test[RUN] and self.testname == test[NAME]: ++ test[REBOOT] = False + + Command("rm -rf %s" % CertEnv.rebootfile).run(ignore_errors=True) + Command("systemctl disable oech").run(ignore_errors=True) +@@ -58,16 +59,16 @@ + + self.job.save_result() + for test in self.job.test_factory: +- if test["run"] and self.testname == test["name"]: +- test["reboot"] = True +- test["status"] = "FAIL" ++ if test[RUN] and self.testname == test[NAME]: ++ test[REBOOT] = True ++ test[STATUS] = FAIL + if not FactoryDocument(CertEnv.factoryfile, self.job.test_factory).save(): + print("Error: save testfactory doc fail before reboot.") + return False + + self.reboot["job_id"] = self.job.job_id + self.reboot["time"] = datetime.datetime.now().strftime("%Y%m%d%H%M%S") +- self.reboot["test"] = self.testname ++ self.reboot[TEST] = self.testname + self.reboot["rebootup"] = self.rebootup + if not Document(CertEnv.rebootfile, self.reboot).save(): + print("Error: save reboot doc fail.") +@@ -88,19 +89,18 @@ + :return: + """ + doc = Document(CertEnv.rebootfile) +- if os.path.exists(CertEnv.rebootfile): +- if not doc.load(): +- print("Error: reboot111 file load fail.") +- return False +- else: ++ if not doc.load(): ++ print("Error: reboot file load fail.") + return False +- ++ + try: +- self.testname = doc.document["test"] ++ self.testname = doc.document[TEST] + self.reboot = doc.document + self.job.job_id = self.reboot["job_id"] ++ self.job.logpath = CertEnv.logdirectoy + "/" + self.job.job_id + "/job.log" + self.job.subtests_filter = self.reboot["rebootup"] +- time_reboot = datetime.datetime.strptime(self.reboot["time"], "%Y%m%d%H%M%S") ++ time_reboot = datetime.datetime.strptime( ++ self.reboot["time"], "%Y%m%d%H%M%S") + except Exception: + print("Error: reboot file format not as expect.") + return False +@@ -108,7 +108,8 @@ + time_now = datetime.datetime.now() + time_delta = (time_now - time_reboot).seconds + cmd = Command("last reboot -s '%s seconds ago'" % time_delta) +- reboot_list = cmd.get_str("^reboot .*$", single_line=False, return_list=True) ++ reboot_list = cmd.get_str( ++ "^reboot .*$", single_line=False, return_list=True) + if len(reboot_list) != 1: + print("Errot:reboot times check fail.") + return False +diff -urN oec-hardware-1.0.0/hwcompatible/test.py oec-hardware/hwcompatible/test.py +--- oec-hardware-1.0.0/hwcompatible/test.py 2022-05-31 22:00:43.445655689 +0800 ++++ oec-hardware/hwcompatible/test.py 2022-05-31 22:01:38.378872627 +0800 +@@ -11,9 +11,7 @@ + # PURPOSE. + # See the Mulan PSL v2 for more details. + # Create: 2020-04-01 +- +-"""Test set template""" +- ++# Desc: Test template + + class Test: + """ +Binary files oec-hardware-1.0.0/oec-hardware-1.1.0.tar.bz2 and oec-hardware/oec-hardware-1.1.0.tar.bz2 differ +diff -urN oec-hardware-1.0.0/oec-hardware.spec oec-hardware/oec-hardware.spec +--- oec-hardware-1.0.0/oec-hardware.spec 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/oec-hardware.spec 2022-05-31 22:01:38.441874023 +0800 +@@ -0,0 +1,91 @@ ++%define version 1.1.0 ++%define release 0 ++%define debug_package %{nil} ++%global _build_id_links none ++%undefine __brp_mangle_shebangs ++ ++Name: oec-hardware ++Summary: openEuler Hardware Compatibility Test Suite ++Version: %{version} ++Release: %{release} ++Group: Development/Tools ++License: Mulan PSL v2 ++URL: https://gitee.com/openeuler/oec-hardware ++Source0: %{name}-%{version}.tar.bz2 ++ ++Buildroot: %{_tmppath}/%{name}-%{version}-root ++BuildRequires: gcc ++Requires: kernel-devel, kernel-headers, dmidecode, tar ++Requires: qperf, fio, memtester ++Requires: kernel >= 4 ++Requires: python3 ++ ++# server subpackage ++%package server ++Summary: openEuler Hardware Compatibility Test Server ++Group: Development/Tools ++Requires: python3, python3-devel, nginx, tar, qperf, psmisc ++ ++%description ++openEuler Hardware Compatibility Test Suite ++ ++%description server ++openEuler Hardware Compatibility Test Server ++ ++%prep ++%setup -q -c ++ ++%build ++[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT; ++DESTDIR=$RPM_BUILD_ROOT VERSION_RELEASE=%{version} make ++ ++%install ++DESTDIR=$RPM_BUILD_ROOT make install ++ ++%clean ++[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT; ++ ++%pre ++ ++%post ++ ++%files ++%defattr(-,root,root) ++/usr/bin/oech ++/usr/share/oech/kernelrelease.json ++/usr/share/oech/lib/hwcompatible ++/usr/share/oech/lib/tests ++/usr/lib/systemd/system/oech.service ++%dir /var/oech ++%dir /usr/share/oech/lib ++%dir /usr/share/oech ++ ++%files server ++%defattr(-,root,root) ++/usr/share/oech/lib/server ++/usr/share/oech/lib/server/uwsgi.ini ++/usr/share/oech/lib/server/uwsgi.conf ++/usr/lib/systemd/system/oech-server.service ++ ++%postun ++rm -rf /var/lock/oech.lock ++ ++%changelog ++* Mon May 30 2022 meitingli <244349477@qq.com> - 1.1.0-0 ++- 1. Add support os version: openEuler 22.03LTS ++- 2. Add FC/RAID/keycard/GPU/infiniband testcases ++- 3. Bugfix ++ ++* Thu Sep 09 2021 Cui XuCui - 1.0.0-8 ++* Thu Jul 15 2021 zhangzikang - 1.0.0-7 ++- Fix cdrom and cpufreq test failed ++ ++* Fri Mar 19 2021 caodongxia - 1.0.0-6 ++* Tue Sep 29 2020 Cui XuCui - 1.0.0-5 ++* Fri Jul 24 2020 Cui XuCui - 1.0.0-4 ++* Sun Jul 18 2020 Cui XuCui - 1.0.0-3 ++* Sun Jul 01 2020 Cui XuCui - 1.0.0-2 ++* Fri Jul 26 2019 Lu Tianxiong - 1.0.0-h1 ++- Initial spec ++ ++ +diff -urN oec-hardware-1.0.0/README.md oec-hardware/README.md +--- oec-hardware-1.0.0/README.md 2022-05-31 22:00:43.445655689 +0800 ++++ oec-hardware/README.md 2022-05-31 22:01:38.363872295 +0800 +@@ -39,7 +39,7 @@ + + 1. 为满足可信要求,必须使用openEuler操作系统,不能随意重编/插入内核模块。 + 2. 通过扫描机制自适应发现硬件列表,来确定要运行的测试用例集合。 +-3. 面向对象抽象各种硬件类型以及测试用例类,用于扩展开发。 ++3. 面向对象抽象各种硬件类型以及测试用例类,用于扩展开发。 + + ## 原理简介 + +@@ -106,13 +106,7 @@ + + ### 客户端 + +-1. 安装 memtester 依赖工具。 +- +- ``` +- dnf install memtester-4.3.0-18.fc33.aarch64(x86_64).rpm +- ``` +- +-2. 配置 [openEuler 官方 repo](https://repo.openeuler.org/) 中对应版本的 everything 源,使用 `dnf` 安装客户端 oec-hardware。 ++1. 配置 [openEuler 官方 repo](https://repo.openeuler.org/) 中对应版本的 everything 源,使用 `dnf` 安装客户端 oec-hardware。 + + ``` + dnf install oec-hardware-XXX.rpm +@@ -158,7 +152,7 @@ + + * `/usr/share/oech/kernelrelease.json` 文件中列出了当前支持的所有系统版本,使用`uname -a` 命令确认当前系统内核版本是否属于框架支持的版本。 + +-* 框架默认会扫描所有网卡,对网卡进行测试前,请自行筛选被测网卡,并给它配上能 `ping` 通服务端的 ip;如果客户端是对 InfiniBand 网卡进行测试,服务端也必须有一个 InfiniBand 网卡并提前配好 ip 。 ++* 框架默认会扫描所有网卡,对网卡进行测试前,请自行筛选被测网卡,并给它配上能 `ping` 通服务端的 ip;如果客户端是对 InfiniBand 网卡进行测试,服务端也必须有一个 InfiniBand 网卡并提前配好 ip 。建议不要使用业务网口进行网卡测试。 + + ## 使用步骤 + +@@ -257,6 +251,17 @@ + + 在 **Result** 列展示测试结果,结果有两种:**PASS** 或者 **FAIL**。如果结果为**FAIL**,可以直接点击结果来查看执行日志,根据报错对照用例代码进行排查。 + ++ ++## 测试结果审核 ++ ++如果测试的硬件、整机需要发布到openEuler的兼容性清单,请将以下测试结果全部上传至相关的适配issue下: ++ ++ - oech测试日志 ++ ++ - oech生成的html测试报告 ++ ++ - 兼容性清单文件(请参考templates目录下的模板) ++ + # 附录:测试项说明 + + ## 已有测试项 +@@ -290,7 +295,7 @@ + + - 使用 ethtool 获取网卡信息和 ifconfig 对网卡进行 down/up 测试。 + - 使用 qperf 测试以太网卡tcp/udp延迟和带宽,以及 http 上传、下载速率。 +- - 使用 perftest 测试 InfiniBand 或 RoCE 网卡延迟和带宽。 ++ - 使用 perftest 测试 infiniband(IB) 或 RoCE 网络协议的延迟和带宽。 + - **注意** 进行网络带宽测试时,请提前确认服务端网卡速率不小于客户端,并保证测试网络无其他流量干扰。 + + 6. **disk** +@@ -328,12 +333,36 @@ + 14. **acpi** + + 利用 acpidump 工具读取数据。 ++ ++15. **FC** ++ ++ 使用 fio 工具进行FC存储服务器的顺序/随机读写测试。 ++ ++16. **RAID** ++ ++ 使用 fio 工具进行RAID下硬盘的顺序/随机读写测试。 ++ ++17. **keycard** ++ ++ 测试加密卡是否能正常使用。 ++ ++18. **GPU** ++ ++ - 使用gpu_burn工具对GPU进行加压测试。 ++ - 使用cuda_samples测试GPU是否能正常使用。 ++ ++19. **infiniband** ++ ++ - 使用 ethtool 获取网卡信息。 ++ - 使用 perftest 测试 infiniband(IB) 网络协议的延迟和带宽。 ++ - **注意** 进行网络带宽测试时,请提前确认服务端网卡速率不小于客户端,并保证测试网络无其他流量干扰。 ++ + + ## 新增测试项 + +-1. 在 `tests/` 添加自己的测试模板,实现自己的测试类继承框架 `Test`。 ++1. 在 `tests/` 目录下添加测试项模板,通过继承框架 `Test` 实现自己的测试类。 + +-2. 重要成员变量或函数。 ++2. 测试类中的重要成员变量或函数介绍: + + - 函数 `test` - **必选**,测试主流程。 + +@@ -344,3 +373,5 @@ + - 变量 `requirements` - 以数组形式存放测试依赖的 rpm 包名,测试开始前框架自动安装。 + + - 变量 `reboot` 和 `rebootup` - 若 `reboot = True` 表示该测试套/测试用例会重启系统,且在重启后继续执行 `rebootup` 指定的函数,可以参考 kdump 测试。 ++ ++3. 在 `hwcompatible/compatibility.py` 文件中添加对应测试项的识别显示。 +\ No newline at end of file +diff -urN oec-hardware-1.0.0/scripts/kernelrelease.json oec-hardware/scripts/kernelrelease.json +--- oec-hardware-1.0.0/scripts/kernelrelease.json 2020-07-01 21:00:19.000000000 +0800 ++++ oec-hardware/scripts/kernelrelease.json 2022-05-31 22:01:38.383872738 +0800 +@@ -1,4 +1,8 @@ + { + "EulerOS 2.0 (SP8)": "4.19.36", +- "openEuler 20.03 (LTS)": "4.19.90" ++ "openEuler 20.03 (LTS)": "4.19.90", ++ "openEuler 20.03 (LTS-SP1)": "4.19.90", ++ "openEuler 20.03 (LTS-SP2)": "4.19.90", ++ "openEuler 20.03 (LTS-SP3)": "4.19.90", ++ "openEuler 22.03 LTS": "5.10.0" + } +diff -urN oec-hardware-1.0.0/scripts/oech-server.service oec-hardware/scripts/oech-server.service +--- oec-hardware-1.0.0/scripts/oech-server.service 2022-05-31 22:00:43.446655712 +0800 ++++ oec-hardware/scripts/oech-server.service 2022-05-31 22:01:38.384872760 +0800 +@@ -8,6 +8,5 @@ + ExecStart=/usr/local/bin/uwsgi --ini /usr/share/oech/lib/server/uwsgi.ini + ExecStop=/usr/local/bin/uwsgi --stop /usr/share/oech/lib/server/uwsgi.pid + +- + [Install] + WantedBy=multi-user.target +diff -urN oec-hardware-1.0.0/server/uwsgi.ini oec-hardware/server/uwsgi.ini +--- oec-hardware-1.0.0/server/uwsgi.ini 2022-05-31 22:00:43.447655734 +0800 ++++ oec-hardware/server/uwsgi.ini 2022-05-31 22:01:38.394872981 +0800 +@@ -6,6 +6,4 @@ + processes = 4 + pidfile = /usr/share/oech/lib/server/uwsgi.pid + master = true +-buffer-size = 65536 +- +- ++buffer-size = 65536 +\ No newline at end of file +Binary files oec-hardware-1.0.0/templates/整机兼容性发布信息模板.xlsx and oec-hardware/templates/整机兼容性发布信息模板.xlsx differ +Binary files oec-hardware-1.0.0/templates/板卡兼容性发布清单模板.xlsx and oec-hardware/templates/板卡兼容性发布清单模板.xlsx differ +diff -urN oec-hardware-1.0.0/tests/acpi/acpi.py oec-hardware/tests/acpi/acpi.py +--- oec-hardware-1.0.0/tests/acpi/acpi.py 2022-05-31 22:00:43.447655734 +0800 ++++ oec-hardware/tests/acpi/acpi.py 2022-05-31 22:01:38.429873757 +0800 +@@ -13,7 +13,7 @@ + # Create: 2020-04-01 + + """acpi test""" +- ++import subprocess + from hwcompatible.test import Test + from hwcompatible.command import Command + +@@ -22,17 +22,34 @@ + """ + acpi test + """ ++ + def __init__(self): + Test.__init__(self) + self.requirements = ["acpica-tools"] ++ self.logpath = None ++ ++ def setup(self, args=None): ++ """ ++ Initialization before test ++ :param args: ++ :return: ++ """ ++ self.args = args or argparse.Namespace() ++ self.logpath = getattr(args, "logdir", None) + "/acpi.log" + + def test(self): + """ + start test + """ + try: +- Command("acpidump").echo() +- return True ++ result = subprocess.getstatusoutput( ++ "acpidump &> %s" % self.logpath) ++ if result[0] == 0: ++ print("Test acpi succeed.") ++ return True ++ ++ print("Test acpi failed.") ++ return False + except Exception as concrete_error: +- print(concrete_error) ++ print("Test acpi failed.\n %s" % concrete_error) + return False +diff -urN oec-hardware-1.0.0/tests/cdrom/cdrom.py oec-hardware/tests/cdrom/cdrom.py +--- oec-hardware-1.0.0/tests/cdrom/cdrom.py 2022-05-31 22:00:43.448655756 +0800 ++++ oec-hardware/tests/cdrom/cdrom.py 2022-05-31 22:01:38.430873779 +0800 +@@ -102,7 +102,7 @@ + if device.get_property("ID_CDROM_" + cd_type) == "1": + return cd_type + +- print("Can not find pr)oper test-type for %s." % device.get_name()) ++ print("Can not find proper test-type for %s." % device.get_name()) + return None + + def get_mode(self, device_type): +diff -urN oec-hardware-1.0.0/tests/clock/clock.py oec-hardware/tests/clock/clock.py +--- oec-hardware-1.0.0/tests/clock/clock.py 2022-05-31 22:00:43.448655756 +0800 ++++ oec-hardware/tests/clock/clock.py 2022-05-31 22:01:38.432873823 +0800 +@@ -15,7 +15,7 @@ + """clock test""" + + import os +- ++import subprocess + from hwcompatible.command import Command, CertCommandError + from hwcompatible.test import Test + +@@ -26,16 +26,36 @@ + """ + Clock Test + """ ++ ++ def __init__(self): ++ Test.__init__(self) ++ self.logpath = None ++ ++ def setup(self, args=None): ++ """ ++ Initialization before test ++ :param args: ++ :return: ++ """ ++ self.args = args or argparse.Namespace() ++ self.logpath = getattr(args, "logdir", None) + "/clock.log" ++ + def test(self): + """ + Clock test case + :return: + """ + try: +- Command("cd %s; ./clock" % clock_dir).echo() +- return True ++ result = subprocess.getstatusoutput( ++ "cd %s; ./clock &>> %s" % (clock_dir, self.logpath)) ++ if result[0] == 0: ++ print("Test clock succeed.") ++ return True ++ ++ print("Test clock failed.") ++ return False + except CertCommandError as concrete_error: +- print(concrete_error) ++ print("Test clock failed.\n %s" % concrete_error) + return False + + +diff -urN oec-hardware-1.0.0/tests/cpufreq/cpufreq.py.orig oec-hardware/tests/cpufreq/cpufreq.py.orig +--- oec-hardware-1.0.0/tests/cpufreq/cpufreq.py.orig 2022-05-31 22:00:43.450655800 +0800 ++++ oec-hardware/tests/cpufreq/cpufreq.py.orig 1970-01-01 08:00:00.000000000 +0800 +@@ -1,466 +0,0 @@ +-#!/usr/bin/env python +-# coding: utf-8 +- +-# Copyright (c) 2020 Huawei Technologies Co., Ltd. +-# oec-hardware is licensed under the Mulan PSL v2. +-# You can use this software according to the terms and conditions of the Mulan PSL v2. +-# You may obtain a copy of Mulan PSL v2 at: +-# http://license.coscl.org.cn/MulanPSL2 +-# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +-# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +-# PURPOSE. +-# See the Mulan PSL v2 for more details. +-# Create: 2020-04-01 +- +-"""cpufreq test""" +- +-from random import randint +-from time import sleep +- +-from hwcompatible.env import CertEnv +-from hwcompatible.test import Test +-from hwcompatible.command import Command +- +- +-class CPU: +- """ +- cpufreq test +- """ +- def __init__(self): +- self.cpu = None +- self.nums = None +- self.list = None +- self.numa_nodes = None +- self.governors = None +- self.original_governor = None +- self.max_freq = None +- self.min_freq = None +- +- def get_info(self): +- """ +- Get CPU info +- :return: +- """ +- cmd = Command("lscpu") +- try: +- nums = cmd.get_str(r'^CPU\S*:\s+(?P\d+)$', 'cpus', False) +- except Exception as concrete_error: +- print(concrete_error) +- return False +- self.nums = int(nums) +- self.list = range(self.nums) +- +- cmd = Command("cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq") +- try: +- max_freq = cmd.get_str() +- except Exception as concrete_error: +- print(concrete_error) +- return False +- self.max_freq = int(max_freq) +- +- cmd = Command("cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq") +- try: +- min_freq = cmd.get_str() +- except Exception as concrete_error: +- print(concrete_error) +- return False +- self.min_freq = int(min_freq) +- +- return True +- +- def set_freq(self, freq, cpu='all'): +- """ +- Set CPU frequency +- :param freq: +- :param cpu: +- :return: +- """ +- cmd = Command("cpupower -c %s frequency-set --freq %s" % (cpu, freq)) +- try: +- cmd.run() +- return cmd.returncode +- except Exception as concrete_error: +- print(concrete_error) +- return False +- +- def get_freq(self, cpu): +- """ +- Get CPU frequency +- :param cpu: +- :return: +- """ +- cmd = Command("cpupower -c %s frequency-info -w" % cpu) +- try: +- return int(cmd.get_str(r'.* frequency: (?P\d+) .*', 'freq', False)) +- except Exception as concrete_error: +- print(concrete_error) +- return False +- +- def set_governor(self, governor, cpu='all'): +- """ +- Set the frequency governor mode of CPU +- :param governor: +- :param cpu: +- :return: +- """ +- cmd = Command("cpupower -c %s frequency-set --governor %s" % (cpu, governor)) +- try: +- cmd.run() +- return cmd.returncode +- except Exception as concrete_error: +- print(concrete_error) +- return False +- +- def get_governor(self, cpu): +- """ +- Get cpu governor +- :param cpu: +- :return: +- """ +- cmd = Command("cpupower -c %s frequency-info -p" % cpu) +- try: +- return cmd.get_str(r'.* governor "(?P\w+)".*', 'governor', False) +- except Exception as concrete_error: +- print(concrete_error) +- return False +- +- def find_path(self, parent_dir, target_name): +- """ +- Find the target path from the specified directory +- :param parent_dir: +- :param target_name: +- :return: +- """ +- cmd = Command("find %s -name %s" % (parent_dir, target_name)) +- try: +- cmd.run() +- return cmd.returncode +- except Exception as concrete_error: +- print(concrete_error) +- return False +- +- +-class Load: +- """ +- Let a program run on a specific CPU +- """ +- def __init__(self, cpu): +- self.cpu = cpu +- self.process = Command("taskset -c {} python -u {}/cpufreq/cal.py".\ +- format(self.cpu, CertEnv.testdirectoy)) +- self.returncode = None +- +- def run(self): +- """ +- Process started +- :return: +- """ +- self.process.start() # background +- +- def get_runtime(self): +- """ +- Get the running time of the process +- :return: +- """ +- if not self.process: +- return None +- +- while self.returncode is None: +- self.returncode = self.process.poll() +- if self.returncode == 0: +- line = self.process.readline() +- return float(line) +- else: +- return False +- +- +-class CPUFreqTest(Test): +- """ +- CPU frequency test +- """ +- def __init__(self): +- Test.__init__(self) +- self.requirements = ['util-linux', 'kernel-tools'] +- self.cpu = CPU() +- self.original_governor = self.cpu.get_governor(0) +- +- def test_userspace(self): +- """ +- userspace mode of testing CPU frequency +- :return: +- """ +- target_cpu = randint(0, self.cpu.nums-1) +- target_freq = randint(self.cpu.min_freq, self.cpu.max_freq) +- if self.cpu.set_freq(target_freq, cpu=target_cpu) != 0: +- print("[X] Set CPU%s to freq %d failed." % (target_cpu, target_freq)) +- return False +- print("[.] Set CPU%s to freq %d." % (target_cpu, target_freq)) +- target_cpu_freq = self.cpu.get_freq(target_cpu) +- print("[.] Current freq of CPU%s is %d." % (target_cpu, target_cpu_freq)) +- +- target_cpu_governor = self.cpu.get_governor(target_cpu) +- if target_cpu_governor != 'userspace': +- print("[X] The governor of CPU%s(%s) is not userspace." % +- (target_cpu, target_cpu_governor)) +- return False +- print("[.] The governor of CPU%s is %s." % +- (target_cpu, target_cpu_governor)) +- +- # min_freq -> max_runtime +- self.cpu.set_freq(self.cpu.min_freq) +- load_list = [] +- runtime_list = [] +- for cpu in self.cpu.list: +- load_test = Load(cpu) +- load_test.run() +- load_list.append(load_test) +- for cpu in self.cpu.list: +- runtime = load_list[cpu].get_runtime() +- runtime_list.append(runtime) +- max_average_runtime = 1.0 * sum(runtime_list) / len(runtime_list) +- if max_average_runtime == 0: +- print("[X] Max average time is 0.") +- return False +- print("[.] Max average time of all CPUs userspace load test: %.2f" % +- max_average_runtime) +- +- # max_freq -> min_runtime +- self.cpu.set_freq(self.cpu.max_freq) +- load_list = [] +- runtime_list = [] +- for cpu in self.cpu.list: +- load_test = Load(cpu) +- load_test.run() +- load_list.append(load_test) +- for cpu in self.cpu.list: +- runtime = load_list[cpu].get_runtime() +- runtime_list.append(runtime) +- min_average_runtime = 1.0 * sum(runtime_list) / len(runtime_list) +- if min_average_runtime == 0: +- print("[X] Min average time is 0.") +- return False +- print("[.] Min average time of all CPUs userspace load test: %.2f" % +- min_average_runtime) +- +- measured_speedup = 1.0 * max_average_runtime / min_average_runtime +- expected_speedup = 1.0 * self.cpu.max_freq / self.cpu.min_freq +- tolerance = 1.0 +- min_speedup = expected_speedup - (expected_speedup - 1.0) * tolerance +- max_speedup = expected_speedup + (expected_speedup - 1.0) * tolerance +- if not min_speedup < measured_speedup < max_speedup: +- print("[X] The speedup(%.2f) is not between %.2f and %.2f" % +- (measured_speedup, min_speedup, max_speedup)) +- return False +- print("[.] The speedup(%.2f) is between %.2f and %.2f" % +- (measured_speedup, min_speedup, max_speedup)) +- +- return True +- +- def test_ondemand(self): +- """ +- ondemand mode of testing CPU frequency +- :return: +- """ +- if self.cpu.set_governor('powersave') != 0: +- print("[X] Set governor of all CPUs to powersave failed.") +- return False +- print("[.] Set governor of all CPUs to powersave.") +- +- if self.cpu.set_governor('ondemand') != 0: +- print("[X] Set governor of all CPUs to ondemand failed.") +- return False +- print("[.] Set governor of all CPUs to ondemand.") +- +- target_cpu = randint(0, self.cpu.nums) +- target_cpu_governor = self.cpu.get_governor(target_cpu) +- if target_cpu_governor != 'ondemand': +- print("[X] The governor of CPU%s(%s) is not ondemand." % +- (target_cpu, target_cpu_governor)) +- return False +- print("[.] The governor of CPU%s is %s." % +- (target_cpu, target_cpu_governor)) +- +- load_test = Load(target_cpu) +- load_test.run() +- sleep(1) +- target_cpu_freq = self.cpu.get_freq(target_cpu) +- if target_cpu_freq != self.cpu.max_freq: +- print("[X] The freq of CPU%s(%d) is not scaling_max_freq(%d)." % +- (target_cpu, target_cpu_freq, self.cpu.max_freq)) +- return False +- print("[.] The freq of CPU%s is scaling_max_freq(%d)." % +- (target_cpu, target_cpu_freq)) +- +- load_test_time = load_test.get_runtime() +- print("[.] Time of CPU%s ondemand load test: %.2f" % +- (target_cpu, load_test_time)) +- target_cpu_freq = self.cpu.get_freq(target_cpu) +- if not target_cpu_freq <= self.cpu.max_freq: +- print("[X] The freq of CPU%s(%d) is not less equal than %d." % +- (target_cpu, target_cpu_freq, self.cpu.max_freq)) +- return False +- print("[.] The freq of CPU%s(%d) is less equal than %d." % +- (target_cpu, target_cpu_freq, self.cpu.max_freq)) +- +- return True +- +- def test_conservative(self): +- """ +- conservative mode of testing CPU frequency +- :return: +- """ +- if self.cpu.set_governor('powersave') != 0: +- print("[X] Set governor of all CPUs to powersave failed.") +- return False +- print("[.] Set governor of all CPUs to powersave.") +- +- if self.cpu.set_governor('conservative') != 0: +- print("[X] Set governor of all CPUs to conservative failed.") +- return False +- print("[.] Set governor of all CPUs to conservative.") +- +- target_cpu = randint(0, self.cpu.nums) +- target_cpu_governor = self.cpu.get_governor(target_cpu) +- if target_cpu_governor != 'conservative': +- print("[X] The governor of CPU%s(%s) is not conservative." % +- (target_cpu, target_cpu_governor)) +- return False +- print("[.] The governor of CPU%s is %s." % +- (target_cpu, target_cpu_governor)) +- +- load_test = Load(target_cpu) +- load_test.run() +- sleep(1) +- target_cpu_freq = self.cpu.get_freq(target_cpu) +- if not self.cpu.min_freq < target_cpu_freq < self.cpu.max_freq: +- print("[X] The freq of CPU%s(%d) is not between %d~%d." % +- (target_cpu, target_cpu_freq, self.cpu.min_freq, self.cpu.max_freq)) +- return False +- print("[.] The freq of CPU%s(%d) is between %d~%d." % +- (target_cpu, target_cpu_freq, self.cpu.min_freq, self.cpu.max_freq)) +- +- load_test_time = load_test.get_runtime() +- print("[.] Time of CPU%s conservative load test: %.2f" % +- (target_cpu, load_test_time)) +- target_cpu_freq = self.cpu.get_freq(target_cpu) +- print("[.] Current freq of CPU%s is %d." % (target_cpu, target_cpu_freq)) +- +- return True +- +- def test_powersave(self): +- """ +- powersave mode of testing CPU frequency +- :return: +- """ +- if self.cpu.set_governor('powersave') != 0: +- print("[X] Set governor of all CPUs to powersave failed.") +- return False +- print("[.] Set governor of all CPUs to powersave.") +- +- target_cpu = randint(0, self.cpu.nums) +- target_cpu_governor = self.cpu.get_governor(target_cpu) +- if target_cpu_governor != 'powersave': +- print("[X] The governor of CPU%s(%s) is not powersave." % +- (target_cpu, target_cpu_governor)) +- return False +- print("[.] The governor of CPU%s is %s." % +- (target_cpu, target_cpu_governor)) +- +- target_cpu_freq = self.cpu.get_freq(target_cpu) +- if target_cpu_freq != self.cpu.min_freq: +- print("[X] The freq of CPU%s(%d) is not scaling_min_freq(%d)." % +- (target_cpu, target_cpu_freq, self.cpu.min_freq)) +- return False +- print("[.] The freq of CPU%s is %d." % (target_cpu, target_cpu_freq)) +- +- load_test = Load(target_cpu) +- load_test.run() +- load_test_time = load_test.get_runtime() +- print("[.] Time of CPU%s powersave load test: %.2f" % +- (target_cpu, load_test_time)) +- target_cpu_freq = self.cpu.get_freq(target_cpu) +- print("[.] Current freq of CPU%s is %d." % (target_cpu, target_cpu_freq)) +- +- return True +- +- def test_performance(self): +- """ +- Performance mode of testing CPU frequency +- :return: +- """ +- if self.cpu.set_governor('performance') != 0: +- print("[X] Set governor of all CPUs to performance failed.") +- return False +- print("[.] Set governor of all CPUs to performance.") +- +- target_cpu = randint(0, self.cpu.nums) +- target_cpu_governor = self.cpu.get_governor(target_cpu) +- if target_cpu_governor != 'performance': +- print("[X] The governor of CPU%s(%s) is not performance." % +- (target_cpu, target_cpu_governor)) +- return False +- print("[.] The governor of CPU%s is %s." % +- (target_cpu, target_cpu_governor)) +- +- target_cpu_freq = self.cpu.get_freq(target_cpu) +- if target_cpu_freq != self.cpu.max_freq: +- print("[X] The freq of CPU%s(%d) is not scaling_max_freq(%d)." % +- (target_cpu, target_cpu_freq, self.cpu.max_freq)) +- return False +- print("[.] The freq of CPU%s is %d." % (target_cpu, target_cpu_freq)) +- +- load_test = Load(target_cpu) +- load_test.run() +- load_test_time = load_test.get_runtime() +- print("[.] Time of CPU%s performance load test: %.2f" % +- (target_cpu, load_test_time)) +- target_cpu_freq = self.cpu.get_freq(target_cpu) +- print("[.] Current freq of CPU%s is %d." % (target_cpu, target_cpu_freq)) +- +- return True +- +- def test(self): +- """ +- Test case +- :return: +- """ +- if not self.cpu.get_info(): +- print("[X] Fail to get CPU info." +- " Please check if the CPU supports cpufreq.") +- return False +- +- ret = True +- print("") +- print("[.] Test userspace") +- if not self.test_userspace(): +- print("[X] Test userspace FAILED") +- ret = False +- print("") +- print("[.] Test ondemand") +- if not self.test_ondemand(): +- print("[X] Test ondemand FAILED") +- ret = False +- print("") +- print("[.] Test conservative") +- if not self.test_conservative(): +- print("[X] Test conservative FAILED") +- ret = False +- print("") +- print("[.] Test powersave") +- if not self.test_powersave(): +- print("[X] Test powersave FAILED") +- ret = False +- print("") +- print("[.] Test performance") +- if not self.test_performance(): +- print("[X] Test performance FAILED") +- ret = False +- +- self.cpu.set_governor(self.original_governor) +- return ret +- +- +-if __name__ == "__main__": +- t = CPUFreqTest() +- t.setup() +- t.test() +diff -urN oec-hardware-1.0.0/tests/disk/disk.py oec-hardware/tests/disk/disk.py +--- oec-hardware-1.0.0/tests/disk/disk.py 2022-05-31 22:00:43.450655800 +0800 ++++ oec-hardware/tests/disk/disk.py 2022-05-31 22:01:38.436873912 +0800 +@@ -12,6 +12,7 @@ + # See the Mulan PSL v2 for more details. + # Create: 2020-04-01 + ++ + """disk test""" + + import os +@@ -23,16 +24,17 @@ + from hwcompatible.commandUI import CommandUI + from hwcompatible.device import CertDevice + +- + class DiskTest(Test): + """ + disk test + """ ++ + def __init__(self): + Test.__init__(self) + self.disks = list() + self.filesystems = ["ext4"] + self.com_ui = CommandUI() ++ self.logpath = "" + + def setup(self, args=None): + """ +@@ -40,25 +42,27 @@ + :return: + """ + try: +- print("Disk Info:") +- Command("fdisk -l").echo(ignore_errors=True) +- print("\nPartition Info:") +- Command("df -h").echo(ignore_errors=True) +- print("\nMount Info:") +- Command("mount").echo(ignore_errors=True) +- print("\nSwap Info:") +- Command("cat /proc/swaps").echo(ignore_errors=True) +- print("\nLVM Info:") +- Command("pvdisplay").echo(ignore_errors=True) +- Command("vgdisplay").echo(ignore_errors=True) +- Command("lvdisplay").echo(ignore_errors=True) +- print("Md Info:") +- Command("cat /proc/mdstat").echo(ignore_errors=True) ++ self.args = args or argparse.Namespace() ++ self.logpath = getattr(args, "logdir", None) + "/disk.log" ++ os.system("echo 'Disk Info: ' >> %s" % self.logpath) ++ Command("fdisk -l &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo 'Partition Info: ' >> %s" % self.logpath) ++ Command("df -h &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo 'Mount Info: ' >> %s" % self.logpath) ++ Command("mount &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo 'Swap Info: ' >> %s" % self.logpath) ++ Command("cat /proc/swaps &>> %s" % ++ self.logpath).echo(ignore_errors=True) ++ os.system("echo 'LVM Info: ' >> %s" % self.logpath) ++ Command("pvdisplay &>> %s" % self.logpath).echo(ignore_errors=True) ++ Command("vgdisplay &>> %s" % self.logpath).echo(ignore_errors=True) ++ Command("lvdisplay &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo 'Md Info: ' >> %s" % self.logpath) ++ Command("cat /proc/mdstat &>> %s" % ++ self.logpath).echo(ignore_errors=True) + sys.stdout.flush() +- print("\n") + except Exception as concrete_error: +- print("Warning: could not get disk info") +- print(concrete_error) ++ print("Warning: could not get disk info.\n", concrete_error) + + def test(self): + """ +@@ -70,7 +74,7 @@ + return False + + self.disks.append("all") +- disk = self.com_ui.prompt_edit("Which disk would you like to test: ",\ ++ disk = self.com_ui.prompt_edit("Which disk would you like to test: ", + self.disks[0], self.disks) + return_code = True + if disk == "all": +@@ -94,7 +98,7 @@ + disks = list() + devices = CertDevice().get_devices() + for device in devices: +- if (device.get_property("DEVTYPE") == "disk" and not \ ++ if (device.get_property("DEVTYPE") == "disk" and not + device.get_property("ID_TYPE")) or device.\ + get_property("ID_TYPE") == "disk": + if "/host" in device.get_property("DEVPATH"): +@@ -132,7 +136,8 @@ + + un_suitable = list(set(disks).difference(set(self.disks))) + if len(un_suitable) > 0: +- print("These disks %s are in use now, skip them." % "|".join(un_suitable)) ++ print("These disks %s are in use now, skip them." % ++ "|".join(un_suitable)) + + def raw_test(self, disk): + """ +@@ -202,8 +207,10 @@ + try: + print("\nFormatting %s to %s ..." % (device, file_sys)) + Command("umount %s" % device).echo(ignore_errors=True) +- Command("mkfs -t %s -F %s 2>/dev/null" % (file_sys, device)).echo() +- Command("mount -t %s %s %s" % (file_sys, device, "vfs_test")).echo() ++ Command("mkfs -t %s -F %s &>/dev/null" % ++ (file_sys, device)).echo() ++ Command("mount -t %s %s %s" % ++ (file_sys, device, "vfs_test")).echo() + + print("\nStarting sequential vfs IO test...") + opts = "-direct=1 -iodepth 4 -rw=rw -rwmixread=50 -name=directoy -runtime=300" +@@ -237,10 +244,9 @@ + max_bs = 64 + a_bs = 4 + while a_bs <= max_bs: +- if os.system("fio %s -size=%dK -bs=%dK %s" % (file_opt, size, a_bs, option)) != 0: ++ if os.system("fio %s -size=%dK -bs=%dK %s &>> %s" % (file_opt, size, a_bs, option, self.logpath)) != 0: + print("Error: %s fio failed." % filepath) + return False +- print("\n") + sys.stdout.flush() + a_bs = a_bs * 2 + return True +diff -urN oec-hardware-1.0.0/tests/fibrechannel/fibrechannel.py oec-hardware/tests/fibrechannel/fibrechannel.py +--- oec-hardware-1.0.0/tests/fibrechannel/fibrechannel.py 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/fibrechannel/fibrechannel.py 2022-05-31 22:01:38.438873956 +0800 +@@ -0,0 +1,250 @@ ++#!/usr/bin/env python ++# coding: utf-8 ++ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-04-09 ++ ++"""FC test""" ++ ++import os ++import sys ++import shutil ++import re ++ ++from hwcompatible.test import Test ++from hwcompatible.command import Command ++from hwcompatible.commandUI import CommandUI ++ ++ ++class FCTest(Test): ++ """ ++ fibre channel test ++ """ ++ ++ def __init__(self): ++ Test.__init__(self) ++ self.disks = list() ++ self.filesystems = ["ext4"] ++ self.com_ui = CommandUI() ++ self.logpath = "" ++ self.name = "" ++ ++ def setup(self, args=None): ++ """ ++ The Setup before testing ++ :return: ++ """ ++ try: ++ self.args = args or argparse.Namespace() ++ self.device = getattr(self.args, 'device', None) ++ self.pci_num = self.device.get_property("DEVPATH").split('/')[-1] ++ self.name = re.search(r'.*\((\S+)', self.device.get_property("ID_MODEL_FROM_DATABASE")).group(1) ++ self.logpath = getattr(args, "logdir", None) + "/fibrechannel-" + self.name + ".log" ++ os.system("echo Vendor Info: >> %s" % self.logpath) ++ Command("lspci -s %s -v &>> %s " % (self.pci_num, self.logpath)).echo() ++ os.system("echo Disk Info: >> %s" % self.logpath) ++ Command("fdisk -l &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo Partition Info: >> %s" % self.logpath) ++ Command("df -h &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo Mount Info: >> %s" % self.logpath) ++ Command("mount &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo Swap Info: >> %s" % self.logpath) ++ Command("cat /proc/swaps &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo LVM Info: >> %s" % self.logpath) ++ Command("pvdisplay &>> %s" % self.logpath).echo(ignore_errors=True) ++ Command("vgdisplay &>> %s" % self.logpath).echo(ignore_errors=True) ++ Command("lvdisplay &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo Md Info: >> %s" % self.logpath) ++ Command("cat /proc/mdstat &>> %s" % self.logpath).echo(ignore_errors=True) ++ sys.stdout.flush() ++ except Exception as concrete_error: ++ print("Warning: could not get disk array info.\n", concrete_error) ++ ++ def test(self): ++ """ ++ start test ++ """ ++ self.get_disk() ++ if len(self.disks) == 0: ++ print("No suite disk found to test.") ++ return False ++ ++ self.disks.append("all") ++ disk = self.com_ui.prompt_edit("Which disk would you like to test: ", ++ self.disks[0], self.disks) ++ return_code = True ++ if disk == "all": ++ for disk in self.disks[:-1]: ++ if not self.raw_test(disk): ++ return_code = False ++ if not self.vfs_test(disk): ++ return_code = False ++ else: ++ if not self.raw_test(disk): ++ return_code = False ++ if not self.vfs_test(disk): ++ return_code = False ++ return return_code ++ ++ def get_disk(self): ++ """ ++ get disk info ++ """ ++ self.disks = list() ++ disks = list() ++ disk_info = Command("cd /sys/block; ls -l").read().split('\n') ++ for disk in disk_info: ++ if self.pci_num in disk: ++ disks.append(disk.split('/')[-1]) ++ ++ partition_file = open("/proc/partitions", "r") ++ partition = partition_file.read() ++ partition_file.close() ++ ++ os.system("swapon -a 2>/dev/null") ++ swap_file = open("/proc/swaps", "r") ++ swap = swap_file.read() ++ swap_file.close() ++ ++ mdstat_file = open("/proc/mdstat", "r") ++ mdstat = mdstat_file.read() ++ mdstat_file.close() ++ ++ mtab_file = open("/etc/mtab", "r") ++ mtab = mtab_file.read() ++ mtab_file.close() ++ ++ mount_file = open("/proc/mounts", "r") ++ mounts = mount_file.read() ++ mount_file.close() ++ ++ for disk in disks: ++ if disk not in partition or ("/dev/%s" % disk) in swap: ++ continue ++ if ("/dev/%s" % disk) in mounts or ("/dev/%s" % disk) in mtab: ++ continue ++ if disk in mdstat or os.system("pvs 2>/dev/null | grep -q '/dev/%s'" % disk) == 0: ++ continue ++ self.disks.append(disk) ++ ++ un_suitable = list(set(disks).difference(set(self.disks))) ++ if len(un_suitable) > 0: ++ print("These disks %s are in use now, skip them." % "|".join(un_suitable)) ++ ++ def raw_test(self, disk): ++ """ ++ raw test ++ """ ++ print("\n#############") ++ print("%s raw IO test" % disk) ++ device = "/dev/" + disk ++ if not os.path.exists(device): ++ print("Error: device %s not exists." % device) ++ proc_path = "/sys/block/" + disk ++ if not os.path.exists(proc_path): ++ proc_path = "/sys/block/*/" + disk ++ size = Command("cat %s/size" % proc_path).get_str() ++ size = int(size) / 2 ++ if size <= 0: ++ print("Error: device %s size not suitable to do test." % device) ++ return False ++ elif size > 1048576: ++ size = 1048576 ++ ++ print("\nStarting sequential raw IO test...") ++ opts = "-direct=1 -iodepth 4 -rw=rw -rwmixread=50 -group_reporting -name=file -runtime=300" ++ if not self.do_fio(device, size, opts): ++ print("%s sequential raw IO test fail." % device) ++ print("#############") ++ return False ++ ++ print("\nStarting rand raw IO test...") ++ opts = "-direct=1 -iodepth 4 -rw=randrw -rwmixread=50 " \ ++ "-group_reporting -name=file -runtime=300" ++ if not self.do_fio(device, size, opts): ++ print("%s rand raw IO test fail." % device) ++ print("#############") ++ return False ++ ++ print("#############") ++ return True ++ ++ def vfs_test(self, disk): ++ """ ++ vfs test ++ """ ++ print("\n#############") ++ print("%s vfs test" % disk) ++ device = "/dev/" + disk ++ if not os.path.exists(device): ++ print("Error: device %s not exists." % device) ++ proc_path = "/sys/block/" + disk ++ if not os.path.exists(proc_path): ++ proc_path = "/sys/block/*/" + disk ++ size = Command("cat %s/size" % proc_path).get_str() ++ size = int(size) / 2 / 2 ++ if size <= 0: ++ print("Error: device %s size not suitable to do test." % device) ++ return False ++ elif size > 1048576: ++ size = 1048576 ++ ++ if os.path.exists("vfs_test"): ++ shutil.rmtree("vfs_test") ++ os.mkdir("vfs_test") ++ path = os.path.join(os.getcwd(), "vfs_test") ++ ++ return_code = True ++ for file_sys in self.filesystems: ++ try: ++ print("\nFormatting %s to %s ..." % (device, file_sys)) ++ Command("umount %s" % device).echo(ignore_errors=True) ++ Command("mkfs -t %s -F %s 2>/dev/null" % (file_sys, device)).echo() ++ Command("mount -t %s %s %s" % (file_sys, device, "vfs_test")).echo() ++ ++ print("\nStarting sequential vfs IO test...") ++ opts = "-direct=1 -iodepth 4 -rw=rw -rwmixread=50 -name=directoy -runtime=300" ++ if not self.do_fio(path, size, opts): ++ return_code = False ++ break ++ ++ print("\nStarting rand vfs IO test...") ++ opts = "-direct=1 -iodepth 4 -rw=randrw -rwmixread=50 -name=directoy -runtime=300" ++ if not self.do_fio(path, size, opts): ++ return_code = False ++ break ++ except Exception as concrete_error: ++ print("concrete_error:", concrete_error) ++ return_code = False ++ break ++ ++ Command("umount %s" % device).echo(ignore_errors=True) ++ Command("rm -rf vfs_test").echo(ignore_errors=True) ++ print("#############") ++ return return_code ++ ++ def do_fio(self, filepath, size, option): ++ """ ++ fio test ++ """ ++ if os.path.isdir(filepath): ++ file_opt = "-directory=%s" % filepath ++ else: ++ file_opt = "-filename=%s" % filepath ++ max_bs = 64 ++ a_bs = 4 ++ while a_bs <= max_bs: ++ if os.system("fio %s -size=%dK -bs=%dK %s &>> %s" % (file_opt, size, a_bs, option, self.logpath)) != 0: ++ print("Error: %s fio failed." % filepath) ++ return False ++ sys.stdout.flush() ++ a_bs = a_bs * 2 ++ return True +diff -urN oec-hardware-1.0.0/tests/fibrechannel/Makefile oec-hardware/tests/fibrechannel/Makefile +--- oec-hardware-1.0.0/tests/fibrechannel/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/fibrechannel/Makefile 2022-05-31 22:01:38.437873934 +0800 +@@ -0,0 +1,22 @@ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-04-09 ++ ++.PHONY: install clean ++ ++all: ; ++ ++install: ++ mkdir -p $(DEST) ++ cp -a *.py $(DEST) ++ chmod a+x $(DEST)/*.py ++ ++clean: ++ rm -rf $(DEST) +diff -urN oec-hardware-1.0.0/tests/gpu/gpu.py oec-hardware/tests/gpu/gpu.py +--- oec-hardware-1.0.0/tests/gpu/gpu.py 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/gpu/gpu.py 2022-05-31 22:01:38.440874000 +0800 +@@ -0,0 +1,115 @@ ++# coding: utf-8 ++ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-04-13 ++ ++"""gpu test""" ++import os ++import subprocess ++import argparse ++import time ++import shutil ++import re ++ ++from hwcompatible.command import Command, CertCommandError ++from hwcompatible.test import Test ++ ++gpu_dir = os.path.dirname(os.path.realpath(__file__)) ++ ++ ++class GpuTest(Test): ++ """ ++ gpu test ++ """ ++ ++ def __init__(self): ++ Test.__init__(self) ++ self.args = None ++ self.device = None ++ self.requirements = ["gcc-c++", "make", "tar", "git"] ++ ++ def setup(self, args=None): ++ self.args = args or argparse.Namespace() ++ self.name = getattr(args, 'testname', None) ++ self.device = getattr(args, 'device', None) ++ self.logpath = getattr(args, "logdir", None) + "/" + self.name + ".log" ++ self.cuda_samples_log = getattr( ++ args, 'logdir', None) + '/cuda_samples.log' ++ self.gpu_burn = getattr(args, 'logdir', None) + '/gpu_burn.log' ++ self.smi_name = "nvidia-smi" ++ ++ def current_card(self): ++ print("Vendor Info:") ++ pci_num = self.device.get_property("DEVPATH").split('/')[-1] ++ Command('lspci -s %s -v' % pci_num).echo() ++ ++ print("Driver Info:") ++ driver = self.device.get_property("DRIVER") ++ if driver == "iluvatar-itr": ++ self.smi_name = "ixsmi" ++ driver = "bi_driver" ++ Command('modinfo %s | head -n 13' % driver).echo() ++ return pci_num ++ ++ def pressure(self): ++ print("Monitor GPU temperature and utilization rate.") ++ pci = [] ++ num = [] ++ pci_key = "GPU 0000" + self.current_card() ++ gpu = Command('%s -q' % self.smi_name) ++ gpu.run_quiet() ++ for line in gpu.output: ++ if "GPU 0000" in line: ++ pci.append(line) ++ if "Minor Number" in line: ++ num.append(line) ++ ++ output = dict(zip(pci, num)) ++ if pci_key in output.keys(): ++ id_num = str(re.findall("\d+", output[pci_key])).strip("['']") ++ os.environ['CUDA_VISIBLE_DEVICES'] = id_num ++ ++ os.system("bash %s/test_gpu.sh install_gpu_burn" % gpu_dir) ++ os.system('cd /opt/gpu-burn && nohup ./gpu_burn 10 &> %s &' % ++ self.gpu_burn) ++ time.sleep(1) ++ while not subprocess.call("ps -ef | grep 'gpu_burn' | grep -v grep >/dev/null", shell=True): ++ os.system('%s &>>%s' % (self.smi_name, self.logpath)) ++ time.sleep(1) ++ ++ def test(self): ++ try: ++ result = True ++ print("Start to test gpu pressure.") ++ self.pressure() ++ if os.path.exists(self.gpu_burn) and os.system("grep 'GPU 0: OK' %s" % self.gpu_burn) == 0: ++ print("Test gpu pressure succeed.") ++ else: ++ print("Test gpu pressure failed.") ++ result = False ++ ++ print("Start to test cuda samples.") ++ sample_case = "simpleOccupancy,bandwidthTest,p2pBandwidthLatencyTest,deviceQuery,clock" ++ code = os.system( ++ "bash %s/test_gpu.sh test_cuda_samples '%s %s'" % (gpu_dir, self.cuda_samples_log, sample_case)) ++ if code == 0: ++ print("Test cuda samples succeed.") ++ else: ++ result = False ++ print("Test cuda samples failded.") ++ ++ return result ++ except Exception as e: ++ print("Failed to run the script because compiling or setting variables", e) ++ return False ++ ++ def teardown(self): ++ os.system("rm -rf /opt/gpu-burn /opt/cuda-samples-master") +diff -urN oec-hardware-1.0.0/tests/gpu/Makefile oec-hardware/tests/gpu/Makefile +--- oec-hardware-1.0.0/tests/gpu/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/gpu/Makefile 2022-05-31 22:01:38.438873956 +0800 +@@ -0,0 +1,23 @@ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-04-13 ++ ++.PHONY: install clean ++ ++all: ; ++ ++install: ++ mkdir -p $(DEST) ++ cp -a *.py $(DEST) ++ cp -a *.sh $(DEST) ++ chmod a+x $(DEST)/*.py ++ ++clean: ++ rm -rf $(DEST) +diff -urN oec-hardware-1.0.0/tests/gpu/test_gpu.sh oec-hardware/tests/gpu/test_gpu.sh +--- oec-hardware-1.0.0/tests/gpu/test_gpu.sh 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/gpu/test_gpu.sh 2022-05-31 22:01:38.439873978 +0800 +@@ -0,0 +1,127 @@ ++#!/usr/bin/bash ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Author: @meitingli ++# Create: 2022-05-05 ++ ++function install_gpu_burn() { ++ cd /opt ++ res_code=0 ++ git clone https://github.com/wilicc/gpu-burn.git ++ cd gpu-burn ++ lsmod | grep bi_driver >/dev/null ++ if [ $? -eq 0 ];then ++ COREX_PATH=${COREX_PATH:-/usr/local/corex} ++ clang++ compare.cu -o compare.ll -I${COREX_PATH}/include --cuda-gpu-arch=ivcore10 --cuda-path=${COREX_PATH} --cuda-device-only -S -x cuda || res_code=1 ++ llc -mcpu=ivcore10 -mtriple=bi-iluvatar-ilurt -show-mc-encoding -filetype=obj compare.ll -o compare.o || res_code=1 ++ lld -flavor ld.lld --no-undefined compare.o -o compare.ptx || res_code=1 ++ rm compare.ll compare.o ++ sed -i '/cuFuncSet/d' gpu_burn-drv.cpp ++ sed -i '/cuParamSet/d' gpu_burn-drv.cpp ++ sed -i 's/nvidia-smi/ixsmi/g' gpu_burn-drv.cpp ++ sed -i 's/.*cuLaunchGridAsync.*/void\* kargs[] = {\&d_Cdata, \&d_faultyElemData, \&d_iters};checkError(cuLaunchKernel(d_function, SIZE\/g_blockSize, SIZE\/g_blockSize, 1, g_blockSize, g_blockSize, 1, 0, 0, kargs, nullptr));/g' gpu_burn-drv.cpp ++ clang++ -std=c++11 -I${COREX_PATH}/include -L${COREX_PATH}/lib64 -lcudart -lcuda -lcublas -o gpu_burn ./gpu_burn-drv.cpp || res_code=1 ++ else ++ make &>/dev/null || res_code=1 ++ fi ++ return $res_code ++} ++ ++function install_cuda_samples() { ++ cd /opt ++ wget https://github.com/NVIDIA/cuda-samples/archive/refs/heads/master.zip ++ unzip master.zip >/dev/null ++ rm -rf master.zip ++ return 0 ++} ++ ++function test_nvidia_case() { ++ casename=$1 ++ logfile=$2 ++ res_code=0 ++ cd /opt/cuda-samples-master ++ path=$(find ./ -name $casename) ++ cd $path ++ make &>/dev/null ++ ./$casename &>>$logfile ++ if [[ $? -eq 0 ]]; then ++ echo "Test $casename succeed." >>$logfile ++ else ++ echo "Test $casename failed." >>$logfile ++ res_code=1 ++ fi ++ return $res_code ++} ++ ++function test_iluvatar_case() { ++ casename=$1 ++ logfile=$2 ++ res_code=0 ++ CUDA_PATH=${CUDA_PATH:-/usr/local/corex} ++ cd /opt/cuda-samples-master ++ path=$(find ./ -name $casename) ++ cd $path ++ src_file=${casename}.cu ++ if [ ! -f ./$src_file ] && [ -f ./${casename}.cpp ];then ++ src_file=${casename}.cpp ++ fi ++ clang++ -std=c++11 -I../../../Common -I${CUDA_PATH}/include --cuda-path=${CUDA_PATH} -L${CUDA_PATH}/lib64 -lcudart -lixlogger -lcuda -lixthunk -o ${casename} ./${src_file} ++ ./$casename &>>$logfile ++ if [[ $? -eq 0 ]]; then ++ echo "Test $casename succeed." ++ else ++ echo "Test $casename failed." ++ res_code=1 ++ fi ++ return $res_code ++} ++ ++function test_cuda_samples() { ++ logfile=$1 ++ allcases=(${2//,/ }) ++ res_code=0 ++ install_cuda_samples ++ cd /opt/cuda-samples-master ++ lsmod | grep bi_driver ++ if [[ $? -eq 0 ]]; then ++ for casename in ${allcases[@]}; do ++ test_iluvatar_case $casename $logfile ++ if [[ $? -eq 1 ]]; then ++ res_code=1 ++ fi ++ done ++ else ++ for casename in ${allcases[@]}; do ++ test_nvidia_case $casename $logfile ++ if [[ $? -eq 1 ]]; then ++ res_code=1 ++ fi ++ done ++ fi ++ return $res_code ++} ++ ++function main() { ++ func_name=$1 ++ param_list=$2 ++ ++ if [[ $func_name == "install_gpu_burn" ]]; then ++ install_gpu_burn ++ elif [[ $func_name == "install_cuda_samples" ]]; then ++ install_cuda_samples ++ elif [[ $func_name == "test_cuda_samples" ]]; then ++ test_cuda_samples $param_list ++ else ++ echo "The function doesn't exist, please check!" ++ return 1 ++ fi ++} ++ ++main "$@" +diff -urN oec-hardware-1.0.0/tests/infiniband/infiniband.py oec-hardware/tests/infiniband/infiniband.py +--- oec-hardware-1.0.0/tests/infiniband/infiniband.py 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/infiniband/infiniband.py 2022-05-31 22:01:38.397873048 +0800 +@@ -0,0 +1,94 @@ ++#!/usr/bin/env python ++# coding: utf-8 ++ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-05-23 ++ ++"""InfiniBand Test""" ++ ++from builtins import input ++from hwcompatible.document import CertDocument ++from hwcompatible.env import CertEnv ++from rdma import RDMATest ++ ++class InfiniBandTest(RDMATest): ++ """ ++ InfiniBand Test ++ """ ++ def __init__(self): ++ RDMATest.__init__(self) ++ self.link_layer = 'InfiniBand' ++ self.subtests = [self.test_ip_info, self.test_ibstatus, self.test_ib_link, ++ self.test_icmp, self.test_rdma] ++ self.speed = 56000 # Mb/s ++ self.target_bandwidth_percent = 0.5 ++ ++ def test_ib_link(self): ++ """ ++ IB Link test ++ :return: ++ """ ++ if 'LinkUp' not in self.phys_state: ++ print("[X] Device is not LinkUp.") ++ ++ if 'ACTIVE' not in self.state: ++ print("[X] Link is not ACTIVE.") ++ ++ if self.base_lid == 0x0: ++ print("[X] Fail to get base lid of %s." % self.interface) ++ return False ++ print("[.] The base lid is %s" % self.base_lid) ++ ++ if self.sm_lid == 0x0: ++ print("[X] Fail to get subnet manager lid of %s." % self.interface) ++ return False ++ print("[.] The subnet manager lid is %s" % self.sm_lid) ++ ++ return True ++ ++ def setup(self, args=None): ++ """ ++ Initialization before test ++ :param args: ++ :return: ++ """ ++ self.args = args or argparse.Namespace() ++ self.device = getattr(self.args, 'device', None) ++ self.interface = self.device.get_property("INTERFACE") ++ ++ self.cert = CertDocument(CertEnv.certificationfile) ++ self.server_ip = self.cert.get_server() ++ ++ def test(self): ++ """ ++ test case ++ :return: ++ """ ++ message = "Please enter the IP of InfiniBand interface on remote server: (default %s)\n> " % self.server_ip ++ self.server_ip = input(message) or self.server_ip ++ ++ for subtest in self.subtests: ++ if not subtest(): ++ return False ++ return True ++ ++ def teardown(self): ++ """ ++ Environment recovery after test ++ :return: ++ """ ++ print("[.] Stop all test servers...") ++ self.call_remote_server('all', 'stop') ++ ++ print("[.] Restore interfaces up...") ++ self.set_other_interfaces_up() ++ ++ print("[.] Test finished.") +diff -urN oec-hardware-1.0.0/tests/infiniband/Makefile oec-hardware/tests/infiniband/Makefile +--- oec-hardware-1.0.0/tests/infiniband/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/infiniband/Makefile 2022-05-31 22:01:38.396873026 +0800 +@@ -0,0 +1,22 @@ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-05-23 ++ ++.PHONY: install clean ++ ++all: ; ++ ++install: ++ mkdir -p $(DEST) ++ cp -a *.py $(DEST) ++ chmod a+x $(DEST)/*.py ++ ++clean: ++ rm -rf $(DEST) +diff -urN oec-hardware-1.0.0/tests/infiniband/network.py oec-hardware/tests/infiniband/network.py +--- oec-hardware-1.0.0/tests/infiniband/network.py 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/infiniband/network.py 2022-05-31 22:01:38.397873048 +0800 +@@ -0,0 +1,147 @@ ++#!/usr/bin/env python ++# coding: utf-8 ++ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-05-23 ++ ++"""Network Test""" ++ ++import os ++import time ++ ++from urllib.parse import urlencode ++from urllib.request import urlopen, Request ++from urllib.error import HTTPError ++ ++from hwcompatible.test import Test ++from hwcompatible.command import Command ++from hwcompatible.document import CertDocument ++from hwcompatible.env import CertEnv ++ ++class NetworkTest(Test): ++ """ ++ :Network Test ++ """ ++ def __init__(self): ++ Test.__init__(self) ++ self.device = None ++ self.requirements = ['ethtool', 'iproute', 'psmisc'] ++ self.subtests = [self.test_ip_info,self.test_icmp] ++ self.interface = None ++ self.other_interfaces = [] ++ self.server_ip = None ++ self.retries = 3 ++ self.speed = 1000 # Mb/s ++ self.target_bandwidth_percent = 0.8 ++ self.testfile = 'testfile' ++ ++ def set_other_interfaces_up(self): ++ """ ++ Set other interfaces to up ++ :return: ++ """ ++ for interface in self.other_interfaces: ++ # Not ifup(), as some interfaces may not be linked ++ os.system("ip link set up %s" % interface) ++ return True ++ ++ def get_interface_ip(self): ++ """ ++ Get interface ip ++ :return: ++ """ ++ com = Command("ip addr show %s" % self.interface) ++ pattern = r".*inet.? (?P.+)/.*" ++ try: ++ ip_addr = com.get_str(pattern, 'ip', False) ++ return ip_addr ++ except Exception: ++ print("[X] No available ip on the interface.") ++ return None ++ ++ def test_icmp(self): ++ """ ++ Test ICMP ++ :return: ++ """ ++ count = 500 ++ com = Command("ping -q -c %d -i 0 %s" % (count, self.server_ip)) ++ pattern = r".*, (?P\d+\.{0,1}\d*)% packet loss.*" ++ ++ for _ in range(self.retries): ++ try: ++ print(com.command) ++ loss = com.get_str(pattern, 'loss', False) ++ com.print_output() ++ if float(loss) == 0: ++ return True ++ except Exception as concrete_error: ++ print(concrete_error) ++ return False ++ ++ def call_remote_server(self, cmd, act='start', ib_server_ip=''): ++ """ ++ Call remote server ++ :param cmd: ++ :param act: ++ :param ib_server_ip: ++ :return: ++ """ ++ form = dict() ++ form['cmd'] = cmd ++ form['ib_server_ip'] = ib_server_ip ++ url = 'http://%s/api/%s' % (self.server_ip, act) ++ data = urlencode(form).encode('utf8') ++ headers = { ++ 'Content-type': 'application/x-www-form-urlencoded', ++ 'Accept': 'text/plain' ++ } ++ try: ++ request = Request(url, data=data, headers=headers) ++ response = urlopen(request) ++ except Exception as concrete_error: ++ print(concrete_error) ++ return False ++ print("Status: %u %s" % (response.code, response.msg)) ++ return int(response.code) == 200 ++ ++ def create_testfile(self): ++ """ ++ Create testfile ++ :return: ++ """ ++ bs = 128 ++ count = self.speed/8 ++ cmd = "dd if=/dev/urandom of=%s bs=%uk count=%u" % (self.testfile, bs, count) ++ return 0 == os.system(cmd) ++ ++ def test_ip_info(self): ++ """ ++ Test ip info ++ :return: ++ """ ++ if not self.interface: ++ print("[X] No interface assigned.") ++ return False ++ print("[.] The test interface is %s." % self.interface) ++ ++ if not self.server_ip: ++ print("[X] No server ip assigned.") ++ return False ++ print("[.] The server ip is %s." % self.server_ip) ++ ++ client_ip = self.get_interface_ip() ++ if not client_ip: ++ print("[X] No available ip on %s." % self.interface) ++ return False ++ print("[.] The client ip is %s on %s." % (client_ip, self.interface)) ++ ++ return True +diff -urN oec-hardware-1.0.0/tests/infiniband/rdma.py oec-hardware/tests/infiniband/rdma.py +--- oec-hardware-1.0.0/tests/infiniband/rdma.py 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/infiniband/rdma.py 2022-05-31 22:01:38.398873070 +0800 +@@ -0,0 +1,204 @@ ++#!/usr/bin/env python ++# coding: utf-8 ++ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-05-24 ++ ++"""RDMA Test""" ++ ++import os ++import re ++ ++from hwcompatible.command import Command ++from hwcompatible.document import CertDocument ++from hwcompatible.env import CertEnv ++from network import NetworkTest ++ ++ ++class RDMATest(NetworkTest): ++ """ ++ RDMA Test ++ """ ++ def __init__(self): ++ NetworkTest.__init__(self) ++ self.device = None ++ self.requirements = ['opensm', 'infiniband-diags', 'librdmacm-utils', 'libibverbs-utils'] ++ self.subtests = [self.test_ibstatus, self.test_icmp, self.test_rdma] ++ self.interface = None ++ self.ib_device = None ++ self.ib_port = None ++ self.base_lid = None ++ self.sm_lid = None ++ self.state = None ++ self.phys_state = None ++ self.server_ip = None ++ self.speed = None # Mb/s ++ self.target_bandwidth_percent = 0.5 ++ ++ def get_ibstatus(self): ++ """ ++ Get ibstatus ++ :return: ++ """ ++ path_netdev = ''.join(['/sys', self.device.get_property("DEVPATH")]) ++ path_pci = path_netdev.split('net')[0] ++ path_ibdev = 'infiniband_verbs/uverb*/ibdev' ++ path_ibdev = ''.join([path_pci, path_ibdev]) ++ cmd = "cat %s" % path_ibdev ++ com = Command(cmd) ++ self.ib_device = com.read() ++ if not self.ib_device: ++ return False ++ ++ path_ibport = '/sys/class/net/%s/dev_id' % self.interface ++ cmd = "cat %s" % path_ibport ++ com = Command(cmd) ++ if not com.read(): ++ return False ++ self.ib_port = int(com.read(), 16) + 1 ++ ++ ib_str = "Infiniband device '%s' port %d" % (self.ib_device, self.ib_port) ++ print("Interface %s ===> %s" % (self.interface, ib_str)) ++ ++ cmd = "ibstatus" ++ print(cmd) ++ com = Command(cmd) ++ try: ++ output = com.read() ++ for info in output.split('\n\n'): ++ if ib_str not in info: ++ continue ++ print(info) ++ self.base_lid = re.search(r"base lid:\s+(.*)", info).group(1) ++ self.sm_lid = re.search(r"sm lid:\s+(.*)", info).group(1) ++ self.state = re.search(r"state:\s+(.*)", info).group(1) ++ self.phys_state = re.search(r"phys state:\s+(.*)", info).group(1) ++ self.link_layer = re.search(r"link_layer:\s+(.*)", info).group(1) ++ self.speed = int(re.search(r"rate:\s+(\d*)", info).group(1)) * 1024 ++ except Exception as concrete_error: ++ print(concrete_error) ++ return False ++ ++ return True ++ ++ def test_rping(self): ++ """ ++ Test rping ++ :return: ++ """ ++ if not self.call_remote_server('rping', 'start', self.server_ip): ++ print("start rping server failed.") ++ return False ++ ++ cmd = "rping -c -a %s -C 50 -v" % self.server_ip ++ print(cmd) ++ return os.system(cmd) == 0 ++ ++ def test_rcopy(self): ++ """ ++ Test rcopy ++ :return: ++ """ ++ if not self.call_remote_server('rcopy', 'start', self.server_ip): ++ print("start rcopy server failed.") ++ return False ++ ++ cmd = "rcopy %s %s" % (self.testfile, self.server_ip) ++ print(cmd) ++ ret = os.system(cmd) ++ self.call_remote_server('rcopy', 'stop') ++ return ret == 0 ++ ++ def test_bw(self, cmd): ++ """ ++ Test bandwidth ++ :param cmd: ++ :return: ++ """ ++ if self.link_layer == 'Ethernet': ++ cmd = cmd + ' -R' ++ ++ if not self.call_remote_server(cmd, 'start', self.server_ip): ++ print("start %s server failed." % cmd) ++ return False ++ ++ cmd = "%s %s -d %s -i %s" % (cmd, self.server_ip, self.ib_device, self.ib_port) ++ print(cmd) ++ com = Command(cmd) ++ pattern = r"\s+(\d+)\s+(\d+)\s+([\.\d]+)\s+(?P[\.\d]+)\s+([\.\d]+)" ++ try: ++ avg_bw = com.get_str(pattern, 'avg_bw', False) # MB/sec ++ avg_bw = float(avg_bw) * 8 ++ ++ tgt_bw = self.target_bandwidth_percent * self.speed ++ print("Current bandwidth is %.2fMb/s, target is %.2fMb/s" % ++ (avg_bw, tgt_bw)) ++ return avg_bw > tgt_bw ++ except Exception as concrete_error: ++ print(concrete_error) ++ self.call_remote_server(cmd, 'stop') ++ return False ++ ++ def test_rdma(self): ++ """ ++ Test Remote Direct Memory Access ++ :return: ++ """ ++ print("[+] Testing rping...") ++ if not self.test_rping(): ++ print("[X] Test rping failed.") ++ return False ++ ++ print("[+] Creating testfile to upload...") ++ if not self.create_testfile(): ++ print("[X] Create testfile failed.") ++ return False ++ ++ print("[+] Testing rcopy...") ++ if not self.test_rcopy(): ++ print("[X] Test rcopy failed.") ++ return False ++ ++ print("[+] Testing ib_read_bw...") ++ if not self.test_bw('ib_read_bw'): ++ print("[X] Test ib_read_bw failed.") ++ return False ++ ++ print("[+] Testing ib_write_bw...") ++ if not self.test_bw('ib_write_bw'): ++ print("[X] Test ib_write_bw failed.") ++ return False ++ ++ print("[+] Testing ib_send_bw...") ++ if not self.test_bw('ib_send_bw'): ++ print("[X] Test ib_send_bw failed.") ++ return False ++ ++ return True ++ ++ def test_ibstatus(self): ++ """ ++ Test ibstatus ++ :return: ++ """ ++ if os.system("systemctl start opensm") != 0: ++ print("[X] start opensm failed.") ++ return False ++ ++ if os.system("modprobe ib_umad") != 0: ++ print("[X] modprobe ib_umad failed.") ++ return False ++ ++ if not self.get_ibstatus(): ++ print("[X] Get status of InfiniBand devices failed.") ++ return False ++ ++ return True +diff -urN oec-hardware-1.0.0/tests/keycard/FunctionTest.c oec-hardware/tests/keycard/FunctionTest.c +--- oec-hardware-1.0.0/tests/keycard/FunctionTest.c 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/keycard/FunctionTest.c 2022-05-31 22:01:38.402873159 +0800 +@@ -0,0 +1,2008 @@ ++/** ++* 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: @sansec/@meitingli ++* Create: 2022-04-11 ++**/ ++#include "TestSDS.h" ++ ++int FunctionTest(int nSel, int nDefaultSelect) ++{ ++ int result; ++ int recode = 0; ++ ++ if (nSel == 1) ++ { ++ printf(" 1|基本函数测试\n"); ++ printf(" | 获取设备信息、随机数功能测试及分析。\n"); ++ printf("\n"); ++ result = BasicFuncTest(1); ++ if (result == 1) ++ { ++ recode = 1; ++ } ++ } ++ ++ if (nSel == 2) ++ { ++ printf(" 2|RSA非对称密码运算函数测试\n"); ++ printf(" | RSA密钥对产生,内部和外部密钥运算,数字信封转换测试。\n"); ++ printf("\n"); ++ result = RSAFuncTest(1); ++ if (result == 1) ++ { ++ recode = 1; ++ } ++ } ++ ++ if (nSel == 3) ++ { ++ printf(" 3|ECC非对称密码运算函数测试\n"); ++ printf(" | ECC密钥对产生,内部和外部密钥运算,密钥交换协议测试\n"); ++ printf("\n"); ++ result = ECCFuncTest(1); ++ if (result == 1) ++ { ++ recode = 1; ++ } ++ } ++ ++ if (nSel == 4) ++ { ++ printf(" 4|对称密码运算函数测试\n"); ++ printf(" | 对称密钥管理,对称算法加、解密,产生MAC值测试。\n"); ++ printf("\n"); ++ result = SymmFuncTest(1); ++ if (result == 1) ++ { ++ recode = 1; ++ } ++ } ++ ++ if (nSel == 5) ++ { ++ printf(" 5|杂凑运算函数测试\n"); ++ printf(" | 杂凑运算功能测试。\n"); ++ printf("\n"); ++ result = HashFuncTest(1); ++ if (result == 1) ++ { ++ recode = 1; ++ } ++ } ++ ++ if (nSel == 6) ++ { ++ printf(" 6|用户文件操作函数测试\n"); ++ printf(" | 创建、删除用户文件,用户文件读写功能测试。\n"); ++ printf("\n"); ++ result = FileFuncTest(1); ++ if (result == 1) ++ { ++ recode = 1; ++ } ++ } ++ ++ return recode; ++} ++ ++int BasicFuncTest(int nDefaultSelect) ++{ ++ int rv; ++ int nSel; ++ int recode = 0; ++ ++ SGD_HANDLE hSessionHandle; ++ ++ if ((nDefaultSelect < 1) || (nDefaultSelect > 2)) ++ nSel = 1; ++ else ++ nSel = nDefaultSelect; ++ ++ //创建会话句柄 ++ rv = SDF_OpenSession(hDeviceHandle, &hSessionHandle); ++ if (rv != SDR_OK) ++ { ++ printf("打开会话句柄错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf(" 1|获取设备信息测试\n"); ++ printf(" | 获取设备出厂信息、维护信息、能力字段等信息,并打印。\n"); ++ printf("\n"); ++ nSel = GetDeviceInfoTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ printf(" 2|随机数测试\n"); ++ printf(" | 产生随机数并对随机数质量进行分析。\n"); ++ printf("\n"); ++ nSel = GenRandomTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ printf("\n"); ++ SDF_CloseSession(hSessionHandle); ++ return recode; ++} ++ ++int GetDeviceInfoTest(SGD_HANDLE hSessionHandle) ++{ ++ int rv; ++ unsigned char sFirmwareVersion[32] = {0}; ++ unsigned int uiFirmwareVersionLen = 32; ++ unsigned char sLibraryVersion[16] = {0}; ++ unsigned int uiLibraryVersionLen = 16; ++ ++ unsigned char CertiedModel[32] = { 0 }; ++ unsigned int CertiedModelLen = 32; ++ ++ DEVICEINFO stDeviceInfo; ++ //获取设备信息 ++ rv = SDF_GetDeviceInfo(hSessionHandle, &stDeviceInfo); ++ if (rv != SDR_OK) ++ { ++ printf("获取设备信息错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("获取设备信息成功。\n"); ++ printf("\n"); ++ printf(" | 项目 | 返回值 \n"); ++ printf(" _|_______________|______________________________________________________\n"); ++ printf(" 1| 生产厂商 | %s\n", stDeviceInfo.IssuerName); ++ printf(" 2| 设备型号 | %s\n", stDeviceInfo.DeviceName); ++ printf(" 3| 设备序列号 | %s\n", stDeviceInfo.DeviceSerial); ++ printf(" 4| 设备版本 | v%08x\n", stDeviceInfo.DeviceVersion); ++ printf(" 5| 支持标准版本 | v%d\n", stDeviceInfo.StandardVersion); ++ printf(" 6| 支持公钥算法 | %08x | %08x\n", stDeviceInfo.AsymAlgAbility[0], stDeviceInfo.AsymAlgAbility[1]); ++ printf(" 7| 支持对称算法 | %08x\n", stDeviceInfo.SymAlgAbility); ++ printf(" 8| 支持杂凑算法 | %08x\n", stDeviceInfo.HashAlgAbility); ++ printf(" 9| 用户存储空间 | %dKB\n", stDeviceInfo.BufferSize >> 10); ++ printf("\n"); ++ ++ //获取固件版本 ++ rv = SDF_GetFirmwareVersion(hSessionHandle, sFirmwareVersion, &uiFirmwareVersionLen); ++ if (rv != SDR_OK) ++ { ++ printf("获取设备固件版本信息错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("设备固件版本:%s\n", sFirmwareVersion); ++ ++ //获取软件库版本 ++ rv = SDF_GetLibraryVersion(hSessionHandle, sLibraryVersion, &uiLibraryVersionLen); ++ if (rv != SDR_OK) ++ { ++ printf("获取软件库版本错误, 错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("设备软件版本:%s\n", sLibraryVersion); ++ ++ //获取认证型号 ++ CertiedModelLen = sizeof(CertiedModel); ++ rv = SDF_ReadFile(hSessionHandle, "CertiedModelFile", strlen("CertiedModelFile"), 0, &CertiedModelLen, CertiedModel); ++ if (rv != SDR_OK) ++ { ++ printf("获取认证型号错误, 错误码[0x%08x]\n", rv); ++ } ++ else ++ { ++ printf("设备认证型号:%s\n", CertiedModel); ++ } ++ ++ printf("\n"); ++ return 0; ++} ++ ++int GenRandomTest(SGD_HANDLE hSessionHandle) ++{ ++ unsigned int rv; ++ int randLen = 16; ++ unsigned char pbOutBuffer[16384]; ++ rv = SDF_GenerateRandom(hSessionHandle, randLen, pbOutBuffer); ++ if (rv != SDR_OK) ++ { ++ printf("产生随机数错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ PrintData("随机数", pbOutBuffer, randLen, 16); ++ printf("\n"); ++ return 0; ++} ++ ++int RSAFuncTest(int nDefaultSelect) ++{ ++ int nSel, rv; ++ int recode = 0; ++ SGD_HANDLE hSessionHandle; ++ //创建会话句柄 ++ rv = SDF_OpenSession(hDeviceHandle, &hSessionHandle); ++ if (rv != SDR_OK) ++ { ++ printf("打开会话句柄错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf(" 1|产生RSA密钥对测试\n"); ++ printf(" | 产生可导出的RSA密钥对,并打印。\n"); ++ printf("\n"); ++ nSel = GenRSAKeyPairTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ printf(" 2|外部RSA密钥运算测试\n"); ++ printf(" | 产生RSA密钥对进行运算。\n"); ++ printf("\n"); ++ nSel = ExtRSAOptTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ SDF_CloseSession(hSessionHandle); ++ return recode; ++} ++ ++int GenRSAKeyPairTest(SGD_HANDLE hSessionHandle) ++{ ++ unsigned int rv; ++ unsigned int pukLen, prkLen; ++ RSArefPublicKey pubKey; ++ RSArefPrivateKey priKey; ++ ++ printf("产生可导出的RSA公私钥对,密钥模长1024。\n"); ++ printf("\n"); ++ printf("产生可导出的RSA公私钥对,密钥模长2048。\n"); ++ printf("\n"); ++ ++ rv = SDF_GenerateKeyPair_RSA(hSessionHandle, 1024, &pubKey, &priKey); ++ if (rv != SDR_OK) ++ { ++ printf("产生RSA密钥对模长1024错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("产生RSA密钥对模长1024成功,并写入 data/prikey.0, data/pubkey.0\n"); ++ pukLen = sizeof(RSArefPublicKey); ++ prkLen = sizeof(RSArefPrivateKey); ++ PrintData("PUBLICKEY", (unsigned char *)&pubKey, pukLen, 16); ++ PrintData("PRIVATEKEY", (unsigned char *)&priKey, prkLen, 16); ++ FileWrite("data/prikey.0", "wb+", (unsigned char *)&priKey, prkLen); ++ FileWrite("data/pubkey.0", "wb+", (unsigned char *)&pubKey, pukLen); ++ printf("\n"); ++ ++ rv = SDF_GenerateKeyPair_RSA(hSessionHandle, 2048, &pubKey, &priKey); ++ if (rv != SDR_OK) ++ { ++ printf("产生RSA密钥对模长2048错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("产生RSA密钥对模长2048成功,并写入 data/prikey.0, data/pubkey.0\n"); ++ pukLen = sizeof(RSArefPublicKey); ++ prkLen = sizeof(RSArefPrivateKey); ++ PrintData("PUBLICKEY", (unsigned char *)&pubKey, pukLen, 16); ++ PrintData("PRIVATEKEY", (unsigned char *)&priKey, prkLen, 16); ++ FileWrite("data/prikey.0", "wb+", (unsigned char *)&priKey, prkLen); ++ FileWrite("data/pubkey.0", "wb+", (unsigned char *)&pubKey, pukLen); ++ printf("\n"); ++ return 0; ++} ++ ++int ExtRSAOptTest(SGD_HANDLE hSessionHandle) ++{ ++ unsigned int rv; ++ RSArefPublicKey pubKey; ++ RSArefPrivateKey priKey; ++ unsigned char inData[512], outData[512], tmpData[512]; ++ unsigned int tmpLen; ++ int recode = 0; ++ ++ printf("外部RSA密钥运算测试:\n"); ++ printf("--------------------\n"); ++ printf("\n"); ++ ++ rv = SDF_GenerateKeyPair_RSA(hSessionHandle, 1024, &pubKey, &priKey); ++ if (rv != SDR_OK) ++ { ++ printf("产生RSA密钥对模长1024错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ inData[0] = 0; ++ rv = SDF_GenerateRandom(hSessionHandle, priKey.bits / 8 - 1, &inData[1]); ++ if (rv != SDR_OK) ++ { ++ printf("产生随机加密数据错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("从产生随机加密数据成功。\n"); ++ PrintData("随机加密数据", inData, priKey.bits / 8, 16); ++ ++ rv = SDF_ExternalPrivateKeyOperation_RSA(hSessionHandle, &priKey, inData, priKey.bits / 8, tmpData, &tmpLen); ++ if (rv != SDR_OK) ++ { ++ printf("私钥运算错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("私钥运算成功。\n"); ++ PrintData("私钥运算结果", tmpData, tmpLen, 16); ++ ++ rv = SDF_ExternalPublicKeyOperation_RSA(hSessionHandle, &pubKey, tmpData, tmpLen, outData, &tmpLen); ++ if (rv != SDR_OK) ++ { ++ printf("公钥运算错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("公钥运算成功。\n"); ++ PrintData("公钥运算结果", outData, tmpLen, 16); ++ ++ if ((priKey.bits / 8 == tmpLen) && (memcmp(inData, outData, priKey.bits / 8) == 0)) ++ { ++ printf("结果比较成功。\n"); ++ } ++ else ++ { ++ printf("结果比较失败。\n"); ++ recode = 1; ++ } ++ return recode; ++} ++ ++int ECCFuncTest(int nDefaultSelect) ++{ ++ int rv; ++ int nSel; ++ SGD_HANDLE hSessionHandle; ++ int recode = 0; ++ //创建会话句柄 ++ rv = SDF_OpenSession(hDeviceHandle, &hSessionHandle); ++ if (rv != SDR_OK) ++ { ++ printf("打开会话句柄错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ if ((nDefaultSelect < 1) || (nDefaultSelect > 10)) ++ nSel = 1; ++ else ++ nSel = nDefaultSelect; ++ ++ printf(" 1|产生ECC密钥对测试\n"); ++ printf(" | 产生可导出的ECC密钥对,并打印。\n"); ++ printf("\n"); ++ nSel = GenECCKeyPairTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ printf(" 2|外部ECC密钥加解密运算测试\n"); ++ printf(" | 使用“1 产生ECC密钥对测试”产生ECC密钥对进行加解密运算。\n"); ++ printf("\n"); ++ nSel = ExtECCOptTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ printf(" 3|外部ECC密钥签名验证运算测试\n"); ++ printf(" | 使用“1 产生ECC密钥对测试”产生ECC密钥对进行签名验证运算。\n"); ++ printf("\n"); ++ nSel = ExtECCSignTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ printf(" 4|ECC标准数据验证测试\n"); ++ printf(" | 使用ECC标准数据进行验证运算,并测试结果。\n"); ++ printf("\n"); ++ nSel = ECCStdDataVerifyTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ printf(" 5|ECC标准数据解密测试\n"); ++ printf(" | 使用ECC标准数据解密运算,并测试结果。\n"); ++ printf("\n"); ++ nSel = ECCStdDataDecTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ SDF_CloseSession(hSessionHandle); ++ return recode; ++} ++ ++int GenECCKeyPairTest(SGD_HANDLE hSessionHandle) ++{ ++ int rv; ++ ECCrefPublicKey pubKey; ++ ECCrefPrivateKey priKey; ++ int pukLen, prkLen; ++ ++ int keyLen = 256; ++ printf("产生ECC密钥对测试:\n"); ++ printf("------------------\n"); ++ printf("\n"); ++ ++ rv = SDF_GenerateKeyPair_ECC(hSessionHandle, SGD_SM2_3, keyLen, &pubKey, &priKey); ++ if (rv != SDR_OK) ++ { ++ printf("产生ECC密钥对错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf("产生ECC密钥对成功,并写入 data/prikey_ecc.0, data/pubkey_ecc.0\n"); ++ pukLen = sizeof(ECCrefPublicKey); ++ prkLen = sizeof(ECCrefPrivateKey); ++ PrintData("PUBLICKEY", (unsigned char *)&pubKey, pukLen, 16); ++ PrintData("PRIVATEKEY", (unsigned char *)&priKey, prkLen, 16); ++ FileWrite("data/prikey_ecc.0", "wb+", (unsigned char *)&priKey, prkLen); ++ FileWrite("data/pubkey_ecc.0", "wb+", (unsigned char *)&pubKey, pukLen); ++ ++ return 0; ++} ++ ++int ExtECCOptTest(SGD_HANDLE hSessionHandle) ++{ ++ int rv; ++ ECCrefPublicKey pubKey; ++ ECCrefPrivateKey priKey; ++ unsigned char inData[512], outData[512], tmpData[512]; ++ unsigned int outDataLen; ++ unsigned int inPlainLen; ++ int keyLen = 256; ++ ++ printf("外部ECC密钥加解密运算测试:\n"); ++ printf("--------------------\n"); ++ printf("\n"); ++ ++ SDF_GenerateKeyPair_ECC(hSessionHandle, SGD_SM2_3, keyLen, &pubKey, &priKey); ++ ++ //通过生成随机数从而设定明文数据长度 ++ rv = SDF_GenerateRandom(hSessionHandle, 1, &inData[0]); ++ if (rv != SDR_OK) ++ { ++ printf("产生随机数错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ inPlainLen = (inData[0] % ECCref_MAX_CIPHER_LEN) + 1; ++ memset(inData, 0, sizeof(inData)); ++ rv = SDF_GenerateRandom(hSessionHandle, inPlainLen, &inData[0]); ++ if (rv != SDR_OK) ++ { ++ printf("产生随机加密数据错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("产生随机加密数据成功。\n"); ++ PrintData("随机加密数据", inData, inPlainLen, 16); ++ memset(tmpData, 0, sizeof(tmpData)); ++ rv = SDF_ExternalEncrypt_ECC(hSessionHandle, SGD_SM2_3, &pubKey, inData, inPlainLen, (ECCCipher *)tmpData); ++ if (rv != SDR_OK) ++ { ++ printf("公钥钥运算错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("公钥运算成功。\n"); ++ memset(outData, 0, sizeof(outData)); ++ outDataLen = sizeof(outData); ++ ++ rv = SDF_ExternalDecrypt_ECC(hSessionHandle, SGD_SM2_3, &priKey, (ECCCipher *)tmpData, outData, &outDataLen); ++ if (rv != SDR_OK) ++ { ++ printf("私钥运算错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("私钥运算成功。\n"); ++ PrintData("私钥运算结果", outData, outDataLen, 16); ++ ++ if ((inPlainLen != outDataLen) || (memcmp(inData, outData, outDataLen) != 0)) ++ { ++ printf("结果比较失败。\n"); ++ return 1; ++ } ++ printf("结果比较成功。\n"); ++ return 0; ++} ++ ++int ExtECCSignTest(SGD_HANDLE hSessionHandle) ++{ ++ int rv; ++ ECCrefPublicKey pubKey; ++ ECCrefPrivateKey priKey; ++ unsigned char inData[512], tmpData[512]; ++ int keyLen = 256; ++ ++ printf("外部ECC密钥签名验证运算测试:\n"); ++ printf("--------------------\n"); ++ printf("\n"); ++ SDF_GenerateKeyPair_ECC(hSessionHandle, SGD_SM2_3, keyLen, &pubKey, &priKey); ++ memset(inData, 0, sizeof(inData)); ++ rv = SDF_GenerateRandom(hSessionHandle, priKey.bits / 8 - 1, &inData[1]); ++ if (rv != SDR_OK) ++ { ++ printf("产生随机签名数据错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("产生随机签名数据成功。\n"); ++ PrintData("随机签名数据", inData, priKey.bits / 8, 16); ++ ++ memset(tmpData, 0, sizeof(tmpData)); ++ rv = SDF_ExternalSign_ECC(hSessionHandle, SGD_SM2_1, &priKey, inData, priKey.bits / 8, (ECCSignature *)tmpData); ++ if (rv != SDR_OK) ++ { ++ printf("签名运算错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("签名运算成功。\n"); ++ PrintData("私钥签名运算结果", tmpData, sizeof(ECCSignature), 16); ++ ++ rv = SDF_ExternalVerify_ECC(hSessionHandle, SGD_SM2_1, &pubKey, inData, priKey.bits / 8, (ECCSignature *)tmpData); ++ if (rv != SDR_OK) ++ { ++ printf("验证签名运算错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("验证签名运算成功。\n"); ++ return 0; ++} ++ ++//ECC标准数据验证测试 ++int ECCStdDataVerifyTest(SGD_HANDLE hSessionHandle) ++{ ++ unsigned int rv; ++ ++ unsigned char xa[32] = {0x5C, 0xA4, 0xE4, 0x40, 0xC5, 0x08, 0xC4, 0x5F, 0xE7, 0xD7, 0x58, 0xAB, 0x10, 0xC4, 0x5D, 0x82, 0x37, 0xC4, 0xF9, 0x55, 0x9F, 0x7D, 0x46, 0x61, 0x85, 0xF2, 0x95, 0x39, 0x9F, 0x0A, 0xA3, 0x7D}; ++ unsigned char ya[32] = {0x59, 0xAD, 0x8A, 0x3C, 0xD1, 0x79, 0x03, 0x28, 0x76, 0x81, 0xBF, 0x9D, 0x21, 0xDA, 0x2E, 0xB3, 0x16, 0xA0, 0xCE, 0x8F, 0xD4, 0x1C, 0x89, 0xCE, 0x1E, 0x2B, 0x3F, 0x1B, 0x8E, 0x04, 0x1A, 0xBA}; ++ ++ //标准数据 ++ unsigned char e[32] = {0x38, 0x54, 0xC4, 0x63, 0xFA, 0x3F, 0x73, 0x78, 0x36, 0x21, 0xB1, 0xCE, 0x4E, 0xF8, 0x3F, 0x7C, 0x78, 0x04, 0x8A, 0xAC, 0x79, 0xB2, 0x21, 0xFC, 0xDD, 0x29, 0x08, 0x66, 0xCC, 0x13, 0x11, 0x74}; ++ ++ //标准签名数据 ++ unsigned char r[32] = {0x6E, 0x5D, 0xB4, 0x9D, 0xBD, 0x09, 0x92, 0xB9, 0x70, 0x40, 0x08, 0x0A, 0x96, 0x00, 0x3C, 0x72, 0x1C, 0xDB, 0x9C, 0xF6, 0x4C, 0x88, 0xD7, 0x43, 0x21, 0xFC, 0x2F, 0x63, 0x0A, 0xDF, 0x37, 0x74}; ++ unsigned char s[32] = {0x2F, 0x6D, 0xFF, 0x45, 0x3D, 0xFC, 0x8D, 0x7A, 0x50, 0x6D, 0x3F, 0x52, 0x30, 0x1B, 0xEE, 0x52, 0x9E, 0x62, 0xFD, 0xDD, 0x38, 0x94, 0x8F, 0x0D, 0x5D, 0x2C, 0xBC, 0xBC, 0x55, 0x90, 0x0C, 0xFA}; ++ ++ ECCrefPublicKey ECC_PubKey; ++ ECCSignature ECC_SignatureValue; ++ ++ printf("ECC标准数据验证测试:\n"); ++ printf("-----------------\n"); ++ printf("\n"); ++ ++ memset(&ECC_PubKey, 0, sizeof(ECCrefPublicKey)); ++ memcpy(ECC_PubKey.x, xa, 32); ++ memcpy(ECC_PubKey.y, ya, 32); ++ ECC_PubKey.bits = 256; ++ ++ memset(&ECC_SignatureValue, 0, sizeof(ECCSignature)); ++ memcpy(ECC_SignatureValue.r, r, 32); ++ memcpy(ECC_SignatureValue.s, s, 32); ++ ++ //验证签名运算 ++ rv = SDF_ExternalVerify_ECC(hSessionHandle, SGD_SM2_1, &ECC_PubKey, e, 32, &ECC_SignatureValue); ++ if (rv != SDR_OK) ++ { ++ printf("ECC标准数据验证错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("ECC标准数据验证成功\n"); ++ return 0; ++} ++ ++//ECC标准数据解密测试 ++int ECCStdDataDecTest(SGD_HANDLE hSessionHandle) ++{ ++ unsigned int rv; ++ ++ unsigned char da[32] = {0xE7, 0xCB, 0x09, 0x60, 0x6A, 0x53, 0x32, 0x0B, 0x34, 0x7F, 0x61, 0xF3, 0xF1, 0x42, 0xDC, 0xB1, 0x18, 0xF7, 0x23, 0xA9, 0xBC, 0x27, 0x87, 0x9F, 0x28, 0x05, 0xBE, 0x77, 0x8F, 0x24, 0xAE, 0xE5}; ++ ++ //标准数据 ++ unsigned char P[32] = {0xEA, 0x4E, 0xC3, 0x52, 0xF0, 0x76, 0xA6, 0xBE}; ++ ++ //标准密文数据 ++ unsigned char cx[32] = {0x9E, 0x2A, 0x4A, 0x1A, 0xA4, 0xCF, 0x77, 0x26, 0x22, 0xAB, 0xBB, 0xF1, 0xC6, 0xD6, 0x61, 0xEE, 0x58, 0xFF, 0x01, 0xFF, 0x98, 0x43, 0x78, 0x2E, 0x5A, 0x63, 0x18, 0x5A, 0xBF, 0x6C, 0x2E, 0xFA}; ++ unsigned char cy[32] = {0x9B, 0x2D, 0x59, 0xB2, 0xB1, 0xE0, 0xD0, 0xA7, 0x95, 0xBF, 0xEF, 0x53, 0xFA, 0xBB, 0x24, 0xC0, 0x3A, 0x02, 0x26, 0x57, 0x51, 0xB8, 0x20, 0x59, 0x12, 0x00, 0xF0, 0xD3, 0x1C, 0x55, 0x1E, 0xD6}; ++ unsigned char cc[32] = {0x7D, 0xFD, 0xFC, 0x65, 0xCC, 0x9D, 0xF7, 0xD6}; ++ unsigned char cM[32] = {0x28, 0x7D, 0x5B, 0xF3, 0x35, 0x8B, 0xED, 0x99, 0x28, 0x81, 0xB6, 0x9F, 0xBA, 0x13, 0xC8, 0xAF, 0x76, 0xEF, 0xC1, 0x57, 0x45, 0x5D, 0xB8, 0x1E, 0xCF, 0xAC, 0xC7, 0xB4, 0x43, 0xEA, 0x1D, 0xB0}; ++ ++ ECCrefPrivateKey ECC_PriKey; ++ ECCCipher ECC_CipherData; ++ ++ //解密结果 ++ unsigned char pucOutData[ECCref_MAX_CIPHER_LEN] = {0}; ++ unsigned int uiOutDataLen; ++ ++ printf("ECC标准数据解密测试:\n"); ++ printf("-----------------\n"); ++ printf("\n"); ++ ++ memset(&ECC_PriKey, 0, sizeof(ECCrefPrivateKey)); ++ memcpy(ECC_PriKey.D, da, 32); ++ ECC_PriKey.bits = 256; ++ ++ memset(&ECC_CipherData, 0, sizeof(ECCCipher)); ++ ECC_CipherData.clength = 8; ++ memcpy(ECC_CipherData.x, cx, 32); ++ memcpy(ECC_CipherData.y, cy, 32); ++ memcpy(ECC_CipherData.C, cc, 8); ++ memcpy(ECC_CipherData.M, cM, 32); ++ ++ //ECC解密运算 ++ rv = SDF_ExternalDecrypt_ECC(hSessionHandle, SGD_SM2_3, &ECC_PriKey, &ECC_CipherData, pucOutData, &uiOutDataLen); ++ if (rv != SDR_OK) ++ { ++ printf("ECC解密运算错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ //解密结果与标准明文比对 ++ if ((uiOutDataLen != 8) || (memcmp(P, pucOutData, 8) != 0)) ++ { ++ printf("ECC解密结果与标准明文不相等\n"); ++ return 1; ++ } ++ printf("ECC解密结果与标准明文相等\n"); ++ return 0; ++} ++ ++int SymmFuncTest(int nDefaultSelect) ++{ ++ int rv, nSel; ++ SGD_HANDLE hSessionHandle; ++ int recode = 0; ++ ++ if ((nDefaultSelect < 1) || (nDefaultSelect > 7)) ++ nSel = 1; ++ else ++ nSel = nDefaultSelect; ++ ++ //创建会话句柄 ++ rv = SDF_OpenSession(hDeviceHandle, &hSessionHandle); ++ if (rv != SDR_OK) ++ { ++ printf("打开会话句柄错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf(" 1|算法正确性测试\n"); ++ printf(" | 使用标准数据验证对称算法的正确性。\n"); ++ printf("\n"); ++ nSel = SymmCorrectnessTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ printf(" 2|MAC算法正确性测试\n"); ++ printf(" | 使用标准数据验证MAC算法的正确性。\n"); ++ printf("\n"); ++ nSel = SymmCalculateMACTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ SDF_CloseSession(hSessionHandle); ++ return recode; ++} ++ ++int SymmCorrectnessTest(SGD_HANDLE hSessionHandle) ++{ ++ int rv; ++ int num = 1; ++ SGD_HANDLE hKeyHandle; ++ DEVICEINFO stDeviceInfo; ++ unsigned char pIv[16]; ++ unsigned int nInlen; ++ ++ memset(&stDeviceInfo, 0, sizeof(DEVICEINFO)); ++ ++ rv = SDF_GetDeviceInfo(hSessionHandle, &stDeviceInfo); ++ if (rv != SDR_OK) ++ { ++ printf("\n获取设备信息错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf("算法正确性测试:\n"); ++ printf("---------------------\n"); ++ printf("\n"); ++ if (stDeviceInfo.SymAlgAbility & SGD_SM1_ECB & SGD_SYMM_ALG_MASK) ++ { ++ //标准数据 ++ unsigned char pbKeyValue[16] = {0x40, 0xbb, 0x12, 0xdd, 0x6a, 0x82, 0x73, 0x86, 0x7f, 0x35, 0x29, 0xd3, 0x54, 0xb4, 0xa0, 0x26}; ++ unsigned char pbPlainText[16] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00}; ++ unsigned char pbCipherText[16] = {0x6d, 0x7f, 0x45, 0xb0, 0x8b, 0xc4, 0xd9, 0x66, 0x44, 0x4c, 0x86, 0xc2, 0xb0, 0x7d, 0x29, 0x93}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| SM1_ECB运算 | ", num++); ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ nInlen = 16; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_SM1_ECB, pIv, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_SM1_ECB, pIv, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,[%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_SM1_CBC & SGD_SYMM_ALG_MASK) ++ { ++ //标准数据 ++ unsigned char pbKeyValue[16] = {0x40, 0xbb, 0x12, 0xdd, 0x6a, 0x82, 0x73, 0x86, 0x7f, 0x35, 0x29, 0xd3, 0x54, 0xb4, 0xa0, 0x26}; ++ unsigned char pbIV[16] = {0xe8, 0x3d, 0x17, 0x15, 0xac, 0xf3, 0x48, 0x63, 0xac, 0xeb, 0x93, 0xe0, 0xe5, 0xab, 0x8b, 0x90}; ++ unsigned char pbPlainText[32] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; ++ unsigned char pbCipherText[32] = {0x3a, 0x70, 0xb5, 0xd4, 0x9a, 0x78, 0x2c, 0x07, 0x2d, 0xe1, 0x13, 0x43, 0x81, 0x9e, 0xc6, 0x59, 0xf8, 0xfc, 0x7a, 0xf0, 0x5e, 0x7c, 0x6d, 0xfb, 0x5f, 0x81, 0x09, 0x0f, 0x0d, 0x87, 0x91, 0xb2}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| SM1_CBC运算 | ", num++); ++ ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ nInlen = 32; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_SM1_CBC, pbIV, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ //加密结果与标准密文比较 ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_SM1_CBC, pbIV, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密后结果与标准明文数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_SSF33_ECB & SGD_SYMM_ALG_MASK) ++ { ++ //与标准数据比较 ++ unsigned char pbKeyValue[16] = {0x67, 0xbe, 0x03, 0x7c, 0x41, 0x96, 0x6d, 0xdb, 0x8c, 0x36, 0x27, 0x48, 0x5a, 0x05, 0x93, 0xa5}; ++ unsigned char pbPlainText[16] = {0xa9, 0x37, 0x07, 0x49, 0xfc, 0x06, 0xaf, 0xe6, 0x4e, 0x30, 0x68, 0x01, 0xd2, 0x31, 0xb3, 0xac}; ++ unsigned char pbCipherText[16] = {0x9a, 0xb7, 0x1c, 0xcc, 0x22, 0x7e, 0x9e, 0x58, 0x7a, 0xa0, 0xe6, 0xcf, 0x49, 0x08, 0x5d, 0x1f}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| SSF33_ECB运算 | ", num++); ++ ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ ++ nInlen = 16; ++ ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_SSF33_ECB, pIv, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ //与标准密文数据比较 ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_SSF33_ECB, pIv, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密后结果与标准明文数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_SSF33_CBC & SGD_SYMM_ALG_MASK) ++ { ++ //标准数据校验 ++ unsigned char pbKeyValue[16] = {0x40, 0xbb, 0x12, 0xdd, 0x6a, 0x82, 0x73, 0x86, 0x7f, 0x35, 0x29, 0xd3, 0x54, 0xb4, 0xa0, 0x26}; ++ unsigned char pbIV[16] = {0xe8, 0x3d, 0x17, 0x15, 0xac, 0xf3, 0x48, 0x63, 0xac, 0xeb, 0x93, 0xe0, 0xe5, 0xab, 0x8b, 0x90}; ++ unsigned char pbPlainText[32] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; ++ unsigned char pbCipherText[32] = {0xfd, 0x3e, 0x17, 0xf4, 0xde, 0x33, 0xe2, 0x96, 0xf9, 0x9e, 0x37, 0x92, 0x45, 0x6b, 0x76, 0x2b, 0x9e, 0xe7, 0x13, 0x44, 0x5d, 0x91, 0x95, 0xf6, 0x4b, 0x34, 0x1b, 0x3a, 0xe7, 0x5c, 0x68, 0x75}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| SSF33_CBC运算 | ", num++); ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ nInlen = 32; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_SSF33_CBC, pbIV, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ //与标准密文数据比较 ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_SSF33_CBC, pbIV, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密结果与标准明文数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_AES_ECB & SGD_SYMM_ALG_MASK) ++ { ++ //与标准数据比较 ++ unsigned char pbKeyValue[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}; ++ unsigned char pbPlainText[16] = {0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20}; ++ unsigned char pbCipherText[16] = {0xde, 0x2e, 0x12, 0xe4, 0x0b, 0xd1, 0xd8, 0x60, 0xe3, 0xe4, 0x24, 0x31, 0x3b, 0xd3, 0x72, 0xdc}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| AES_ECB运算 | ", num++); ++ ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ nInlen = 16; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_AES_ECB, pIv, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ //与标准密文数据比较 ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_AES_ECB, pIv, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密结果与标准明文数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_DES_ECB & SGD_SYMM_ALG_MASK) ++ { ++ //与标准数据比较 ++ unsigned char pbKeyValue[8] = {0x67, 0xbe, 0x03, 0x7c, 0x41, 0x96, 0x6d, 0xdb}; ++ unsigned char pbPlainText[8] = {0xa9, 0x37, 0x07, 0x49, 0xfc, 0x06, 0xaf, 0xe6}; ++ unsigned char pbCipherText[8] = {0x60, 0x78, 0x32, 0xe8, 0xb3, 0x5a, 0x9c, 0x6d}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| DES_ECB运算 | ", num++); ++ ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 8, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ nInlen = 8; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_DES_ECB, pIv, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ //与标准密文数据比较 ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_DES_ECB, pIv, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密结果与标准数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_3DES_ECB & SGD_SYMM_ALG_MASK) ++ { ++ //与标准数据比较 ++ unsigned char pbKeyValue[16] = {0x40, 0xbb, 0x12, 0xdd, 0x6a, 0x82, 0x73, 0x86, 0x7f, 0x35, 0x29, 0xd3, 0x54, 0xb4, 0xa0, 0x26}; ++ unsigned char pbPlainText[8] = {0x49, 0x07, 0x37, 0xa9, 0xe6, 0xaf, 0x06, 0xfc}; ++ unsigned char pbCipherText[8] = {0x43, 0x01, 0xc5, 0x6b, 0x14, 0x00, 0xe7, 0xce}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| 3DES_ECB运算 | ", num++); ++ ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ nInlen = 8; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_3DES_ECB, pIv, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ //与标准密文数据比较 ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_3DES_ECB, pIv, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密结果与标准数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_SM4_ECB & SGD_SYMM_ALG_MASK) ++ { ++ //与标准数据比较 ++ unsigned char pbKeyValue[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; ++ unsigned char pbPlainText[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; ++ unsigned char pbCipherText[16] = {0x68, 0x1e, 0xdf, 0x34, 0xd2, 0x06, 0x96, 0x5e, 0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 0x42, 0x46}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| SM4_ECB运算 | ", num++); ++ ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ nInlen = 16; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_SM4_ECB, pIv, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ //与标准密文数据比较 ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pIv, 0, 16); ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_SM4_ECB, pIv, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密结果与标准明文数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_SM4_CBC & SGD_SYMM_ALG_MASK) ++ { ++ //与标准数据比较 ++ unsigned char pbKeyValue[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; ++ unsigned char pbIV[16] = {0xeb, 0xee, 0xc5, 0x68, 0x58, 0xe6, 0x04, 0xd8, 0x32, 0x7b, 0x9b, 0x3c, 0x10, 0xc9, 0x0c, 0xa7}; ++ unsigned char pbPlainText[32] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x29, 0xbe, 0xe1, 0xd6, 0x52, 0x49, 0xf1, 0xe9, 0xb3, 0xdb, 0x87, 0x3e, 0x24, 0x0d, 0x06, 0x47}; ++ unsigned char pbCipherText[32] = {0x3f, 0x1e, 0x73, 0xc3, 0xdf, 0xd5, 0xa1, 0x32, 0x88, 0x2f, 0xe6, 0x9d, 0x99, 0x6c, 0xde, 0x93, 0x54, 0x99, 0x09, 0x5d, 0xde, 0x68, 0x99, 0x5b, 0x4d, 0x70, 0xf2, 0x30, 0x9f, 0x2e, 0xf1, 0xb7}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| SM4_CBC运算 | ", num++); ++ ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ nInlen = 32; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_SM4_CBC, pbIV, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ //与标准密文数据比较 ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_SM4_CBC, pbIV, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密结果与标准明文数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if ((stDeviceInfo.SymAlgAbility & SGD_SM4_XTS & SGD_SYMM_ALG_MASK) && (stDeviceInfo.SymAlgAbility & SGD_SM4_XTS & SGD_SYMM_ALG_MODE_MASK)) ++ { ++ //与标准数据比较 ++ unsigned char pbKeyValue[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; ++ unsigned char pbIV[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; ++ unsigned char pbPlainText[48] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, ++ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x11, ++ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x12}; ++ unsigned char pbCipherText[48] = {0x55, 0x13, 0xa7, 0x57, 0x57, 0xaf, 0xc1, 0xc2, 0xa2, 0xb6, 0xc2, 0x11, 0x6f, 0xeb, 0x2b, 0x19, ++ 0x29, 0x53, 0x9b, 0x73, 0xe5, 0x35, 0x00, 0x06, 0xab, 0x29, 0xb6, 0xe0, 0x84, 0x7b, 0xe1, 0x67, ++ 0x6d, 0xd9, 0x21, 0x65, 0x41, 0x51, 0x4a, 0x24, 0xc4, 0x19, 0xd3, 0xb7, 0xd7, 0xe0, 0x3c, 0xf1}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| SM4_XTS运算 | ", num++); ++ ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ nInlen = 48; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_Encrypt_Ex(hSessionHandle, hKeyHandle, hKeyHandle, SGD_SM4_XTS, pbIV, pbPlainText, nInlen, pbTempData, &ulTempDataLen, nInlen); ++ if (rv == SDR_OK) ++ { ++ //与标准密文数据比较 ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ rv = SDF_Decrypt_Ex(hSessionHandle, hKeyHandle, hKeyHandle, SGD_SM4_XTS, pbIV, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen, ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密结果与标准明文数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_SM7_ECB & SGD_SYMM_ALG_MASK) ++ { ++ //标准数据 -- 第一组 ++ //unsigned char pbKeyValue[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff}; ++ //unsigned char pbPlainText[8] = {0x77,0x66,0x55,0x44,0x33,0x22,0x11,0x00}; ++ //unsigned char pbCipherText[8] = {0x67,0xfa,0xa9,0x75,0xf1,0x28,0xd1,0xfc}; ++ ++ //标准数据 -- 第二组 ++ //unsigned char pbKeyValue[16] = {0x1F,0xD3,0x84,0xD8,0x6B,0x50,0xBE,0x01,0x21,0x43,0xD6,0x16,0x18,0x15,0x19,0x83}; ++ //unsigned char pbPlainText[8] = {0xE2,0x73,0x2F,0xB8,0x1D,0x7D,0x7E,0x51}; ++ //unsigned char pbCipherText[8] = {0xCE,0x3C,0x08,0xD4,0x02,0xAE,0x24,0x7C}; ++ ++ //标准数据 -- 第三组 ++ unsigned char pbKeyValue[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}; ++ unsigned char pbPlainText[8] = {0x1a, 0x17, 0x02, 0xe5, 0xea, 0x62, 0x31, 0xb4}; ++ unsigned char pbCipherText[8] = {0xaf, 0xa2, 0xb6, 0x9d, 0xca, 0x09, 0xa3, 0xef}; ++ ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ unsigned char pbOutData[128] = {0}; ++ unsigned int ulOutDataLen; ++ ++ printf(" %02d| SM7_ECB运算 | ", num++); ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ nInlen = 8; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_Encrypt(hSessionHandle, hKeyHandle, SGD_SM7_ECB, NULL, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((nInlen == ulTempDataLen) && (memcmp(pbCipherText, pbTempData, nInlen) == 0)) ++ { ++ printf("运算结果:加密密文与标准密文数据比较成功。\n"); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密密文与标准密文数据比较失败。\n"); ++ return 1; ++ } ++ ++ memset(pbOutData, 0, sizeof(pbOutData)); ++ ulOutDataLen = sizeof(pbOutData); ++ ++ rv = SDF_Decrypt(hSessionHandle, hKeyHandle, SGD_SM7_ECB, NULL, pbTempData, ulTempDataLen, pbOutData, &ulOutDataLen); ++ if (rv == SDR_OK) ++ { ++ if ((ulOutDataLen == nInlen) && (memcmp(pbPlainText, pbOutData, nInlen) == 0)) ++ { ++ printf("标准数据加密、解密及结果比较均正确。\n"); ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密后结果与标准明文数据比较失败。\n"); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:解密错误,[%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:加密错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++//计算MAC测试 ++int SymmCalculateMACTest(SGD_HANDLE hSessionHandle) ++{ ++ int rv; ++ int num = 1; ++ SGD_HANDLE hKeyHandle; ++ DEVICEINFO stDeviceInfo; ++ unsigned int nInlen; ++ ++ memset(&stDeviceInfo, 0, sizeof(DEVICEINFO)); ++ ++ rv = SDF_GetDeviceInfo(hSessionHandle, &stDeviceInfo); ++ if (rv != SDR_OK) ++ { ++ printf("\n获取设备信息错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf("MAC算法正确性测试:\n"); ++ printf("---------------------\n"); ++ printf("\n"); ++ printf("\n"); ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_SM1_CBC & SGD_SYMM_ALG_MASK) ++ { ++ //标准数据 ++ unsigned char pbKeyValue[16] = {0x40, 0xbb, 0x12, 0xdd, 0x6a, 0x82, 0x73, 0x86, 0x7f, 0x35, 0x29, 0xd3, 0x54, 0xb4, 0xa0, 0x26}; ++ unsigned char pbIV[16] = {0xe8, 0x3d, 0x17, 0x15, 0xac, 0xf3, 0x48, 0x63, 0xac, 0xeb, 0x93, 0xe0, 0xe5, 0xab, 0x8b, 0x90}; ++ unsigned char pbPlainText[32] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; ++ unsigned char pbCipherText[32] = {0x3a, 0x70, 0xb5, 0xd4, 0x9a, 0x78, 0x2c, 0x07, 0x2d, 0xe1, 0x13, 0x43, 0x81, 0x9e, 0xc6, 0x59, 0xf8, 0xfc, 0x7a, 0xf0, 0x5e, 0x7c, 0x6d, 0xfb, 0x5f, 0x81, 0x09, 0x0f, 0x0d, 0x87, 0x91, 0xb2}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ ++ printf(" %02d| SM1_MAC | ", num++); ++ ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ //标准数据计算MAC测试 ++ nInlen = 32; ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ ++ rv = SDF_CalculateMAC(hSessionHandle, hKeyHandle, SGD_SM1_MAC, pbIV, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv != SDR_OK) ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:标准数据计算MAC错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ //销毁对称密钥 ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ ++ //与标准MAC比较 ++ if ((ulTempDataLen != 16) || (memcmp(&pbCipherText[16], pbTempData, 16) != 0)) ++ { ++ printf("运算结果:标准数据计算MAC结果值与标准MAC值不相等。\n"); ++ return 1; ++ } ++ else ++ { ++ printf("标准数据计算MAC值及结果比较均正确。\n"); ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_SSF33_CBC & SGD_SYMM_ALG_MASK) ++ { ++ //标准数据校验 ++ unsigned char pbKeyValue[16] = {0x40, 0xbb, 0x12, 0xdd, 0x6a, 0x82, 0x73, 0x86, 0x7f, 0x35, 0x29, 0xd3, 0x54, 0xb4, 0xa0, 0x26}; ++ unsigned char pbIV[16] = {0xe8, 0x3d, 0x17, 0x15, 0xac, 0xf3, 0x48, 0x63, 0xac, 0xeb, 0x93, 0xe0, 0xe5, 0xab, 0x8b, 0x90}; ++ unsigned char pbPlainText[32] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; ++ unsigned char pbCipherText[32] = {0xfd, 0x3e, 0x17, 0xf4, 0xde, 0x33, 0xe2, 0x96, 0xf9, 0x9e, 0x37, 0x92, 0x45, 0x6b, 0x76, 0x2b, 0x9e, 0xe7, 0x13, 0x44, 0x5d, 0x91, 0x95, 0xf6, 0x4b, 0x34, 0x1b, 0x3a, 0xe7, 0x5c, 0x68, 0x75}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ ++ printf(" %02d| SSF33_MAC | ", num++); ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ //标准数据计算MAC测试 ++ nInlen = 32; ++ ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ rv = SDF_CalculateMAC(hSessionHandle, hKeyHandle, SGD_SSF33_MAC, pbIV, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv != SDR_OK) ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:标准数据计算MAC错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ //销毁对称密钥 ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ ++ //与标准MAC比较 ++ if ((ulTempDataLen != 16) || (memcmp(&pbCipherText[16], pbTempData, 16) != 0)) ++ { ++ printf("运算结果:标准数据计算MAC结果值与标准MAC值不相等。\n"); ++ return 1; ++ } ++ else ++ { ++ printf("标准数据计算MAC值及结果比较均正确。\n"); ++ } ++ } ++ ++ if (stDeviceInfo.SymAlgAbility & SGD_SM4_CBC & SGD_SYMM_ALG_MASK) ++ { ++ //与标准数据比较 ++ unsigned char pbKeyValue[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; ++ unsigned char pbIV[16] = {0xeb, 0xee, 0xc5, 0x68, 0x58, 0xe6, 0x04, 0xd8, 0x32, 0x7b, 0x9b, 0x3c, 0x10, 0xc9, 0x0c, 0xa7}; ++ unsigned char pbPlainText[32] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x29, 0xbe, 0xe1, 0xd6, 0x52, 0x49, 0xf1, 0xe9, 0xb3, 0xdb, 0x87, 0x3e, 0x24, 0x0d, 0x06, 0x47}; ++ unsigned char pbCipherText[32] = {0x3f, 0x1e, 0x73, 0xc3, 0xdf, 0xd5, 0xa1, 0x32, 0x88, 0x2f, 0xe6, 0x9d, 0x99, 0x6c, 0xde, 0x93, 0x54, 0x99, 0x09, 0x5d, 0xde, 0x68, 0x99, 0x5b, 0x4d, 0x70, 0xf2, 0x30, 0x9f, 0x2e, 0xf1, 0xb7}; ++ unsigned char pbTempData[128] = {0}; ++ unsigned int ulTempDataLen; ++ ++ printf(" %02d| SM4_MAC | ", num++); ++ rv = SDF_ImportKey(hSessionHandle, pbKeyValue, 16, &hKeyHandle); ++ if (rv != SDR_OK) ++ { ++ printf("导入明文会话密钥错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ //标准数据计算MAC测试 ++ nInlen = 32; ++ ++ memset(pbTempData, 0, sizeof(pbTempData)); ++ ulTempDataLen = sizeof(pbTempData); ++ ++ rv = SDF_CalculateMAC(hSessionHandle, hKeyHandle, SGD_SM4_MAC, pbIV, pbPlainText, nInlen, pbTempData, &ulTempDataLen); ++ if (rv != SDR_OK) ++ { ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ printf("运算结果:标准数据计算MAC错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ //销毁对称密钥 ++ SDF_DestroyKey(hSessionHandle, hKeyHandle); ++ ++ //与标准MAC比较 ++ if ((ulTempDataLen != 16) || (memcmp(&pbCipherText[16], pbTempData, 16) != 0)) ++ { ++ printf("运算结果:标准数据计算MAC结果值与标准MAC值不相等。\n"); ++ return 1; ++ } ++ else ++ { ++ printf("标准数据计算MAC值及结果比较均正确。\n"); ++ } ++ } ++ ++ return 0; ++} ++ ++int HashFuncTest(int nDefaultSelect) ++{ ++ int rv; ++ int nSel; ++ int recode = 0; ++ SGD_HANDLE hSessionHandle; ++ ++ if ((nDefaultSelect < 1) || (nDefaultSelect > 2)) ++ nSel = 1; ++ else ++ nSel = nDefaultSelect; ++ ++ //创建会话句柄 ++ rv = SDF_OpenSession(hDeviceHandle, &hSessionHandle); ++ if (rv != SDR_OK) ++ { ++ printf("打开会话句柄错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf(" 1|杂凑算法运算测试\n"); ++ printf(" | 对输入数据进行杂凑运算并输出结果。\n"); ++ printf("\n"); ++ nSel = HashTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ printf(" 2|杂凑算法正确性测试\n"); ++ printf(" | 使用标准数据验证杂凑算法的正确性。\n"); ++ printf("\n"); ++ nSel = HashCorrectnessTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ SDF_CloseSession(hSessionHandle); ++ return recode; ++} ++ ++int HashTest(SGD_HANDLE hSessionHandle) ++{ ++ int rv; ++ unsigned int puiAlg[20]; ++ int nSelAlg = 1; ++ int i = 1; ++ int nInlen, nOutlen; ++ DEVICEINFO stDeviceInfo; ++ unsigned char pIndata[16384], pOutdata[128]; ++ ++ memset(&stDeviceInfo, 0, sizeof(DEVICEINFO)); ++ ++ rv = SDF_GetDeviceInfo(hSessionHandle, &stDeviceInfo); ++ if (rv != SDR_OK) ++ { ++ printf("\n获取设备信息错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf("哈希算法运算测试:\n"); ++ printf("-------------\n"); ++ printf("\n"); ++ printf("当前密码卡支持以下算法,默认测试第一项。\n"); ++ printf("\n"); ++ ++ if (stDeviceInfo.HashAlgAbility & SGD_SM3 & 0xFF) ++ { ++ printf(" %d | SGD_SM3\n\n", i); ++ puiAlg[i++] = SGD_SM3; ++ } ++ if (stDeviceInfo.HashAlgAbility & SGD_SHA1 & 0xFF) ++ { ++ printf(" %d | SGD_SHA1\n\n", i); ++ puiAlg[i++] = SGD_SHA1; ++ } ++ if (stDeviceInfo.HashAlgAbility & SGD_SHA224 & 0xFF) ++ { ++ printf(" %d | SGD_SHA224\n\n", i); ++ puiAlg[i++] = SGD_SHA224; ++ } ++ if (stDeviceInfo.HashAlgAbility & SGD_SHA256 & 0xFF) ++ { ++ printf(" %d | SGD_SHA256\n\n", i); ++ puiAlg[i++] = SGD_SHA256; ++ } ++ if (stDeviceInfo.HashAlgAbility & SGD_SHA384 & 0xFF) ++ { ++ printf(" %d | SGD_SHA384\n\n", i); ++ puiAlg[i++] = SGD_SHA384; ++ } ++ if (stDeviceInfo.HashAlgAbility & SGD_SHA512 & 0xFF) ++ { ++ printf(" %d | SGD_SHA512\n\n", i); ++ puiAlg[i++] = SGD_SHA512; ++ } ++ if (stDeviceInfo.HashAlgAbility & SGD_MD5 & 0xFF) ++ { ++ printf(" %d | SGD_MD5\n\n", i); ++ puiAlg[i++] = SGD_MD5; ++ } ++ nSelAlg = 1; ++ nInlen = 1024; ++ printf("算法标识:0x%08x\n", puiAlg[nSelAlg]); ++ printf("数据长度:%d\n", nInlen); ++ ++ rv = SDF_GenerateRandom(hSessionHandle, nInlen, pIndata); ++ if (rv == SDR_OK) ++ { ++ rv = SDF_HashInit(hSessionHandle, puiAlg[nSelAlg], NULL, NULL, 0); ++ if (rv == SDR_OK) ++ { ++ rv = SDF_HashUpdate(hSessionHandle, pIndata, nInlen); ++ if (rv == SDR_OK) ++ { ++ rv = SDF_HashFinal(hSessionHandle, pOutdata, &nOutlen); ++ if (rv == SDR_OK) ++ { ++ PrintData("运算结果", pOutdata, nOutlen, 16); ++ } ++ else ++ { ++ printf("运算结果:SDF_HashFinal()错误,[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ printf("运算结果:SDF_HashUpdate()错误,[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ printf("运算结果:SDF_HashInit()错误,[0x%08x]\n", rv); ++ return 1; ++ } ++ } ++ else ++ { ++ printf("运算结果:产生随机加密数据错误,[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int HashCorrectnessTest(SGD_HANDLE hSessionHandle) ++{ ++ unsigned int rv; ++ int num = 1; ++ ++ DEVICEINFO stDeviceInfo; ++ ++ memset(&stDeviceInfo, 0, sizeof(DEVICEINFO)); ++ ++ rv = SDF_GetDeviceInfo(hSessionHandle, &stDeviceInfo); ++ if (rv != SDR_OK) ++ { ++ printf("\n获取设备信息错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf("杂凑算法正确性测试:\n"); ++ printf("---------------------\n"); ++ printf("\n"); ++ ++ if (stDeviceInfo.HashAlgAbility & SGD_SM3) ++ { ++ unsigned char bHashData[64] = {0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, ++ 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, ++ 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, ++ 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 0x64}; ++ ++ unsigned char bHashStdResult[32] = {0xde, 0xbe, 0x9f, 0xf9, 0x22, 0x75, 0xb8, 0xa1, 0x38, 0x60, 0x48, 0x89, 0xc1, 0x8e, 0x5a, 0x4d, ++ 0x6f, 0xdb, 0x70, 0xe5, 0x38, 0x7e, 0x57, 0x65, 0x29, 0x3d, 0xcb, 0xa3, 0x9c, 0x0c, 0x57, 0x32}; ++ unsigned char bHashResult[256]; ++ unsigned int uiHashResultLen; ++ ++ printf(" %02d| SM3运算 | ", num++); ++ ++ rv = SDF_HashInit(hSessionHandle, SGD_SM3, NULL, NULL, 0); ++ if (rv != SDR_OK) ++ { ++ printf("SDF_HashInit函数错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ rv = SDF_HashUpdate(hSessionHandle, bHashData, 64); ++ if (rv != SDR_OK) ++ { ++ printf("SDF_HashUpdate函数错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ memset(bHashResult, 0x0, sizeof(bHashResult)); ++ uiHashResultLen = sizeof(bHashResult); ++ ++ rv = SDF_HashFinal(hSessionHandle, bHashResult, &uiHashResultLen); ++ if (rv != SDR_OK) ++ { ++ printf("SDF_HashFinal函数错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ //哈希值与标准哈希值比对 ++ if ((uiHashResultLen != 32) || (memcmp(bHashStdResult, bHashResult, 32) != 0)) ++ { ++ printf("杂凑值与标准数据杂凑值比较失败\n"); ++ return 1; ++ } ++ else ++ { ++ printf("标准数据杂凑运算验证成功。\n"); ++ } ++ } ++ ++ return 0; ++} ++ ++int FileFuncTest(int nDefaultSelect) ++{ ++ int nSel, rv; ++ SGD_HANDLE hSessionHandle; ++ int recode = 0; ++ ++ if ((nDefaultSelect < 1) || (nDefaultSelect > 4)) ++ nSel = 1; ++ else ++ nSel = nDefaultSelect; ++ ++ //创建会话句柄 ++ rv = SDF_OpenSession(hDeviceHandle, &hSessionHandle); ++ if (rv != SDR_OK) ++ { ++ printf("打开会话句柄错误,错误码[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ printf(" 1|用户文件操作测试\n"); ++ printf(" | 根据指定的文件名和大小,创建用户文件。\n"); ++ printf(" | 将数据写入用户文件。\n"); ++ printf(" | 读取用户文件。\n"); ++ printf(" | 根据指定的文件名删除用户文件。\n"); ++ printf("\n"); ++ nSel = CreateFileTest(hSessionHandle); ++ if (nSel == 1) ++ { ++ recode = 1; ++ } ++ ++ SDF_CloseSession(hSessionHandle); ++ ++ return recode; ++} ++ ++int CreateFileTest(SGD_HANDLE hSessionHandle) ++{ ++ char filename[256]; ++ int nInlen; ++ int nOffset = 0; ++ unsigned char inData[65536]; ++ unsigned int rv; ++ ++ printf("创建用户文件测试:\n"); ++ printf("-----------------\n"); ++ strcpy(filename, "keycard_test_del_file"); ++ nInlen = 32; ++ printf("文件名称:%s\n", filename); ++ printf("文件大小:%d\n", nInlen); ++ ++ rv = SDF_CreateFile(hSessionHandle, filename, (unsigned int)strlen(filename), nInlen); ++ if (rv != SDR_OK) ++ { ++ printf("执行结果:创建文件错误,[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("执行结果:创建文件成功\n"); ++ ++ rv = SDF_GenerateRandom(hSessionHandle, nInlen, inData); ++ if (rv != SDR_OK) ++ { ++ printf("产生随机数据错误,[0x%08x]\n", rv); ++ return 1; ++ } ++ ++ rv = SDF_WriteFile(hSessionHandle, filename, (unsigned int)strlen(filename), nOffset, nInlen, inData); ++ if (rv != SDR_OK) ++ { ++ printf("执行结果:写文件错误,[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("执行结果:写文件成功\n"); ++ PrintData("写入数据", inData, nInlen, 16); ++ ++ rv = SDF_ReadFile(hSessionHandle, filename, (unsigned int)strlen(filename), nOffset, &nInlen, inData); ++ if (rv != SDR_OK) ++ { ++ printf("执行结果:读文件错误,[0x%08x]\n", rv); ++ return 1; ++ } ++ printf("执行结果:读文件成功\n"); ++ PrintData("读取数据", inData, nInlen, 16); ++ ++ rv = SDF_DeleteFile(hSessionHandle, filename, (unsigned int)strlen(filename)); ++ if (rv != SDR_OK) ++ { ++ printf("执行结果:删除文件错误,错误码[%08x]\n", rv); ++ return 1; ++ } ++ printf("执行结果:删除文件成功\n"); ++ ++ return 0; ++} +\ No newline at end of file +diff -urN oec-hardware-1.0.0/tests/keycard/keycard.py oec-hardware/tests/keycard/keycard.py +--- oec-hardware-1.0.0/tests/keycard/keycard.py 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/keycard/keycard.py 2022-05-31 22:01:38.405873225 +0800 +@@ -0,0 +1,79 @@ ++#!/usr/bin/env python ++# coding: utf-8 ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2.gica's ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Author: @meitingli ++# Create: 2022-03-28 ++ ++"""public key card test""" ++ ++import os ++import subprocess ++ ++from hwcompatible.command import Command, CertCommandError ++from hwcompatible.test import Test ++from hwcompatible.commandUI import CommandUI ++ ++keycard_dir = os.path.dirname(os.path.realpath(__file__)) ++ ++ ++class KeyCardTest(Test): ++ """ ++ Key card Test ++ """ ++ ++ def __init__(self): ++ Test.__init__(self) ++ self.logpath = None ++ self.com_ui = CommandUI() ++ ++ def setup(self, args=None): ++ """ ++ Initialization before test ++ """ ++ self.args = args or argparse.Namespace() ++ self.name = getattr(args, "testname", "keycard") ++ self.logpath = getattr(args, "logdir", None) + "/" + self.name + ".log" ++ ++ def test(self): ++ """ ++ Run key card test case ++ return: result ++ """ ++ result = True ++ ui_message_list = [ ++ "Which test suite would you like to test: ", ++ "1|基本函数测试", ++ "2|RSA非对称密码运算函数测试", ++ "3|ECC非对称密码运算函数测试", ++ "4|对称密码运算函数测试", ++ "5|杂凑运算函数测试", ++ "6|用户文件操作函数测试", ++ "Enter space to split(ex: 1 2 3)\n" ++ ] ++ ui_message = "\n".join(ui_message_list) ++ execnum = self.com_ui.prompt(ui_message) ++ print("Start to test, please wait...") ++ execnum = execnum.split(" ") ++ for num in execnum: ++ if os.system("cd %s; echo %s | ./TestSDS &>> %s" % (keycard_dir, num, self.logpath)) != 0: ++ result = False ++ ++ if result: ++ print("Test key card succeed.") ++ else: ++ print("Test key card failed.") ++ return result ++ ++ ++if __name__ == '__main__': ++ t = KeyCardTest() ++ t.setup() ++ t.test() +Binary files oec-hardware-1.0.0/tests/keycard/libswsds_aarch64.so and oec-hardware/tests/keycard/libswsds_aarch64.so differ +Binary files oec-hardware-1.0.0/tests/keycard/libswsds_x86_64.so and oec-hardware/tests/keycard/libswsds_x86_64.so differ +diff -urN oec-hardware-1.0.0/tests/keycard/Makefile oec-hardware/tests/keycard/Makefile +--- oec-hardware-1.0.0/tests/keycard/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/keycard/Makefile 2022-05-31 22:01:38.403873181 +0800 +@@ -0,0 +1,46 @@ ++#!/usr/bin/env python ++# coding: utf-8 ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Author: @meitingli ++# Create: 2022-04-11 ++ ++CC=gcc ++CFLAGS=-Wall -D_LOG_TRACE_ -fPIC -I. ++LIBS = -L . -lswsds -lpthread ++OBJS=./TestSDS.o FunctionTest.o Util.o ++APPS=TestSDS ++ARCH := $(shell uname -m) ++SO=libswsds_$(ARCH).so ++ ++all: $(APPS) ++ ++install: ++ mkdir -p $(DEST) ++ cp $(SO) /usr/lib64/libswsds.so ++ cp $(SO) $(DEST)/libswsds.so ++ $(CC) -O2 -fPIC -Wl,--hash-style=sysv -o $(APPS) $(OBJS) $(LIBS) ++ cp -a *.py $(DEST) ++ cp $(APPS) $(DEST) ++ chmod a+x $(DEST)/*.py ++ ++%.o:%.c ++ $(CC) -O2 -c $(CFLAGS) $< -o $@ ++ ++$(APPS):$(OBJS) ++ cp $(SO) /usr/lib64/libswsds.so ++ cp $(SO) libswsds.so ++ $(CC) -O2 -fPIC -Wl,--hash-style=sysv -o $(APPS) $(OBJS) $(LIBS) ++ ++clean: ++ rm -f *.o $(APPS) libswsds.so ++ ++cleanall: ++ rm -f *.o $(APPS) libswsds.so +diff -urN oec-hardware-1.0.0/tests/keycard/swsds.h oec-hardware/tests/keycard/swsds.h +--- oec-hardware-1.0.0/tests/keycard/swsds.h 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/keycard/swsds.h 2022-05-31 22:01:38.412873380 +0800 +@@ -0,0 +1,206 @@ ++/** ++* 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: @sansec/@meitingli ++* Create: 2022-04-11 ++**/ ++ ++#ifndef _SW_SDS_H_ ++#define _SW_SDS_H_ 1 ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++ /*数据类型定义*/ ++ typedef char SGD_CHAR; ++ typedef char SGD_INT8; ++ typedef short SGD_INT16; ++ typedef int SGD_INT32; ++ typedef long long SGD_INT64; ++ typedef unsigned char SGD_UCHAR; ++ typedef unsigned char SGD_UINT8; ++ typedef unsigned short SGD_UINT16; ++ typedef unsigned int SGD_UINT32; ++ typedef unsigned long long SGD_UINT64; ++ typedef unsigned int SGD_RV; ++ typedef void *SGD_OBJ; ++ typedef int SGD_BOOL; ++ typedef void *SGD_HANDLE; ++ ++ typedef struct DeviceInfo_st ++ { ++ unsigned char IssuerName[40]; ++ unsigned char DeviceName[16]; ++ unsigned char DeviceSerial[16]; ++ unsigned int DeviceVersion; ++ unsigned int StandardVersion; ++ unsigned int AsymAlgAbility[2]; ++ unsigned int SymAlgAbility; ++ unsigned int HashAlgAbility; ++ unsigned int BufferSize; ++ } DEVICEINFO; ++ ++#define RSAref_MAX_BITS 2048 ++#define RSAref_MAX_LEN ((RSAref_MAX_BITS + 7) / 8) ++#define RSAref_MAX_PBITS ((RSAref_MAX_BITS + 1) / 2) ++#define RSAref_MAX_PLEN ((RSAref_MAX_PBITS + 7) / 8) ++ ++ typedef struct RSArefPublicKey_st ++ { ++ unsigned int bits; ++ unsigned char m[RSAref_MAX_LEN]; ++ unsigned char e[RSAref_MAX_LEN]; ++ } RSArefPublicKey; ++ ++ typedef struct RSArefPrivateKey_st ++ { ++ unsigned int bits; ++ unsigned char m[RSAref_MAX_LEN]; ++ unsigned char e[RSAref_MAX_LEN]; ++ unsigned char d[RSAref_MAX_LEN]; ++ unsigned char prime[2][RSAref_MAX_PLEN]; ++ unsigned char pexp[2][RSAref_MAX_PLEN]; ++ unsigned char coef[RSAref_MAX_PLEN]; ++ } RSArefPrivateKey; ++ ++/*ECC密钥*/ ++#define ECCref_MAX_BITS 256 ++#define ECCref_MAX_LEN ((ECCref_MAX_BITS + 7) / 8) ++#define ECCref_MAX_CIPHER_LEN 136 ++ ++ typedef struct ECCrefPublicKey_st ++ { ++ unsigned int bits; ++ unsigned char x[ECCref_MAX_LEN]; ++ unsigned char y[ECCref_MAX_LEN]; ++ } ECCrefPublicKey; ++ ++ typedef struct ECCrefPrivateKey_st ++ { ++ unsigned int bits; ++ unsigned char D[ECCref_MAX_LEN]; ++ } ECCrefPrivateKey; ++ ++ typedef struct ECCCipher_st ++ { ++ unsigned int clength; ++ unsigned char x[ECCref_MAX_LEN]; ++ unsigned char y[ECCref_MAX_LEN]; ++ unsigned char C[ECCref_MAX_CIPHER_LEN]; ++ unsigned char M[ECCref_MAX_LEN]; ++ } ECCCipher; ++ ++ typedef struct ECCSignature_st ++ { ++ unsigned char r[ECCref_MAX_LEN]; ++ unsigned char s[ECCref_MAX_LEN]; ++ } ECCSignature; ++ ++/*算法标识*/ ++#define SGD_SM1_ECB 0x00000101 ++#define SGD_SM1_CBC 0x00000102 ++#define SGD_SM1_MAC 0x00000110 ++ ++#define SGD_SSF33_ECB 0x00000201 ++#define SGD_SSF33_CBC 0x00000202 ++#define SGD_SSF33_MAC 0x00000210 ++ ++#define SGD_AES_ECB 0x00000401 ++#define SGD_3DES_ECB 0x00000801 ++ ++#define SGD_SM4_ECB 0x00002001 ++#define SGD_SM4_CBC 0x00002002 ++#define SGD_SM4_MAC 0x00002010 ++#define SGD_SM4_XTS 0x00002040 ++ ++#define SGD_DES_ECB 0x00004001 ++ ++#define SGD_SM7_ECB 0x00008001 ++ ++#define SGD_RSA_SIGN 0x00010100 ++#define SGD_SM2_1 0x00020100 ++#define SGD_SM2_2 0x00020200 ++#define SGD_SM2_3 0x00020400 ++ ++#define SGD_SM3 0x00000001 ++#define SGD_SHA1 0x00000002 ++#define SGD_SHA256 0x00000004 ++#define SGD_SHA512 0x00000008 ++#define SGD_SHA384 0x00000010 ++#define SGD_SHA224 0x00000020 ++#define SGD_MD5 0x00000080 ++ ++#define SGD_SYMM_ALG_MASK 0xFFFFFF00 ++#define SGD_SYMM_ALG_MODE_MASK 0x000000FF ++ ++/*标准错误码定义*/ ++#define SDR_OK 0x0 /*成功*/ ++#define SDR_BASE 0x01000000 ++ ++ /*设备管理类函数*/ ++ SGD_RV SDF_OpenDevice(SGD_HANDLE *phDeviceHandle); ++ SGD_RV SDF_CloseDevice(SGD_HANDLE hDeviceHandle); ++ SGD_RV SDF_OpenSession(SGD_HANDLE hDeviceHandle, SGD_HANDLE *phSessionHandle); ++ SGD_RV SDF_CloseSession(SGD_HANDLE hSessionHandle); ++ SGD_RV SDF_GetDeviceInfo(SGD_HANDLE hSessionHandle, DEVICEINFO *pstDeviceInfo); ++ SGD_RV SDF_GenerateRandom(SGD_HANDLE hSessionHandle, SGD_UINT32 uiLength, SGD_UCHAR *pucRandom); ++ SGD_RV SDF_GetFirmwareVersion(SGD_HANDLE hSessionHandle, SGD_UCHAR *sFirmware, SGD_UINT32 *ulFirmwareLen); ++ SGD_RV SDF_GetLibraryVersion(SGD_HANDLE hSessionHandle, SGD_UCHAR *sLibraryVersion, SGD_UINT32 *ulLibraryVersionLen); ++ ++ /*密钥管理类函数*/ ++ SGD_RV SDF_GenerateKeyPair_RSA(SGD_HANDLE hSessionHandle, SGD_UINT32 uiKeyBits, RSArefPublicKey *pucPublicKey, RSArefPrivateKey *pucPrivateKey); ++ SGD_RV SDF_ImportKey(SGD_HANDLE hSessionHandle, SGD_UCHAR *pucKey, SGD_UINT32 uiKeyLength, SGD_HANDLE *phKeyHandle); ++ SGD_RV SDF_DestroyKey(SGD_HANDLE hSessionHandle, SGD_HANDLE hKeyHandle); ++ ++ SGD_RV SDF_GenerateKeyPair_ECC(SGD_HANDLE hSessionHandle, SGD_UINT32 uiAlgID, SGD_UINT32 uiKeyBits, ECCrefPublicKey *pucPublicKey, ECCrefPrivateKey *pucPrivateKey); ++ ++ /*非对称密码运算函数*/ ++ SGD_RV SDF_ExternalPublicKeyOperation_RSA(SGD_HANDLE hSessionHandle, RSArefPublicKey *pucPublicKey, SGD_UCHAR *pucDataInput, SGD_UINT32 uiInputLength, SGD_UCHAR *pucDataOutput, ++ SGD_UINT32 *puiOutputLength); ++ SGD_RV SDF_ExternalPrivateKeyOperation_RSA(SGD_HANDLE hSessionHandle, RSArefPrivateKey *pucPrivateKey, SGD_UCHAR *pucDataInput, SGD_UINT32 uiInputLength, SGD_UCHAR *pucDataOutput, ++ SGD_UINT32 *puiOutputLength); ++ ++ SGD_RV SDF_ExternalSign_ECC(SGD_HANDLE hSessionHandle, SGD_UINT32 uiAlgID, ECCrefPrivateKey *pucPrivateKey, SGD_UCHAR *pucData, SGD_UINT32 uiDataLength, ECCSignature *pucSignature); ++ SGD_RV SDF_ExternalVerify_ECC(SGD_HANDLE hSessionHandle, SGD_UINT32 uiAlgID, ECCrefPublicKey *pucPublicKey, SGD_UCHAR *pucDataInput, SGD_UINT32 uiInputLength, ECCSignature *pucSignature); ++ SGD_RV SDF_ExternalEncrypt_ECC(SGD_HANDLE hSessionHandle, SGD_UINT32 uiAlgID, ECCrefPublicKey *pucPublicKey, SGD_UCHAR *pucData, SGD_UINT32 uiDataLength, ECCCipher *pucEncData); ++ SGD_RV SDF_ExternalDecrypt_ECC(SGD_HANDLE hSessionHandle, SGD_UINT32 uiAlgID, ECCrefPrivateKey *pucPrivateKey, ECCCipher *pucEncData, SGD_UCHAR *pucData, SGD_UINT32 *puiDataLength); ++ ++ /*对称密码运算函数*/ ++ SGD_RV SDF_Encrypt(SGD_HANDLE hSessionHandle, SGD_HANDLE hKeyHandle, SGD_UINT32 uiAlgID, SGD_UCHAR *pucIV, SGD_UCHAR *pucData, SGD_UINT32 uiDataLength, SGD_UCHAR *pucEncData, ++ SGD_UINT32 *puiEncDataLength); ++ SGD_RV SDF_Decrypt(SGD_HANDLE hSessionHandle, SGD_HANDLE hKeyHandle, SGD_UINT32 uiAlgID, SGD_UCHAR *pucIV, SGD_UCHAR *pucEncData, SGD_UINT32 uiEncDataLength, SGD_UCHAR *pucData, ++ SGD_UINT32 *puiDataLength); ++ SGD_RV SDF_CalculateMAC(SGD_HANDLE hSessionHandle, SGD_HANDLE hKeyHandle, SGD_UINT32 uiAlgID, SGD_UCHAR *pucIV, SGD_UCHAR *pucData, SGD_UINT32 uiDataLength, SGD_UCHAR *pucMAC, ++ SGD_UINT32 *puiMACLength); ++ ++ SGD_RV SDF_Encrypt_Ex(SGD_HANDLE hSessionHandle, SGD_HANDLE hKeyHandle_1, SGD_HANDLE hKeyHandle_2, SGD_UINT32 uiAlgID, SGD_UCHAR *pucIV, SGD_UCHAR *pucData, SGD_UINT32 uiDataLength, ++ SGD_UCHAR *pucEncData, SGD_UINT32 *puiEncDataLength, SGD_UINT32 uiDataUnitLength); ++ SGD_RV SDF_Decrypt_Ex(SGD_HANDLE hSessionHandle, SGD_HANDLE hKeyHandle_1, SGD_HANDLE hKeyHandle_2, SGD_UINT32 uiAlgID, SGD_UCHAR *pucIV, SGD_UCHAR *pucEncData, SGD_UINT32 uiEncDataLength, ++ SGD_UCHAR *pucData, SGD_UINT32 *puiDataLength, SGD_UINT32 uiDataUnitLength); ++ ++ /*杂凑运算函数*/ ++ SGD_RV SDF_HashInit(SGD_HANDLE hSessionHandle, SGD_UINT32 uiAlgID, ECCrefPublicKey *pucPublicKey, SGD_UCHAR *pucID, SGD_UINT32 uiIDLength); ++ SGD_RV SDF_HashUpdate(SGD_HANDLE hSessionHandle, SGD_UCHAR *pucData, SGD_UINT32 uiDataLength); ++ SGD_RV SDF_HashFinal(SGD_HANDLE hSessionHandle, SGD_UCHAR *pucHash, SGD_UINT32 *puiHashLength); ++ SGD_RV SDF_HashInit_ECC(SGD_HANDLE hSessionHandle, SGD_UINT32 uiAlgID, SGD_UCHAR *pucParamID); ++ ++ /*用户文件操作函数*/ ++ SGD_RV SDF_CreateFile(SGD_HANDLE hSessionHandle, SGD_UCHAR *pucFileName, SGD_UINT32 uiNameLen, SGD_UINT32 uiFileSize); ++ SGD_RV SDF_ReadFile(SGD_HANDLE hSessionHandle, SGD_UCHAR *pucFileName, SGD_UINT32 uiNameLen, SGD_UINT32 uiOffset, SGD_UINT32 *puiReadLength, SGD_UCHAR *pucBuffer); ++ SGD_RV SDF_WriteFile(SGD_HANDLE hSessionHandle, SGD_UCHAR *pucFileName, SGD_UINT32 uiNameLen, SGD_UINT32 uiOffset, SGD_UINT32 uiWriteLength, SGD_UCHAR *pucBuffer); ++ SGD_RV SDF_DeleteFile(SGD_HANDLE hSessionHandle, SGD_UCHAR *pucFileName, SGD_UINT32 uiNameLen); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /*#ifndef _SW_SDS_H_*/ +\ No newline at end of file +diff -urN oec-hardware-1.0.0/tests/keycard/TestSDS.c oec-hardware/tests/keycard/TestSDS.c +--- oec-hardware-1.0.0/tests/keycard/TestSDS.c 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/keycard/TestSDS.c 2022-05-31 22:01:38.403873181 +0800 +@@ -0,0 +1,36 @@ ++/** ++* 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: @sansec/@meitingli ++* Create: 2022-04-11 ++**/ ++#include "TestSDS.h" ++ ++SGD_HANDLE hDeviceHandle; ++unsigned int g_nTestRepeat; ++ ++int main(int argc, char *argv[]) ++{ ++ int rv; ++ int nSel; ++ ++ //Connect to device ++ rv = SDF_OpenDevice(&hDeviceHandle); ++ if (rv != SDR_OK) ++ { ++ printf("Open device failed, the error code is [0x%08x]\n", rv); ++ return 1; ++ } ++ scanf("%d", &nSel); ++ rv = FunctionTest(nSel, 1); ++ SDF_CloseDevice(hDeviceHandle); ++ ++ return rv; ++} +\ No newline at end of file +diff -urN oec-hardware-1.0.0/tests/keycard/TestSDS.h oec-hardware/tests/keycard/TestSDS.h +--- oec-hardware-1.0.0/tests/keycard/TestSDS.h 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/keycard/TestSDS.h 2022-05-31 22:01:38.404873203 +0800 +@@ -0,0 +1,96 @@ ++/** ++* 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: @sansec/@meitingli ++* Create: 2022-04-11 ++**/ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef WIN32 ++#include ++#include ++#include ++#include ++#else ++#include ++#include ++#include ++#include ++#endif ++ ++#include "swsds.h" ++ ++#ifdef WIN32 ++#define PUTCH(ch) _putch(ch) ++#define GETCH() _getch() ++#define GETANYKEY() _getch() ++#define SLEEP(msec) Sleep(msec) ++#define THREAD_EXIT() _endthread() ++#define GETCURRENTTHREADID GetCurrentThreadId ++#else ++#define PUTCH(ch) putchar(ch) ++#define GETCH() getch_unix() ++#define GETANYKEY() getch_unix() ++#define SLEEP(msec) usleep(msec * 1000) ++#define THREAD_EXIT() pthread_exit(NULL) ++#define GETCURRENTTHREADID (int)pthread_self ++#endif ++ ++#define OPT_EXIT -1 ++#define OPT_RETURN -2 ++#define OPT_PREVIOUS -3 ++#define OPT_NEXT -4 ++#define OPT_YES -5 ++#define OPT_CANCEL -6 ++ ++#define TESTSDS_VERSION "v3.3" //版本控制信息 ++#define _NOT_TEST_KEK_ 1 //压力测试时不测试KEK功能 ++#define _NOT_USE_RANDOME_TEST_ 1 //性能测试时使用随机数据测试 ++#define MAX_SYMM_DATA_LENGTH 131072 ++ ++extern SGD_HANDLE hDeviceHandle; ++extern unsigned int g_nTestRepeat; ++ ++//功能测试函数声明 ++int BasicFuncTest(int nDefaultSelect); ++int CreateFileTest(SGD_HANDLE hSessionHandle); ++int ECCStdDataVerifyTest(SGD_HANDLE hSessionHandle); ++int ECCStdDataDecTest(SGD_HANDLE hSessionHandle); ++int ECCFuncTest(int nDefaultSelect); ++int ExtECCOptTest(SGD_HANDLE hSessionHandle); ++int ExtECCSignTest(SGD_HANDLE hSessionHandle); ++int ExtRSAOptTest(SGD_HANDLE hSessionHandle); ++int FileFuncTest(int nDefaultSelect); ++int FunctionTest(int nSel, int nDefaultSelect); ++int GenECCKeyPairTest(SGD_HANDLE hSessionHandle); ++int GenRandomTest(SGD_HANDLE hSessionHandle); ++int GenRSAKeyPairTest(SGD_HANDLE hSessionHandle); ++int GetDeviceInfoTest(SGD_HANDLE hSessionHandle); ++int HashFuncTest(int nDefaultSelect); ++int HashTest(SGD_HANDLE hSessionHandle); ++int HashCorrectnessTest(SGD_HANDLE hSessionHandle); ++int RSAFuncTest(int nDefaultSelect); ++int SymmCorrectnessTest(SGD_HANDLE hSessionHandle); ++int SymmCalculateMACTest(SGD_HANDLE hSessionHandle); ++int SymmFuncTest(int nDefaultSelect); ++ ++//辅助函数声明 ++#ifndef WIN32 ++int getch_unix(void); ++#endif ++ ++void GetAnyKey(); ++int PrintData(char *itemName, unsigned char *sourceData, unsigned int dataLength, unsigned int rowCount); ++unsigned int FileWrite(char *filename, char *mode, unsigned char *buffer, size_t size); +\ No newline at end of file +diff -urN oec-hardware-1.0.0/tests/keycard/Util.c oec-hardware/tests/keycard/Util.c +--- oec-hardware-1.0.0/tests/keycard/Util.c 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/keycard/Util.c 2022-05-31 22:01:38.404873203 +0800 +@@ -0,0 +1,109 @@ ++/** ++* 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: @sansec/@meitingli ++* Create: 2022-04-11 ++**/ ++#include "TestSDS.h" ++ ++int PrintData(char *itemName, unsigned char *sourceData, unsigned int dataLength, unsigned int rowCount) ++{ ++ int i, j; ++ ++ if ((sourceData == NULL) || (rowCount == 0) || (dataLength == 0)) ++ return -1; ++ ++ if (itemName != NULL) ++ printf("%s[%d]:\n", itemName, dataLength); ++ ++ for (i = 0; i < (int)(dataLength / rowCount); i++) ++ { ++ printf("%08x ", i * rowCount); ++ ++ for (j = 0; j < (int)rowCount; j++) ++ { ++ printf("%02x ", *(sourceData + i * rowCount + j)); ++ } ++ ++ printf("\n"); ++ } ++ ++ if (!(dataLength % rowCount)) ++ return 0; ++ ++ printf("%08x ", (dataLength / rowCount) * rowCount); ++ ++ for (j = 0; j < (int)(dataLength % rowCount); j++) ++ { ++ printf("%02x ", *(sourceData + (dataLength / rowCount) * rowCount + j)); ++ } ++ ++ printf("\n"); ++ ++ return 0; ++} ++ ++unsigned int FileWrite(char *filename, char *mode, unsigned char *buffer, size_t size) ++{ ++ FILE *fp; ++ unsigned int rw, rwed; ++ ++ if ((fp = fopen(filename, mode)) == NULL) ++ { ++ return 0; ++ } ++ ++ rwed = 0; ++ ++ while (size > rwed) ++ { ++ if ((rw = (unsigned int)fwrite(buffer + rwed, 1, size - rwed, fp)) <= 0) ++ { ++ break; ++ } ++ ++ rwed += rw; ++ } ++ ++ fclose(fp); ++ ++ return rwed; ++} ++ ++#ifndef WIN32 ++int getch_unix(void) ++{ ++ struct termios oldt, newt; ++ int ch; ++ ++ tcgetattr(0, &oldt); ++ ++ newt = oldt; ++ ++ newt.c_lflag &= ~(ICANON | ECHO); ++ ++ tcsetattr(0, TCSANOW, &newt); ++ ++ ch = getchar(); ++ ++ tcsetattr(0, TCSANOW, &oldt); ++ ++ return ch; ++} ++#endif ++ ++void GetAnyKey() ++{ ++ int ch; ++ ++ ch = GETCH(); ++ ++ return; ++} +diff -urN oec-hardware-1.0.0/tests/memory/memory.py oec-hardware/tests/memory/memory.py +--- oec-hardware-1.0.0/tests/memory/memory.py 2022-05-31 22:00:43.453655867 +0800 ++++ oec-hardware/tests/memory/memory.py 2022-05-31 22:01:38.415873447 +0800 +@@ -25,6 +25,7 @@ + """ + Memory Test + """ ++ + def __init__(self): + Test.__init__(self) + self.requirements = ["libhugetlbfs-utils"] +@@ -36,6 +37,7 @@ + self.hugepage_total = 0 + self.hugepage_free = 0 + self.retry_list = list() ++ self.logpath = None + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + + def setup(self, args=None): +@@ -43,6 +45,8 @@ + Initialization before test + :return: + """ ++ self.args = args or argparse.Namespace() ++ self.logpath = getattr(args, "logdir", None) + "/memory.log" + self.get_memory() + + def test(self): +@@ -59,9 +63,6 @@ + if not self.hugetlb_test(): + return False + +- if not self.memory_hotplug(): +- return False +- + return True + + def get_memory(self): +@@ -111,6 +112,7 @@ + test_mem = self.free_memory*90/100 + if test_mem > 1024*4: + test_mem = 1024*4 ++ + if os.system("memtester %sM 1" % test_mem) != 0: + print("Error: memtester fail.") + return False +@@ -130,7 +132,8 @@ + print("Error: get system memory fail.") + return False + if self.swap_memory < 512: +- print("Error: swap memory of %s MB is too small." % self.swap_memory) ++ print("Error: swap memory of %s MB is too small." % ++ self.swap_memory) + return False + + extra_mem = self.free_memory/100 +@@ -159,12 +162,12 @@ + if self.hugepage_size >= 512: + self.huge_pages = 10 + if not self.hugepage_total: +- os.system("hugeadm --create-mounts") +- os.system("hugeadm --pool-pages-min %dMB:%d" % +- (self.hugepage_size, self.huge_pages)) ++ os.system("hugeadm --create-mounts &>> %s" % self.logpath) ++ os.system("hugeadm --pool-pages-min %dMB:%d &>> %s" % ++ (self.hugepage_size, self.huge_pages, self.logpath)) + elif self.hugepage_free < self.huge_pages: +- os.system("hugeadm --pool-pages-min %dMB:%d" % +- (self.hugepage_size, self.hugepage_total + self.huge_pages)) ++ os.system("hugeadm --pool-pages-min %dMB:%d &>> %s" % ++ (self.hugepage_size, self.hugepage_total + self.huge_pages, self.logpath)) + else: + update_hugepage = 0 + +@@ -180,11 +183,11 @@ + return False + + try: +- Command("cd %s; ./hugetlb_test" % self.test_dir).echo() ++ Command("cd %s; ./hugetlb_test &>> %s" % ++ (self.test_dir, self.logpath)).echo() + print("Hugetlb test succ.\n") + except CertCommandError as concrete_error: +- print(concrete_error) +- print("Error: hugepages test fail.\n") ++ print("Error: hugepages test fail.\n", concrete_error) + return False + return True + +@@ -209,11 +212,11 @@ + :param memory_path: + :return: + """ +- print("Keep %s online before test." % memory_path) ++ os.system("echo 'Keep %s online before test.' &>> %s"% (memory_path, self.logpath)) + if not self.online_memory(memory_path): + return False + +- print("Try to offline...") ++ os.system("echo 'Try to offline...' &>> %s"%self.logpath) + self.get_memory() + total_mem_1 = self.system_memory + if not self.offline_memory(memory_path): +@@ -224,7 +227,7 @@ + if total_mem_2 >= total_mem_1: + return False + +- print("Try to online...") ++ os.system("echo 'Try to online...' &>> %s"%self.logpath) + if not self.online_memory(memory_path): + self.retry_list.append(memory_path) + return False +@@ -233,6 +236,8 @@ + if total_mem_3 != total_mem_1: + return False + ++ return True ++ + def online_memory(self, memory_path): + """ + Set memory online +@@ -291,7 +296,8 @@ + for memory_path in mem_path_list: + try: + Command("cat %s/removable" % memory_path).get_str("1") +- print("%s is removable, start testing..." % os.path.basename(memory_path)) ++ print("%s is removable, start testing..." % ++ os.path.basename(memory_path)) + test_flag = 1 + except: + continue +@@ -314,4 +320,4 @@ + if __name__ == "__main__": + main = MemoryTest() + main.setup() +- main.test() ++ main.test() +\ No newline at end of file +diff -urN oec-hardware-1.0.0/tests/network/ethernet.py oec-hardware/tests/network/ethernet.py +--- oec-hardware-1.0.0/tests/network/ethernet.py 2022-05-31 22:00:43.453655867 +0800 ++++ oec-hardware/tests/network/ethernet.py 2022-05-31 22:01:38.417873491 +0800 +@@ -17,11 +17,11 @@ + import os + import argparse + ++from builtins import input + from hwcompatible.env import CertEnv + from hwcompatible.document import CertDocument + from rdma import RDMATest + +- + class EthernetTest(RDMATest): + """ + Ethernet Test +@@ -60,10 +60,6 @@ + self.server_ip = self.cert.get_server() + + if self.is_RoCE(): +- try: +- input = raw_input +- except NameError: +- from builtins import input + choice = input("[!] RoCE interface found. " + "Run RDMA tests instead? [y/N] ") + if choice.lower() != "y": +@@ -79,7 +75,4 @@ + Test case + :return: + """ +- for subtest in self.subtests: +- if not subtest(): +- return False +- return True ++ return self.tests() +diff -urN oec-hardware-1.0.0/tests/network/infiniband.py oec-hardware/tests/network/infiniband.py +--- oec-hardware-1.0.0/tests/network/infiniband.py 2022-05-31 22:00:43.453655867 +0800 ++++ oec-hardware/tests/network/infiniband.py 1970-01-01 08:00:00.000000000 +0800 +@@ -1,53 +0,0 @@ +-#!/usr/bin/env python +-# coding: utf-8 +- +-# Copyright (c) 2020 Huawei Technologies Co., Ltd. +-# oec-hardware is licensed under the Mulan PSL v2. +-# You can use this software according to the terms and conditions of the Mulan PSL v2. +-# You may obtain a copy of Mulan PSL v2 at: +-# http://license.coscl.org.cn/MulanPSL2 +-# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +-# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +-# PURPOSE. +-# See the Mulan PSL v2 for more details. +-# Create: 2020-04-01 +- +-"""InfiniBand Test""" +- +-from rdma import RDMATest +- +- +-class InfiniBandTest(RDMATest): +- """ +- InfiniBand Test +- """ +- def __init__(self): +- RDMATest.__init__(self) +- self.link_layer = 'InfiniBand' +- self.subtests = [self.test_ip_info, self.test_ibstatus, self.test_ib_link, +- self.test_icmp, self.test_rdma] +- self.speed = 56000 # Mb/s +- self.target_bandwidth_percent = 0.5 +- +- def test_ib_link(self): +- """ +- IB Link test +- :return: +- """ +- if 'LinkUp' not in self.phys_state: +- print("[X] Device is not LinkUp.") +- +- if 'ACTIVE' not in self.state: +- print("[X] Link is not ACTIVE.") +- +- if self.base_lid == 0x0: +- print("[X] Fail to get base lid of %s." % self.interface) +- return False +- print("[.] The base lid is %s" % self.base_lid) +- +- if self.sm_lid == 0x0: +- print("[X] Fail to get subnet manager lid of %s." % self.interface) +- return False +- print("[.] The subnet manager lid is %s" % self.sm_lid) +- +- return True +diff -urN oec-hardware-1.0.0/tests/network/network.py oec-hardware/tests/network/network.py +--- oec-hardware-1.0.0/tests/network/network.py 2022-05-31 22:00:43.454655889 +0800 ++++ oec-hardware/tests/network/network.py 2022-05-31 22:01:38.418873513 +0800 +@@ -16,21 +16,13 @@ + + import os + import time +-import argparse + import base64 +-try: +- from urllib.parse import urlencode +- from urllib.request import urlopen, Request +- from urllib.error import HTTPError +-except ImportError: +- from urllib import urlencode +- from urllib2 import urlopen, Request, HTTPError + ++from urllib.parse import urlencode ++from urllib.request import urlopen, Request ++from urllib.error import HTTPError + from hwcompatible.test import Test + from hwcompatible.command import Command +-from hwcompatible.document import CertDocument +-from hwcompatible.env import CertEnv +- + + class NetworkTest(Test): + """ +@@ -38,18 +30,8 @@ + """ + def __init__(self): + Test.__init__(self) +- self.args = None +- self.cert = None +- self.device = None + self.requirements = ['ethtool', 'iproute', 'psmisc', 'qperf'] +- self.subtests = [self.test_ip_info, self.test_eth_link, self.test_icmp, +- self.test_udp_tcp, self.test_http] +- self.interface = None +- self.other_interfaces = [] +- self.server_ip = None + self.retries = 3 +- self.speed = 1000 # Mb/s +- self.target_bandwidth_percent = 0.8 + self.testfile = 'testfile' + + def ifdown(self, interface): +@@ -78,53 +60,6 @@ + return True + return False + +- def get_other_interfaces(self): +- """ +- Get other interfaces +- :return: +- """ +- ignore_interfaces = ['^lo', '^v', 'docker', 'br', 'bond'] +- cmd = "ip route show default | awk '/default/ {print $5}'" +- com = Command(cmd) +- management_interface = com.read() +- if management_interface: +- ignore_interfaces.append(management_interface) +- # print(cmd) +- # print("Management interface: %s" % management_interface) +- +- ignore_pattern = '|'.join(ignore_interfaces) +- # print(ignore_pattern) +- cmd = "ls /sys/class/net/ | grep -vE '%s'" % ignore_pattern +- # print(cmd) +- com = Command(cmd) +- try: +- com.run() +- return com.output +- except Exception as concrete_error: +- print(concrete_error) +- return [] +- +- def set_other_interfaces_down(self): +- """ +- Judge whether the interface is closed +- :return: +- """ +- for interface in self.other_interfaces: +- if not self.ifdown(interface): +- return False +- return True +- +- def set_other_interfaces_up(self): +- """ +- Set other interfaces to up +- :return: +- """ +- for interface in self.other_interfaces: +- # Not ifup(), as some interfaces may not be linked +- os.system("ip link set up %s" % interface) +- # os.system("ip link | grep -w %s" % interface) +- return True +- + def get_speed(self): + """ + Get speed on the interface +@@ -386,14 +321,6 @@ + Test eth link + :return: + """ +- self.other_interfaces = self.get_other_interfaces() +- print("[+] Setting irrelevant interfaces down...") +- if not self.set_other_interfaces_down(): +- print("[X] Fail to set irrelevant interfaces down.") +- print("[X] Stop test and restore interfaces up...") +- self.set_other_interfaces_up() +- return False +- + print("[+] Setting interface %s down..." % self.interface) + if not self.ifdown(self.interface): + print("[X] Fail to set interface %s down." % self.interface) +@@ -436,20 +363,7 @@ + + return True + +- def setup(self, args=None): +- """ +- Initialization before test +- :param args: +- :return: +- """ +- self.args = args or argparse.Namespace() +- self.device = getattr(self.args, 'device', None) +- self.interface = self.device.get_property("INTERFACE") +- +- self.cert = CertDocument(CertEnv.certificationfile) +- self.server_ip = self.cert.get_server() +- +- def test(self): ++ def tests(self): + """ + test case + :return: +@@ -467,7 +381,4 @@ + print("[.] Stop all test servers...") + self.call_remote_server('all', 'stop') + +- print("[.] Restore interfaces up...") +- self.set_other_interfaces_up() +- + print("[.] Test finished.") +diff -urN oec-hardware-1.0.0/tests/network/rdma.py oec-hardware/tests/network/rdma.py +--- oec-hardware-1.0.0/tests/network/rdma.py 2022-05-31 22:00:43.454655889 +0800 ++++ oec-hardware/tests/network/rdma.py 2022-05-31 22:01:38.418873513 +0800 +@@ -18,6 +18,7 @@ + import re + import argparse + ++from builtins import input + from hwcompatible.command import Command + from hwcompatible.document import CertDocument + from hwcompatible.env import CertEnv +@@ -33,8 +34,7 @@ + self.args = None + self.cert = None + self.device = None +- self.requirements = ['ethtool', 'iproute', 'psmisc', 'qperf', +- 'perftest', 'opensm', 'infiniband-diags', ++ self.requirements = ['perftest', 'opensm', 'infiniband-diags', + 'librdmacm-utils', 'libibverbs-utils'] + self.subtests = [self.test_ibstatus, self.test_icmp, self.test_rdma] + self.interface = None +@@ -237,16 +237,8 @@ + test case + :return: + """ +- try: +- input = raw_input +- except NameError: +- from builtins import input +- + message = "Please enter the IP of InfiniBand interface on remote server: \ + (default %s)\n> " % self.server_ip + self.server_ip = input(message) or self.server_ip +- +- for subtest in self.subtests: +- if not subtest(): +- return False +- return True ++ ++ return self.tests() +diff -urN oec-hardware-1.0.0/tests/raid/Makefile oec-hardware/tests/raid/Makefile +--- oec-hardware-1.0.0/tests/raid/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/raid/Makefile 2022-05-31 22:01:38.422873602 +0800 +@@ -0,0 +1,22 @@ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-04-09 ++ ++.PHONY: install clean ++ ++all: ; ++ ++install: ++ mkdir -p $(DEST) ++ cp -a *.py $(DEST) ++ chmod a+x $(DEST)/*.py ++ ++clean: ++ rm -rf $(DEST) +diff -urN oec-hardware-1.0.0/tests/raid/raid.py oec-hardware/tests/raid/raid.py +--- oec-hardware-1.0.0/tests/raid/raid.py 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/tests/raid/raid.py 2022-05-31 22:01:38.422873602 +0800 +@@ -0,0 +1,249 @@ ++#!/usr/bin/env python ++# coding: utf-8 ++ ++# Copyright (c) 2022 Huawei Technologies Co., Ltd. ++# oec-hardware is licensed under the Mulan PSL v2. ++# You can use this software according to the terms and conditions of the Mulan PSL v2. ++# You may obtain a copy of Mulan PSL v2 at: ++# http://license.coscl.org.cn/MulanPSL2 ++# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++# PURPOSE. ++# See the Mulan PSL v2 for more details. ++# Create: 2022-04-09 ++ ++"""raid test""" ++ ++import os ++import sys ++import shutil ++ ++from hwcompatible.test import Test ++from hwcompatible.command import Command ++from hwcompatible.commandUI import CommandUI ++ ++ ++class RaidTest(Test): ++ """ ++ raid test ++ """ ++ ++ def __init__(self): ++ Test.__init__(self) ++ self.disks = list() ++ self.filesystems = ["ext4"] ++ self.com_ui = CommandUI() ++ self.logpath = "" ++ self.name = "" ++ ++ def setup(self, args=None): ++ """ ++ The Setup before testing ++ :return: ++ """ ++ try: ++ self.args = args or argparse.Namespace() ++ self.device = getattr(self.args, 'device', None) ++ self.pci_num = self.device.get_property("DEVPATH").split('/')[-1] ++ self.name = '-'.join(self.device.get_property("ID_MODEL_FROM_DATABASE").split(' ')) ++ self.logpath = getattr(args, "logdir", None) + "/raid-" + self.name + ".log" ++ os.system("echo Vendor Info: >> %s" % self.logpath) ++ Command("lspci -s %s -v &>> %s " % (self.pci_num, self.logpath)).echo() ++ os.system("echo Disk Info: >> %s" % self.logpath) ++ Command("fdisk -l &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo Partition Info: >> %s" % self.logpath) ++ Command("df -h &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo Mount Info: >> %s" % self.logpath) ++ Command("mount &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo Swap Info: >> %s" % self.logpath) ++ Command("cat /proc/swaps &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo LVM Info: >> %s" % self.logpath) ++ Command("pvdisplay &>> %s" % self.logpath).echo(ignore_errors=True) ++ Command("vgdisplay &>> %s" % self.logpath).echo(ignore_errors=True) ++ Command("lvdisplay &>> %s" % self.logpath).echo(ignore_errors=True) ++ os.system("echo Md Info: >> %s" % self.logpath) ++ Command("cat /proc/mdstat &>> %s" % self.logpath).echo(ignore_errors=True) ++ sys.stdout.flush() ++ except Exception as concrete_error: ++ print("Warning: could not get disk info.\n", concrete_error) ++ ++ def test(self): ++ """ ++ start test ++ """ ++ self.get_disk() ++ if len(self.disks) == 0: ++ print("No suite disk found to test.") ++ return False ++ ++ self.disks.append("all") ++ disk = self.com_ui.prompt_edit("Which disk would you like to test: ", ++ self.disks[0], self.disks) ++ return_code = True ++ if disk == "all": ++ for disk in self.disks[:-1]: ++ if not self.raw_test(disk): ++ return_code = False ++ if not self.vfs_test(disk): ++ return_code = False ++ else: ++ if not self.raw_test(disk): ++ return_code = False ++ if not self.vfs_test(disk): ++ return_code = False ++ return return_code ++ ++ def get_disk(self): ++ """ ++ get disk info ++ """ ++ self.disks = list() ++ disks = list() ++ disk_info = Command("cd /sys/block; ls -l").read().split('\n') ++ for disk in disk_info: ++ if self.pci_num in disk: ++ disks.append(disk.split('/')[-1]) ++ ++ partition_file = open("/proc/partitions", "r") ++ partition = partition_file.read() ++ partition_file.close() ++ ++ os.system("swapon -a 2>/dev/null") ++ swap_file = open("/proc/swaps", "r") ++ swap = swap_file.read() ++ swap_file.close() ++ ++ mdstat_file = open("/proc/mdstat", "r") ++ mdstat = mdstat_file.read() ++ mdstat_file.close() ++ ++ mtab_file = open("/etc/mtab", "r") ++ mtab = mtab_file.read() ++ mtab_file.close() ++ ++ mount_file = open("/proc/mounts", "r") ++ mounts = mount_file.read() ++ mount_file.close() ++ ++ for disk in disks: ++ if disk not in partition or ("/dev/%s" % disk) in swap: ++ continue ++ if ("/dev/%s" % disk) in mounts or ("/dev/%s" % disk) in mtab: ++ continue ++ if disk in mdstat or os.system("pvs 2>/dev/null | grep -q '/dev/%s'" % disk) == 0: ++ continue ++ self.disks.append(disk) ++ ++ un_suitable = list(set(disks).difference(set(self.disks))) ++ if len(un_suitable) > 0: ++ print("These disks %s are in use now, skip them." % "|".join(un_suitable)) ++ ++ def raw_test(self, disk): ++ """ ++ raw test ++ """ ++ print("\n#############") ++ print("%s raw IO test" % disk) ++ device = "/dev/" + disk ++ if not os.path.exists(device): ++ print("Error: device %s not exists." % device) ++ proc_path = "/sys/block/" + disk ++ if not os.path.exists(proc_path): ++ proc_path = "/sys/block/*/" + disk ++ size = Command("cat %s/size" % proc_path).get_str() ++ size = int(size) / 2 ++ if size <= 0: ++ print("Error: device %s size not suitable to do test." % device) ++ return False ++ elif size > 1048576: ++ size = 1048576 ++ ++ print("\nStarting sequential raw IO test...") ++ opts = "-direct=1 -iodepth 4 -rw=rw -rwmixread=50 -group_reporting -name=file -runtime=300" ++ if not self.do_fio(device, size, opts): ++ print("%s sequential raw IO test fail." % device) ++ print("#############") ++ return False ++ ++ print("\nStarting rand raw IO test...") ++ opts = "-direct=1 -iodepth 4 -rw=randrw -rwmixread=50 " \ ++ "-group_reporting -name=file -runtime=300" ++ if not self.do_fio(device, size, opts): ++ print("%s rand raw IO test fail." % device) ++ print("#############") ++ return False ++ ++ print("#############") ++ return True ++ ++ def vfs_test(self, disk): ++ """ ++ vfs test ++ """ ++ print("\n#############") ++ print("%s vfs test" % disk) ++ device = "/dev/" + disk ++ if not os.path.exists(device): ++ print("Error: device %s not exists." % device) ++ proc_path = "/sys/block/" + disk ++ if not os.path.exists(proc_path): ++ proc_path = "/sys/block/*/" + disk ++ size = Command("cat %s/size" % proc_path).get_str() ++ size = int(size) / 2 / 2 ++ if size <= 0: ++ print("Error: device %s size not suitable to do test." % device) ++ return False ++ elif size > 1048576: ++ size = 1048576 ++ ++ if os.path.exists("vfs_test"): ++ shutil.rmtree("vfs_test") ++ os.mkdir("vfs_test") ++ path = os.path.join(os.getcwd(), "vfs_test") ++ ++ return_code = True ++ for file_sys in self.filesystems: ++ try: ++ print("\nFormatting %s to %s ..." % (device, file_sys)) ++ Command("umount %s" % device).echo(ignore_errors=True) ++ Command("mkfs -t %s -F %s 2>/dev/null" % (file_sys, device)).echo() ++ Command("mount -t %s %s %s" % (file_sys, device, "vfs_test")).echo() ++ ++ print("\nStarting sequential vfs IO test...") ++ opts = "-direct=1 -iodepth 4 -rw=rw -rwmixread=50 -name=directoy -runtime=300" ++ if not self.do_fio(path, size, opts): ++ return_code = False ++ break ++ ++ print("\nStarting rand vfs IO test...") ++ opts = "-direct=1 -iodepth 4 -rw=randrw -rwmixread=50 -name=directoy -runtime=300" ++ if not self.do_fio(path, size, opts): ++ return_code = False ++ break ++ except Exception as concrete_error: ++ print(concrete_error) ++ return_code = False ++ break ++ ++ Command("umount %s" % device).echo(ignore_errors=True) ++ Command("rm -rf vfs_test").echo(ignore_errors=True) ++ print("#############") ++ return return_code ++ ++ def do_fio(self, filepath, size, option): ++ """ ++ fio test ++ """ ++ if os.path.isdir(filepath): ++ file_opt = "-directory=%s" % filepath ++ else: ++ file_opt = "-filename=%s" % filepath ++ max_bs = 64 ++ a_bs = 4 ++ while a_bs <= max_bs: ++ if os.system("fio %s -size=%dK -bs=%dK %s &>> %s" % (file_opt, size, a_bs, option, self.logpath)) != 0: ++ print("Error: %s fio failed." % filepath) ++ return False ++ sys.stdout.flush() ++ a_bs = a_bs * 2 ++ return True +diff -urN oec-hardware-1.0.0/tests/system/system.py oec-hardware/tests/system/system.py +--- oec-hardware-1.0.0/tests/system/system.py 2022-05-31 22:00:43.457655955 +0800 ++++ oec-hardware/tests/system/system.py 2022-05-31 22:01:38.424873646 +0800 +@@ -30,12 +30,13 @@ + """ + System Test + """ ++ + def __init__(self): + Test.__init__(self) + self.pri = 1 + self.sysinfo = SysInfo(CertEnv.releasefile) + self.args = None +- self.logdir = None ++ self.logpath = "" + + def setup(self, args=None): + """ +@@ -44,18 +45,18 @@ + :return: + """ + self.args = args or argparse.Namespace() +- self.logdir = getattr(args, "logdir", None) ++ self.logpath = getattr(args, "logdir", None) + "/system.log" + + def test(self): + """ + test case + :return: + """ +- os.system("uname -a") ++ os.system("uname -a &>> %s" % self.logpath) + print("") +- os.system("lsmod") ++ os.system("lsmod &>> %s" % self.logpath) + print("") +- os.system("dmidecode") ++ os.system("dmidecode &>> %s" % self.logpath) + sys.stdout.flush() + + return_code = True +@@ -78,7 +79,8 @@ + print("\nChecking installed cert package...") + return_code = True + for cert_package in ["oec-hardware"]: +- rpm_verify = Command("rpm -V --nomtime --nomode --nocontexts %s" % cert_package) ++ rpm_verify = Command( ++ "rpm -V --nomtime --nomode --nocontexts %s &>> %s" % (cert_package, self.logpath)) + try: + rpm_verify.echo() + sys.stdout.flush() +@@ -112,7 +114,8 @@ + + try: + if kernel_dict.document[os_version] != self.sysinfo.kernel_version: +- print("Error: kernel %s check GA status fail." % self.sysinfo.kernel_version) ++ print("Error: kernel %s check GA status fail." % ++ self.sysinfo.kernel_version) + return_code = False + except Exception: + print("Error: %s is not supported." % os_version) +@@ -150,24 +153,22 @@ + + tainted_file.close() + except Exception as concrete_error: +- print(concrete_error) +- print("Error: could not determine if kernel is tainted.") ++ print("Error: could not determine if kernel is tainted. \n", ++ concrete_error) + return_code = False + +- except_list = ["/modules.dep$", "/modules.symbols$", "/modules.dep.bin$", \ ++ except_list = ["/modules.dep$", "/modules.symbols$", "/modules.dep.bin$", + "/modules.symbols.bin$"] +- if os.system("rpm -V --nomtime --nomode --nocontexts %s | grep -Ev '%s'" % \ +- (kernel_rpm, "|".join(except_list))) is 0: +- print("Error: files from %s were modified." % kernel_rpm) +- print("") ++ if os.system("rpm -V --nomtime --nomode --nocontexts %s | grep -Ev '%s'" % ++ (kernel_rpm, "|".join(except_list))) == 0: ++ print("Error: files from %s were modified.\n" % kernel_rpm) + return_code = False + + try: + params = Command("cat /proc/cmdline").get_str() + print("Boot Parameters: %s" % params) + except Exception as concrete_error: +- print(concrete_error) +- print("Error: could not determine boot parameters.") ++ print("Error: could not determine boot parameters. \n", concrete_error) + return_code = False + + return return_code +@@ -197,7 +198,8 @@ + """ + whitelist_path = [("/lib/modules/kabi-current/kabi_whitelist_" + self.sysinfo.arch), + ("/lib/modules/kabi/kabi_whitelist_" + self.sysinfo.arch), +- ("/usr/src/kernels/%s/kabi_whitelist" % self.sysinfo.kernel) ++ ("/usr/src/kernels/%s/kabi_whitelist" % ++ self.sysinfo.kernel) + ] + whitelist = "" + for whitelist in whitelist_path: +@@ -205,7 +207,8 @@ + break + + if not os.path.exists(whitelist): +- print("Error: could not find whitelist file in any of the following locations:") ++ print( ++ "Error: could not find whitelist file in any of the following locations:") + print("\n".join(whitelist_path)) + return False + +@@ -320,12 +323,14 @@ + :return: + """ + print("\nChecking selinux...") +- status = os.system("/usr/sbin/sestatus | grep 'SELinux status' | grep -qw 'enabled'") +- mode = os.system("/usr/sbin/sestatus | grep 'Current mode' | grep -qw 'enforcing'") ++ status = os.system( ++ "/usr/sbin/sestatus | grep 'SELinux status' | grep -qw 'enabled'") ++ mode = os.system( ++ "/usr/sbin/sestatus | grep 'Current mode' | grep -qw 'enforcing'") + if mode == 0 and status == 0: +- print("SElinux is enforcing.") ++ print("SElinux is enforcing as expect.") + return True + else: +- print("SElinux is not enforcing.") ++ print("SElinux is not enforcing, expect is enforcing.") + os.system("/usr/sbin/sestatus") + return False +diff -urN oec-hardware-1.0.0/vendor_tests/Readme.md oec-hardware/vendor_tests/Readme.md +--- oec-hardware-1.0.0/vendor_tests/Readme.md 1970-01-01 08:00:00.000000000 +0800 ++++ oec-hardware/vendor_tests/Readme.md 2022-05-31 22:01:38.339871763 +0800 +@@ -0,0 +1,5 @@ ++# 概述 ++ ++## 目录介绍 ++ ++该目录用于板卡厂商提供不同板卡的测试工具。 +\ No newline at end of file diff --git a/oec-hardware.spec b/oec-hardware.spec index 2f42f89f0d9eec3f74238804878be536296bb945..45c3cd8c6cb16efbcd24cbc0342cb1aefb9da71a 100644 --- a/oec-hardware.spec +++ b/oec-hardware.spec @@ -4,12 +4,12 @@ Name: oec-hardware Summary: openEuler Hardware Compatibility Test Suite -Version: 1.0.0 -Release: 8 +Version: 1.1.0 +Release: 0 Group: Development/Tools License: Mulan PSL v2 URL: https://gitee.com/openeuler/oec-hardware -Source0: https://gitee.com/openeuler/oec-hardware/repository/archive/v%{version}.tar.gz +Source0: https://gitee.com/openeuler/oec-hardware/repository/archive/v1.0.0.tar.gz #PATCH-FIX-https://gitee.com/src-openEuler/ patch from oec-hardware-1.0.0 project Patch0001: oec-hardware-1.0.0-system.patch @@ -20,6 +20,7 @@ Patch0002: oec-hardware-1.0.0-delete-tape.patch Patch0003: oec-hardware-1.0.0-fix-cdrom.patch Patch0004: oec-hardware-1.0.0-fix-cpufreq.patch Patch0005: oec-hardware-1.0.0-optimization.patch +Patch0006: oec-hardware-1.1.0-add-cases.patch Buildroot: %{_tmppath}/%{name}-%{version}-root BuildRequires: gcc @@ -46,6 +47,7 @@ openEuler Hardware Compatibility Test Server %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 %build @@ -86,6 +88,11 @@ DESTDIR=$RPM_BUILD_ROOT make install rm -rf /var/lock/oech.lock %changelog +* Mon May 30 2022 meitingli <244349477@qq.com> - 1.1.0-0 +- 1. Add support os version: openEuler 22.03LTS +- 2. Add FC/RAID/keycard/GPU/infiniband testcases +- 3. Bugfix + * Thu Sep 09 2021 Cui XuCui - 1.0.0-8 * Thu Jul 15 2021 zhangzikang - 1.0.0-7 - Fix cdrom and cpufreq test failed @@ -94,7 +101,7 @@ rm -rf /var/lock/oech.lock * Tue Sep 29 2020 Cui XuCui - 1.0.0-5 * Fri Jul 24 2020 Cui XuCui - 1.0.0-4 * Sun Jul 18 2020 Cui XuCui - 1.0.0-3 -* Sun Jul 01 2020 Cui XuCui - 1.0.0-2 +* Wed Jul 01 2020 Cui XuCui - 1.0.0-2 * Fri Jul 26 2019 Lu Tianxiong - 1.0.0-h1 - Initial spec