同步操作将从 openGauss/Yat 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
本文是Yat测试框架快速入门介绍,文中介绍了基本的安装方法,用例编写,调度文件编写,配置文件修改、JDBC驱动安装方法和用例执行, 文中举一个测试zenith 逻辑导入导出lob类型特性的例子,初学者按照此例子可以进行简单用例编写和熟悉Yat框架。
执行如下命令拉取源码包:
git clone git@gitee.com:opengauss/Yat.git
执行如下命令一键构建:
cd Yat/yat-master
chmod 755 gradlew
./gradlew pack
执行如下命令安装:
cd Yat/yat-master/pkg
./install -F
-F表示强制安装,如果环境中已经存在-F参数会先卸载旧版本Yat然后再执行安装
依赖的python第三方包列表如下:
install脚本会使用pip进行以上三方包的安装,需要用户环境上自行安装好pip
Yat提供命令创建测试套模板,执行如下命令:
yat suite init -d test-suite-name
test-suite-name
指要创建测试套目录名字,一般取要测试特性的名字,本文举例测试逻辑导入导出lob类型特性,执行如下命令:
yat suite init -d exp-imp-lob
此命令会在当前目录创建一个exp-imp-lob
的目录,目录中已经存在若干目录和文件,此目录就是我们生成的测试套
执行完yat init
命令后,指定的测试套目录下会有testcase
目录,所有的测试用例都放在此目录下,支持的用例类型有:
通用用例类型
zenith 独有用例类型
说明:为什么要有zsql用例和zsql交互式用例
1) zenith中有很多功能性SQL是只能在zsql客户端中执行,如exp/imp/load/dump,此时如果用shell去调用zsql, 用户会书写用例会比较繁琐; 2) zenith中的zsql客户端工具有许多特性是JDBC无法承载的,如交互式绑定参数、server output等;3) JDBC的连接存活检查机制会后台启动一个线程去连接数据库测试数据库是否有响应,这样导致部分在nomount模式的用例(restore/recover)无法执行, 因为nomount模式只能有一个sys用户连接数据库,测试概率性JDBC的活性检查线程如果先链接上了数据库,会导致用例链接报错,不允许连接
openGauss(postgresql like database)
说明:如果是原生postgresql数据库,sql执行是用psql,需要在conf/configure.yml中设置gsql的路径/名字为psql即可:
conf/configure.yml:
# other setting
yat.gsql.path: psql
承接文中举例,我们做如下操作:
cd exp-imp-lob
touch testcase/create_user.sql
touch testcase/create_lob_data.py
touch testcase/exp.z.sql
touch testcase/imp.z.sql
touch testcase/cleanup.sql
每个文件内容如下:
create_user.sql:
@conn sys;
create user yat identified by 'gauss@123';
grant dba to yat;
create_lob_data.py:
def test_create_lob_csv(node):
node.sql('create table lob_tbl(a clob)').ok()
for _ in range(200):
node.sql('insert into lob_tbl values(?)', ('0'*1000)).ok()
exp.z.sql:
exp table=lob_tbl file="temp/lob_bin_exp.dmp" filetype=bin parallel=3;
imp.z.sql:
imp file="temp/lob_bin_exp.dmp" filetype=bin table=lob_tbl;
cleanup.sql:
drop user yat cascade
除了setup和cleanup用例,上面我们创建了2个用例在testcase目录下,下一步是编写调度文件。
执行完yat init命令后,指定的测试套目录下会有schedule目录,创建schedule/schedule.schd文件指定调度顺序。
test: test_case_001 test_case_002
test: test_case_003
test: test_case_004 test_case_005 test_case_006
语法要点:
功能要点:
扩展后的语法兼容原始Regression格式语法,同时提供两级语法支持。
level 1
setup: setup_case_001(valid = false) setup_case_002(valid = false)
macro: DB_USER test_user1
group: test_case_001 test_case_002
group: test_case_003(diff = false valid=false)
group: test_case_004 test_case_005
test_case_006 test_case_007
test_case_007 test_case_008
import: sub-suite.schd
cleanup: cleanup_case
语法要点:
group:
开头,当然老版本的 test:
开头依然支持,但是建议都用 group:
开头,用例之间可以任意换行setup
用例组表示一个测试套中的前置用例cleanup
用例组表示一个测试套中的后置清理用例macro
标签不是一个用例组,表示一个宏变量定义import
标签不是一个用例组,表示导入子调度文件功能要点:
setup
用例组无论放到哪里都会最先执行cleanup
用例无论放到哪里都会最后执行macro
标签配置的宏变量可以在本组用例中使用import
导入的子调度文件level 2
name: user_without_grant
setup: setup_case_001(valid = false) setup_case_002(valid = false)
macro: DB_USER test_user1
group: test_case_001 test_case_002
group: test_case_003(diff = false)
group: test_case_004 test_case_005 test_case_006
import: sub-suite.schd
------
name: user_with_grant
setup: setup_case_003(valid = false)
macro: DB_USER test_user2
group: test_case_001 test_case_002
group: test_case_003(diff = false)
group: test_case_004 test_case_005 test_case_006
import: sub-suite.schd
group: test_case_100
cleanup: cleanup_case
在level 1的基础上,用户可以指定name
选项,指定子测试套名称,并通过------
分隔开两个子测试套
Yat框架配置节点信息的文件为conf/nodes.yml,配置如下:
# 配置默认节点,链接zenith数据库
default:
host: '127.0.0.1'
db:
type: 'zenith'
username: 'yat'
password: 'gauss@123'
port: 1611
ssh:
port: 22
username: yat
password: 'Gauss_234'
# 配置数据库超级用户链接节点,链接zenith数据库
sys:
host: '127.0.0.1'
db:
type: 'zenith'
username: 'sys'
password: 'Changeme_123'
port: 1611
ssh:
port: 22
username: root
password: 'Gauss_234'
上述配置文件中配置了两个节点信息,都是连接本地节点,不同之处在于sys
节点, 使用操作系统root
用户进行ssh
访问,default
节点使用数据库sys
用户进行数据库访问。
可以配置多个节点的信息,至少需要配置name
为default
的节点
在数据库上执行用例,需要安装对应版本的JDBC驱动,提供三种驱动安装方式。
jdbc的驱动jar文件,需要放到测试套java子目录中
适用场景,只有一个测试套需要运行
在测试套根目录添加java目录,并将驱动拷贝到此目录,注意驱动文件要有读权限
mkdir -p java
cp /path/to/com.huwei.gauss.jdbc.ZenithDriver-XXX.jar java
chmod a+r java/*.jar
最终目录结构如下:
|-- suite1
| |-- conf
| |-- schedule
| |-- testcase
| | |-- tc_test_001.sql
| | |-- tc_test_002.sql
| |-- java
| | |-- com.huwei.gauss.jdbc.ZenithDriver-XXX.jar
试用场景,有多个测试套需要共享JDBC驱动的场景
例如如下目录结构:
|-- suites
| |-- suite1
| | |-- conf
| | |-- schedule
| | |-- testcase
| |-- suite2
| | |-- conf
| | |-- schedule
| | |-- testcase
| |-- suite3
| | |-- conf
| | |-- schedule
| | |-- testcase
| |-- common
| | |-- java
| | | |-- com.huwei.gauss.jdbc.ZenithDriver-XXX.jar
| | |-- lib
| | |-- python
执行时带上--library/-L选项指向common目录即可,让suite1、suite2、suite3三个测试套共享相同的jdbc驱动、python驱动等
yat suite -d suites/suite1 -L suites/common
和局部安装类似,直接将JDBC jar驱动包拷贝的yat安装目录下的java目录中
例如yat默认安装到了/usr/local/yat目录中,执行以下命令安装驱动
cp /path/to/com.huwei.gauss.jdbc.ZenithDriver-XXX.jar /usr/local/yat/java
chmod a+r /usr/local/yat/java
进入测试套根目录,并执行:
cd exp-imp-lob
yat suite [run]
不在测试套根目录,通过命令行参数指定测试套路径执行
Yat suite [run] -d /data/gaussdba/testcase/exp-imp-lob
查看yat帮助说明
yat --help
Yat子命令如init、schedule、run-test也都有自己的帮助命令,执行:
yat --help查看具体信息,例如run-test子命令的帮助信息
yat suite --help
yat playbook --help
查看yat版本
yat version
yat suite [sub-command] [options]
支持的子命令有:
run
init
mkschd
bkfill (not support now)
run命令用来执行测试套,其中run关键字可以省略,例如:
yat suite run
yat suite # 等于 yat suite run
run命令支持很多选项以丰富其功能,具体的每一项选项如下:
用来指定测试套所在目录,不指定默认为当前目录
用来指定要执行的调度文件,不指定的话默认从schedule/schedule.schd中加载,如果找不到给定的文件,就会报错
需要注意
如果用户指定的调度文件路径是一个相对路径,调度文件的搜索顺序为:
当前目录
测试套根目录下的schedule目录
如果用户指定的调度文件是一个绝对路径,这直接使用此文件
推荐将调度文件都放到测试套根目录下的schedule目录中,所有需要指定调度文件时,直接使用相对路径指定即可
如,在下面目录结构下:
.
├── conf
│ ├── configure.yml
│ ├── env.sh
│ ├── macro.yml
│ └── nodes.yml
├── expect
│ └── abc
├── lib
│ └── pyzenith.so
├── log
├── result
│ └── test_001
├── schedule
│ ├── schedule1.schd
│ ├── schedule2.schd
│ └── sub-schedule
│ ├── schedule3.schd
│ └── schedule4.schd
├── temp
└── testcase
└── test_001.py
指定不同的调度文件可以这么写:
yat sutie -s schedule1.schd
yat suite -s schedule2.schd
yat suite -s sub-schedule/schedule3.schd
yat suite -s sub-schedule/schedule4.schd
可以看到用户根本不需要关系调度文件的绝对路径和位置,只需要指定名称即可
用例超时设置,①通过配置文件设置,在configure.xml中添加yat.case.timeout = 5
;②通过命令行设置,yat suite --timeout 5
;③通过用例属性设置,group:tc_test_case_001(timeout=5) tc_test_case_002
)
设置打印报告宽度,在用例名字特别长、嵌套目录特别深的情况下,由于报告宽度限制,用例名字会被截断,适当增加打印宽度
Note
其实终极解决办法是,用例命名规范、用例目录嵌套规范,如果目录嵌套大于4层,用例名字过长,要考虑一下自己对用例的类型划分和用例要测什么 真的清楚了吗?思路越清晰,用例越简单!!
不打印报告头和报告尾信息,直接打印一行一行的用例执行情况
打印报告在终端中彩色输出
Warning
前提是中断支持彩色模式
只要有用例失败,就直接退出yat
init子命令可以初始化一个空的默认测试套模板,用户可以使用此命令快速生成测试套
同run,不指定默认在当前目录生成测试套模板
如:
yat suite init # 在当前目录生成测试套模板
yat suite init -d ../abc # 在上级目录生成一个目录名字为abc的测试套
初始化测试套时,覆盖默认的配置文件
mkschd子命令用来生成默认的调度文件
Warning
使用此命令生成的调度文件默认使用用例名字字典序,如果对调度顺序没有要求,这样是方便快捷的,但是如果对调度顺序敏感,就不适合直接生成了 用户可以使用此命令生成一个用例名字字典序排序的调度文件,然后手工调整
同run
文件默认在conf/configure.yml中
yat.testcase.out.suffix
配置result和expect文件后缀 默认值:空,没有后缀
Note
result目录下存放sql用例执行结果,expect目录下存放sql用例执行期望
例: 默认情况下result和expect情况如下:
|-- suite
| |-- conf
| |-- schedule
| |-- result
| | |-- tc_test_case_001
| | |-- tc_test_case_002
| | |-- tc_test_case_003
| |-- expect
| | |-- tc_test_case_001
| | |-- tc_test_case_002
| | |-- tc_test_case_003
配置yat中断打印报告空白部分的填充字符 默认值:.
例: 默认打印格式如下
####################################### 2023-12-29 10:37:26 ########################################
Yat Version: Version 0.13.1 Build At 2023-12-27T19:54:20.557+08:00[Asia/Shanghai]
Test Suite: abc
[+] [2023-12-29 10:37:26] [00.029 s] [v] tc_script ............................................ : ok
[-] [2023-12-29 10:37:26] [00.534 s] [v] tc_sql_001 ........................................... : er
[+] [2023-12-29 10:37:27] [00.006 s] [v] tc_sql_002 ........................................... : er
################## Testing Result 1/3 Using Time PT0.604S At 2023-12-29 10:37:27 ##################
空白部分用.填充,如果设置为,空格``
yat.filling: ' '
效果如下:
####################################### 2021-12-29 10:41:57 ########################################
Yat Version: Version 0.13.1 Build At 2021-12-27T19:54:20.557+08:00[Asia/Shanghai]
Test Suite: abc
[+] [2021-12-29 10:41:57] [00.035 s] [v] tc_script : ok
[-] [2021-12-29 10:41:57] [00.591 s] [v] tc_sql_001 : er
[+] [2021-12-29 10:41:58] [00.005 s] [v] tc_sql_002 : er
################## Testing Result 1/3 Using Time PT0.669S At 2021-12-29 10:41:58 ###################
配置中断打印报告的字符宽度 默认值:100
配置最大执行用例数目,默认值:500,建议尽量设置大一些
配置单个用例文件大小,默认值:15K,建议尽量设置大一些
配置执行用例目录层级深度,默认值:2,根据实际执行用例的目录层级设置
用例文件命名需要符合正则表达式,默认值:'[a-zA-Z0-9_-]+'
设置gsql程序路径 默认值: gsql
如果程序路径在PATH中,直接设置为:gsql即可,如果不在PATH中可以直接指定相对或绝对路径
例如:
gsql在/home/tester/bin/gsql目录,且不在PATH,这可以这样设置:
yat.gsql.path: /home/tester/bin/gsql
设置zsql程序路径 默认值: gsql
同yat.gsql.path
nodes.yml是yat中非常重要的一个配置文件,这个文件中定义了我们如何连接数据库,连接数据库的用户名密码IP端口等信息, 同时配置了目标主机的ssh用户名密码,方便我们远程执行shell命令
定义一个节点的方法如下
# 定义链接zenith的节点
default:
host: '127.0.0.1'
db:
type: 'zenith'
username: 'yat'
password: 'gauss@123'
port: 1611
ssh:
port: 22
username: yat
password: 'Gauss_234'
注意type字段,此字段指明我们要定义的node链接zenith数据库,我们不需要写url和driver,yat知道默认的url和driver, 但是如果需要自定义链接url,则定义如下
定义链接zenith的节点,CN读写分离
default:
host: '127.0.0.1'
db:
type: 'zenith'
url: 'jdbc:zenith:db:@ip1:port1,ip2:port2?shardRwFlag=rw'
username: 'yat'
password: 'gauss@123'
port: 1611
ssh:
port: 22
username: yat
password: 'Gauss_234'
这里不用写driver字段,因为定义了type字段,yat知道driver是什么
当前yat支持的type字段为:
但是如果遇到了yat不支持type字段如何定义那?
我们这么定义:
# 定义链接不直接支持的数据库,CN读写分离
default:
host: '127.0.0.1'
db:
driver: 'org.xxx.xxx.XXXDriver'
url: 'jdbc:xxx://${host}:${port}/dbname'
username: 'yat'
password: 'gauss@123'
port: 1611
ssh:
port: 22
username: yat
password: 'Gauss_234'
用户可以同时定义多个不同命的节点信息,例如定义三个节点信息:
default:
host: '127.0.0.1'
db:
type: 'zenith'
username: 'yat'
password: 'gauss@123'
port: 1611
ssh:
port: 22
username: yat
password: 'Gauss_234'
admin:
host: '192.168.1.3'
db:
type: 'zenith'
username: 'sys'
password: 'Changeme_123'
port: 1611
ssh:
port: 22
username: root
password: 'Gauss_234'
normal:
host: '192.168.1.3'
db:
type: 'zenith'
username: 'yat'
password: 'gauss@123'
port: 1611
ssh:
port: 22
username: yat
password: 'Gauss_234'
上面我们定义了3个节点,用户可以在用例中自由指定连接那个节点进行用例操作
yat默认会使用名字叫default的节点去做所有没有明确指定节点的用例操作,用户可以通过yat命令行中的-t参数指定默认使用哪个节点
例如
默认使用default节点
yat suite run
使用admin节点
yat suite run -t admin
@conn admin;
可以通过conn node_name的方式,指定使用指定名字的节点进行数据库重新链接
# 连接节点名字为default的节点,并执行sql语句
zsql $(node_conn default) -q -c "select * from v$session"
# 连接节点名字为admin的节点
zsql $(node_conn admin) -q -c "select * from v$session"
可以通过命令node_conn 获得给定节点名字zsql形式的连接字符串
from unittest import TestCase
from yat.test import Node
class TestSelect(TestCase):
primary = None
standby = None
@classmethod
def setUpClass(cls):
self.primary = Node(node='primary')
self.standby = Node(node='standby')
def test_select_sessions(self):
self.primary.sql('select * from v$session').count(200)
self.standby.sql('select * from v$session').count(1)
self.standby.shell('zctl.py -t stop')
通过yat.test.Node对象获取对应node名字的链接对象,并以此对象进行sql和shell操作
由于zsql用例的sql文本解析和执行都是有yat启动一个zsql子进程来执行的,不受yat控制,所以zsql用例只能通过conn命令进行数据库链接切换
conn ${DEFAULT_DB_USER}/${DEFAULT_DB_PASSWD}@${DEFAULT_DB_HOST}:${DEFAULT_DB_PORT}
conn ${ADMIN_DB_USER}/${ADMIN_DB_PASSWD}@${ADMIN_DB_HOST}:${ADMIN_DB_PORT}
用户不需要自己在定义${DEFAULT_DB_USER} ${ADMIN_DB_PASSWD}等之类的宏变量了,系统默认会根据nodes.yml中的定义自动定义这些变量
宏配置文件只能配置在conf/macro.yml中,用户通过key-value的方式指定变量值
为了兼容老版本的yat测试套,支持java properties文件形式的宏配置文件,但是在未来版本可能移除这种兼容支持
yat宏系统中的宏变量可以在用例和期望文件中使用
5.2.1 在用例中
主要分为两种情况
例如,如果定义宏配置文件如下:
COMMON_PATH: temp/test_path
select * from tbl_test where path like '%${COMMON_PATH}%';
from unittest import TestCase
from yat.test import Node
from yat.test import macro
class TestMacro(TestCase):
node = None
@classmethod
def setUpClass(cls):
self.node = Node()
def test_select(self):
sql = 'select * from tbl_test where path like '%{}%'.format(macro.COMMON_PATH)
self.node.sql(sql).expect(
(0, 'abc', 34, 'temp/test_path'),
(1, 'bcx', 35, 'temp/test_path'),
)
zsql ${DEFAULT_DB_USER}/${DEFAULT_DB_PASSWD}@${DEFAULT_DB_HOST}:${DEFAULT_DB_PORT}
-c "select * from tbl_test where path like '%${COMMON_PATH}%'
例如上述SQL用例的期望文件查询结果中带${COMMON_PATH}变量的实际值,如果环境或者路径改变,期望文件也会频繁修改,为了应对这种情况我们可以在 期望文件中使用宏变量来消除这种路径依赖
select * from tbl_test where path like '%${COMMON_PATH}%';
ID | NAME | MARK | PATH |
-----------------------------------------
0 abc 34 ${COMMON_PATH}
1 bcx 35 ${COMMON_PATH}
表示当前执行的测试套名称,如果有子测试套,就是子测试套的名称
表示当前测试套根目录的绝对路径
表示当前测试套根目录下的temp目录的绝对路径
在nodes.yml
中配置的每一个节点信息都会对应9个宏变量如下:
这里面的<NODE_NAME>
表示nodes.yml中定义的节点的名字
例如nodes.yml中有如下定义
default:
host: '127.0.0.1'
db:
url: 'jdbc:zenith:@${host}:${port}'
driver: 'com.huawei.gauss.jdbc.ZenithDriver'
username: 'yat'
dbname: 'dbname'
password: 'gauss@123'
type: zenith
port: 1611
ssh:
port: 22
username: yat
password: 'Gauss_234'
sys:
host: '127.0.0.1'
db:
url: 'jdbc:zenith:@${host}:${port}'
driver: 'com.huawei.gauss.jdbc.ZenithDriver'
username: 'sys'
password: 'Changeme_123'
dbname: 'dbname'
port: 1611
ssh:
port: 22
username: root
password: 'Gauss_234'
则默认会定义如下宏变量
DEFAULT_DB_USER: yat
DEFAULT_DB_PASSWD: 'gauss@123'
DEFAULT_DB_HOST: 127.0.0.1
DEFAULT_DB_PORT: '1611'
DEFAULT_DB_TYPE: zenith
DEFAULT_DB_URL: 'jdbc:zenith:@${host}:${port}'
DEFAULT_DB_DBNAME: 'dbname'
DEFAULT_SSH_USER: yat
DEFAULT_SSH_PASSWD: 'Gauss_234'
DEFAULT_SSH_HOST: 127.0.0.1
DEFAULT_SSH_PORT: 22
SYS_DB_USER: sys
SYS_DB_PASSWD: 'Changeme_123'
SYS_DB_HOST: 127.0.0.1
SYS_DB_PORT: '1611'
SYS_DB_URL: 'jdbc:zenith:@${host}:${port}'
SYS_DB_DBNAME: 'dbname'
SYS_SSH_USER: root
SYS_SSH_PASSWD: 'Gauss_234'
SYS_SSH_HOST: 127.0.0.1
SYS_SSH_PORT: 22
Yat Schedule是Yat提供的一种同时调度多个Yat测试套的调度器,用户通过制定调度文件来进行多个Yat测试套的并行或串行的调度
parallel {
suite 'path/to/suite/dir/1';
suite 'path/to/suite/dir/2' '-s' 'schedule-A.schd';
suite 'path/to/suite/dir/2' '-s' 'schedule-B.schd';
...
}
parallel {}
表示一组并行调度的调度列表,将所需要进行调度的测试套列表写进{}中间即可suite suite-path param1 param2 param3 ...
描述了调度一个测试套需要的信息,包括:suite
suite-path
测试套的路径,此路径如果是相对路径,相对schedule调度文件所在目录param1 param2 param3 ...
运行yat测试套需要的参数,相当于运行yat suite run param1 param2 param3 ...
parallel {}
中所有的测试套都是并行调度的serial {
suite 'path/to/suite/dir/1';
suite 'path/to/suite/dir/2' '-s' 'schedule-A.schd';
suite 'path/to/suite/dir/2' '-s' 'schedule-B.schd';
...
}
所有的文法表示都和并行调度相同,不同点:
serial
开头serial {
suite 'path/to/suite/dir/1';
suite 'path/to/suite/dir/2' '-s' 'schedule-A.schd';
suite 'path/to/suite/dir/2' '-s' 'schedule-B.schd';
...
parallel {
suite 'path/to/suite/dir/1';
suite 'path/to/suite/dir/2' '-s' schedule-A.schd '-m' single;
suite 'path/to/suite/dir/2' '-s' 'schedule-B.schd';
serial {
suite 'path/to/suite/dir/1';
suite 'path/to/suite/dir/2' '-s' 'schedule-A.schd';
suite 'path/to/suite/dir/2' '-s' 'schedule-B.schd';
}
}
...
}
yat schedule -s all.ys
yat schedule --help
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。