1、kunit是什么?
kunit是内核的自测试框架。Linux内核代码树里早就有了内核自测框架(kselftest),但最近社区又来一个称作KUnit的内核单元测试框架。
用KUnit跑测试要依赖用户模式Linux(UML)。尽管Python包裹的脚本仍然得跑在UML上,但现在KUnit基本上能够跑着任何架构上了。
使用UML的目的就是“避免在真实硬件或虚拟机上起内核”。Kselftest是“用户空间测试集合,一些case需要少量的内核模块来支持”,而KUnit为内核测试提供了一个框架。
总结一下:
- kunit是针对内核的测试框架
- kunit可以对驱动进行测试
- kunit可在用户态下运行测试无需虚拟化硬件以及硬件
- kunit测试支持大多数的平台
- kunit支持在内核运行时测试,也支持在加载时运行
(就是可以将其编译到内核中,内核启动的时候就运行。也可以做成ko模块,然后进行加载时候运行测试用例。只有kernel大于5.5版本才支持kunit)
2、kunit这个东西怎么用?
1、主要看这个
https://kunit.dev/third_party/kernel/docs/
2、kunit的简单使用
本页概述了kunit_tool和kunit框架,介绍了如何运行现有测试,然后如何编写一个简单的测试用例,并介绍了用户首次使用kunit时面临的常见问题。
安装依赖项
KUnit与Linux内核具有相同的依赖性。只要能够构建内核,就可以运行KUnit。
使用kunit_tool运行测试
kunit_tool是一个Python脚本,用于配置和构建内核、运行测试并格式化测试结果。从内核存储库中,可以运行kunit_tool:
./tools/testing/kunit/kunit.py run
您可能会看到以下错误:“源树不干净,请运行'makeARCH=ummrproper'” 这是因为内部库尼特。py通过参数--build_dir指定.kunit(默认选项)作为命令make O=output/dir中的构建目录。 因此,在开始树外构建之前,源树必须是干净的。 在管理指南的“Build directory for the kernel”一节中也提到了同样的警告,即它的使用,它必须用于make的所有调用。 好消息是,它确实可以通过运行makeARCH=ummrproper来解决,只需注意这将删除当前配置和所有生成的文件。
如果一切正常,您应该看到以下内容:
Configuring KUnit Kernel ... Building KUnit Kernel ... Starting KUnit Kernel ...
测试将通过或失败。
因为它是第一次构建很多源代码,所以构建KUnit内核的步骤可能需要一段时间。
有关此包装器的详细信息,请参阅:Documentation/dev/tools/kunit/run_wrapper.rst。
选择要运行的测试
默认情况下,kunit_tool以最小配置运行所有可访问的测试,即对大多数kconfig选项使用默认值。但是,您可以选择运行哪些测试:
- 自定义用于编译内核的Kconfig,或
- 按名称筛选测试,以具体选择要运行的已编译测试。
自定义Kconfig
kunitconfig的一个好的起点是KUnit默认配置。如果你不跑库尼特。py运行,您可以通过运行以下命令生成它:
cd $PATH_TO_LINUX_REPO tools/testing/kunit/kunit.py config cat .kunit/.kunitconfig
.kunitconfig位于kunit使用的–build_dir中。py,默认为.kunit。
在运行测试之前,kunit_tool确保在.kunitconfig中设置的所有配置选项都在kernel.config中设置。如果未包含所用选项的依赖项,它将警告您。
有许多方法可以自定义配置:
- 编辑.kunit/.kunitconfig。该文件应包含运行所需测试所需的kconfig选项列表,包括它们的依赖项。您可能希望从.kunitconfig中删除CONFIG_KUNIT_ALL_TESTS,因为它将启用许多您可能不需要的其他测试。如果您需要在UML以外的架构上运行,请参阅在QEMU上运行测试。
- 在.kunit/.kunitconfig上启用其他kconfig选项。例如,要包含内核的链接列表测试,可以运行:
./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_LIST_KUNIT_TEST=y
- 提供树中一个或多个.kunitconfig文件的路径。例如,要仅运行FAT_FS和EXT4测试,可以运行:
./tools/testing/kunit/kunit.py run \ --kunitconfig ./fs/fat/.kunitconfig \ --kunitconfig ./fs/ext4/.kunitconfig
- 如果更改.kunitconfig,请使用kunit。py将触发.config文件的重建。但是,您可以直接编辑.config文件,也可以使用makemenuconfig O=.kunit等工具。只要它是.kunitconfig的超集,kunit。py不会覆盖您的更改。
要在找到满意的配置后保存.kunitconfig,请执行以下操作: make savedefconfig O=.kunit cp .kunit/defconfig .kunit/.kunitconfig
按名称筛选测试
如果您想比Kconfig提供的更具体,还可以通过传递glob过滤器(阅读手册页glob(7)中有关模式的说明)来选择在启动时执行哪些测试。如果过滤器中有一个“.”(句点),则它将被解释为测试套件名称和测试用例之间的分隔符,否则,它将被理解为测试套件的名称。例如,假设我们使用默认配置:
- 通知测试套件的名称,如“kunit_executor_test”,以运行它包含的每个测试用例:
./tools/testing/kunit/kunit.py run "kunit_executor_test"
- 通知以测试套件为前缀的测试用例的名称,如“example.example_simple_test”,以专门运行该测试用例:
./tools/testing/kunit/kunit.py run "example.example_simple_test"
- 使用通配符(?[)运行与模式匹配的任何测试用例,如“.64”运行任何测试套件中名称中包含“64”的测试用例:
./tools/testing/kunit/kunit.py run "*.*64*"
3、在没有KUnit Wrapper的情况下运行测试
如果您不想使用KUnit Wrapper(例如:您希望测试中的代码与其他系统集成,或者使用不同的/不受支持的体系结构或配置),那么KUnit可以包含在任何内核中,并手动读取和解析结果。
注意:在生产环境中不应启用CONFIG_KUNIT。启用KUnit将禁用内核地址空间布局随机化(KASLR),测试可能会以不适合生产的方式影响内核的状态。
- 1、配置内核
要启用KUnit本身,您需要启用CONFIG_KUnit Kconfig选项(在menuconfig中的内核黑客/内核测试和覆盖下)。从那里,您可以启用任何KUnit测试。它们通常具有以_KUNIT_TEST结尾的配置选项。
KUnit和KUnit测试可以编译为模块。模块中的测试将在加载模块时运行。 - 2、 运行测试(无KUnit Wrapper)
构建并运行内核。在内核日志中,测试输出以TAP格式打印出来。默认情况下,只有KUnit/tests内置时才会发生这种情况。否则,需要加载模块。
注意:TAP输出中可能会穿插一些行和/或数据。
4、编写第一次测试
在内核存储库中,让我们添加一些可以测试的代码。
- 1、 创建文件driver/misc/example.h, 其中包括:
int misc_example_add(int left, int right);
- 2、 创建文件 drivers/misc/example.c, 其中包括
#include <linux/errno.h> #include "example.h" int misc_example_add(int left, int right) { return left + right; }
- 3、 在drivers/misc/Kconfig添加如下
config MISC_EXAMPLE bool "My example"
- 4、 在drivers/misc/Makefile添加如下
obj-$(CONFIG_MISC_EXAMPLE) += example.o
现在我们已经准备好编写测试用例了。
- 1、在drivers/misc/example_test.c中添加以下测试用例:
#include <kunit/test.h> #include "example.h" /* Define the test cases. */ static void misc_example_add_test_basic(struct kunit *test) { KUNIT_EXPECT_EQ(test, 1, misc_example_add(1, 0)); KUNIT_EXPECT_EQ(test, 2, misc_example_add(1, 1)); KUNIT_EXPECT_EQ(test, 0, misc_example_add(-1, 1)); KUNIT_EXPECT_EQ(test, INT_MAX, misc_example_add(0, INT_MAX)); KUNIT_EXPECT_EQ(test, -1, misc_example_add(INT_MAX, INT_MIN)); } static void misc_example_test_failure(struct kunit *test) { KUNIT_FAIL(test, "This test never passes."); } static struct kunit_case misc_example_test_cases[] = { KUNIT_CASE(misc_example_add_test_basic), KUNIT_CASE(misc_example_test_failure), {} }; static struct kunit_suite misc_example_test_suite = { .name = "misc-example", .test_cases = misc_example_test_cases, }; kunit_test_suite(misc_example_test_suite);
- 2、将以下行添加到drivers/misc/Kconfig:
config MISC_EXAMPLE_TEST tristate "Test for my example" if !KUNIT_ALL_TESTS depends on MISC_EXAMPLE && KUNIT=y default KUNIT_ALL_TESTS
- 3、将以下行添加到drivers/misc/Makefile:
obj-$(CONFIG_MISC_EXAMPLE_TEST) += example_test.o
- 4、将以下行添加到.kunit/.kunitconfig中:
CONFIG_MISC_EXAMPLE=y CONFIG_MISC_EXAMPLE_TEST=y
- 5、Run the test:
./tools/testing/kunit/kunit.py run
您应该看到以下故障:
... [16:08:57] [PASSED] misc-example:misc_example_add_test_basic [16:08:57] [FAILED] misc-example:misc_example_test_failure [16:08:57] EXPECTATION FAILED at drivers/misc/example-test.c:17 [16:08:57] This test never passes. ...
小结
到这里就完成了这个简单的kunit,当然这个kunit怎么跑起来,我觉得这个方式就很多种。还有一种你可以模块化,然后使用ko的方式。
关于kunit更多的信息–>https://kunit.dev/third_party/kernel/docs/start.html