LeavaTailの日記

LeavaTailの日記

Linuxエンジニアを目指した技術者の備忘録

KUnitフレームワークによるLinuxカーネルのテスト実施方法

概要

本記事では、kunit_toolを使用して、既存のKUnitテストをQEMU(armアーキテクチャ)で実行する手順について確認する。

はじめに

KUnitは、Linuxカーネル用のテストフレームワークである。
Linuxカーネル v5.5から導入されたスクリプトtools/testing/kunit.pyを実行することで、テスト実行・結果解析することができる。
このスクリプトを利用することで、User Mode Linux (UML) やQEMUでテストを実行することができる。

KUnitでは、内部ライブラリ (include/linux/list.hなど) といったユーザ空間からテストすることができる。 また、アサーションの作成やsetup/clean-upなどのテストを簡単に書くためのライブラリを提供している。

実験環境

本記事で使用した開発用PC (Host PC)の構成は次の通りとなっている。

環境 概要
CPU AMD Ryzen 3 3300X
RAM DDR4-2666 16GB ×2
Host OS Ubuntu Desktop 22.04
Target kernel v5.15.37
QEMU 6.2.0 (Debian 1:6.2-+dfsg-2ubuntu6)

準備

LinuxのソースツリーがDirtyの場合、次のエラーが発生する。あらかじめmake mrproperを実施しておくこと。

leava@kbuild:~/workspace/linux$ ./tools/testing/kunit/kunit.py run --arch=arm --cross_compile=arm-linux-gnueabihf- --jobs=12 --qemu_config=./tools/testing/kunit/qemu_configs/arm.py 
[18:35:11] Configuring KUnit Kernel ...
Generating .config ...
Populating config with:
$ make ARCH=arm olddefconfig CROSS_COMPILE=arm-linux-gnueabihf- O=.kunit
ERROR:root:make[1]: Entering directory '/home/leava/workspace/linux/.kunit'
***
*** The source tree is not clean, please run 'make ARCH=arm mrproper'
*** in /home/leava/workspace/linux
***
make[1]: *** [/home/leava/workspace/linux/Makefile:570: outputmakefile] Error 1
make[1]: Leaving directory '/home/leava/workspace/linux/.kunit'
make: *** [Makefile:219: __sub-make] Error 2

また、KUnitを実行するためには、次のカーネルコンフィグが必要となる。 

CONFIG_KUNIT=y
CONFIG_MSDOS_FS=y
CONFIG_FAT_KUNIT_TEST=y

KUnitでは、Linuxカーネルのコンフィグファイル.configとは別のファイル.kunit/.kunitconfigでもカーネルコンフィグを管理することができる。

コンフィグファイルの生成

kunit_toolのconfigを指定することでKUnitに必要な生成される。

leava@kbuild:~/workspace/linux$ ./tools/testing/kunit/kunit.py config
[22:41:14] Configuring KUnit Kernel ...
Generating .config ...
Populating config with:
$ make ARCH=um olddefconfig O=.kunit
[22:41:16] Elapsed time: 2.409s

leava@kbuild:~/workspace/linux$ ls -lA .kunit/
total 48
-rw-r--r-- 1 leava root 22976 May  8 22:41 .config
-rw-r--r-- 1 leava root    68 May  8 22:41 .config.old
-rw-r--r-- 1 leava root    39 May  8 22:41 .gitignore
-rw-r--r-- 1 leava root    68 May  8 22:41 .kunitconfig
-rw-r--r-- 1 leava root    73 May  8 22:41 Makefile
drwxr-xr-x 4 leava root  4096 May  8 22:41 include
drwxr-xr-x 4 leava root  4096 May  8 22:41 scripts
lrwxrwxrwx 1 leava root     2 May  8 22:41 source -> ..

leava@kbuild:~/workspace/linux$ cat .kunit/.kunitconfig 
CONFIG_KUNIT=y
CONFIG_KUNIT_EXAMPLE_TEST=y
CONFIG_KUNIT_ALL_TESTS=y

カーネルのビルド

kunit_toolのbuildを指定することでKUnitで実行するカーネルをビルドする。 このとき、--arch--cross_compileオプションを指定することでクロスコンパイルすることができる。

leava@kbuild:~/workspace/linux$ ./tools/testing/kunit/kunit.py build --arch=arm --cross_compile=arm-linux
[23:09:22] Building KUnit Kernel ...
Populating config with:
$ make ARCH=arm olddefconfig CROSS_COMPILE=arm-linux-gnueabihf- O=.kunit
Building with:
$ make ARCH=arm --jobs=12 CROSS_COMPILE=arm-linux-gnueabihf- O=.kunit
[23:09:57] Elapsed time: 35.098s

leava@kbuild:~/workspace/linux$ ls -la .kunit/
total 19400
drwxr-xr-x 19 leava root    4096 May  8 23:09 .
drwxrwxr-x 26 leava leava    4096 May  8 22:41 ..
-rw-r--r--  1 leava root   37237 May  8 23:09 .config
-rw-r--r--  1 leava root   22976 May  8 22:41 .config.old
-rw-r--r--  1 leava root      39 May  8 22:41 .gitignore
-rw-r--r--  1 leava root      68 May  8 22:41 .kunitconfig
-rw-r--r--  1 leava root     633 May  8 23:09 .missing-syscalls.d
-rw-r--r--  1 leava root  448911 May  8 23:09 .tmp_System.map
-rwxr-xr-x  1 leava root 4125012 May  8 23:09 .tmp_vmlinux.kallsyms1
-rw-r--r--  1 leava root  959465 May  8 23:09 .tmp_vmlinux.kallsyms1.S
-rw-r--r--  1 leava root  165852 May  8 23:09 .tmp_vmlinux.kallsyms1.o
-rwxr-xr-x  1 leava root 4256384 May  8 23:09 .tmp_vmlinux.kallsyms2
-rw-r--r--  1 leava root  959465 May  8 23:09 .tmp_vmlinux.kallsyms2.S
-rw-r--r--  1 leava root  165852 May  8 23:09 .tmp_vmlinux.kallsyms2.o
-rw-r--r--  1 leava root       2 May  8 23:09 .version
-rw-r--r--  1 leava root    1172 May  8 23:09 .vmlinux.cmd
-rw-r--r--  1 leava root      73 May  8 23:09 Makefile
-rw-r--r--  1 leava root  448911 May  8 23:09 System.map
drwxr-xr-x  5 leava root    4096 May  8 23:09 arch
drwxr-xr-x  3 leava root    4096 May  8 23:09 block
drwxr-xr-x  2 leava root    4096 May  8 23:09 certs
drwxr-xr-x  2 leava root    4096 May  8 23:09 crypto
drwxr-xr-x 44 leava root    4096 May  8 23:09 drivers
drwxr-xr-x 11 leava root    4096 May  8 23:09 fs
drwxr-xr-x  4 leava root    4096 May  8 22:41 include
drwxr-xr-x  2 leava root    4096 May  8 23:09 init
drwxr-xr-x  2 leava root    4096 May  8 23:09 ipc
drwxr-xr-x 12 leava root    4096 May  8 23:09 kernel
drwxr-xr-x  5 leava root   12288 May  8 23:09 lib
drwxr-xr-x  2 leava root    4096 May  8 23:09 mm
-rw-r--r--  1 leava root    1378 May  8 23:09 modules.builtin
-rw-r--r--  1 leava root    8994 May  8 23:09 modules.builtin.modinfo
drwxr-xr-x  6 leava root    4096 May  8 23:09 scripts
drwxr-xr-x  2 leava root    4096 May  8 23:09 security
drwxr-xr-x  2 leava root    4096 May  8 23:09 sound
lrwxrwxrwx  1 leava root       2 May  8 23:09 source -> ..
drwxr-xr-x  2 leava root    4096 May  8 23:09 usr
drwxr-xr-x  3 leava root    4096 May  8 23:09 virt
-rwxr-xr-x  1 leava root 4256384 May  8 23:09 vmlinux
-rw-r--r--  1 leava root 4678424 May  8 23:09 vmlinux.o
-rw-r--r--  1 leava root       0 May  8 23:09 vmlinux.symvers    

テスト実行

kunit_toolのrunを指定することでKUnitで実行するカーネルをビルドする。 このとき、--arch--cross_compileオプションを指定することで起動するカーネルアーキテクチャを指定することができる。

jobsオプションを指定することで、makeコマンド実行を並列処理させることができる。

また、デフォルトはUMLでの起動となっているが、QEMUで起動する場合には--qemu_configオプションを指定する。 パラメータとして指定するファイルには、QEMUで実行する場合に必要となるパラメータ (qemuのパラメータや追加のカーネルコンフィグなど)を指定することができる。

leava@kbuild:~/workspace/linux$ ./tools/testing/kunit/kunit.py run \        
                                --arch=arm \
                                --cross_compile=arm-linux-gnueabihf- \
                                --jobs=12 \
                                --timeout=300 \
                                --qemu_config=./tools/testing/kunit/qemu_configs/arm.py

上記のコマンドを実行すると、次のような結果が得られる。

テスト実施時の様子

おわりに

本稿では、既存のKUnitのテストをQEMU (armアーキテクチャ) で実行する手順を確認した。

また、KUnitは公式ドキュメントが充実しており、ドキュメントを一読するだけでも簡単なテストを作成することができると思われる。 そのため、興味のある人はカーネルドキュメントを参考に一度KUnitを利用してみることをお勧めする。

変更履歴

  • 2022/5/9: 記事公開

参考文献