// SPDX-License-Identifier: GPL-2.0 /* * Example KUnit test to show how to use KUnit. * * Copyright (C) 2019, Google LLC. * Author: Brendan Higgins <[email protected]> */ #include <kunit/test.h> #include <kunit/static_stub.h> /* * This is the most fundamental element of KUnit, the test case. A test case * makes a set EXPECTATIONs and ASSERTIONs about the behavior of some code; if * any expectations or assertions are not met, the test fails; otherwise, the * test passes. * * In KUnit, a test case is just a function with the signature * `void (*)(struct kunit *)`. `struct kunit` is a context object that stores * information about the current test. */ static void example_simple_test(struct kunit *test) { … } /* * This is run once before each test case, see the comment on * example_test_suite for more information. */ static int example_test_init(struct kunit *test) { … } /* * This is run once after each test case, see the comment on * example_test_suite for more information. */ static void example_test_exit(struct kunit *test) { … } /* * This is run once before all test cases in the suite. * See the comment on example_test_suite for more information. */ static int example_test_init_suite(struct kunit_suite *suite) { … } /* * This is run once after all test cases in the suite. * See the comment on example_test_suite for more information. */ static void example_test_exit_suite(struct kunit_suite *suite) { … } /* * This test should always be skipped. */ static void example_skip_test(struct kunit *test) { … } /* * This test should always be marked skipped. */ static void example_mark_skipped_test(struct kunit *test) { … } /* * This test shows off all the types of KUNIT_EXPECT macros. */ static void example_all_expect_macros_test(struct kunit *test) { … } /* This is a function we'll replace with static stubs. */ static int add_one(int i) { … } /* This is used as a replacement for the above function. */ static int subtract_one(int i) { … } /* * If the function to be replaced is static within a module it is * useful to export a pointer to that function instead of having * to change the static function to a non-static exported function. * * This pointer simulates a module exporting a pointer to a static * function. */ static int (* const add_one_fn_ptr)(int i) = …; /* * This test shows the use of static stubs. */ static void example_static_stub_test(struct kunit *test) { … } /* * This test shows the use of static stubs when the function being * replaced is provided as a pointer-to-function instead of the * actual function. This is useful for providing access to static * functions in a module by exporting a pointer to that function * instead of having to change the static function to a non-static * exported function. */ static void example_static_stub_using_fn_ptr_test(struct kunit *test) { … } static const struct example_param { … } example_params_array[] = …; static void example_param_get_desc(const struct example_param *p, char *desc) { … } KUNIT_ARRAY_PARAM(example, example_params_array, example_param_get_desc); /* * This test shows the use of params. */ static void example_params_test(struct kunit *test) { … } /* * This test shows the use of test->priv. */ static void example_priv_test(struct kunit *test) { … } /* * This test should always pass. Can be used to practice filtering attributes. */ static void example_slow_test(struct kunit *test) { … } /* * Here we make a list of all the test cases we want to add to the test suite * below. */ static struct kunit_case example_test_cases[] = …; /* * This defines a suite or grouping of tests. * * Test cases are defined as belonging to the suite by adding them to * `kunit_cases`. * * Often it is desirable to run some function which will set up things which * will be used by every test; this is accomplished with an `init` function * which runs before each test case is invoked. Similarly, an `exit` function * may be specified which runs after every test case and can be used to for * cleanup. For clarity, running tests in a test suite would behave as follows: * * suite.suite_init(suite); * suite.init(test); * suite.test_case[0](test); * suite.exit(test); * suite.init(test); * suite.test_case[1](test); * suite.exit(test); * suite.suite_exit(suite); * ...; */ static struct kunit_suite example_test_suite = …; /* * This registers the above test suite telling KUnit that this is a suite of * tests that need to be run. */ kunit_test_suites(…); static int __init init_add(int x, int y) { … } /* * This test should always pass. Can be used to test init suites. */ static void __init example_init_test(struct kunit *test) { … } /* * The kunit_case struct cannot be marked as __initdata as this will be * used in debugfs to retrieve results after test has run */ static struct kunit_case __refdata example_init_test_cases[] = …; /* * The kunit_suite struct cannot be marked as __initdata as this will be * used in debugfs to retrieve results after test has run */ static struct kunit_suite example_init_test_suite = …; /* * This registers the test suite and marks the suite as using init data * and/or functions. */ kunit_test_init_section_suites(…); MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;