使用 kunit_tool 运行测试

我们可以使用 kunit_tool 运行 KUnit 测试,也可以手动运行测试,然后使用 kunit_tool 来解析结果。要手动运行测试,请参见:不使用 kunit_tool 运行测试。只要我们可以构建内核,就可以运行 KUnit。

kunit_tool 是一个 Python 脚本,用于配置和构建内核、运行测试以及格式化测试结果。

运行命令

./tools/testing/kunit/kunit.py run

我们应该看到以下内容

Configuring KUnit Kernel ...
Building KUnit kernel...
Starting KUnit kernel...

我们可能想要使用以下选项

./tools/testing/kunit/kunit.py run --timeout=30 --jobs=`nproc --all`
  • --timeout 设置测试运行的最长时间。

  • --jobs 设置构建内核的线程数。

如果不存在其他 .kunitconfig 文件(在构建目录中),kunit_tool 将生成一个带有默认配置的 .kunitconfig。此外,它还会验证生成的 .config 文件是否包含 .kunitconfig 中的 CONFIG 选项。也可以将单独的 .kunitconfig 片段传递给 kunit_tool。如果我们有几个不同的测试组要独立运行,或者我们想要对某些子系统使用预定义的测试配置,这将非常有用。

要使用不同的 .kunitconfig 文件(例如,为测试特定子系统提供的文件),请将其作为选项传递

./tools/testing/kunit/kunit.py run --kunitconfig=fs/ext4/.kunitconfig

要查看 kunit_tool 标志(可选的命令行参数),请运行

./tools/testing/kunit/kunit.py run --help

创建 .kunitconfig 文件

如果我们想要运行一组特定的测试(而不是 KUnit defconfig 中列出的那些测试),我们可以在 .kunitconfig 文件中提供 Kconfig 选项。有关默认 .kunitconfig,请参见:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/testing/kunit/configs/default.config.kunitconfig 是一个 minconfig(通过运行 make savedefconfig 生成的 .config),用于运行一组特定的测试。此文件包含带有特定测试目标的常规内核配置。.kunitconfig 还包含测试所需的任何其他配置选项(例如:被测功能的依赖项、启用/禁用某些代码块的配置、架构配置等)。

要使用 KUnit defconfig 创建 .kunitconfig,请执行以下操作

cd $PATH_TO_LINUX_REPO
cp tools/testing/kunit/configs/default.config .kunit/.kunitconfig

然后我们可以添加任何其他 Kconfig 选项。例如

CONFIG_LIST_KUNIT_TEST=y

kunit_tool 确保在运行测试之前,内核 .config 中设置了 .kunitconfig 中的所有配置选项。如果我们没有包含选项依赖项,它会发出警告。

注意

.kunitconfig 中删除某些内容不会重建 .config file。仅当 .kunitconfig 不是 .config 的子集时,才会更新配置。这意味着我们可以使用其他工具(例如:make menuconfig)来调整其他配置选项。必须设置构建目录才能使 make menuconfig 正常工作,因此默认情况下使用 make O=.kunit menuconfig

配置、构建和运行测试

如果我们想要手动更改 KUnit 构建过程,我们可以独立运行 KUnit 构建过程的一部分。从 .kunitconfig 运行 kunit_tool 时,我们可以使用 config 参数生成 .config

./tools/testing/kunit/kunit.py config

要从当前的 .config 构建 KUnit 内核,我们可以使用 build 参数

./tools/testing/kunit/kunit.py build

如果我们已经构建了带有内置 KUnit 测试的 UML 内核,我们可以运行内核,并使用 exec 参数显示测试结果

./tools/testing/kunit/kunit.py exec

第 **使用 kunit_tool 运行测试** 节中讨论的 run 命令相当于按顺序运行上述三个命令。

解析测试结果

KUnit 测试输出以 TAP(测试协议)格式显示结果。运行测试时,kunit_tool 会解析此输出并打印摘要。要以 TAP 格式查看原始测试结果,我们可以传递 --raw_output 参数

./tools/testing/kunit/kunit.py run --raw_output

如果我们有原始 TAP 格式的 KUnit 结果,我们可以解析它们并使用 kunit_tool 的 parse 命令打印人类可读的摘要。此命令接受一个文件名作为参数,或者从标准输入读取。

# Reading from a file
./tools/testing/kunit/kunit.py parse /var/log/dmesg
# Reading from stdin
dmesg | ./tools/testing/kunit/kunit.py parse

过滤测试

通过将 bash 风格的 glob 过滤器传递给 execrun 命令,我们可以运行内置于内核中的测试子集。例如:如果我们只想运行 KUnit 资源测试,请使用

./tools/testing/kunit/kunit.py run 'kunit-resource*'

这使用了带有通配符的标准 glob 格式。

在 QEMU 上运行测试

kunit_tool 支持通过 qemu 以及 UML 运行测试。默认情况下,要在 qemu 上运行测试,需要两个标志

  • --arch: 选择一个配置集合(Kconfig、qemu 配置选项等),允许以最小的方式在指定的架构上运行 KUnit 测试。架构参数与 Kbuild 使用的 ARCH 变量传递的选项名称相同。并非所有架构当前都支持此标志,但我们可以使用 --qemu_config 来处理它。如果传递了 um(或者忽略此标志),测试将通过 UML 运行。非 UML 架构,例如:i386、x86_64、arm 等;在 qemu 上运行。

    --arch help 列出所有有效的 --arch 值。

  • --cross_compile: 指定 Kbuild 工具链。它传递与 Kbuild 使用的 CROSS_COMPILE 变量相同的参数。作为提醒,这将是工具链二进制文件(例如 GCC)的前缀。例如

    • sparc64-linux-gnu 如果我们的系统上安装了 sparc 工具链。

    • $HOME/toolchains/microblaze/gcc-9.2.0-nolibc/microblaze-linux/bin/microblaze-linux 如果我们从 0-day 网站下载了 microblaze 工具链到我们主目录中名为 toolchains 的目录。

这意味着对于大多数架构,在 qemu 下运行就像

./tools/testing/kunit/kunit.py run --arch=x86_64

交叉编译时,我们可能需要指定不同的工具链,例如

./tools/testing/kunit/kunit.py run \
        --arch=s390 \
        --cross_compile=s390x-linux-gnu-

如果我们要运行 --arch 标志不支持的架构上的 KUnit 测试,或者想要使用非默认配置在 qemu 上运行 KUnit 测试;那么我们可以编写自己的 ``QemuConfig``。这些 QemuConfigs 是用 Python 编写的。它们在文件顶部有一个导入行 from..qemu_config import QemuArchParams。该文件必须包含一个名为 QEMU_ARCH 的变量,该变量具有分配给它的 QemuArchParams 实例。请参见以下示例:tools/testing/kunit/qemu_configs/x86_64.py

一旦我们有了 QemuConfig,我们就可以使用 --qemu_config 标志将其传递给 kunit_tool。使用时,此标志将替换 --arch 标志。例如:使用 tools/testing/kunit/qemu_configs/x86_64.py,调用如下所示

./tools/testing/kunit/kunit.py run \
        --timeout=60 \
        --jobs=12 \
        --qemu_config=./tools/testing/kunit/qemu_configs/x86_64.py

运行命令行参数

kunit_tool 有许多其他命令行参数,这些参数对我们的测试环境很有用。以下是最常用的命令行参数

  • --help: 列出所有可用选项。要列出常用选项,请将 --help 放在命令之前。要列出特定于该命令的选项,请将 --help 放在命令之后。

    注意

    不同的命令(configbuildrun 等)具有不同的支持选项。

  • --build_dir: 指定 kunit_tool 构建目录。它包括 .kunitconfig.config 文件和已编译的内核。

  • --make_options: 指定编译内核时要传递给 make 的其他选项(使用 buildrun 命令)。例如:要启用编译器警告,我们可以传递 --make_options W=1

  • --alltests: 启用一组预定义的选项,以便构建尽可能多的测试。

    注意

    可以在 tools/testing/kunit/configs/all_tests.config 中找到已启用选项的列表。

    如果您只想启用所有测试以及其他已满足的依赖项,请改为将 CONFIG_KUNIT_ALL_TESTS=y 添加到您的 .kunitconfig

  • --kunitconfig: 指定 .kunitconfig 文件的路径或目录。例如

    • lib/kunit/.kunitconfig 可以是该文件的路径。

    • lib/kunit 可以是该文件所在的目录。

    此文件用于构建和运行一组预定义的测试及其依赖项。例如,运行给定子系统的测试。

  • --kconfig_add: 指定要附加到 .kunitconfig 文件的其他配置选项。例如

    ./tools/testing/kunit/kunit.py run --kconfig_add CONFIG_KASAN=y
    
  • --arch: 在指定的架构上运行测试。架构参数与 Kbuild ARCH 环境变量相同。例如,i386、x86_64、arm、um 等。非 UML 架构在 qemu 上运行。默认为 *um*。

  • --cross_compile: 指定 Kbuild 工具链。它传递与 Kbuild 使用的 CROSS_COMPILE 变量相同的参数。这将是工具链二进制文件(例如 GCC)的前缀。例如

    • sparc64-linux-gnu- 如果我们的系统上安装了 sparc 工具链。

    • $HOME/toolchains/microblaze/gcc-9.2.0-nolibc/microblaze-linux/bin/microblaze-linux 如果我们从 0-day 网站下载了 microblaze 工具链到我们主目录中名为 toolchains 的指定路径。

  • --qemu_config: 指定包含自定义 qemu 架构定义的文件路径。这应该是一个包含 QemuArchParams 对象的 python 文件。

  • --qemu_args: 指定其他 qemu 参数,例如,-smp 8

  • --jobs: 指定要同时运行的作业(命令)数。默认情况下,此值设置为系统上的核心数。

  • --timeout: 指定允许所有测试运行的最长时间(以秒为单位)。这不包括构建测试所花费的时间。

  • --kernel_args: 指定其他内核命令行参数。可以重复。

  • --run_isolated: 如果设置,则为每个单独的套件/测试启动内核。这对于调试非封闭测试很有用,该测试可能会根据之前运行的内容而通过/失败。

  • --raw_output: 如果设置,则生成来自内核的未格式化输出。可能的选项有

    • all: 要查看完整的内核输出,请使用 --raw_output=all

    • kunit: 这是默认选项,并过滤到 KUnit 输出。使用 --raw_output--raw_output=kunit

  • --json: 如果设置,则将测试结果存储为 JSON 格式,并打印到 stdout 或保存到文件中(如果指定了文件名)。

  • --filter: 指定对测试属性的过滤,例如,speed!=slow。可以通过将输入包装在引号中并用逗号分隔过滤器来使用多个过滤器。示例:--filter "speed>slow, module=example"

  • --filter_action: 如果设置为 skip,则过滤后的测试将在输出中显示为已跳过,而不是不显示输出。

  • --list_tests: 如果设置,则列出将要运行的所有测试。

  • --list_tests_attr: 如果设置,则列出将要运行的所有测试及其所有属性。