diff --git a/docs/develop_doc/add_testcase.md b/docs/develop_doc/add_testcase.md new file mode 100644 index 0000000000000000000000000000000000000000..478c0e12a1bed17e1994fcbb8bea9b90a85633a1 --- /dev/null +++ b/docs/develop_doc/add_testcase.md @@ -0,0 +1,116 @@ +# `oec-hardware` 添加测试用例 +## 添加用例 + +下面以添加nvme用例为例 + +### 添加用例文件夹 +首先确定用例属于那个类别,如果类别已经存在,在该类别下面添加该用例文件夹。由于`nvme`属于`compatibility`类别,所以在`test/compatibility`下面添加`nvme`文件夹。 + ![testcase](../pictures/testcase.png) + +### 添加用例入口文件 +在用例文件夹下面添加和文件夹相同名称的`py`文件,该文件是用例的入口文件, 添加`nvme.py`文件。如果还需要其它功能模块可在nvme文件夹下面直接添加。 + + **`py`文件中重要函数说明** + - 函数`init` ,定义用例属性, -**可选** + ``` + def __init__(self): + Test.__init__(self) //继承Test类的构造函数 + self.requirements = ["nvme-cli"] //测试前需要安装的依赖 + self.args = None //测试对象 + self.device = None //测试设备 + self.filename = "test.file" //生成的测试文件名称 + ``` + + - 函数`test`,测试主流程。-**必选** + ``` + def test(self): + """ + test case + :return: + """ + disk = self.device.get_name() //获取设备名称 + if self.in_use(disk): //检测硬盘是否被使用 + self.logger.error("%s is in use now, skip this test." % disk) + return False + + block_count = getoutput("cat /sys/block/%s/size" % disk) //获取块的数量 + block_size = getoutput("cat /sys/block/%s/queue/logical_block_size" % disk) //获取每个块的大小 + ... //后面的代码省略 + ``` + + - 函数`setup`,测试开始前环境准备,主要用于初始化被测用例相关信息。-**可选** + ``` + def setup(self, args=None): + """ + Initialization before test + :param args: + :return: + """ + self.args = args or argparse.Namespace() //传递的对象 + self.logger = getattr(args, "test_logger", None) //日志属性 + self.command = Command(self.logger) //命令执行属性 + self.device = getattr(args, "device", None) //设备属性 + self.show_driver_info() //显示驱动信息 + self.command.run_cmd("nvme list", ignore_errors=True) //执行nvme list命令 + ``` + + - 函数`teardown`,测试完成后环境清理,主要用于确保无论测试成功失败都能正确恢复环境。-**可选** + ``` + def teardown(self): + """ + Environment recovery + """ + if os.path.exists(self.filename): + os.remove(self.filename) //如果存在测试过程中生成的文件,则删除。 + ``` +### 添加`MakeFile`编译文件 +``` + all: ; + + install: + mkdir -p $(DEST) + cp -a *.py $(DEST) //编译生成的目标文件复制到指定的目录中 + chmod a+x $(DEST)/*.py //设置文件权限 + + clean: //删除生成的目标文件 + rm -rf $(DEST) +``` +`nvme`用例的完整代码可参考`tests/compatible/nvme/nvme.py`文件。 + +## 添加用例特殊功能 + +1、 测试过程需要重启系统,添加self.rebootup属性和函数,可参考watchdog。 +``` + class WatchDogTest(Test): + """ + WatchDog Test + """ + def __init__(self): + Test.__init__(self) + self.pri = 9 //默认值为`0`,如果需要重启值为`9`。 + self.reboot = True //默认为`False`,如果需要重启为`True`。 + self.rebootup = "startup" //值为重启后要运行的函数名称。 +``` + 重启后调用的函数 + ``` + def startup(self, logger): + """ + Initialization before test + :return: + """ + logger.info("Recover from watchdog.") //调用watchdog后,系统重启正常。 + return True + ``` + +2、测试前需要安装rpm依赖,在self.requirement属性列表中列出rpm包名称。 +``` + class NvmeTest(Test): + def __init__(self): + Test.__init__(self) + self.requirements = ["nvme-cli"] //测试前需要安装`nvme-cli`依赖包 + self.args = None + self.device = None + self.filename = "test.file" + self.logpath = "" +``` + diff --git a/docs/develop_doc/get_board.md b/docs/develop_doc/get_board.md index 20fcdea5864ff4c07a25adf02381ba5a28a7ce38..98b266d2e9d87b9c7009ca04abc39906dfa4e58e 100644 --- a/docs/develop_doc/get_board.md +++ b/docs/develop_doc/get_board.md @@ -29,9 +29,119 @@ | 4 | `get_model()` | `device` |获取设备芯片和模块型号 | | 5 | `NO_CONFIG_DEVICES` | `constants` | 不需要配置信息的板卡 | -板卡配置信息 +## 板卡配置信息 | 序号 | 文件名称 | 文件描述| | --------- | -------- | --------------- | | 1 |`test_config.yaml`|板卡配置信息模板文件 | +## 示例 + +下面以识别`raid`卡为例,介绍如果识别板卡和获取板卡信息。 + +### 生成device.json文件 + +安装`oec-hardware`工具,命令行输入oech进入工具,根据提示输入`ID`、`URL`、`Server`配置项。这时已生成环境硬件文件`/var/oech/device.json`。 + +### 获取识别板卡字段 + +打开`device.json`文件,搜索PCI号`3b:00.0`,可以会搜索多个对象,使用板卡信息比较全面的那个对象,如下面板卡对象就使用第一个对象。下来判断使用那个字段可表示该类板卡,比如要识别`raid`卡,一般`raid`卡`ID_PCI_SUBCLASS_FROM_DATABASE`参数的值包含`raid`字符,但是这个对象中没有包含,下来通过观察是否可通过别的字段来表示该类`raid`卡,判断`ID_PCI_SUBCLASS_FROM_DATABASE`中含有`SCSI`,但是`ID_MODEL_FROM_DATABASE`中不含有`HBA`可表示该类`raid`卡。 +``` + { + "DEVPATH": "/devices/pci0000:3a/0000:3a:00.0/0000:3b:00.0", + "SUBSYSTEM": "pci", + "DRIVER": "smartpqi", + "PCI_CLASS": "10700", + "PCI_ID": "9005:028F", + "PCI_SUBSYS_ID": "9005:0801", + "PCI_SLOT_NAME": "0000:3b:00.0", + "MODALIAS": "pci:v00009005d0000028Fsv00009005sd00000801bc01sc07i00", + "USEC_INITIALIZED": "18417922", + "ID_PCI_CLASS_FROM_DATABASE": "Mass storage controller", + "ID_PCI_SUBCLASS_FROM_DATABASE": "Serial Attached SCSI controller", + "ID_VENDOR_FROM_DATABASE": "Adaptec", + "ID_MODEL_FROM_DATABASE": "Smart Storage PQI SAS (SmartRAID 3152-8i)" + }, + { + "DEVPATH": "/devices/pci0000:3a/0000:3a:00.0/0000:3b:00.0/host14", + "SUBSYSTEM": "scsi", + "DEVTYPE": "scsi_host" + }, + { + "DEVPATH": "/devices/pci0000:3a/0000:3a:00.0/0000:3b:00.0/host14/bsg/sas_host14", + "SUBSYSTEM": "bsg", + "DEVNAME": "/dev/bsg/sas_host14", + "MAJOR": "247", + "MINOR": "0" + }, +``` +### 添加板卡识别方法 +在`hwcompatible/compatibility.py`模块的`sort_tests`方法中添加板卡识别方法,在板卡识别功能段的最后添加板卡的识别方法,下面是`raid`卡的添加方法。 +``` +for device in devices: + .... + if "RAID" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") or \ + ("SCSI" in device.get_property("ID_PCI_SUBCLASS_FROM_DATABASE") and + "HBA" not in device.get_property("ID_MODEL_FROM_DATABASE")): + if "raid" in sort_devices.keys(): + sort_devices["raid"].extend([device]) + else: + sort_devices["raid"] = [device] + continue + ... +``` +### 添加板卡芯片和模块型号获取方法 +在`hwcompatible/device.py`模块的`get_model`方法中添加板卡芯片和模块型号的识别方法,先判断要添加的板卡类型是否已经有识别方法,如果已有不用添加,否则添加。在`/usr/share/oech/lib/config/pci.ids`文件中根据四元组信息先查找到板卡,根据板卡信息特点提取该板卡的芯片和模块型号信息。对FC、gpu、raid等板卡信息因为格式相同,就可以使用一种方法获取该类卡的芯片和模块型号。对于网卡,多家芯片厂商板卡格式不一样,需要根据芯片单独添加识别方法。 + +获取板卡信息和模块型号方法调用 +``` +try: + if name == "fc": + self.get_fc_card() + elif name == "gpu" or name == "vgpu": + self.get_gpu_card() + elif name == "raid": + self.get_raid_card() + ... +``` + +获取板卡信息和模块型号方法实现 +``` + def get_raid_card(self): + """ + get the board model and chip model of raid card + """ + flag = 0 + for ln in self.file.readlines(): + if flag == 0: + if re.match(self.quad[0], ln): + flag += 1 + elif flag == 1: + if re.match("\t" + self.quad[1], ln): + flag += 1 + self.chip = self._search_info(r"\b(SAS\S*)\s*", ln) + if len(self.chip) < 7: + self.chip = self._search_info(r"(\bSAS\S* \S*)\s*", ln) + if not self.chip: + self.chip = ln.replace(ln[0:7], "").strip() + elif flag == 2: + if re.match("\t\t" + self.quad[2] + " " + self.quad[3], ln): + self.board = ln.split(" ")[-1].strip() + break +``` + +### 配置信息添加 +如果用例测试过程中需要提供一些信息才可继续往下测试,就需要在`config/test_config.yaml`文件中添加配置信息。比如raid卡测试过程中需要提供硬盘模块才可继续测试,就需要在配置文件中给出要测试的硬件模块。 + +``` +raid: //raid板卡 + raid1: //第一个raid卡对象 + device: '0000:02:00.0' //raid卡的pci号,可从测试界面获取。 + disk: all //要测试的硬盘模块,all表示所有满足条件的模块都测试,否则测试指定的模块。 + raid2: + device: '0000:0a:00.1' + disk: sdb +``` +**注意** +对于非板卡用例,比如`perf`、`ipmi`、`system`等需要在`NODEVICE`常量中添加用例名称。 +对于板卡用例,不需要添加配置信息,需要在`NO_CONFIG_DEVICES`常量中添加上该板卡用例名称。 diff --git a/docs/pictures/testcase.png b/docs/pictures/testcase.png new file mode 100644 index 0000000000000000000000000000000000000000..831f55298bfdd01c21ee4ce6d4f0bd0b7db7d85b Binary files /dev/null and b/docs/pictures/testcase.png differ