Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kselftest: Add test module framework header

kselftest runs as a userspace process. Sometimes we need to test things
from kernel space. One way of doing this is by creating a test module.
Currently doing so requires developers to write a bunch of boiler plate
in the module if kselftest is to be used to run the tests. This means
we currently have a load of duplicate code to achieve these ends. If we
have a uniform method for implementing test modules then we can reduce
code duplication, ensure uniformity in the test framework, ease code
maintenance, and reduce the work required to create tests. This all
helps to encourage developers to write and run tests.

Add a C header file that can be included in test modules. This provides
a single point for common test functions/macros. Implement a few macros
that make up the start of the test framework.

Add documentation for new kselftest header to kselftest documentation.

Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Tobin C. Harding <tobin@kernel.org>
Signed-off-by: Shuah Khan <shuah@kernel.org>

authored by

Tobin C. Harding and committed by
Shuah Khan
eebf4dd4 d3460527

+140 -2
+92 -2
Documentation/dev-tools/kselftest.rst
··· 14 14 run on a single cpu as opposed to all hotplug capable cpus, and memory 15 15 hotplug test is run on 2% of hotplug capable memory instead of 10%. 16 16 17 + kselftest runs as a userspace process. Tests that can be written/run in 18 + userspace may wish to use the `Test Harness`_. Tests that need to be 19 + run in kernel space may wish to use a `Test Module`_. 20 + 17 21 Running the selftests (hotplug tests are run in limited mode) 18 22 ============================================================= 19 23 ··· 165 161 166 162 e.g: tools/testing/selftests/android/config 167 163 164 + Test Module 165 + =========== 166 + 167 + Kselftest tests the kernel from userspace. Sometimes things need 168 + testing from within the kernel, one method of doing this is to create a 169 + test module. We can tie the module into the kselftest framework by 170 + using a shell script test runner. ``kselftest_module.sh`` is designed 171 + to facilitate this process. There is also a header file provided to 172 + assist writing kernel modules that are for use with kselftest: 173 + 174 + - ``tools/testing/kselftest/kselftest_module.h`` 175 + - ``tools/testing/kselftest/kselftest_module.sh`` 176 + 177 + How to use 178 + ---------- 179 + 180 + Here we show the typical steps to create a test module and tie it into 181 + kselftest. We use kselftests for lib/ as an example. 182 + 183 + 1. Create the test module 184 + 185 + 2. Create the test script that will run (load/unload) the module 186 + e.g. ``tools/testing/selftests/lib/printf.sh`` 187 + 188 + 3. Add line to config file e.g. ``tools/testing/selftests/lib/config`` 189 + 190 + 4. Add test script to makefile e.g. ``tools/testing/selftests/lib/Makefile`` 191 + 192 + 5. Verify it works: 193 + 194 + .. code-block:: sh 195 + 196 + # Assumes you have booted a fresh build of this kernel tree 197 + cd /path/to/linux/tree 198 + make kselftest-merge 199 + make modules 200 + sudo make modules_install 201 + make TARGETS=lib kselftest 202 + 203 + Example Module 204 + -------------- 205 + 206 + A bare bones test module might look like this: 207 + 208 + .. code-block:: c 209 + 210 + // SPDX-License-Identifier: GPL-2.0+ 211 + 212 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 213 + 214 + #include "../tools/testing/selftests/kselftest_module.h" 215 + 216 + KSTM_MODULE_GLOBALS(); 217 + 218 + /* 219 + * Kernel module for testing the foobinator 220 + */ 221 + 222 + static int __init test_function() 223 + { 224 + ... 225 + } 226 + 227 + static void __init selftest(void) 228 + { 229 + KSTM_CHECK_ZERO(do_test_case("", 0)); 230 + } 231 + 232 + KSTM_MODULE_LOADERS(test_foo); 233 + MODULE_AUTHOR("John Developer <jd@fooman.org>"); 234 + MODULE_LICENSE("GPL"); 235 + 236 + Example test script 237 + ------------------- 238 + 239 + .. code-block:: sh 240 + 241 + #!/bin/bash 242 + # SPDX-License-Identifier: GPL-2.0+ 243 + $(dirname $0)/../kselftest_module.sh "foo" test_foo 244 + 245 + 168 246 Test Harness 169 247 ============ 170 248 171 - The kselftest_harness.h file contains useful helpers to build tests. The tests 172 - from tools/testing/selftests/seccomp/seccomp_bpf.c can be used as example. 249 + The kselftest_harness.h file contains useful helpers to build tests. The 250 + test harness is for userspace testing, for kernel space testing see `Test 251 + Module`_ above. 252 + 253 + The tests from tools/testing/selftests/seccomp/seccomp_bpf.c can be used as 254 + example. 173 255 174 256 Example 175 257 -------
+48
tools/testing/selftests/kselftest_module.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + #ifndef __KSELFTEST_MODULE_H 3 + #define __KSELFTEST_MODULE_H 4 + 5 + #include <linux/module.h> 6 + 7 + /* 8 + * Test framework for writing test modules to be loaded by kselftest. 9 + * See Documentation/dev-tools/kselftest.rst for an example test module. 10 + */ 11 + 12 + #define KSTM_MODULE_GLOBALS() \ 13 + static unsigned int total_tests __initdata; \ 14 + static unsigned int failed_tests __initdata 15 + 16 + #define KSTM_CHECK_ZERO(x) do { \ 17 + total_tests++; \ 18 + if (x) { \ 19 + pr_warn("TC failed at %s:%d\n", __func__, __LINE__); \ 20 + failed_tests++; \ 21 + } \ 22 + } while (0) 23 + 24 + static inline int kstm_report(unsigned int total_tests, unsigned int failed_tests) 25 + { 26 + if (failed_tests == 0) 27 + pr_info("all %u tests passed\n", total_tests); 28 + else 29 + pr_warn("failed %u out of %u tests\n", failed_tests, total_tests); 30 + 31 + return failed_tests ? -EINVAL : 0; 32 + } 33 + 34 + #define KSTM_MODULE_LOADERS(__module) \ 35 + static int __init __module##_init(void) \ 36 + { \ 37 + pr_info("loaded.\n"); \ 38 + selftest(); \ 39 + return kstm_report(total_tests, failed_tests); \ 40 + } \ 41 + static void __exit __module##_exit(void) \ 42 + { \ 43 + pr_info("unloaded.\n"); \ 44 + } \ 45 + module_init(__module##_init); \ 46 + module_exit(__module##_exit) 47 + 48 + #endif /* __KSELFTEST_MODULE_H */