资源 API

此文件记录了 KUnit 资源 API。

大多数用户不需要直接使用此 API,高级用户可以使用它来存储每个测试的状态,注册自定义清理操作等等。

struct kunit_resource

表示一个测试管理的资源

定义:

struct kunit_resource {
    void *data;
    const char *name;
    kunit_resource_free_t free;
};

成员

data

供用户存储任意数据。

name

可选名称

free

用户提供的函数来释放资源。

描述

表示一个测试管理的资源,该资源将在测试用例结束时自动清理。此清理由“free”函数执行。如果 struct kunit_resource 本身是由 KUnit 分配的(例如,通过 kunit_alloc_resource()),则它会通过 kfree() 自动释放,否则必须由用户释放。

资源是引用计数的,因此如果通过 kunit_alloc_and_get_resource()kunit_find_resource() 检索资源,我们需要调用 kunit_put_resource() 来减少资源引用计数,当使用完毕时。请注意,kunit_alloc_resource() 不需要 kunit_resource_put(),因为它不会检索资源本身。

struct kunit_kmalloc_params {
        size_t size;
        gfp_t gfp;
};

static int kunit_kmalloc_init(struct kunit_resource *res, void *context)
{
        struct kunit_kmalloc_params *params = context;
        res->data = kmalloc(params->size, params->gfp);

        if (!res->data)
                return -ENOMEM;

        return 0;
}

static void kunit_kmalloc_free(struct kunit_resource *res)
{
        kfree(res->data);
}

void *kunit_kmalloc(struct kunit *test, size_t size, gfp_t gfp)
{
        struct kunit_kmalloc_params params;

        params.size = size;
        params.gfp = gfp;

        return kunit_alloc_resource(test, kunit_kmalloc_init,
                kunit_kmalloc_free, gfp, &params);
}

资源也可以被命名,并且也可以基于名称进行查找/删除。kunit_add_named_resource()kunit_find_named_resource() 和 kunit_destroy_named_resource()。资源名称在测试实例中必须是唯一的。

示例

void kunit_get_resource(struct kunit_resource *res)

保留资源以供使用。大多数用户应该不需要使用它,因为我们会自动获取由 kunit_find_resource*() 检索的资源。

参数

struct kunit_resource *res

资源

void kunit_put_resource(struct kunit_resource *res)

当调用者完成检索到的资源时,应调用 kunit_put_resource() 来减少引用计数。资源列表维护资源的引用计数,因此如果没有用户正在使用资源,并且该资源已从资源列表中删除,则将通过关联的 free 函数释放(如果有)。只有当我们 alloc_and_get() 或 find() 资源时才需要使用它。

参数

struct kunit_resource *res

资源

int __kunit_add_resource(struct kunit *test, kunit_resource_init_t init, kunit_resource_free_t free, struct kunit_resource *res, void *data)

添加资源的内部辅助函数。

参数

struct kunit *test

测试上下文对象。

kunit_resource_init_t init

用户提供的函数来初始化结果(如果需要)。如果没有提供任何函数,则资源数据值将直接设置为 data。如果提供了 init 函数,则会将 data 传递给它。

kunit_resource_free_t free

用户提供的函数来释放资源(如果需要)。

struct kunit_resource *res

资源。

void *data

传递给 init 函数或在资源数据字段中设置的值。

描述

res->should_kfree 未初始化。

int kunit_add_resource(struct kunit *test, kunit_resource_init_t init, kunit_resource_free_t free, struct kunit_resource *res, void *data)

添加一个测试管理的资源

参数

struct kunit *test

测试上下文对象。

kunit_resource_init_t init

用户提供的函数来初始化结果(如果需要)。如果没有提供任何函数,则资源数据值将直接设置为 data。如果提供了 init 函数,则会将 data 传递给它。

kunit_resource_free_t free

用户提供的函数来释放资源(如果需要)。

struct kunit_resource *res

资源。

void *data

传递给 init 函数或在资源数据字段中设置的值。

int kunit_add_named_resource(struct kunit *test, kunit_resource_init_t init, kunit_resource_free_t free, struct kunit_resource *res, const char *name, void *data)

添加一个命名的测试管理的资源

参数

struct kunit *test

测试上下文对象。

kunit_resource_init_t init

用户提供的函数来初始化资源数据,如果需要。

kunit_resource_free_t free

用户提供的函数来释放资源数据,如果需要。

struct kunit_resource *res

资源。

const char *name

要为资源设置的名称。

void *data

传递给 init 函数或在资源数据字段中设置的值。

struct kunit_resource *kunit_alloc_and_get_resource(struct kunit *test, kunit_resource_init_t init, kunit_resource_free_t free, gfp_t internal_gfp, void *context)

分配并返回一个测试管理的资源

参数

struct kunit *test

测试上下文对象。

kunit_resource_init_t init

用户提供的函数来初始化资源。

kunit_resource_free_t free

用户提供的函数来释放资源(如果需要)。

gfp_t internal_gfp

gfp 用于内部内存分配,如果不确定,请使用 GFP_KERNEL

void *context

供用户将任意数据传递给初始化函数。

描述

分配一个测试托管资源,该资源将在测试用例结束时自动清理。有关示例,请参见 struct kunit_resource

这实际上与 kunit_alloc_resource 相同,但返回 struct kunit_resource 指针,而不仅仅是 ‘data’ 指针。因此,它还会增加资源的引用计数,所以当你使用完它时,应该调用 kunit_put_resource()

注意

KUnit 需要为 kunit_resource 对象分配内存。你必须指定一个与你的资源使用上下文兼容的 internal_gfp

void *kunit_alloc_resource(struct kunit *test, kunit_resource_init_t init, kunit_resource_free_t free, gfp_t internal_gfp, void *context)

分配一个测试托管资源

参数

struct kunit *test

测试上下文对象。

kunit_resource_init_t init

用户提供的函数来初始化资源。

kunit_resource_free_t free

用户提供的函数来释放资源(如果需要)。

gfp_t internal_gfp

gfp 用于内部内存分配,如果不确定,请使用 GFP_KERNEL

void *context

供用户将任意数据传递给初始化函数。

描述

分配一个测试托管资源,该资源将在测试用例结束时自动清理。有关示例,请参见 struct kunit_resource

注意

KUnit 需要为 kunit_resource 对象分配内存。你必须指定一个与你的资源使用上下文兼容的 internal_gfp

bool kunit_resource_name_match(struct kunit *test, struct kunit_resource *res, void *match_name)

匹配具有相同名称的资源。

参数

struct kunit *test

资源所属的测试用例。

struct kunit_resource *res

资源。

void *match_name

要匹配的名称。

struct kunit_resource *kunit_find_resource(struct kunit *test, kunit_resource_match_t match, void *match_data)

使用匹配函数/数据查找资源。

参数

struct kunit *test

资源所属的测试用例。

kunit_resource_match_t match

要应用于资源/匹配数据的匹配函数。

void *match_data

匹配中使用的数据。

struct kunit_resource *kunit_find_named_resource(struct kunit *test, const char *name)

使用匹配名称查找资源。

参数

struct kunit *test

资源所属的测试用例。

const char *name

匹配名称。

int kunit_destroy_resource(struct kunit *test, kunit_resource_match_t match, void *match_data)

查找 kunit_resource 并销毁它。

参数

struct kunit *test

资源所属的测试用例。

kunit_resource_match_t match

匹配函数。返回给定的资源是否与 match_data 匹配。

void *match_data

传递给 match 的数据。

返回值

如果找到并释放了 kunit_resource,则返回 0;如果未找到,则返回 -ENOENT。

void kunit_remove_resource(struct kunit *test, struct kunit_resource *res)

从与测试关联的资源列表中删除资源。

参数

struct kunit *test

测试上下文对象。

struct kunit_resource *res

要删除的资源。

描述

请注意,该资源不会立即释放,因为它很可能调用者通过 alloc_and_get() 或 find() 对其进行了引用;在这种情况下,需要最后调用 kunit_put_resource()

KUNIT_DEFINE_ACTION_WRAPPER

KUNIT_DEFINE_ACTION_WRAPPER (wrapper, orig, arg_type)

封装一个函数以用作延迟操作。

参数

wrapper

新封装函数定义的名称。

orig

要封装的原始函数。

arg_type

orig 接受的参数类型。

描述

为一个接受单个指针大小参数的函数定义一个封装器。然后可以将此封装器传递给 kunit_add_action() 等。这应该优先于将函数直接强制转换为 kunit_action_t,因为强制转换函数指针会破坏控制流完整性 (CFI),从而导致崩溃。

int kunit_add_action(struct kunit *test, kunit_action_t *action, void *ctx)

在测试结束时调用一个函数。

参数

struct kunit *test

要将操作与之关联的测试用例。

kunit_action_t *action

测试退出时要运行的函数

void *ctx

传递给 func 的数据

描述

将函数的执行延迟到测试退出时,无论是正常退出还是由于失败而退出。ctx 作为附加上下文传递。所有使用 kunit_add_action() 注册的函数都将按照与注册顺序相反的顺序执行。

这对于清理已分配的内存和资源很有用,因为即使测试由于例如断言失败而提前中止,也会调用这些函数。

另请参见:devm_add_action() 获取 devres 等效项。

返回值

成功返回 0,如果无法延迟操作,则返回错误。

int kunit_add_action_or_reset(struct kunit *test, kunit_action_t *action, void *ctx)

在测试结束时调用一个函数。

参数

struct kunit *test

要将操作与之关联的测试用例。

kunit_action_t *action

测试退出时要运行的函数

void *ctx

传递给 func 的数据

描述

将函数的执行延迟到测试退出时,无论是正常退出还是由于失败而退出。ctx 作为附加上下文传递。所有使用 kunit_add_action() 注册的函数都将按照与注册顺序相反的顺序执行。

这对于清理已分配的内存和资源很有用,因为即使测试由于例如断言失败而提前中止,也会调用这些函数。

如果无法创建操作(例如,由于系统内存不足),则将立即调用 action(ctx),并且将返回错误。

另请参见:devm_add_action_or_reset() 获取 devres 等效项。

返回值

成功返回 0,如果无法延迟操作,则返回错误。

void kunit_remove_action(struct kunit *test, kunit_action_t *action, void *ctx)

取消匹配的延迟操作。

参数

struct kunit *test

操作与之关联的测试用例。

kunit_action_t *action

要取消的延迟函数。

void *ctx

传递给延迟函数以触发的上下文。

描述

阻止通过 kunit_add_action() 延迟的操作在测试终止时执行。

如果函数/上下文对被延迟多次,则只会取消最近的一次。

另请参阅:devm_remove_action(),了解 devres 等效项。

void kunit_release_action(struct kunit *test, kunit_action_t *action, void *ctx)

立即运行匹配的操作调用。

参数

struct kunit *test

操作与之关联的测试用例。

kunit_action_t *action

要触发的延迟函数。

void *ctx

传递给延迟函数以触发的上下文。

描述

立即执行通过 kunit_add_action() 延迟的函数,而不是在测试结束时执行。

如果函数/上下文对被延迟多次,则此处只会执行一次。最近的延迟将不再在测试结束时执行。

kunit_release_action(test, func, ctx); 等效于 func(ctx); kunit_remove_action(test, func, ctx);

另请参阅:devm_release_action(),了解 devres 等效项。

托管设备

用于使用 KUnit 管理的 struct devicestruct device_driver 的函数。包含 kunit/device.h 以使用它们。

struct device_driver *kunit_driver_create(struct kunit *test, const char *name)

创建附加到 kunit_bus 的 struct device_driver

参数

struct kunit *test

测试上下文对象。

const char *name

为创建的驱动程序提供的名称。

描述

创建附加到 kunit_bus 的 struct device_driver,名称为 name。此驱动程序将在测试退出时自动清理。

返回值

由 KUnit 管理的、名为 name 的存根 struct device_driver

struct device *kunit_device_register(struct kunit *test, const char *name)

创建一个 struct device 以在 KUnit 测试中使用

参数

struct kunit *test

测试上下文对象。

const char *name

为创建的设备提供的名称。

描述

创建一个具有给定名称的结构 kunit_device(它是 struct device)和一个相应的驱动程序。设备和驱动程序将在测试退出时或调用 kunit_device_unregister 时清理。如果您希望提供自己的 struct device_driver,另请参阅 kunit_device_register_with_driver。

返回值

指向 struct device 的指针,它将在测试退出时清理;如果无法分配或注册设备,则为错误指针。

struct device *kunit_device_register_with_driver(struct kunit *test, const char *name, const struct device_driver *drv)

创建一个 struct device 以在 KUnit 测试中使用

参数

struct kunit *test

测试上下文对象。

const char *name

为创建的设备提供的名称。

const struct device_driver *drv

要与设备关联的 struct device_driver

描述

创建一个具有给定名称和驱动程序的结构 kunit_device(它是 struct device)。设备将在测试退出时或调用 kunit_device_unregister 时清理。如果您希望 KUnit 为您创建和管理驱动程序,另请参阅 kunit_device_register。

返回值

指向 struct device 的指针,它将在测试退出时清理;如果无法分配或注册设备,则为错误指针。

void kunit_device_unregister(struct kunit *test, struct device *dev)

注销 KUnit 管理的设备

参数

struct kunit *test

创建设备的测试上下文对象

struct device *dev

设备。

描述

注销并销毁使用 kunit_device_register 或 kunit_device_register_with_driver 创建的 struct device。如果 KUnit 创建了驱动程序,则也会将其清理。