# anolis-sys-tests
## 介绍
anolis-sys-tests是基于avocado-framework框架编写的针对Anolis OS的系统功能测试集。
## 安装教程
1. 安装系统依赖,python3 pip (or pip3)
```bash
yum install -y python3 python-pip (or python3-pip)
```
2. 克隆项目
```bash
git clone https://gitee.com/anolis/anolis-sys-tests.git
```
3. 安装项目依赖
```bash
pip(or pip3) install -r requirements.txt
```
## 使用说明
### 环境变量配置
配置PYTHONPATH环境变量,指向项目tests目录
```bash
export PYTHONPATH=$PYTHONPATH:path/to/repo/tests
```
### 运行测试
```bash
# 默认运行多个用例时使用并发运行,很多场景并发运行会出现冲突,因此要加--nrunner-max-parallel-tasks 参数:
avocado run --nrunner-max-parallel-tasks 1 tests/$pkg1_class_folder/$pkg1_folder
```
#### 运行单个测试用例
```bash
avocado run tests/$pkg_class_folder/$pkg_folder/$testcase.py # 运行pkg包下testcase单个用例
```
#### 运行单包所有测试用例
```bash
avocado run tests/$pkg_class_folder/$pkg_folder # 运行pkg单包所有用例
```
#### 运行多个包测试用例
```bash
avocado run tests/$pkg1_class_folder/$pkg1_folder tests/$pkg2_class_folder/$pkg2_folder # 运行pkg1和pkg2两个包所有用例
```
#### 按单个标签运行测试用例
```bash
avocado run -t P0 tests # 运行所有P0级case
```
#### 按多个标签交集运行测试用例
```bash
avocado run -t P0,noarch tests # 运行所有P0级且全架构支持的case
```
#### 按多个标签并集运行测试用例
```bash
avocado run -t x86_64 -t aarch64 tests # 运行仅支持x86_64和仅支持aarch64的case
```
#### 按标签补集运行测试用例
```bash
avocado run -t=-x86_64 tests # 运行除了仅支持x86_64之外的所有case
```
#### 运行远程测试
1.准备运行硬件环境,远程测试所需运行环境为1台主控机+N台测试机,测试代码部署在主控机,通过ssh在测试机上执行测试
2.创建hosts.yaml来配置远程机器
* 配置单台远程机器时,需配置\$username、\$password、\$remote_ip,默认ssh端口22,注意username、password、remote这3个key不可随意更改
```yaml
username: $username
password: $password
remote: $remote_ip
```
* 配置多台远程机器时,按如下格式编写,运行时会在多台远程机器执行相同的用例
```yaml
username: $username # 全局用户名,当所有测试机用户名相同时仅配置全局的即可
password: $password # 全局密码,当所有测试机密码相同时仅配置全局的即可
remote: !mux
remote_host1: # 用户可读的远程机器名
remote: $remote_ip1
remote_host2:
remote: $remote_ip2
username: $username # 用户名局部配置,覆盖全局用户名,仅对当前远程生效
password: $password # 密码局部配置,覆盖全局密码,仅对当前远程机器生效
```
3.运行测试
运行测试时通过-m参数指定hosts.yaml配置,注意即使对于本地用例,当指定hosts.yaml参数时也会通过ssh在远程机器上运行。
```bash
avocado run tests -m hosts.yaml
```
### 查看日志
* 运行时可以指定--show all在控制台打印所有日志,在控制台查看运行日志
* job日志存储在avocado框架配置的logdir下,具体请参考[avocado文档](https://avocado-framework.readthedocs.io/en/96.0/guides/user/chapters/results.html)
## 参与贡献
### 文本用例贡献规范
- 目录结构:文本用例和用例代码保持相同组织形式
- 一级目录:docs
- 二级目录:src包分类
- 三级目录:src包名
- 文件名:yaml文件格式,文件名即用例名,全部小写,"\_"连接,命名规则:tc_{rpm包名}\_{子模块名/服务名/命令名}_{功能点/func_xxx/stress_xxx}.yaml,用例名唯一不可重复
- {rpm包名}:必写,注意字符"-"需要转换成"_"
- {子模块名/服务名/命令名}
- 如果包功能比较复杂,包含子模块的,写子模块名
- 如果测试的是system service,写服务名,如果服务名和rpm包名重名,则只写service即可
- 例1,服务名和rpm包名相同:tc_rsyslog_service_func_001
- 例2,服务名和rpm包名不同: tc_kexec_tools_kdump_generate_vmcore
- 如果测试的是cmdline,写命令名,如ls、cd
- {功能点/func_xxx/stress_xxx}
- 测试功能点明确的,写测试的功能点
- 测试功能点不好命名的,写func_xxx,其中xxx是3位的编号,如001、002
- 压力测试用例,写stress_xxx,其中xxx是3位的编号,如001、002
- 文件内容:
- 优先级:必填项,P0-P3
- P0:最基础功能case,缺失了这些功能,会直接影响软件包的使用,客户会第一时间发现,直接影响客户的使用,如某个软件包服务启动失败
- P1:非必需但是个重要功能,比如rsyslog,远程日志传输,该功能失效不会影响本机的使用,但它是一个重要功能,在远程传输场景失效
- P2:比较偏僻的功能,比如rsyslog的日志限速功能失效
- P3:软件包的一些压力、可靠性功能case,比如nginx,构造大量并发,反复重启进程,看是否会产生coredump
- 支持架构:必填项,支持CPU的架构,包括x86_64、aarch64等(arch命令查询返回的结果),不能自定义
- 如果支持多个架构,可写多个架构,通过","分隔
- 如果全架构支持,可填写noarch
- 执行方式:必填项,自动/手动
- 测试类型:必填项,功能测试/性能测试/压力测试
- 通用标签:会映射到测试代码里tags注释,多个通过","分隔,执行模式(目前包括local/remote)没有单独定义字段,需在通用标签里填写,local/remote分别对应继承LocalTest/RemoteTest编写的case
- 用例描述:必填项,简要描述用例意图
- 前置条件:可选项,如硬件配置、软件配置,按照yaml数组格式定义每一步前置条件,如果前置条件为空填写~(yaml中表示null)
- 测试步骤:必填项,按照yaml数组格式填写每一步步骤描述,有命令行必须给出完整命令
- 期望结果:必填项,按照yaml数组格式填写与步骤对应的期望结果,每个步骤对应一个期望结果,如果期望结果为空填写~(yaml中表示null),一般代码中一条assert语句对应一个期望结果
文本用例sample如下,更多sample请查看samples文件夹
```yaml
作者: your_name
优先级: P0
支持架构: noarch
执行方式: 自动
测试类型: 功能测试
通用标签: local,其他标签(如filesystem、network等)
用例描述: 本地测试样例
前置条件: ~
测试步骤:
- 执行ls | wc -l,获取当前目录文件和文件夹数量为N
- 执行uname -a | awk '{print $2}'获取本机hostname
- 执行cat nonexistent_file,查看不存在文件内容,获取命令输出
期望结果:
- 期望当前目录文件和文件夹数量N>0
- 期望hostname不为空
- 期望”No such file"字符串出现在命令返回中
```
### 代码用例贡献规范
- 用例组织:同文本用例组织结构保持一致,放在tests目录下
- 用例命名:
- 文件名:tc_{rpm包名}\_{子模块名/服务名/命令名}\_{功能点/func_xxx/stress_xxx}.py,命名规范与文本用例名命名规范完全一致
- 类名:Test
- 函数名:
- 单个测试函数命名:test()
- 多个测试函数命名:test_001、test_002,以此类推
- 用例兼容:多产品/多架构兼容需在case内部实现处理
- 用例粒度:按功能点划分测试用例,可能涉及1条或多条命令行
- 用例标签:必填项,按照avocado的规范填写,依次按照优先级、支持架构、运行模式(local/remote)、其他标签的顺序填写,与文本用例必须保持一致
- 测试基类:在tests/common/basetest.py中封装了LocalTest、RemoteTest分别用于本地运行和远程运行模式的基类,测试用例必须继承测试基类
- LocalTest:默认为本地执行,当指定远程机器hosts.yaml配置时,切换为远程执行。LocalTest封装了cmd()方法,使用cmd()方法编写测试用例,另外编写本地测试时也可以使用avocado提供的utils库来实现,需要注意的是如果用utils来实现LocalTest,则无法支持在远程机器执行
- RemoteTest:适用于必须双机运行的用例(如reboot测试机的用例),提供remote和local两个对象分别代表远程机器和本地机器,通过self.remote.cmd()和self.local.cmd()分别执行远程命令和本地命令,以此编写测试用例
- setUp&tearDown:如果没有setUp和tearDown可以不写
- assertion方法:测试基类继承自unittest.TestCase,支持assertEqual、assertTrue等方法,建议用例中的期望结果使用对应assertion方法来实现
代码用例sample如下,更多sample请查看samples文件夹
```python
# -*- encoding: utf-8 -*-
"""
@File: tc_sample_local.py
@Time: 2022/05/12 16:22:50
@Author: your_name
@Version: 1.0
@Contact: example@email.com
@License: Mulan PSL v2
"""
class Test(LocalTest):
"""
Description about this testcase on localhost
:avocado: tags=priority,arch,mode,other_tag
"""
def setUp():
super().setUp()
pass
def test():
pass
def tearDown():
super().tearDown()
pass
```
### 用例贡献流程
1. Fork 本仓库
2. 新建 tc_xxx分支
3. 提交文本&代码用例
4. 新建Pull Request,建议PR的粒度为单个用例或单个包的一组用例
5. 评审用例
## 已知问题
1. 目前通过ssh执行远程命令不能包含单引号,在使用awk等命令时请使用双引号"+转义来代替单引号。
2. LocalTest支持使用avocado提供的utils库来编写,但无法支持在远程机器环境中执行,如果期望LocalTest同时可以在本地和远程环境中执行,请使用LocalTest提供的cmd()方法来编写用例
## 参考资料
1. [avocado官方文档](https://avocado-framework.readthedocs.io/en/96.0/guides/user/chapters/tags.html)