在之前的文章中,我们介绍了如何修复一个 MySQL 的 bug,里面提到了在官方修复中,通常会附带一个 MTR 测试用例。通过运行该测试用例,我们就可以验证我们自己的修复是否已经将 bug 成功修复。那大家可能就会对这个 MTR 测试用例是如何写的比较感兴趣,所以,本篇我们将简单介绍一下 MTR 测试框架及如何编写一个 MTR 测试用例。
1
MTR简介
首先,我们简单介绍一下 MTR(MySQL Test Framework)。MTR 是 MySQL 官方研发的一套测试框架,主要是通过一套 perl 脚本来实现 MySQL 的基本功能测试。通过MTR测试框架提供的环境,可以非常简单,快速,方便的测试自己研发的特性和验证 bug 的修复。
通常情况下,MTR 的主要部分在 MySQL 安装路径的 mysql-test 目录下,主要包括以下一些主要组成部分:
-
perl 脚本:mysql-test-run.pl 等 perl 脚本是 MTR 运行的主体部分。这些 perl 脚本主要提供了 MySQL 测试的基本流程,如:初始化实例,启动实例,从 .test 测试用例文件中读取 SQL 运行,对比结果,清理测试环境等。
-
.test 、.inc 测试文件和 .result 结果文件:.test 文件是包含测试逻辑的文本文件,它可以包含若干个 .inc 文件,用以简化一些基本逻辑。.result 文件则是包含测试结果的文本文件,里面是预期的测试结果。MTR 的测试脚本会对比运行的输出和 result 文件来判断测试是否通过。
-
.opt 配置文件:.opt 和 .cnf 文件主要包含的是测试过程中实例需要用到的一些特殊的配置参数。比如:新增特性后增加的服务器参数。
内嵌的 debug sync 同步机制和调试代码:为了方便调试一些并发问题, MTR 还建立了一整套用于 debug 的同步机制,通过在源码中预埋一些同步点来实现各个线程之间的相互协同,使得并发问题更容易重现。另外,我们还可以在 MySQL 源码中嵌入一些调试代码,用以测试代码逻辑或打印调试信息。
MTR的运行流程:
如下图所示,MTR 的基本运行过程主要包括这样一些步骤:读取测试用例文件,初始化测试实例,运行测试逻辑,对比测试结果和清理测试环境。
2
编写一个简单的MTR测试用例
以下,我们以编写一个简单的 MTR 测试为例,详细介绍一下如何编写和运行一个测试用例。
在 mysql-test/t 目录下,创建一个t.test的文件,内容如下:
基本逻辑就是创建表,插入数据,查询数据。
保存文件后,回到 mysql-test 目录,运行测试命令:./mtr -mem t
运行结果如下:
由于我们没有对应的 .result 文件,所以 MTR 运行时报了一个缺少result文件的错误,但从上图可以看清MTR的整体测试流程。
如下所示,通过MTR的 -record 参数,我们可以很方便的通过录制测试结果来产生 result 文件。
录制完成 .test 文件后,再次运行测试,则该测试用例顺利通过。
3
常用的MTR测试命令参数
常用的 MTR 测试命令参数:
-
-mem:将测试产生的所有文件放置在内存盘中,以减少磁盘消耗和加速。
-
-suite:运行一整套的测试,比如:-suite=innodb,会运行整个mysql-test/suite/innodb/t下的所有测试用例。
-
-parallel:并行运行,如:-parallel=8,即以并行度8来运行所有测试。
-
-force:强制运行所有测试,即使有失败用例。缺省情况下,有失败用例,测试就自动中止。
-
-retry-failure:失败用例重测次数,缺省为3次。
-gdb:自动弹出gdb调试终端,调试测试用例逻辑。
以下测试命令是一个测试所有innodb用例的例子:
./mtr -mem -suite=innodb -parallel=8 -force -retry-failure=0
4
总结
本文简单介绍了 MySQL 内核开发的 MTR 测试框架及其使用方法,而实际上,MTR 所能提供的功能远非如此简单,在后续的文章里,我们将会介绍一些 MTR测试的复杂功能,比如:debug sync 同步机制来测试并发问题,通过内嵌测试代码来控制测试逻辑,复制场景下的测试等等。