mita2 database life

主にMySQLに関するメモです

MySQL テストコードを書いてみる

先日、MySQLをソースからビルドする方法を書きました。今日はテストコードについてのエントリーです。 mita2db.hateblo.jp

MySQL のテストコード

mysql-test/suite ディレクトリ以下にテストコードが記述されています。 5800以上のテストが記述されています。

$ find ~/mysql-8.0.18/mysql-test/suite/ -type f -name '*.test' | wc -l
5854

MySQL 8.0 でも 500以上のテストが追加されたとアピールされてます(スライド11ページ)。MySQLの品質はこのテストコードで担保されているんですね。

www.slideshare.net

テストを実行してみる

ビルドしたディレクトリの mysql-test ディレクトリ以下に、テストを実行するためのスクリプトが配置されます。 mtrmysql-test-run がそのスクリプトです。どちらも実態は mysql-test-run.pl で、同じものです。

$ ls -alh
total 24K
drwxr-xr-x  5 mita2san users  174 Dec 27 11:03 .
drwxr-xr-x 32 mita2san users 4.0K Dec 26 17:02 ..
drwxr-xr-x  3 mita2san users   87 Dec 26 13:41 CMakeFiles
-rw-r--r--  1 mita2san users 2.5K Dec 26 13:41 cmake_install.cmake
-rw-r--r--  1 mita2san users  295 Dec 21 14:07 CTestTestfile.cmake
drwxr-xr-x  3 mita2san users   16 Dec 21 14:07 lib
-rw-r--r--  1 mita2san users 7.8K Dec 26 13:41 Makefile
lrwxrwxrwx  1 mita2san users   19 Dec 26 13:40 mtr -> ./mysql-test-run.pl
lrwxrwxrwx  1 mita2san users   19 Dec 26 13:40 mysql-test-run -> ./mysql-test-run.pl
-rwxr-xr-x  1 mita2san users  252 Dec 21 14:07 mysql-test-run.pl
drwxr-xr-x  8 mita2san users   97 Dec 27 11:03 var

このコマンドの引数にテストのファイル名を指定することで、特定のテストだけを実行することができます。 何も引数を指定しなければ全てのテストが実行されます。

$ ls  mysql-test/suite/sys_vars/t/ | grep binlog_format
binlog_format_basic.test

$ ./mtr binlog_format_basic
<snip>
==============================================================================
                  TEST NAME                       RESULT  TIME (ms) COMMENT
------------------------------------------------------------------------------
[100%] sys_vars.binlog_format_basic              [ pass ]     13
------------------------------------------------------------------------------
The servers were restarted 0 times
The servers were reinitialized 0 times
Spent 0.013 of 17 seconds executing testcases

Completed: All 1 tests were successful.

binlog_format_basic はこのようなテストコードです。 performance_schema.global_variablesbinlog_format の列が存在することを確かめていまいした。

--echo '#---------------------BS_STVARS_002_03----------------------#'
#################################################################
# Check if the value in GLOBAL Table matches value in variable  #
#################################################################

--disable_warnings
SELECT @@GLOBAL.binlog_format = VARIABLE_VALUE
FROM performance_schema.global_variables
WHERE VARIABLE_NAME='binlog_format';
--enable_warnings
--echo 1 Expected

テストを記述してみる

オリジナルのテストを記述してみたいと思います。

mysql-test/suite/ 以下に任意のデュレクトリを作成し、その下に t というディレクトリにテストスクリプトを記述します。 r にはそのスクリプトの期待される出力を記述します。 SELECTを1回だけ実行するシンプルなテストを記述してみました。

$ cd ../mysql-test/suite/
$ mkdir -p mita2/{t,r}
$ touch mita2/r/sample_t.result

$ vim mita2/t/sample_t.test
SELECT "123";
--echo 123 Expected

実行します。

$ ./mtr sample_t
Logging: /home/mita2san/mysql-8.0.18/mysql-test/mysql-test-run.pl sample_t
MySQL Version 8.0.18
Checking supported features
 - Binaries are debug compiled
Using 'all' suites
Collecting tests
Checking leftover processes
Removing old var directory
Creating var directory '/home/mita2san/mysql-8.0.18/build/mysql-test/var'
Installing system database
Using parallel: 1

==============================================================================
                  TEST NAME                       RESULT  TIME (ms) COMMENT
------------------------------------------------------------------------------
[100%] mita2.sample_t                            [ fail ]
        Test ended at 2019-12-27 12:20:10

CURRENT_TEST: mita2.sample_t
--- /home/mita2san/mysql-8.0.18/mysql-test/suite/mita2/r/sample_t.result        2019-12-27 05:30:37.966983335 +0300
+++ /home/mita2san/mysql-8.0.18/build/mysql-test/var/log/sample_t.reject        2019-12-27 06:20:09.905602126 +0300
@@ -0,0 +1,4 @@
+SELECT "123";
+123
+123
+123 Expected

mysqltest: Result length mismatch

safe_process[21816]: Child process: 21817, exit: 1

 - the logfile can be found in '/home/mita2san/mysql-8.0.18/build/mysql-test/var/log/mita2.sample_t/sample_t.log'

[ fail ] と、失敗しました。 まだ、r ディレクトリに 期待する出力結果を記述していないため、失敗と判定されました。 ログディレクトリに実行結果が記録されています。これを r ディレクトリにコピーします。

$ cat build/mysql-test/var/log/sample_t.reject
SELECT "123";
123
123
123 Expected
$ mv build/mysql-test/var/log/sample_t.reject mysql-test/suite/mita2/r/sample_t.result

今度はテストをパスしました。めでたしめでたし。

$ ./mtr sample_t
Logging: /home/mita2san/mysql-8.0.18/mysql-test/mysql-test-run.pl sample_t
MySQL Version 8.0.18
Checking supported features
 - Binaries are debug compiled
Using 'all' suites
Collecting tests
Checking leftover processes
Removing old var directory
Creating var directory '/home/mita2san/mysql-8.0.18/build/mysql-test/var'
Installing system database
Using parallel: 1

==============================================================================
                  TEST NAME                       RESULT  TIME (ms) COMMENT
------------------------------------------------------------------------------
[100%] mita2.sample_t                            [ pass ]      1
------------------------------------------------------------------------------
The servers were restarted 0 times
The servers were reinitialized 0 times
Spent 0.001 of 17 seconds executing testcases

Completed: All 1 tests were successful.