快速使用
kvm_unit_test是一个kvm的测试套,代码仓库路径在这里。
./configure; make 编译后会生成对应的elf和flat文件,这些文件不是直接使用,需要作为
qemu的参数使用。
还可以使用./configure; make standalone编译,这样会在tests生成对应的脚本,这些脚本
是可以直接使用的。这些脚本里调用qemu去执行对应的测试程序。
看一个make standalone编译运行micro-bench测试的例子,把编程生成的micro-bench中的
最后一行中的kvm改成tcg,这样随便找个tcg的qemu也可以做测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| sherlock@m1:~/repos/kvm-unit-tests/tests$ export QEMU=/home/sherlock/repos/qemu/build/qemu-system-aarch64 sherlock@m1:~/repos/kvm-unit-tests/tests$ ./micro-bench BUILD_HEAD=220ac1e0 Test marked not to be run by default, are you sure (y/N)? y timeout -k 1s --foreground 90s /home/sherlock/repos/qemu/build/qemu-system-aarch64 -nodefaults -machine virt -accel tcg -cpu cortex-a57 -device virtio-serial-device -device virtc onsole,chardev=ctd -chardev testdev,id=ctd -device pci-testdev -display none -serial stdio -kernel /tmp/tmp.yrCCPNO4tn -smp 2 # -initrd /tmp/tmp.fkPDjJfrO8 Timer Frequency 62500000 Hz (Output in microseconds)
name total ns avg ns -------------------------------------------------------------------------------------------- hvc 7711984.0 117.0 mmio_read_user 16534304.0 252.0 mmio_read_vgic 14945696.0 228.0 eoi 17121360.0 261.0 ipi 549007696.0 8377.0 ipi_hw test skipped lpi test skipped timer_10ms 214614144.0 838336.0
EXIT: STATUS=1 PASS micro-bench
|
可以看见kvm_unit_test的脚本会拉起一个qemu做测试,被测试内容被隔离到了一个vm里,
理论上是不会对系统运行的其他qemu有影响的。
代码构架分析
kut整个结构可以大概分为两个部分,一个是后面要直接在qemu上跑的程序,一个是一堆shell
脚本,编译的时候使用这些脚本生成可以直接跑的测试用例。
前者的C代码在kvm-unit-tests/arm(这里以ARM构架为例),对应的配置文件为
kvm-unit-tests/arm/unittests.cfg,这个配置文件里定义每个测试用例的参数,比如,
qemu上跑的文件,qemu配置多少个core,qemu架构,启动参数等。
后者根据配置文件生成测试脚本,每个测试用例对应一个测试脚本,每个测试脚本拉起一个
qemu跑测试程序。可以顺着make standalone看看大概的逻辑。
这里$cfg就是unittests.cfg,for_each_unittest对于unittests.cfg中的每个配置项调用
mkstandalone生成测试脚本。
1 2
| /* scripts/mkstandalone.sh */ for_each_unittest $cfg mkstandalone
|
mkstandalone的入参就是从配置项里解析得到的具体配置,mkstandalone再调用generate_test
具体生成测试脚本。
1 2 3 4 5 6 7 8 9 10 11 12
| mkstandalone +-> generate_test +-> echo "#!/usr/bin/env bash" <-- 生成测试脚本 ... +-> temp_file ERRATATXT "$ERRATATXT" +-> echo "$var=\`mktemp\`" <-- 插入测试脚本中生成临时文件, echo "cleanup=\"\$$var \$cleanup\"" 清理环境,解压二进制的脚本 echo "base64 -d << 'BIN_EOF' | zcat > \$$var || exit 2" gzip -c "$file" | base64 <-- 把测试代码的二进制压缩base64 ... 编码后写入测试脚本 +-> cat scripts/runtime.bash <-- 加入公共脚本 +-> echo "run ${args[*]}" <-- 加入最后运行的shell函数
|
这里需要注意的是,对于qemu执行的二进制,generate_test把对应的二进制gzip压缩并用
base64编码,然后把编码直接写入最终的测试脚本文件里。测试脚本里先生成一个临时文件,
再把脚本中保存的二进制解码解压缩后写入临时文件,qemu使用对应的临时文件跑测试。
相关的辅助脚本也都在generate_test里写入测试脚本文件。
对着生成的测试脚本,如上的逻辑会看的很清楚。