KTEST_CREATE_MODULE(9F) Kernel Functions for Drivers KTEST_CREATE_MODULE(9F)

ktest_create_module, ktest_add_suite, ktest_add_test, ktest_register_module, ktest_unregister_module, ktest_free_modulecreate and register ktest test modules

#include <sys/ktest.h>

int
ktest_create_module(const char *name, ktest_module_hdl_t **km_hdl);

int
ktest_add_suite(ktest_module_hdl_t *km_hdl, const char *name, ktest_suite_hdl_t **ks_hdl);

int
ktest_add_test(ktest_suite_hdl_t *ks_hdl, const char *name, ktest_fn_t fn, ktest_test_flags_t flags);

int
ktest_register_module(ktest_module_hdl_t *km_hdl);

void
ktest_unregister_module(const char *name);

void
ktest_free_module(ktest_module_hdl_t *km_hdl);

This interface is still evolving in illumos. API and ABI stability is not guaranteed.

name
The name of the module, suite, or test. See the "Names" section below.
km_hdl
The handle to a ktest module.
ks_hdl
The handle to a ktest suite.
fn
A pointer to the test function.
flags
The set of test flags. See the ktest(9) page for a description of the valid flags.

A ktest test module is created by building up a module object and registering it with the ktest facility. The module object consists of a name and one or more suite objects. The suite object consists of a name and one or more test objects. Each test object consists of a name, a function pointer to the test function, and a set of test flags.

Test module object creation and registration should happen as part of the test module's _init(9E) routine. The sequence of calls inside a test module's _init(9E) should proceed in the following order.

  1. ()
  2. ()
  3. (), 1 or more times
  4. back to step 2 if more than one suite
  5. ()

Conversely, the test module should unregister its test module object as part of its _fini(9E) routine.

The name is the string used to reference a particular module, suite, or test. Any given test is uniquely identified by the combination of its module, suite, and test name -- also referred to as its "triple". This triple is how the user identifies a test when making use of the ktest(8) command.

The module name may be the same as the module-under-test, but that isn't a requirement. At the end of the day, the test module's name is simply a string used to organize suites of tests in some logical manner. In some cases it makes sense to name the test module something other than the module-under-test. For example, when the module-under-test is large, such as genunix. Or when the test module is testing a property of the larger system that spans more than a single module.

Module names must be unique. Suite names must be unique for a given module. Test names must be unique for a given suite. That implies that suite and test names may be reused so long as they are unique within their given namespace.

No flags specified.
This test requires an input stream.

Create a module object. Return failure if the name is not valid, or if the object could not be allocated.
Create a suite object and add it to the module object referenced by km_hdl. Return failure if the name is already in use, the name is not valid, or if the object could not be allocated.
Create a test object and add it to the suite object referenced by ks_hdl. The fn should be a pointer to the test function and flags should contain a value derived from a bitwise-OR of one or more test flag values. Return failure if the name is already in use, the name is not valid, or if the object could not be allocated.
Register the test module object referenced by km_hdl. Return failure if the module name already exists.
Unregister the test module object that maps to the name.
Used to free the module along with its contained suites and tests in the event that the module failed to register.

The ktest_create_module(), ktest_add_suite(), ktest_add_test(), and ktest_register_module() functions return 0 on success or an error value for failure.

The following example provides a template for how one would typically organize the source code of a test module.

#include <sys/ktest.h>

void
foo_test1(ktest_ctx_hdl_t *ctx)
{
	...
}

void
foo_test2(ktest_ctx_hdl_t *ctx)
{
	...
}

void
foo_test3(ktest_ctx_hdl_t *ctx)
{
	...
}

static struct modlmisc foo_test_modlmisc = {
	.misc_modops = &mod_miscops,
	.misc_linkinfo = "foo ktest module"
};

static struct modlinkage foo_test_modlinkage = {
	.ml_rev = MODREV_1,
	.ml_linkage = { &foo_test_modlmisc, NULL }
};

int
_init()
{
	int ret;
	ktest_module_hdl_t *km = NULL;
	ktest_suite_hdl_t *ks = NULL;

	VERIFY0(ktest_create_module("foo", &km));
	VERIFY0(ktest_add_suite("suite1", &ks));
	VERIFY0(ktest_add_test(ks, "foo_test1", foo_test1,
	    KTEST_FLAG_NONE));
	VERIFY0(ktest_add_test(ks, "foo_test2", foo_test2,
	    KTEST_FLAG_NONE));
	VERIFY0(ktest_add_test(ks, "foo_test3", foo_test3,
	    KTEST_FLAG_INPUT));

	if ((ret = ktest_register_module(km)) != 0) {
		ktest_free_module(km);
		return (ret);
	}

	if ((ret = mod_install(&foo_test_modlinkage)) != 0) {
		ktest_unregister_module("foo");
		return (ret);
	}

	return (0);
}

int
_fini(void)
{
	ktest_unregister_module("foo");
	return (mod_remove(&mac_test_modlinkage));
}

The name already exists.
The name contains illegal characters.
The module, suite, or test object could not be allocated.
The name value is too long.

ktest(8), ktest(9), _fini(9E), _init(9E)

February 8, 2024 OmniOS