KTEST(9) | Kernel Concepts | KTEST(9) |
ktest
— kernel
test facility
The ktest facility provides the means for writing and executing kernel test modules. A kernel test module is a kernel module that contains test functions designed to execute and verify some aspect of the kernel. You can test any aspect of the kernel for which you can create the requisite context, whether that be its local arguments or shared state.
The key design idea behind ktest is to put the test in the same context as the code it's testing: kernel context. By writing tests as kernel functions it allows one to more thoroughly test particular aspects of the kernel. The ktest facility complements user-space testing by allowing targeted testing of the kernel that is not as easily exercised via user-space.
The ktest facility provides a kernel API for creating tests as well as a character device for interacting with the facility from user-space. The latter of which should be done by way of the ktest(8) command.
This page concerns itself with the various kernel-side concepts of the ktest facility and acts as a guide to the various 9F APIs.
A test is uniquely identified by its test triple. The triple is a three-level namespace comprising of the module name, suite name, and test name. Each part of the namespace is separated by the ':' character.
<module>:<suite>:<test>
For a name to be considered valid it must meet the following criteria.
The context handle provides the means through which the test communicates with the ktest facility. All test functions must conform to the following prototype.
typedef void (*ktest_fn_t)(ktest_ctx_hdl_t *ctx);
The test interacts with ctx through various ktest routines documented in their requisite sections.
The ultimate goal of a test function is to return a result. See ktest_result_pass(9f) for the complete guide to setting test results.
Some tests require an input stream to test against. The input stream is provided at runtime by the user. The user may run the same test against one or more different input streams.
This is useful when a test applies to many different scenarios with the same general logic. For example, a test that verifies a checksum routine applies to any byte stream; or a test that verifies TCP header parsing applies to any byte stream as well.
Writing a test against an input stream provides several benefits.
A test that requires input must specify the KTEST_FLAG_INPUT flag when calling ktest_add_test(9f). To retrieve the input stream the test uses the ktest_get_input(9f) function.
A test facility that can't test private ( static ) functions is going to be pretty limited. Some of the most useful functions to test are those that act as "helpers" to other, larger functions. These functions are often declared static and not directly accessible to the test module which is built as its own compilation unit.
One solution would be to alter ktest to also allow declaring test functions inside the regular kernel modules themselves, but it currently does not offer that capability. Instead, ktest provides the ktest_get_fn(9f) function for obtaining a handle to private functions. See that page for more detail.
Only registered tests are accessible to the user. See ktest_create_module(9f) for more information.
There are several conventions to follow when creating a new test module.
KT_ASSERT(9F), KT_ERROR(9F), KT_FAIL(9F), KT_PASS(9F), KT_SKIP(9F), ktest_add_suite(9F), ktest_add_test(9F), ktest_create_module(9F), ktest_get_fn(9F), ktest_get_input(9F), ktest_hold_mod(9F), ktest_msg_clear(9F), ktest_msg_prepend(9F), ktest_register_module(9F), ktest_release_mod(9F), ktest_unregister_module(9F), modlmisc(9S)
February 17, 2023 | OmniOS |