关于kunit的一点够用就行知识概念

简介: 关于kunit的一点够用就行知识概念

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

目录
相关文章
|
存储 安全 Unix
了解服务器,原来这一篇就够了!
了解服务器,原来这一篇就够了!
186 0
|
存储 编译器 C语言
还在为每次打开程序的输入烦恼吗,这篇文章让你不在迷茫
在之前我们编写的程序中,我们总要录入一些数据给予程序用于计算,但是当我们退出程序后录入的数据会销毁,因为此时数据都是存放在内存中。等到下次再运行程序时,数据又得从新录入,这样就非常的难受。
67 0
还在为每次打开程序的输入烦恼吗,这篇文章让你不在迷茫
|
6月前
|
测试技术
关于kunit的二点够用就行知识概念
关于kunit的二点够用就行知识概念
117 0
|
人工智能 算法 Python
你的代码,换我的书
鼓励具有学习性的项目,希望你的代码或文章需要有较好的可读性,可以给他人带来价值。之前获奖过的项目请勿重复使用
|
存储 弹性计算 人工智能
关于 ByteHouse 你想知道的一切,看这一篇就够了
关于 ByteHouse 你想知道的一切,看这一篇就够了
|
程序员 数据库
什么是网站404,为啥是404?
无论何时浏览网页出现404错误,我们都知道这意味着网页出现了访问错误,即网页丢失。事实上,这早已是人所共知的常识。404作为一个标准的HTTP返回代码,被用来表示网页服务器HTTP的响应状态。但是,它的历史来源却充满了神秘和诱人的探索。21世纪初,甚至有一群人试图研究404错误的来源。
601 0
什么是网站404,为啥是404?
|
Java
本来想用“{{”秀一波,结果却导致了内存溢出!(上)
本来想用“{{”秀一波,结果却导致了内存溢出!
128 0
本来想用“{{”秀一波,结果却导致了内存溢出!(上)
|
Java API
本来想用“{{”秀一波,结果却导致了内存溢出!(下)
本来想用“{{”秀一波,结果却导致了内存溢出!
172 0
本来想用“{{”秀一波,结果却导致了内存溢出!(下)
|
Go 计算机视觉 Windows
两小时写完vs2019永久配置opencv完整图文教程(小白也能看懂)
两小时写完vs2019永久配置opencv完整图文教程(小白也能看懂)
307 0
两小时写完vs2019永久配置opencv完整图文教程(小白也能看懂)