# 内核测试框架 — DragonOS dev 文档

# 内核测试框架

DragonOS提供了一个测试框架，旨在对内核的一些模块进行自动化测试。内核测试框架位于`ktest/`下。

我们可以使用这个测试框架，按照规范编写测试代码，然后在合适的地方使用`ktest_start()`创建一个全新的内核线程并发起测试。

## 使用方法

### 创建自动测试程序

假如您要对kfifo模块进行自动测试，您可以在`ktest/`下，创建一个名为`test-kfifo.c`的测试文件，并编写Makefile。

在`test-kfifo.c`中，包含`ktest_utils.h`和`ktest.h`这两个头文件。

您需要像下面这样，在`test-kfifo.c`中，创建一个测试用例函数表，并把测试用例函数填写到其中：

    static ktest_case_table kt_kfifo_func_table[] = {
        ktest_kfifo_case0_1,
    };

然后创建一个函数，作为kfifo测试的主函数。请注意，您需要将它的声明添加到`ktest.h`中。

    uint64_t ktest_test_kfifo(uint64_t arg)
    {
        kTEST("Testing kfifo...");
        for (int i = 0; i < sizeof(kt_kfifo_func_table) / sizeof(ktest_case_table); ++i)
        {
            kTEST("Testing case %d", i);
            kt_kfifo_func_table[i](i, 0);
        }
        kTEST("kfifo Test done.");
        return 0;
    }

### 编写测试用例

您可以创建一个或多个测试用例，命名为：`ktest_kfifo_case_xxxxx`. 在这个例子中，我创建了一个测试用例，命名为：`ktest_kfifo_case0_1`.如下所示：

    static long ktest_kfifo_case0_1(uint64_t arg0, uint64_t arg1)

这里最多允许我们传递两个参数到测试函数里面。

那么，我们该如何编写测试用例呢？

我们主要是需要设置一些情节，以便能测试到目标组件的每个情况。为了检验模块的行为是否符合预期，我们需要使用`assert(condition)`宏函数，对目标`condition`进行校验。若`condition`为1，则表明测试通过。否则，将会输出一行assert failed信息到屏幕上。

### 发起测试

我们可以在pid≥1的内核线程中发起测试。由于DragonOS目前尚不完善，您可以在`process/process.c`中的`initial_kernel_thread()`函数内，发起内核自动测试。具体的代码如下：

    ktest_start(ktest_test_kfifo, 0);

这样就发起了一个内核测试，它会创建一个新的内核线程进行自动测试，您不必担心第一个内核线程会被阻塞。

## API文档

### ktest_start

`pid_t ktest_start(uint64_t (*func)(uint64_t arg), uint64_t arg)`

#### 描述

开启一个新的内核线程以进行测试

#### 参数

func

测试函数. 新的测试线程将会执行该函数，以进行测试。

arg

传递给测试函数的参数

#### 返回值

测试线程的pid

### assert

`#define assert(condition)`

#### 描述

判定condition是否为1，若不为1，则输出一行错误日志信息：

    [ kTEST FAILED ] Ktest Assertion Failed, file:%s, Line:%d

### kTEST

`#define kTEST(...)`

#### 描述

格式化输出一行以`[ kTEST ] file:%s, Line:%d`开头的日志信息。

### ktest_case_table

`typedef long (*ktest_case_table)(uint64_t arg0, uint64_t arg1)`

#### 描述

ktest用例函数的类型定义。

Other Versions v: V0.1.8

Tags
  V0.1.0
  V0.1.1
  V0.1.10
  V0.1.2
  V0.1.3
  V0.1.4
  V0.1.5
  V0.1.6
  V0.1.7
  V0.1.8
  V0.1.9
  V0.2.0
  V0.3.0
  V0.4.0

Branches
  master