0
点赞
收藏
分享

微信扫一扫

2022-10-27 mysql-mtr-test说明


mysql-test quick-start:

参考​​MySQL: The MySQL Test Framework​​

​​MySQL: Writing Replication Tests​​

2022-10-27 mysql-mtr-test说明_测试用例

运行用例

1、  进到测试目录

shell> cd mysql-version/mysql-test

2、创建测试文件t/​test_name​.test

3、创建空的结果文件

touch r/test_name.result

4、执行测试

./mysql-test-run.pl test_name

5、假设测试产生了输出文件,此时测试的结果一定是fail的,因为判断用例是否通过是判断运行的输出与结果文件是否一致。失败后会产生一个文件 ​​r/​​​test_name​​​.reject​​。检查reject文件的内容,如果里面是期望的输出,则将内容拷贝到.result文件中,作为以后判断运行结果是否通过的依据。Mysql-test还提供了一个参数—record实现自动生成result文件的方式

./mysql-test-run.pl --record test_name

6、再次执行测试,结果会是成功的

./mysql-test-run.pl test_name

如果后面不带有任何参数,将运行所有的case,包括上面刚刚加入的用例

在测试用例的组织上,建议每个.test文件取合适的长度以包含多个测试点;如果每个测试点都独立为单独的文件,会导致测试执行时间变长,影响效率。

为了保持测试用例的独立性,需要避免用例间的互相依赖。当有通用的需求时,例如在多个测试中可能用到同一个表,那么将这个表的定义放在目录 ​​mysq-test/include​​​中,命名 ​​mysql-test/include/create_my_table.inc​​,并通过source命令在每个case中进行调用。使用inc结尾是习惯做法,并没有特殊要求。调用方法如下:


--source include/create_my_table.inc


每个case中需要保证case结束时将这个表drop掉。

测试用例编写的规范或者使用指南:

1、  尽可能避免每行超过80个字符

2、  使用#开头,作为注释

3、  缩进使用空格,避免使用tab

4、  SQL 语句使用相同的风格,包括关键字大写,其它变量、表名、列名等小写

5、  增加合适的注释。特别是文件的开头,注释出测试的目的、可能的引用或者修复的bug编号

6、  一般情况下,mysql-test-run.pl启动自己的Mysql服务来进行测试,除非在启动时指定参数—extern,来说明使用的Mysql服务。为了避免可能的冲突,习惯上表命名使用t1、t2...... 视图命名使用v1、v2。。。。。。

一个简单的测试用例的例子:​​MySQL: The MySQL Test Framework​​

基于运行效率的考量,mysqltest的测试引擎会使用同一个server来连续的执行不同的测试文件,在运行的过程中会使用同一个database。在case结束时要保证将新建的表以及临时文件等清除掉。一般情况下,在case运行前,也对可能有干扰的表先做清除,例如:


--disable_warnings


DROP TABLE IF EXISTS t1,t2;


--enable_warnings


Case运行失败的可能原因:

1、  用例文件中的sql是不合法的

2、  产生的结果文件与期望文件diff结果不一致

处理期望的错误输出:

在期望有返回错误的前面使用error指令,例如创建一个已经存在的表名时,可以任选下面任一种方式


--error 1050


--error ER_TABLE_EXISTS_ERROR


其中数字对应错误码,ER_TABLE_EXISTS_ERROR对应错误的逻辑名。这样在mysqltest运行后,会将返回的错误信息一起写入结果文件,这些错误信息就作为期望结果的一部分了。

也可以使用SQLSTATE来指示期望有错误返回,例如与Mysql错误码1050关联的SQLSTATE值是42S01,使用下面的方式,注意编码增加了S前缀:


--error S42S01


在指令error后面是可以加入多个错误码作为参数的,使用逗号分隔即可

错误码及逻辑值的对应关系参考Mysql源代码include目录下的​​mysqld_error.h​​​ 和​​sql_state.h​

显示和关闭结果信息

显示影响的结果,指令和结果如下:


--enable_info


CREATE TABLE t2 (Period SMALLINT);


affected rows: 0


INSERT INTO t1 VALUES (9410,9412);


affected rows: 1


INSERT INTO t2 VALUES (9410),(9411),(9412),(9413);


affected rows: 4


--disable_info


如果不想记录在测试文件中写的sql statements可以通过指令打开enable_query_log和​​disable_query_log​​ 关闭,如果想控制是否记录执行命令的输出,可以通过执行disable_result_log关闭和enable_result_log打开。

处理输出中可能变化的值

某些查询结果列的值,在每次运行后可能返回不同的值,如果我们并不关心这一列具体的值时,可以将它转换为一个常量记录在结果文件中。通过将replace_column写在查询语句之前,例如,第一列可能是变化的值且我们不关心它是什么时:


--replace_column 1 XXX


SELECT * FROM t1;


也可以同时替换多个列,在后面直接写即可

由mysql-test-run.pl向mysqld传递运行参数

1、向mysqld传递两个参数​​--skip-innodb​​​ 和 ​​--key_buffer_size=16384​​​​。注意​​​​—mysqld​​​​需要写两次​

mysql-test-run.pl --mysqld=--skip-innodb --mysqld=--key_buffer_size=16384

2、使用--combination传递,效果是连续运行两次,分别使用其中一行的参数传给mysqld。如果只有一行,那么与—mysqld是一样的

mysql-test-run.pl

--combination=--skip-innodb

--combination=--innodb,--innodb-file-per-table

更多示例参考​​Section 4.12.1, “Controlling the Binary Log Format Used for an Entire Test Run”​​

定义case关联的Mysql Server参数或用法

当测试需要使用指定的命令行参数重启server时,可以定义文件 ​​mysql-test/t/​​​test_name​​​-master.opt​​,mysql-test-run.pl在执行test_name这个用例时会检查当前server是否含有这些参数,如果没有则使用这些参数重启mysqld

在某些特殊情况下,会有意的让mysqld服务 crash掉,--skip-core-file参数会避免在测试过程中产生core文件

当需要在case执行前执行外部的命令时,将命令写到 ​​t/​​​test_name​​​-master.sh​​中,它会在启动server前执行。因为需要shell执行脚本,所以在windows环境下会自动跳过。

使用include文件简化用例

在include目录下已经保存了很多文件,作为公共的文件,封装了各种复杂的操作,这样在执行用例时可以实现简单的调用,例如当我们想验证是否支持csv类型的存储引擎时,可以在用例文件中增加如下引用:


--source include/have_csv.inc


测试用例中需要确保include的文件存在,否则测试会直接退出。

使用场景:

1、  检查是否支持指定的存储引擎

2、  检查支持的字符集

3、  是否需要debug选项

4、  等待一个条件变成true

5、  控制binlog格式

6、  控制从库服务

可以将include文件看做是一个子程序模块,可以通过设定变量的方式向它传递参数,以及获取它们的返回值。

控制binlog格式

如果我们的测试用例rpl.rpl_row*需要在不同的binlog模式(row和statement)下运行,可以通过下面两种方式:

mysql-test-run.pl --suite=rpl --do-test=rpl_row

--combination=--binlog_format=row

--combination=--binlog_format=mixed

或者通过combinations文件的方式,即增加文件suite/rpl/combinations,内容如下:


[row]


--binlog_format=row



[mixed]


--binlog_format=mixed


执行方式:

mysql-test-run.pl --suite=rpl --do-test=row

上面的控制方法或是影响运行的全部case,或者是影响suite/rpl目录下的所有case。如果想控制每个case有单独的设置,需要借助include的方式来实现。将case文件中包含如下其中的一行即可:


--source include/have_binlog_format_row.inc


--source include/have_binlog_format_statement.inc


--source include/have_binlog_format_mixed.inc


如果是需要支持两种格式,则在下面选择一行:


--source include/have_binlog_format_mixed_or_row.inc


--source include/have_binlog_format_mixed_or_statement.inc


--source include/have_binlog_format_row_or_statement.inc


在mtr执行前,mtr会检查系统的binlog格式是否满足source中指定,一直后采取执行case,否则会skip。

如果不包含have_binlog_format_*.inc,则视为支持所有的格式。

主从复制相关的用例

​​MySQL: The MySQL Test Framework​​

Case文件中只需要添加如下的指令即可:


--source include/master-slave.inc


在主从间切换:


connection master;


connection slave;


屏蔽期望的errors和warnings

测试用例执行完毕后,没有出现错误的情况下,mtr会继续坚持server记录的log,如果发现了任何warning或者error,结果也会是failed。此时我们需要忽略掉一些warnings或者error,因为有些异常是测试输入的条件。文件include/mtr_warnings.sql中,列出了所有需要忽略的warings或者errors,文件中的内容是支持正则表达式的。

也可以通过用例中的指令来屏蔽错误,例如:


--disable_query_log


call mtr.add_suppression("The table 't[0-9]*' is full");


--enable_query_log


另一种屏蔽的方式是给mysql-test-run.pl传递参数:--nowarnings

测试执行过程中停止Server

​​MySQL: The MySQL Test Framework​​

通过mtr启动一个mysqld用来调试:

shell> cd mysql-test

shell> ./mysql-test-run.pl --start alias &

shell> ../mysql -S ./var/tmp/mysqld.1.sock -h localhost -u root

使用的配置文件就是默认跑所有case情况下,第一个case使用的配置文件

使用参数--start-and-exit的含义:是启动mysqld后,mtr就退出。其它效果含义同—start

Mysql-test-run术语及说明和语言参考

1、  Command:是mysqltest本身能够识别和执行的输入语句

2、  Statements:是SQL statements,是mysqltest发送给MySQL服务端执行的语句。

3、  Mysqltest启动后,使用的连接名为default与MySQL server连接。用例中通过connect command打开其它连接,使用connection command在多个连接间进行切换。

4、  注释以#开头,除此之外,mysqltest首先把它认为是command去执行,如果是它不认识关键字,则作为statements发送给MySQL server去执行。确认命令的结尾是依赖分隔符的,来区分一行中可能有的多个command,或者多行相连才是一条完整的语句,默认的分隔符就是分号,当然这也是可以通过delimiter command来修改。回车换行并不是作为一条command或者statements结束的标志。当statements中sql开头的keywords也是mysqltest的command时,为了避免歧义,使用以双短横线 “--“开头的方式书写命令。如下两种方式的语义是相同的

--sleep 2


sleep 2;

循环语句:


let $1= 10;


while ($1)


{


# execute your statements here


dec $1;


}


语句之间暂停


sleep 0.2;


跳过执行用例

skip [message]


let $v= 0;


if (!$v)


{


  skip value is zero, skipping test;


}


echo This command is never reached;


skip是一条command,后面是输出的skip原因,mtr在打印完message后退出,不再执行测试文件中的后续内容。

举报

相关推荐

0 条评论