assert.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Assertion and expectation serialization API.
  4. *
  5. * Copyright (C) 2019, Google LLC.
  6. * Author: Brendan Higgins <brendanhiggins@google.com>
  7. */
  8. #include <kunit/assert.h>
  9. #include <kunit/test.h>
  10. #include <kunit/visibility.h>
  11. #include "string-stream.h"
  12. void kunit_assert_prologue(const struct kunit_loc *loc,
  13. enum kunit_assert_type type,
  14. struct string_stream *stream)
  15. {
  16. const char *expect_or_assert = NULL;
  17. switch (type) {
  18. case KUNIT_EXPECTATION:
  19. expect_or_assert = "EXPECTATION";
  20. break;
  21. case KUNIT_ASSERTION:
  22. expect_or_assert = "ASSERTION";
  23. break;
  24. }
  25. string_stream_add(stream, "%s FAILED at %s:%d\n",
  26. expect_or_assert, loc->file, loc->line);
  27. }
  28. EXPORT_SYMBOL_GPL(kunit_assert_prologue);
  29. VISIBLE_IF_KUNIT
  30. void kunit_assert_print_msg(const struct va_format *message,
  31. struct string_stream *stream)
  32. {
  33. if (message->fmt)
  34. string_stream_add(stream, "\n%pV", message);
  35. }
  36. void kunit_fail_assert_format(const struct kunit_assert *assert,
  37. const struct va_format *message,
  38. struct string_stream *stream)
  39. {
  40. string_stream_add(stream, "%pV", message);
  41. }
  42. EXPORT_SYMBOL_GPL(kunit_fail_assert_format);
  43. void kunit_unary_assert_format(const struct kunit_assert *assert,
  44. const struct va_format *message,
  45. struct string_stream *stream)
  46. {
  47. const struct kunit_unary_assert *unary_assert;
  48. unary_assert = container_of(assert, struct kunit_unary_assert, assert);
  49. if (unary_assert->expected_true)
  50. string_stream_add(stream,
  51. KUNIT_SUBTEST_INDENT "Expected %s to be true, but is false\n",
  52. unary_assert->condition);
  53. else
  54. string_stream_add(stream,
  55. KUNIT_SUBTEST_INDENT "Expected %s to be false, but is true\n",
  56. unary_assert->condition);
  57. kunit_assert_print_msg(message, stream);
  58. }
  59. EXPORT_SYMBOL_GPL(kunit_unary_assert_format);
  60. void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
  61. const struct va_format *message,
  62. struct string_stream *stream)
  63. {
  64. const struct kunit_ptr_not_err_assert *ptr_assert;
  65. ptr_assert = container_of(assert, struct kunit_ptr_not_err_assert,
  66. assert);
  67. if (!ptr_assert->value) {
  68. string_stream_add(stream,
  69. KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n",
  70. ptr_assert->text);
  71. } else if (IS_ERR(ptr_assert->value)) {
  72. string_stream_add(stream,
  73. KUNIT_SUBTEST_INDENT "Expected %s is not error, but is: %ld\n",
  74. ptr_assert->text,
  75. PTR_ERR(ptr_assert->value));
  76. }
  77. kunit_assert_print_msg(message, stream);
  78. }
  79. EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format);
  80. /* Checks if `text` is a literal representing `value`, e.g. "5" and 5 */
  81. VISIBLE_IF_KUNIT bool is_literal(const char *text, long long value)
  82. {
  83. char *buffer;
  84. int len;
  85. bool ret;
  86. len = snprintf(NULL, 0, "%lld", value);
  87. if (strlen(text) != len)
  88. return false;
  89. buffer = kmalloc(len+1, GFP_KERNEL);
  90. if (!buffer)
  91. return false;
  92. snprintf(buffer, len+1, "%lld", value);
  93. ret = strncmp(buffer, text, len) == 0;
  94. kfree(buffer);
  95. return ret;
  96. }
  97. void kunit_binary_assert_format(const struct kunit_assert *assert,
  98. const struct va_format *message,
  99. struct string_stream *stream)
  100. {
  101. const struct kunit_binary_assert *binary_assert;
  102. binary_assert = container_of(assert, struct kunit_binary_assert,
  103. assert);
  104. string_stream_add(stream,
  105. KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
  106. binary_assert->text->left_text,
  107. binary_assert->text->operation,
  108. binary_assert->text->right_text);
  109. if (!is_literal(binary_assert->text->left_text, binary_assert->left_value))
  110. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)\n",
  111. binary_assert->text->left_text,
  112. binary_assert->left_value,
  113. binary_assert->left_value);
  114. if (!is_literal(binary_assert->text->right_text, binary_assert->right_value))
  115. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)",
  116. binary_assert->text->right_text,
  117. binary_assert->right_value,
  118. binary_assert->right_value);
  119. kunit_assert_print_msg(message, stream);
  120. }
  121. EXPORT_SYMBOL_GPL(kunit_binary_assert_format);
  122. void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
  123. const struct va_format *message,
  124. struct string_stream *stream)
  125. {
  126. const struct kunit_binary_ptr_assert *binary_assert;
  127. binary_assert = container_of(assert, struct kunit_binary_ptr_assert,
  128. assert);
  129. string_stream_add(stream,
  130. KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
  131. binary_assert->text->left_text,
  132. binary_assert->text->operation,
  133. binary_assert->text->right_text);
  134. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px\n",
  135. binary_assert->text->left_text,
  136. binary_assert->left_value);
  137. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px",
  138. binary_assert->text->right_text,
  139. binary_assert->right_value);
  140. kunit_assert_print_msg(message, stream);
  141. }
  142. EXPORT_SYMBOL_GPL(kunit_binary_ptr_assert_format);
  143. /* Checks if KUNIT_EXPECT_STREQ() args were string literals.
  144. * Note: `text` will have ""s where as `value` will not.
  145. */
  146. VISIBLE_IF_KUNIT bool is_str_literal(const char *text, const char *value)
  147. {
  148. int len;
  149. len = strlen(text);
  150. if (len < 2)
  151. return false;
  152. if (text[0] != '\"' || text[len - 1] != '\"')
  153. return false;
  154. return strncmp(text + 1, value, len - 2) == 0;
  155. }
  156. void kunit_binary_str_assert_format(const struct kunit_assert *assert,
  157. const struct va_format *message,
  158. struct string_stream *stream)
  159. {
  160. const struct kunit_binary_str_assert *binary_assert;
  161. binary_assert = container_of(assert, struct kunit_binary_str_assert,
  162. assert);
  163. string_stream_add(stream,
  164. KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
  165. binary_assert->text->left_text,
  166. binary_assert->text->operation,
  167. binary_assert->text->right_text);
  168. if (!is_str_literal(binary_assert->text->left_text, binary_assert->left_value))
  169. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"\n",
  170. binary_assert->text->left_text,
  171. binary_assert->left_value);
  172. if (!is_str_literal(binary_assert->text->right_text, binary_assert->right_value))
  173. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"",
  174. binary_assert->text->right_text,
  175. binary_assert->right_value);
  176. kunit_assert_print_msg(message, stream);
  177. }
  178. EXPORT_SYMBOL_GPL(kunit_binary_str_assert_format);
  179. /* Adds a hexdump of a buffer to a string_stream comparing it with
  180. * a second buffer. The different bytes are marked with <>.
  181. */
  182. VISIBLE_IF_KUNIT
  183. void kunit_assert_hexdump(struct string_stream *stream,
  184. const void *buf,
  185. const void *compared_buf,
  186. const size_t len)
  187. {
  188. size_t i;
  189. const u8 *buf1 = buf;
  190. const u8 *buf2 = compared_buf;
  191. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT);
  192. for (i = 0; i < len; ++i) {
  193. if (!(i % 16) && i)
  194. string_stream_add(stream, "\n" KUNIT_SUBSUBTEST_INDENT);
  195. if (buf1[i] != buf2[i])
  196. string_stream_add(stream, "<%02x>", buf1[i]);
  197. else
  198. string_stream_add(stream, " %02x ", buf1[i]);
  199. }
  200. }
  201. void kunit_mem_assert_format(const struct kunit_assert *assert,
  202. const struct va_format *message,
  203. struct string_stream *stream)
  204. {
  205. const struct kunit_mem_assert *mem_assert;
  206. mem_assert = container_of(assert, struct kunit_mem_assert,
  207. assert);
  208. if (!mem_assert->left_value) {
  209. string_stream_add(stream,
  210. KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n",
  211. mem_assert->text->left_text);
  212. } else if (!mem_assert->right_value) {
  213. string_stream_add(stream,
  214. KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n",
  215. mem_assert->text->right_text);
  216. } else {
  217. string_stream_add(stream,
  218. KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
  219. mem_assert->text->left_text,
  220. mem_assert->text->operation,
  221. mem_assert->text->right_text);
  222. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s ==\n",
  223. mem_assert->text->left_text);
  224. kunit_assert_hexdump(stream, mem_assert->left_value,
  225. mem_assert->right_value, mem_assert->size);
  226. string_stream_add(stream, "\n");
  227. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s ==\n",
  228. mem_assert->text->right_text);
  229. kunit_assert_hexdump(stream, mem_assert->right_value,
  230. mem_assert->left_value, mem_assert->size);
  231. kunit_assert_print_msg(message, stream);
  232. }
  233. }
  234. EXPORT_SYMBOL_GPL(kunit_mem_assert_format);