• 关于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
    
    • 1
    您可能会看到以下错误:“源树不干净,请运行'makeARCH=ummrproper'”
    这是因为内部库尼特。py通过参数--build_dir指定.kunit(默认选项)作为命令make O=output/dir中的构建目录。
    因此,在开始树外构建之前,源树必须是干净的。
    在管理指南的“Build directory for the kernel”一节中也提到了同样的警告,即它的使用,它必须用于make的所有调用。
    好消息是,它确实可以通过运行makeARCH=ummrproper来解决,只需注意这将删除当前配置和所有生成的文件。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果一切正常,您应该看到以下内容:

    Configuring KUnit Kernel ...
    Building KUnit Kernel ...
    Starting KUnit Kernel ...
    
    • 1
    • 2
    • 3

    测试将通过或失败。

    因为它是第一次构建很多源代码,所以构建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
    
    
    • 1
    • 2
    • 3
    • 4

    .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
    
    • 1
    • 2
    • 提供树中一个或多个.kunitconfig文件的路径。例如,要仅运行FAT_FS和EXT4测试,可以运行:
    ./tools/testing/kunit/kunit.py run \
            --kunitconfig ./fs/fat/.kunitconfig \
            --kunitconfig ./fs/ext4/.kunitconfig
    
    • 1
    • 2
    • 3
    • 如果更改.kunitconfig,请使用kunit。py将触发.config文件的重建。但是,您可以直接编辑.config文件,也可以使用makemenuconfig O=.kunit等工具。只要它是.kunitconfig的超集,kunit。py不会覆盖您的更改。
    要在找到满意的配置后保存.kunitconfig,请执行以下操作:
    
    make savedefconfig O=.kunit
    cp .kunit/defconfig .kunit/.kunitconfig
    
    • 1
    • 2
    • 3
    • 4

    按名称筛选测试

    如果您想比Kconfig提供的更具体,还可以通过传递glob过滤器(阅读手册页glob(7)中有关模式的说明)来选择在启动时执行哪些测试。如果过滤器中有一个“.”(句点),则它将被解释为测试套件名称和测试用例之间的分隔符,否则,它将被理解为测试套件的名称。例如,假设我们使用默认配置:

    • 通知测试套件的名称,如“kunit_executor_test”,以运行它包含的每个测试用例:
    ./tools/testing/kunit/kunit.py run "kunit_executor_test"
    
    
    • 1
    • 2
    • 通知以测试套件为前缀的测试用例的名称,如“example.example_simple_test”,以专门运行该测试用例:
    ./tools/testing/kunit/kunit.py run "example.example_simple_test"
    
    
    • 1
    • 2
    • 使用通配符(?[)运行与模式匹配的任何测试用例,如“.64”运行任何测试套件中名称中包含“64”的测试用例:
    ./tools/testing/kunit/kunit.py run "*.*64*"
    
    
    • 1
    • 2

    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);
    
    
    • 1
    • 2
    • 2、 创建文件 drivers/misc/example.c, 其中包括
    #include 
    
    #include "example.h"
    
    int misc_example_add(int left, int right)
    {
            return left + right;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 3、 在drivers/misc/Kconfig添加如下
    config MISC_EXAMPLE
            bool "My example"
    
    • 1
    • 2
    • 4、 在drivers/misc/Makefile添加如下
    obj-$(CONFIG_MISC_EXAMPLE) += example.o
    
    • 1

    现在我们已经准备好编写测试用例了。

    • 1、在drivers/misc/example_test.c中添加以下测试用例:
    #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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 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
    
    • 1
    • 2
    • 3
    • 4
    • 3、将以下行添加到drivers/misc/Makefile:
    obj-$(CONFIG_MISC_EXAMPLE_TEST) += example_test.o
    
    
    • 1
    • 2
    • 4、将以下行添加到.kunit/.kunitconfig中:
    CONFIG_MISC_EXAMPLE=y
    CONFIG_MISC_EXAMPLE_TEST=y
    
    • 1
    • 2
    • 5、Run the test:
    ./tools/testing/kunit/kunit.py run
    
    
    • 1
    • 2

    您应该看到以下故障:

    ...
    [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.
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    小结

    到这里就完成了这个简单的kunit,当然这个kunit怎么跑起来,我觉得这个方式就很多种。还有一种你可以模块化,然后使用ko的方式。

    关于kunit更多的信息–>https://kunit.dev/third_party/kernel/docs/start.html

  • 相关阅读:
    内存映射与物理内存结构
    Android MQTT开发之 Hivemq MQTT Client
    python学习笔记——file(文件)、OS模块操作、random模块
    工业化生产预测(xgboost)(笔记版)
    【Nginx】使用nginx进行反向代理与负载均衡
    最好的期货开户的标准是什么?
    排序算法-----快速排序(递归)
    Xcode调试内存最新理解
    MySQL 索引失效的几种类型以及解决方式
    【开源电路】STM8S903K3T6C开发板
  • 原文地址:https://blog.csdn.net/weixin_45264425/article/details/127932494