KUnit 架構¶
KUnit 架構分為兩部分
核心內測試框架¶
核心測試庫支援使用 KUnit 以 C 編寫的 KUnit 測試。這些 KUnit 測試是核心程式碼。KUnit 執行以下任務
組織測試
報告測試結果
提供測試實用程式
測試用例¶
測試用例是 KUnit 中的基本單元。 KUnit 測試用例被組織成套件。 KUnit 測試用例是一個函式,其型別簽名為 void (*)(struct kunit *test)。這些測試用例函式包裝在一個名為 struct kunit_case 的結構中。
每個 KUnit 測試用例都會收到一個 struct kunit 上下文物件,該物件跟蹤正在執行的測試。 KUnit 斷言宏和其他 KUnit 實用程式使用 struct kunit 上下文物件。作為一個例外,有兩個欄位
->priv:setup 函式可以使用它來儲存任意測試使用者資料。->param_value:它包含引數值,可以在引數化測試中檢索該引數值。
測試套件¶
一個 KUnit 套件包括一系列測試用例。 KUnit 套件由 struct kunit_suite 表示。例如
static struct kunit_case example_test_cases[] = {
KUNIT_CASE(example_test_foo),
KUNIT_CASE(example_test_bar),
KUNIT_CASE(example_test_baz),
{}
};
static struct kunit_suite example_test_suite = {
.name = "example",
.init = example_test_init,
.exit = example_test_exit,
.test_cases = example_test_cases,
};
kunit_test_suite(example_test_suite);
在上面的示例中,測試套件 example_test_suite 執行測試用例 example_test_foo、example_test_bar 和 example_test_baz。在執行測試之前,呼叫 example_test_init,在執行測試之後,呼叫 example_test_exit。 kunit_test_suite(example_test_suite) 將測試套件註冊到 KUnit 測試框架。
執行器¶
KUnit 執行器可以列出並執行啟動時內建的 KUnit 測試。測試套件儲存在名為 .kunit_test_suites 的連結器部分中。有關程式碼,請參見 include/asm-generic/vmlinux.lds.h 中的 KUNIT_TABLE() 宏定義。連結器部分由指向 struct kunit_suite 的指標陣列組成,並由 kunit_test_suites() 宏填充。 KUnit 執行器迭代連結器部分陣列,以便執行編譯到核心中的所有測試。
KUnit 套件記憶體圖¶
在核心啟動時,KUnit 執行器使用此部分的起始和結束地址來迭代並執行所有測試。有關執行器的實現,請參見 lib/kunit/executor.c。當作為模組構建時,kunit_test_suites() 宏定義了一個 module_init() 函式,該函式執行編譯單元中的所有測試,而不是利用執行器。
在 KUnit 測試中,某些錯誤類不影響其他測試或核心的其他部分,每個 KUnit 用例都在單獨的執行緒上下文中執行。 請參見 lib/kunit/try-catch.c 中的 kunit_try_catch_run() 函式。
斷言宏¶
KUnit 測試使用期望/斷言來驗證狀態。 所有期望/斷言的格式為:KUNIT_{EXPECT|ASSERT}_<op>[_MSG](kunit, property[, message])
{EXPECT|ASSERT}確定檢查是斷言還是期望。 如果發生故障,測試流程的差異如下對於期望,測試被標記為失敗,並且記錄失敗。
另一方面,斷言失敗會導致測試用例立即終止。
斷言呼叫函式:
void __noreturn __kunit_abort(struct kunit *)。__kunit_abort呼叫函式:void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)。kunit_try_catch_throw呼叫函式:void kthread_complete_and_exit(struct completion *, long) __noreturn;並終止特殊的執行緒上下文。
<op>表示具有以下選項的檢查:TRUE(提供的屬性具有布林值“true”),EQ(兩個提供的屬性相等),NOT_ERR_OR_NULL(提供的指標不為空且不包含“err”值)。[_MSG]在失敗時列印自定義訊息。
測試結果報告¶
KUnit 以 KTAP 格式列印測試結果。 KTAP 基於 TAP14,請參閱 核心測試通用協議 (KTAP),版本 1。 KTAP 可與 KUnit 和 Kselftest 配合使用。 KUnit 執行器將 KTAP 結果列印到 dmesg 和 debugfs(如果已配置)。
引數化測試¶
每個 KUnit 引數化測試都與一個引數集合相關聯。該測試被多次呼叫,每個引數值呼叫一次,並且該引數儲存在 param_value 欄位中。測試用例包括一個 KUNIT_CASE_PARAM() 宏,該宏接受一個生成器函式。生成器函式傳遞先前的引數,並返回下一個引數。它還包括一個用於生成基於陣列的常見用例生成器的宏。
kunit_tool (命令列測試工具)¶
kunit_tool 是一個 Python 指令碼,位於 tools/testing/kunit/kunit.py 中。 它用於配置、構建、執行、解析測試結果,並以正確的順序執行所有先前的命令(即,配置、構建、執行和解析)。 您可以選擇兩種方式來執行 KUnit 測試:構建啟用 KUnit 的核心並手動解析結果(請參閱 不使用 kunit_tool 執行測試),或者使用 kunit_tool(請參閱 使用 kunit_tool 執行測試)。
configure命令從.kunitconfig檔案(以及任何特定於體系結構的選擇)生成核心.config。qemu_configs資料夾中提供的 Python 指令碼(例如,tools/testing/kunit/qemu configs/powerpc.py)包含特定體系結構的附加配置選項。 它解析現有的.config檔案和.kunitconfig檔案,以確保.config是.kunitconfig的超集。 如果不是,它將合併這兩個檔案並執行make olddefconfig以重新生成.config檔案。 然後,它檢查.config是否已成為超集。 這驗證了所有 Kconfig 依賴項是否在檔案.kunitconfig中正確指定。kunit_config.py指令碼包含用於解析 Kconfig 的程式碼。 執行make olddefconfig的程式碼是kunit_kernel.py指令碼的一部分。 您可以透過以下命令呼叫此命令:./tools/testing/kunit/kunit.py config並生成一個.config檔案。build使用必需的選項(取決於體系結構和一些選項,例如:build_dir)在核心樹上執行make並報告任何錯誤。 要從當前的.config構建 KUnit 核心,可以使用build引數:./tools/testing/kunit/kunit.py build。exec命令直接(使用使用者模式 Linux 配置)或透過模擬器(例如 QEMU)執行核心結果。 它使用標準輸出 (stdout) 從日誌中讀取結果,並將它們傳遞給parse進行解析。 如果您已經構建了一個帶有內建 KUnit 測試的核心,則可以執行該核心並使用exec引數顯示測試結果:./tools/testing/kunit/kunit.py exec。parse從核心日誌中提取 KTAP 輸出,解析測試結果,並列印摘要。 對於失敗的測試,將包含任何診斷輸出。