tips.rst 5.0 KB

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