brintos

brintos / linux-shallow public Read only

0
0
Text · 10.4 KiB · 3056d6b Raw
379 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Example KUnit test to show how to use KUnit.4 *5 * Copyright (C) 2019, Google LLC.6 * Author: Brendan Higgins <brendanhiggins@google.com>7 */8 9#include <kunit/test.h>10#include <kunit/static_stub.h>11 12/*13 * This is the most fundamental element of KUnit, the test case. A test case14 * makes a set EXPECTATIONs and ASSERTIONs about the behavior of some code; if15 * any expectations or assertions are not met, the test fails; otherwise, the16 * test passes.17 *18 * In KUnit, a test case is just a function with the signature19 * `void (*)(struct kunit *)`. `struct kunit` is a context object that stores20 * information about the current test.21 */22static void example_simple_test(struct kunit *test)23{24	/*25	 * This is an EXPECTATION; it is how KUnit tests things. When you want26	 * to test a piece of code, you set some expectations about what the27	 * code should do. KUnit then runs the test and verifies that the code's28	 * behavior matched what was expected.29	 */30	KUNIT_EXPECT_EQ(test, 1 + 1, 2);31}32 33/*34 * This is run once before each test case, see the comment on35 * example_test_suite for more information.36 */37static int example_test_init(struct kunit *test)38{39	kunit_info(test, "initializing\n");40 41	return 0;42}43 44/*45 * This is run once after each test case, see the comment on46 * example_test_suite for more information.47 */48static void example_test_exit(struct kunit *test)49{50	kunit_info(test, "cleaning up\n");51}52 53 54/*55 * This is run once before all test cases in the suite.56 * See the comment on example_test_suite for more information.57 */58static int example_test_init_suite(struct kunit_suite *suite)59{60	kunit_info(suite, "initializing suite\n");61 62	return 0;63}64 65/*66 * This is run once after all test cases in the suite.67 * See the comment on example_test_suite for more information.68 */69static void example_test_exit_suite(struct kunit_suite *suite)70{71	kunit_info(suite, "exiting suite\n");72}73 74 75/*76 * This test should always be skipped.77 */78static void example_skip_test(struct kunit *test)79{80	/* This line should run */81	kunit_info(test, "You should not see a line below.");82 83	/* Skip (and abort) the test */84	kunit_skip(test, "this test should be skipped");85 86	/* This line should not execute */87	KUNIT_FAIL(test, "You should not see this line.");88}89 90/*91 * This test should always be marked skipped.92 */93static void example_mark_skipped_test(struct kunit *test)94{95	/* This line should run */96	kunit_info(test, "You should see a line below.");97 98	/* Skip (but do not abort) the test */99	kunit_mark_skipped(test, "this test should be skipped");100 101	/* This line should run */102	kunit_info(test, "You should see this line.");103}104 105/*106 * This test shows off all the types of KUNIT_EXPECT macros.107 */108static void example_all_expect_macros_test(struct kunit *test)109{110	const u32 array1[] = { 0x0F, 0xFF };111	const u32 array2[] = { 0x1F, 0xFF };112 113	/* Boolean assertions */114	KUNIT_EXPECT_TRUE(test, true);115	KUNIT_EXPECT_FALSE(test, false);116 117	/* Integer assertions */118	KUNIT_EXPECT_EQ(test, 1, 1); /* check == */119	KUNIT_EXPECT_GE(test, 1, 1); /* check >= */120	KUNIT_EXPECT_LE(test, 1, 1); /* check <= */121	KUNIT_EXPECT_NE(test, 1, 0); /* check != */122	KUNIT_EXPECT_GT(test, 1, 0); /* check >  */123	KUNIT_EXPECT_LT(test, 0, 1); /* check <  */124 125	/* Pointer assertions */126	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, test);127	KUNIT_EXPECT_PTR_EQ(test, NULL, NULL);128	KUNIT_EXPECT_PTR_NE(test, test, NULL);129	KUNIT_EXPECT_NULL(test, NULL);130	KUNIT_EXPECT_NOT_NULL(test, test);131 132	/* String assertions */133	KUNIT_EXPECT_STREQ(test, "hi", "hi");134	KUNIT_EXPECT_STRNEQ(test, "hi", "bye");135 136	/* Memory block assertions */137	KUNIT_EXPECT_MEMEQ(test, array1, array1, sizeof(array1));138	KUNIT_EXPECT_MEMNEQ(test, array1, array2, sizeof(array1));139 140	/*141	 * There are also ASSERT variants of all of the above that abort test142	 * execution if they fail. Useful for memory allocations, etc.143	 */144	KUNIT_ASSERT_GT(test, sizeof(char), 0);145 146	/*147	 * There are also _MSG variants of all of the above that let you include148	 * additional text on failure.149	 */150	KUNIT_EXPECT_GT_MSG(test, sizeof(int), 0, "Your ints are 0-bit?!");151	KUNIT_ASSERT_GT_MSG(test, sizeof(int), 0, "Your ints are 0-bit?!");152}153 154/* This is a function we'll replace with static stubs. */155static int add_one(int i)156{157	/* This will trigger the stub if active. */158	KUNIT_STATIC_STUB_REDIRECT(add_one, i);159 160	return i + 1;161}162 163/* This is used as a replacement for the above function. */164static int subtract_one(int i)165{166	/* We don't need to trigger the stub from the replacement. */167 168	return i - 1;169}170 171/*172 * If the function to be replaced is static within a module it is173 * useful to export a pointer to that function instead of having174 * to change the static function to a non-static exported function.175 *176 * This pointer simulates a module exporting a pointer to a static177 * function.178 */179static int (* const add_one_fn_ptr)(int i) = add_one;180 181/*182 * This test shows the use of static stubs.183 */184static void example_static_stub_test(struct kunit *test)185{186	/* By default, function is not stubbed. */187	KUNIT_EXPECT_EQ(test, add_one(1), 2);188 189	/* Replace add_one() with subtract_one(). */190	kunit_activate_static_stub(test, add_one, subtract_one);191 192	/* add_one() is now replaced. */193	KUNIT_EXPECT_EQ(test, add_one(1), 0);194 195	/* Return add_one() to normal. */196	kunit_deactivate_static_stub(test, add_one);197	KUNIT_EXPECT_EQ(test, add_one(1), 2);198}199 200/*201 * This test shows the use of static stubs when the function being202 * replaced is provided as a pointer-to-function instead of the203 * actual function. This is useful for providing access to static204 * functions in a module by exporting a pointer to that function205 * instead of having to change the static function to a non-static206 * exported function.207 */208static void example_static_stub_using_fn_ptr_test(struct kunit *test)209{210	/* By default, function is not stubbed. */211	KUNIT_EXPECT_EQ(test, add_one(1), 2);212 213	/* Replace add_one() with subtract_one(). */214	kunit_activate_static_stub(test, add_one_fn_ptr, subtract_one);215 216	/* add_one() is now replaced. */217	KUNIT_EXPECT_EQ(test, add_one(1), 0);218 219	/* Return add_one() to normal. */220	kunit_deactivate_static_stub(test, add_one_fn_ptr);221	KUNIT_EXPECT_EQ(test, add_one(1), 2);222}223 224static const struct example_param {225	int value;226} example_params_array[] = {227	{ .value = 3, },228	{ .value = 2, },229	{ .value = 1, },230	{ .value = 0, },231};232 233static void example_param_get_desc(const struct example_param *p, char *desc)234{235	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "example value %d", p->value);236}237 238KUNIT_ARRAY_PARAM(example, example_params_array, example_param_get_desc);239 240/*241 * This test shows the use of params.242 */243static void example_params_test(struct kunit *test)244{245	const struct example_param *param = test->param_value;246 247	/* By design, param pointer will not be NULL */248	KUNIT_ASSERT_NOT_NULL(test, param);249 250	/* Test can be skipped on unsupported param values */251	if (!is_power_of_2(param->value))252		kunit_skip(test, "unsupported param value %d", param->value);253 254	/* You can use param values for parameterized testing */255	KUNIT_EXPECT_EQ(test, param->value % param->value, 0);256}257 258/*259 * This test shows the use of test->priv.260 */261static void example_priv_test(struct kunit *test)262{263	/* unless setup in suite->init(), test->priv is NULL */264	KUNIT_ASSERT_NULL(test, test->priv);265 266	/* but can be used to pass arbitrary data to other functions */267	test->priv = kunit_kzalloc(test, 1, GFP_KERNEL);268	KUNIT_EXPECT_NOT_NULL(test, test->priv);269	KUNIT_ASSERT_PTR_EQ(test, test->priv, kunit_get_current_test()->priv);270}271 272/*273 * This test should always pass. Can be used to practice filtering attributes.274 */275static void example_slow_test(struct kunit *test)276{277	KUNIT_EXPECT_EQ(test, 1 + 1, 2);278}279 280/*281 * Here we make a list of all the test cases we want to add to the test suite282 * below.283 */284static struct kunit_case example_test_cases[] = {285	/*286	 * This is a helper to create a test case object from a test case287	 * function; its exact function is not important to understand how to288	 * use KUnit, just know that this is how you associate test cases with a289	 * test suite.290	 */291	KUNIT_CASE(example_simple_test),292	KUNIT_CASE(example_skip_test),293	KUNIT_CASE(example_mark_skipped_test),294	KUNIT_CASE(example_all_expect_macros_test),295	KUNIT_CASE(example_static_stub_test),296	KUNIT_CASE(example_static_stub_using_fn_ptr_test),297	KUNIT_CASE(example_priv_test),298	KUNIT_CASE_PARAM(example_params_test, example_gen_params),299	KUNIT_CASE_SLOW(example_slow_test),300	{}301};302 303/*304 * This defines a suite or grouping of tests.305 *306 * Test cases are defined as belonging to the suite by adding them to307 * `kunit_cases`.308 *309 * Often it is desirable to run some function which will set up things which310 * will be used by every test; this is accomplished with an `init` function311 * which runs before each test case is invoked. Similarly, an `exit` function312 * may be specified which runs after every test case and can be used to for313 * cleanup. For clarity, running tests in a test suite would behave as follows:314 *315 * suite.suite_init(suite);316 * suite.init(test);317 * suite.test_case[0](test);318 * suite.exit(test);319 * suite.init(test);320 * suite.test_case[1](test);321 * suite.exit(test);322 * suite.suite_exit(suite);323 * ...;324 */325static struct kunit_suite example_test_suite = {326	.name = "example",327	.init = example_test_init,328	.exit = example_test_exit,329	.suite_init = example_test_init_suite,330	.suite_exit = example_test_exit_suite,331	.test_cases = example_test_cases,332};333 334/*335 * This registers the above test suite telling KUnit that this is a suite of336 * tests that need to be run.337 */338kunit_test_suites(&example_test_suite);339 340static int __init init_add(int x, int y)341{342	return (x + y);343}344 345/*346 * This test should always pass. Can be used to test init suites.347 */348static void __init example_init_test(struct kunit *test)349{350	KUNIT_EXPECT_EQ(test, init_add(1, 1), 2);351}352 353/*354 * The kunit_case struct cannot be marked as __initdata as this will be355 * used in debugfs to retrieve results after test has run356 */357static struct kunit_case __refdata example_init_test_cases[] = {358	KUNIT_CASE(example_init_test),359	{}360};361 362/*363 * The kunit_suite struct cannot be marked as __initdata as this will be364 * used in debugfs to retrieve results after test has run365 */366static struct kunit_suite example_init_test_suite = {367	.name = "example_init",368	.test_cases = example_init_test_cases,369};370 371/*372 * This registers the test suite and marks the suite as using init data373 * and/or functions.374 */375kunit_test_init_section_suites(&example_init_test_suite);376 377MODULE_DESCRIPTION("Example KUnit test suite");378MODULE_LICENSE("GPL v2");379