kunit是内核的自测试框架。Linux内核代码树里早就有了内核自测框架(kselftest),但最近社区又来一个称作KUnit的内核单元测试框架。
用KUnit跑测试要依赖用户模式Linux(UML)。尽管Python包裹的脚本仍然得跑在UML上,但现在KUnit基本上能够跑着任何架构上了。
使用UML的目的就是“避免在真实硬件或虚拟机上起内核”。Kselftest是“用户空间测试集合,一些case需要少量的内核模块来支持”,而KUnit为内核测试提供了一个框架。
总结一下:
https://kunit.dev/third_party/kernel/docs/
本页概述了kunit_tool和kunit框架,介绍了如何运行现有测试,然后如何编写一个简单的测试用例,并介绍了用户首次使用kunit时面临的常见问题。
KUnit与Linux内核具有相同的依赖性。只要能够构建内核,就可以运行KUnit。
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选项使用默认值。但是,您可以选择运行哪些测试:
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
./tools/testing/kunit/kunit.py run \
--kunitconfig ./fs/fat/.kunitconfig \
--kunitconfig ./fs/ext4/.kunitconfig
要在找到满意的配置后保存.kunitconfig,请执行以下操作:
make savedefconfig O=.kunit
cp .kunit/defconfig .kunit/.kunitconfig
如果您想比Kconfig提供的更具体,还可以通过传递glob过滤器(阅读手册页glob(7)中有关模式的说明)来选择在启动时执行哪些测试。如果过滤器中有一个“.”(句点),则它将被解释为测试套件名称和测试用例之间的分隔符,否则,它将被理解为测试套件的名称。例如,假设我们使用默认配置:
./tools/testing/kunit/kunit.py run "kunit_executor_test"
./tools/testing/kunit/kunit.py run "example.example_simple_test"
./tools/testing/kunit/kunit.py run "*.*64*"
如果您不想使用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输出中可能会穿插一些行和/或数据。
在内核存储库中,让我们添加一些可以测试的代码。
int misc_example_add(int left, int right);
#include
#include "example.h"
int misc_example_add(int left, int right)
{
return left + right;
}
config MISC_EXAMPLE
bool "My example"
obj-$(CONFIG_MISC_EXAMPLE) += example.o
现在我们已经准备好编写测试用例了。
#include
#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);
config MISC_EXAMPLE_TEST
tristate "Test for my example" if !KUNIT_ALL_TESTS
depends on MISC_EXAMPLE && KUNIT=y
default KUNIT_ALL_TESTS
obj-$(CONFIG_MISC_EXAMPLE_TEST) += example_test.o
CONFIG_MISC_EXAMPLE=y
CONFIG_MISC_EXAMPLE_TEST=y
./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