1.. SPDX-License-Identifier: GPL-2.0
2
3============================
4Tips For Writing KUnit Tests
5============================
6
7Exiting early on failed expectations
8------------------------------------
9
10``KUNIT_EXPECT_EQ`` and friends will mark the test as failed and continue
11execution.  In some cases, it's unsafe to continue and you can use the
12``KUNIT_ASSERT`` variant to exit on failure.
13
14.. code-block:: c
15
16	void example_test_user_alloc_function(struct kunit *test)
17	{
18		void *object = alloc_some_object_for_me();
19
20		/* Make sure we got a valid pointer back. */
21		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, object);
22		do_something_with_object(object);
23	}
24
25Allocating memory
26-----------------
27
28Where you would use ``kzalloc``, you should prefer ``kunit_kzalloc`` instead.
29KUnit will ensure the memory is freed once the test completes.
30
31This is particularly useful since it lets you use the ``KUNIT_ASSERT_EQ``
32macros to exit early from a test without having to worry about remembering to
33call ``kfree``.
34
35Example:
36
37.. code-block:: c
38
39	void example_test_allocation(struct kunit *test)
40	{
41		char *buffer = kunit_kzalloc(test, 16, GFP_KERNEL);
42		/* Ensure allocation succeeded. */
43		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer);
44
45		KUNIT_ASSERT_STREQ(test, buffer, "");
46	}
47
48
49Testing static functions
50------------------------
51
52If you don't want to expose functions or variables just for testing, one option
53is to conditionally ``#include`` the test file at the end of your .c file, e.g.
54
55.. code-block:: c
56
57	/* In my_file.c */
58
59	static int do_interesting_thing();
60
61	#ifdef CONFIG_MY_KUNIT_TEST
62	#include "my_kunit_test.c"
63	#endif
64
65Injecting test-only code
66------------------------
67
68Similarly to the above, it can be useful to add test-specific logic.
69
70.. code-block:: c
71
72	/* In my_file.h */
73
74	#ifdef CONFIG_MY_KUNIT_TEST
75	/* Defined in my_kunit_test.c */
76	void test_only_hook(void);
77	#else
78	void test_only_hook(void) { }
79	#endif
80
81This test-only code can be made more useful by accessing the current kunit
82test, see below.
83
84Accessing the current test
85--------------------------
86
87In some cases, you need to call test-only code from outside the test file, e.g.
88like in the example above or if you're providing a fake implementation of an
89ops struct.
90There is a ``kunit_test`` field in ``task_struct``, so you can access it via
91``current->kunit_test``.
92
93Here's a slightly in-depth example of how one could implement "mocking":
94
95.. code-block:: c
96
97	#include <linux/sched.h> /* for current */
98
99	struct test_data {
100		int foo_result;
101		int want_foo_called_with;
102	};
103
104	static int fake_foo(int arg)
105	{
106		struct kunit *test = current->kunit_test;
107		struct test_data *test_data = test->priv;
108
109		KUNIT_EXPECT_EQ(test, test_data->want_foo_called_with, arg);
110		return test_data->foo_result;
111	}
112
113	static void example_simple_test(struct kunit *test)
114	{
115		/* Assume priv is allocated in the suite's .init */
116		struct test_data *test_data = test->priv;
117
118		test_data->foo_result = 42;
119		test_data->want_foo_called_with = 1;
120
121		/* In a real test, we'd probably pass a pointer to fake_foo somewhere
122		 * like an ops struct, etc. instead of calling it directly. */
123		KUNIT_EXPECT_EQ(test, fake_foo(1), 42);
124	}
125
126
127Note: here we're able to get away with using ``test->priv``, but if you wanted
128something more flexible you could use a named ``kunit_resource``, see
129Documentation/dev-tools/kunit/api/test.rst.
130
131Failing the current test
132------------------------
133
134But sometimes, you might just want to fail the current test. In that case, we
135have ``kunit_fail_current_test(fmt, args...)`` which is defined in ``<kunit/test-bug.h>`` and
136doesn't require pulling in ``<kunit/test.h>``.
137
138E.g. say we had an option to enable some extra debug checks on some data structure:
139
140.. code-block:: c
141
142	#include <kunit/test-bug.h>
143
144	#ifdef CONFIG_EXTRA_DEBUG_CHECKS
145	static void validate_my_data(struct data *data)
146	{
147		if (is_valid(data))
148			return;
149
150		kunit_fail_current_test("data %p is invalid", data);
151
152		/* Normal, non-KUnit, error reporting code here. */
153	}
154	#else
155	static void my_debug_function(void) { }
156	#endif
157
158
159Customizing error messages
160--------------------------
161
162Each of the ``KUNIT_EXPECT`` and ``KUNIT_ASSERT`` macros have a ``_MSG`` variant.
163These take a format string and arguments to provide additional context to the automatically generated error messages.
164
165.. code-block:: c
166
167	char some_str[41];
168	generate_sha1_hex_string(some_str);
169
170	/* Before. Not easy to tell why the test failed. */
171	KUNIT_EXPECT_EQ(test, strlen(some_str), 40);
172
173	/* After. Now we see the offending string. */
174	KUNIT_EXPECT_EQ_MSG(test, strlen(some_str), 40, "some_str='%s'", some_str);
175
176Alternatively, one can take full control over the error message by using ``KUNIT_FAIL()``, e.g.
177
178.. code-block:: c
179
180	/* Before */
181	KUNIT_EXPECT_EQ(test, some_setup_function(), 0);
182
183	/* After: full control over the failure message. */
184	if (some_setup_function())
185		KUNIT_FAIL(test, "Failed to setup thing for testing");
186
187Next Steps
188==========
189*   Optional: see the Documentation/dev-tools/kunit/usage.rst page for a more
190    in-depth explanation of KUnit.
191