KUnit

news/2024/11/15 13:26:39/文章来源:https://www.cnblogs.com/alanli07/p/18399622

基本介绍

KUnit Suite Memory

每一个kUnit都有自己的上下文,所以一个崩溃了,不会影响到其他的suit。

开关

目前可以有下面几种方法控制case测试。

menuconfig控制
使用.kunitconfig控制编译的测试文件
使用宏选择性开启某些case
使用debugfs
kunit_get_current_test

总开关

CONFIG_KUNIT=y
CONFIG_KUNIT_DEFAULT_ENABLED=y

CONFIG_KUNIT: 将KUNIT框架编入内核。
CONFIG_KUNIT_DEFAULT_ENABLED:开启测试,如果是n会关闭测试。

测试文件开关

使用menuconfig

通过在Kconfig中配置测试文件的构建选项来控制是否加入测试。

例如,有Kunit测试文件 kunit-example-test.c , 可以通过在Kconfig中加入 CONFIG_KUNIT_EXAMPLE_TEST选项可以是y/m/n,并且在Makefile中添加:

obj-$(CONFIG_KUNIT_EXAMPLE_TEST) += kunit-example-test.o

如果设置成m就会编译出.ko的驱动文件。在挂载的时候进行测试。

使用.kunitconfig

.kunitconfig是 a minconfig(通过运行生成的 .config ),用于运行一组特定的测试。如果想运行一组特定的测试,可以在.kunitconfig中提供Kconfig选项,以及所依赖的其他配置选项(架构配置、启动/禁用默写代码块配置、依赖项)。其根本也是使用Kconfig用来配置构建选项,具体可以见这里.

使用debugfs

可以通过配置 CONFIG_KUNIT_DEBUGFS=y ,开启Kunit提供的debugfs的功能。Kunit会在 /sys/kernel/debug/kunit// 下创建两个文件result和run。

cat results 就可以输出测试结果
echo anything > run 可以再次运行测试并输出测试结果

测试函数开关

使用宏来选择性开启case

可以在代码段中通过宏条件编译的方式选择性开启case。或者如果不想将测试的函数或者变量导出给测试文件使用,也可以使用下面的方法

static int do_interesting_thing();#ifdef CONFIG_MY_KUNIT_TEST
#include "my_kunit_test.c"
#endif

kunit_get_current_test()

当需要用测试文件外部调用仅测试代码时,可以使用 kunit_get_current_test 。该函数可以通过task_struct中kunit_test来分析出当前的kunit上下文,并且如果Kunit没有启用,该函数返回null,也可以安全调用,并且对性能的影响忽略不计。所以可以通过这个特性,在待测函数中植入kunit测试,通过启用Kunit测试当做开关。例如:

#include <kunit/test-bug.h> /* for kunit_get_current_test */struct test_data {int foo_result;int want_foo_called_with;
};static int fake_foo(int arg)
{
// 本函数从外部得到kunit上下文进行测试struct kunit *test = kunit_get_current_test();struct test_data *test_data = test->priv;KUNIT_EXPECT_EQ(test, test_data->want_foo_called_with, arg);return test_data->foo_result;
}static void example_simple_test(struct kunit *test)
{/* Assume priv (private, a member used to pass test data from* the init function) is allocated in the suite's .init */struct test_data *test_data = test->priv;test_data->foo_result = 42;test_data->want_foo_called_with = 1;/* In a real test, we'd probably pass a pointer to fake_foo somewhere* like an ops struct, etc. instead of calling it directly. */KUNIT_EXPECT_EQ(test, fake_foo(1), 42);
}

使用kunit提供的一些状态函数

kunit_skip:跳过当前test

一些测试模板

最简测试模板

// 假测试函数
static void foo_test_fake(struct kunit *test)
{const u32 array1[] = { 0x0F, 0xFF };const u32 array2[] = { 0x1F, 0xFF };/* Boolean assertions */KUNIT_EXPECT_TRUE(test, true);KUNIT_EXPECT_FALSE(test, false);/* Integer assertions */KUNIT_EXPECT_EQ(test, 1, 1); /* check == */KUNIT_EXPECT_GE(test, 1, 1); /* check >= */KUNIT_EXPECT_LE(test, 1, 1); /* check <= */KUNIT_EXPECT_NE(test, 1, 0); /* check != */KUNIT_EXPECT_GT(test, 1, 0); /* check >  */KUNIT_EXPECT_LT(test, 0, 1); /* check <  *//* Pointer assertions */KUNIT_EXPECT_NOT_ERR_OR_NULL(test, test);KUNIT_EXPECT_PTR_EQ(test, NULL, NULL);KUNIT_EXPECT_PTR_NE(test, test, NULL);KUNIT_EXPECT_NULL(test, NULL);KUNIT_EXPECT_NOT_NULL(test, test);/* String assertions */KUNIT_EXPECT_STREQ(test, "hi", "hi");KUNIT_EXPECT_STRNEQ(test, "hi", "bye");/* Memory block assertions */KUNIT_EXPECT_MEMEQ(test, array1, array1, sizeof(array1));KUNIT_EXPECT_MEMNEQ(test, array1, array2, sizeof(array1));/** There are also ASSERT variants of all of the above that abort test* execution if they fail. Useful for memory allocations, etc.*/KUNIT_ASSERT_GT(test, sizeof(char), 0);/** There are also _MSG variants of all of the above that let you include* additional text on failure.*/KUNIT_EXPECT_GT_MSG(test, sizeof(int), 0, "Your ints are 0-bit?!");KUNIT_ASSERT_GT_MSG(test, sizeof(int), 0, "Your ints are 0-bit?!");
}// 需要执行的cases
static struct kunit_case sample_tests[] = {KUNIT_CASE(foo_test_fake),{ /* sentinel */ }
};static struct kunit_suite sample_test_suite = {.name = "sample-test",.test_cases = sample_tests,
};kunit_test_suite(sample_test_suite);

driver需要fake device

可以使用 kunit_device_register 来创建一个fake device,当测试结束时会自动清理。同时在init中使用test→priv 传递device到各个cases中。

static void test_my_device(struct kunit *test)
{struct device *fake_device;const char *dev_managed_string;// Create a fake device.fake_device = kunit_device_register(test, "my_device");KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_device)// Pass it to functions which need a device.dev_managed_string = devm_kstrdup(fake_device, "Hello, World!");// Everything is cleaned up automatically when the test ends.
}在 linux-next/drivers/fpga/tests/fpga-region-test.c中有static int fpga_region_test_init(struct kunit *test)
{struct test_ctx *ctx;struct fpga_region_info region_info = { 0 };ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);ctx->mgr_dev = kunit_device_register(test, "fpga-manager-test-dev");KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->mgr_dev);ctx->mgr = devm_fpga_mgr_register(ctx->mgr_dev, "Fake FPGA Manager",&fake_mgr_ops, &ctx->mgr_stats);KUNIT_ASSERT_FALSE(test, IS_ERR_OR_NULL(ctx->mgr));
.....ctx->region = fpga_region_register_full(ctx->region_dev, &region_info);KUNIT_ASSERT_FALSE(test, IS_ERR_OR_NULL(ctx->region));test->priv = ctx;return 0;
}//cases中
static void fpga_region_test_class_find(struct kunit *test)
{
//使用传入的fake devicestruct test_ctx *ctx = test->priv;struct fpga_region *region;region = fpga_region_class_find(NULL, ctx->region_dev, fake_region_match);KUNIT_EXPECT_PTR_EQ(test, region, ctx->region);put_device(region->dev);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/792911.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python批量采集某东评论,实现可视化分析

女朋友没事就喜欢网购,买一大堆又不用,总说不合适,为了不让她花冤枉钱,于是我决定用Python写一个采集商品评论的脚本,然后对商品进行分析,这样就不怕踩到坑了! 让我们直接开始本次操作准备工作 环境安装Python 3.10 Pycharm 模块使用采集数据模块 -DrissionPage ->…

linux启动流程

KASLR kernel address space layout randomization 内核地址空间布局随机化 本质是将链接的地址做了随机偏移,这样System.map中的地址也不一样了,需要用 cat /proc/kallsyms才能查看到实际的地址。主要还是为了安全,这样地址布局随机化,来增加安全,被攻击的难度会增加。防…

推荐一款流量录制回放工具:jvm-sandbox-repeater

在软件开发和测试过程中,我们经常会遇到需要对网络请求进行录制和回放的需求,以便进行调试、测试和分析。为了模拟真实的用户请求,我们通常会使用各种流量录制回放工具来记录并重放网络请求。 其中,jvm-sandbox-repeater 是一款功能强大的流量录制回放工具,可以帮助我们轻…

第三章 路由系统

3.路由系统 本质上:URL和函数的对应关系。 3.1 传统的路由 from django.contrib import admin from django.urls import path from apps.web import viewsurlpatterns = [path(home/, views.home),path(news/<int:nid>/edit/, views.news),path(article/, views.article…

Java工程师多年之后看指针

指针是基本数据类型,占用4个字节。Int 类型的 数据 计算机处理语言中是处 中间层。使用图形化方式可以这样更形象直观。计算机对二进制处理数据的方式比较敏感。现 人们的大脑计数方式是通过十进制的方式计算日常和工作中需要的业务。操作符的限制,才增加了十六进制机制。数字…

记录 VMware Workstation 官方下载方式

VMware Workstation 对个人使用已免费,但想找到官方下载地址很困难,在此记录一下 下载地址:https://support.broadcom.com/group/ecx/productdownloads?subfamily=VMware+Workstation+Pro 有账号的话直接登录,没有的话右上角注册即可(注册后需要主动登录) 经过不太友好的…

工业制造企业如何与供应商间 进行高效安全的企业间文件传输?

工业制造企业的供应商数量通常较多,这主要是由于工业制造行业的复杂性和多元化特点所决定的。工业制造企业的产品结构往往较为复杂,涉及到多种原材料、零部件和设备。这些物资的需求不仅数量大,而且种类繁多,因此需要与多个供应商建立合作关系,以满足不同产品的生产需求。…

IC设计企业进行云租户数据传输最大的问题是什么?如何解决?

越来越多的IC设计企业基于云租户进行芯片的设计、仿真及验证流程,其原因在于: 降低成本:由于资源共享,租户无需单独购买、部署和维护昂贵的硬件设备,只需按需付费,大大降低了初期投资和运营成本。 弹性扩展:云租户可以根据业务需求快速、灵活地调整计算和存储资源,无需…

【精选】文件摆渡系统:跨网文件传输的安全与效率之选

文件摆渡系统可以解决哪些问题? 文件摆渡系统(File Shuttle System)主要是应用于不同网络、网段、区域之间的文件数据传输流转场景, 用于解决以下几类问题: 文件传输问题: 大文件传输:系统可以处理大文件的上传和下载,减少文件传输中的中断和错误。 异地传输:支持不同…

51nod 2180 争渡

争渡 常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。 ——李清照《如梦令常记溪亭日暮》 给出线段上界和下界,要在严格递增地在区间内选数,问到最后一条线段的方案数。见上图,第 i 条线段 j 点的方案数为 i-1 条线段的 j-1 到 l[i] 的方…

【SQL Server】将EXEC的变量结果赋值输出

动态传入表名和表的某些属性,然后将标的属性赋值到参数中,以便后续使用。 首先一张表(表和字段设计略),使用动态的语句如下:1 DECLARE @tablename VARCHAR(255) = BomNo 2 ,@id INT = 1 3 ,@sql NVARCHAR(MAX) ; 4 SET @sql =SELECT fnumber,sonFnumber FROM Bom…

首发 最新AWVS/Acunetix Premium V24.8高级版漏洞扫描器(最新版)Windows/Linux下载

前言 Acunetix Premium 是一种 Web 应用程序安全解决方案,用于管理多个网站、Web 应用程序和 API 的安全。集成功能允许您自动化 DevOps 和问题管理基础架构。 Acunetix Premium:全面的 Web 应用程序安全解决方案 Web 应用程序对于企业和组织与客户、合作伙伴和员工的联系至关…