Docker热迁移工具CRIU原理系列:测试集 ZDTM

 

 

        ZDTM 代表 Zero DownTime Migration,零宕机迁移。ZDTM 测试集本是为OpenVZ 热迁移开发的测试集,CRIU也使用它作为测试集。ZDTM 测试集由许多测试用例组成,目前在CRIU里面包含384个测试用例。同时ZDTM测试套件是一个自动化套件,它将各个子测试作为进程启动,等待它们准备就绪,然后转储已启动的进程,然后还原它们,并要求检查还原的状态是否是测试认为正确的状态。测试本身位于test/zdtm/子目录之一。完整的循环套件是test/zdtm.py脚本。

       本文介绍它的基本使用和测试接口ZDTM API。

一、准备工作:下载依赖包和criu源码并编译

        运行ZDTM测试集需要当前主机安装libaio-devel (RPM) 或者 libaio-dev (DEB)包。同时测试脚本 zdtm.py需要安装PyYAML (RPM) 或者 python-yaml (DEB)包。

       ZDTM相关代码在criu源码的test目录。我们可以下载并编译criu源码中的ZDTM测试集,命令是
 

[local@localhost test]$ git clone  https://github.com/checkpoint-restore/criu.git
[local@localhost test]$ cd criu
[local@localhost test]$ su
[root@localhost test]# make clean ; make zdtm

编译完成后,我们就可以进入test目录查看ZDTM测试集列表:
 

[root@localhost test]# cd test
[root@localhost test]# ./test/zdtm.py list

zdtm/static/env00
zdtm/static/file_append
zdtm/static/cgroup00
zdtm/transition/maps008
zdtm/transition/epoll
zdtm/transition/ipc
zdtm/transition/fork2
zdtm/transition/socket-tcp
zdtm/transition/unix_sock
。。。

 

二、运行ZDTM全部测试集或单个测试用例

      运行单个ZDTM测试用例使用命令”zdtm.py -t Name“。这里Name 表示用例名称。例如

[root@localhost test]# cd test
[root@localhost test]#./zdtm.py run -t zdtm/static/env00

=== Run 1/1 ================ zdtm/static/env00
========================== Run zdtm/static/env00 in h ==========================
Start test
./env00 --pidfile=env00.pid --outfile=env00.out --envname=ENV_00_TEST
Run criu dump
Run criu restore
Send the 15 signal to  44
Wait for zdtm/static/env00(44) to die for 0.100000
Removing dump/zdtm/static/env00/44
========================= Test zdtm/static/env00 PASS ==========================
========================= Run zdtm/static/env00 in ns ==========================
Start test
./env00 --pidfile=env00.pid --outfile=env00.out --envname=ENV_00_TEST
Run criu dump
=[log]=> dump/zdtm/static/env00/92/1/dump.log
------------------------ grep Error ------------------------
(00.476455) 	Running ip route save
(00.478566) 	Running ip -6 route save
(00.480640) 	Running ip rule save
Command "save" is unknown, try "ip rule help".
(00.482652) Warn  (criu/net.c:1878): Check if "ip rule save" is supported!
------------------------ ERROR OVER ------------------------
Run criu restore
Send the 15 signal to  111
Wait for zdtm/static/env00(111) to die for 0.100000
Removing dump/zdtm/static/env00/92
========================= Test zdtm/static/env00 PASS ==========================

在这里,”Test zdtm/static/env00 PASS“显示env00测试用例测试结果通过,其过程中生成的*.img临时文件默认已经被删除,从” Removing dump/zdtm/static/env00/92“可以看出。

 

        如果要在运行某个测试用例过程中保留测试用例的中间.img文件,可以在命令”zdtm.py run“命令里添加” --keep-img always“选项。例如:

[root@localhost test]# ./zdtm.py run -t zdtm/static/env00 --keep-img always

运行后生成的*.img文件在目录dump/zdtm/下。例如查看测试env00用例生成的.img结果如下:

[root@localhost test]# cd dump/zdtm/static/env00/44/1/
[root@localhost 1]# ls
core-44.img   fs-44.img      pagemap-44.img		restore.cropt
dump.cropt    ids-44.img     pagemap-shmem-3620349.img	restore.log
dump.log      inventory.img  pages-1.img		seccomp.img
fdinfo-2.img  memfd.img      pages-2.img		stats-dump
files.img     mm-44.img      pstree.img			stats-restore

        

         运行所有ZDTM测试集使用命令” zdtm.py -a “ 或者  ”zdtm.py -a --parallel 2“

./zdtm.py run -a --parallel 2

这里”-a“代表all,即运行全部用例。” --parallel “代表并行执行,” --parallel 2“代表占用2个线程运行。全部跑完382个测试用例也着实需要一些时间。运行结束后,会收到如下信息:

 

三、ZDTM API

       为了编写更多的子测试,开发人员应该使用下面声明的API。一个ZDTM测试用例基本包括如下3阶段:

准备阶段:进程开始备份(Checkpoint)之前的动作。

执行阶段:在这个阶段,进程可以在任意位置被中断和备份。

验证阶段:恢复之后,测试程序验证正确性并报告结果。

       相关的API如下:

test_init(argc, argv):初始化测试子系统。在这个调用之后,准备阶段开始。

test_daemon():准备阶段完成,随时可以进入执行阶段进行备份程序。

test_go():检查程序dump/restore过程是否完成。

test_waitsig():阻塞任务直到进程被恢复。

pass():通知测试成功。

fail(message):通知测试失败

err(message):通知测试不能正常运行。

test_msg(message):测试信息。

  一个典型的测试用例如下:

int main(int argc, char **argv)
{
	test_init(argc, argv);

	/* Preparations */

	test_daemon();

#if test want to act and get c/r-ed unexpectedly
	while (test_go()) {
		/* Actions go here */
	}
#else test just want to wait for c/r to happen
	/* Actions go here. */

	test_waitsig();
#endif

	/* checks */

	if (test_passed())
		pass();
	else
		fail("Something went wrong");

	return 0;
}

 

 

 

 

 

 

 

 

你可能感兴趣的:(docker)