Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 
0003 ============================
0004 Tips For Writing KUnit Tests
0005 ============================
0006 
0007 Exiting early on failed expectations
0008 ------------------------------------
0009 
0010 ``KUNIT_EXPECT_EQ`` and friends will mark the test as failed and continue
0011 execution.  In some cases, it's unsafe to continue and you can use the
0012 ``KUNIT_ASSERT`` variant to exit on failure.
0013 
0014 .. code-block:: c
0015 
0016         void example_test_user_alloc_function(struct kunit *test)
0017         {
0018                 void *object = alloc_some_object_for_me();
0019 
0020                 /* Make sure we got a valid pointer back. */
0021                 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, object);
0022                 do_something_with_object(object);
0023         }
0024 
0025 Allocating memory
0026 -----------------
0027 
0028 Where you would use ``kzalloc``, you should prefer ``kunit_kzalloc`` instead.
0029 KUnit will ensure the memory is freed once the test completes.
0030 
0031 This is particularly useful since it lets you use the ``KUNIT_ASSERT_EQ``
0032 macros to exit early from a test without having to worry about remembering to
0033 call ``kfree``.
0034 
0035 Example:
0036 
0037 .. code-block:: c
0038 
0039         void example_test_allocation(struct kunit *test)
0040         {
0041                 char *buffer = kunit_kzalloc(test, 16, GFP_KERNEL);
0042                 /* Ensure allocation succeeded. */
0043                 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer);
0044 
0045                 KUNIT_ASSERT_STREQ(test, buffer, "");
0046         }
0047 
0048 
0049 Testing static functions
0050 ------------------------
0051 
0052 If you don't want to expose functions or variables just for testing, one option
0053 is to conditionally ``#include`` the test file at the end of your .c file, e.g.
0054 
0055 .. code-block:: c
0056 
0057         /* In my_file.c */
0058 
0059         static int do_interesting_thing();
0060 
0061         #ifdef CONFIG_MY_KUNIT_TEST
0062         #include "my_kunit_test.c"
0063         #endif
0064 
0065 Injecting test-only code
0066 ------------------------
0067 
0068 Similarly to the above, it can be useful to add test-specific logic.
0069 
0070 .. code-block:: c
0071 
0072         /* In my_file.h */
0073 
0074         #ifdef CONFIG_MY_KUNIT_TEST
0075         /* Defined in my_kunit_test.c */
0076         void test_only_hook(void);
0077         #else
0078         void test_only_hook(void) { }
0079         #endif
0080 
0081 This test-only code can be made more useful by accessing the current kunit
0082 test, see below.
0083 
0084 Accessing the current test
0085 --------------------------
0086 
0087 In some cases, you need to call test-only code from outside the test file, e.g.
0088 like in the example above or if you're providing a fake implementation of an
0089 ops struct.
0090 There is a ``kunit_test`` field in ``task_struct``, so you can access it via
0091 ``current->kunit_test``.
0092 
0093 Here's a slightly in-depth example of how one could implement "mocking":
0094 
0095 .. code-block:: c
0096 
0097         #include <linux/sched.h> /* for current */
0098 
0099         struct test_data {
0100                 int foo_result;
0101                 int want_foo_called_with;
0102         };
0103 
0104         static int fake_foo(int arg)
0105         {
0106                 struct kunit *test = current->kunit_test;
0107                 struct test_data *test_data = test->priv;
0108 
0109                 KUNIT_EXPECT_EQ(test, test_data->want_foo_called_with, arg);
0110                 return test_data->foo_result;
0111         }
0112 
0113         static void example_simple_test(struct kunit *test)
0114         {
0115                 /* Assume priv is allocated in the suite's .init */
0116                 struct test_data *test_data = test->priv;
0117 
0118                 test_data->foo_result = 42;
0119                 test_data->want_foo_called_with = 1;
0120 
0121                 /* In a real test, we'd probably pass a pointer to fake_foo somewhere
0122                  * like an ops struct, etc. instead of calling it directly. */
0123                 KUNIT_EXPECT_EQ(test, fake_foo(1), 42);
0124         }
0125 
0126 
0127 Note: here we're able to get away with using ``test->priv``, but if you wanted
0128 something more flexible you could use a named ``kunit_resource``, see
0129 Documentation/dev-tools/kunit/api/test.rst.
0130 
0131 Failing the current test
0132 ------------------------
0133 
0134 But sometimes, you might just want to fail the current test. In that case, we
0135 have ``kunit_fail_current_test(fmt, args...)`` which is defined in ``<kunit/test-bug.h>`` and
0136 doesn't require pulling in ``<kunit/test.h>``.
0137 
0138 E.g. say we had an option to enable some extra debug checks on some data structure:
0139 
0140 .. code-block:: c
0141 
0142         #include <kunit/test-bug.h>
0143 
0144         #ifdef CONFIG_EXTRA_DEBUG_CHECKS
0145         static void validate_my_data(struct data *data)
0146         {
0147                 if (is_valid(data))
0148                         return;
0149 
0150                 kunit_fail_current_test("data %p is invalid", data);
0151 
0152                 /* Normal, non-KUnit, error reporting code here. */
0153         }
0154         #else
0155         static void my_debug_function(void) { }
0156         #endif
0157 
0158 
0159 Customizing error messages
0160 --------------------------
0161 
0162 Each of the ``KUNIT_EXPECT`` and ``KUNIT_ASSERT`` macros have a ``_MSG`` variant.
0163 These take a format string and arguments to provide additional context to the automatically generated error messages.
0164 
0165 .. code-block:: c
0166 
0167         char some_str[41];
0168         generate_sha1_hex_string(some_str);
0169 
0170         /* Before. Not easy to tell why the test failed. */
0171         KUNIT_EXPECT_EQ(test, strlen(some_str), 40);
0172 
0173         /* After. Now we see the offending string. */
0174         KUNIT_EXPECT_EQ_MSG(test, strlen(some_str), 40, "some_str='%s'", some_str);
0175 
0176 Alternatively, one can take full control over the error message by using ``KUNIT_FAIL()``, e.g.
0177 
0178 .. code-block:: c
0179 
0180         /* Before */
0181         KUNIT_EXPECT_EQ(test, some_setup_function(), 0);
0182 
0183         /* After: full control over the failure message. */
0184         if (some_setup_function())
0185                 KUNIT_FAIL(test, "Failed to setup thing for testing");
0186 
0187 Next Steps
0188 ==========
0189 *   Optional: see the Documentation/dev-tools/kunit/usage.rst page for a more
0190     in-depth explanation of KUnit.