assert.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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 <[email protected]>
  7. */
  8. #include <kunit/assert.h>
  9. #include <kunit/test.h>
  10. #include "string-stream.h"
  11. void kunit_assert_prologue(const struct kunit_loc *loc,
  12. enum kunit_assert_type type,
  13. struct string_stream *stream)
  14. {
  15. const char *expect_or_assert = NULL;
  16. switch (type) {
  17. case KUNIT_EXPECTATION:
  18. expect_or_assert = "EXPECTATION";
  19. break;
  20. case KUNIT_ASSERTION:
  21. expect_or_assert = "ASSERTION";
  22. break;
  23. }
  24. string_stream_add(stream, "%s FAILED at %s:%d\n",
  25. expect_or_assert, loc->file, loc->line);
  26. }
  27. EXPORT_SYMBOL_GPL(kunit_assert_prologue);
  28. static void kunit_assert_print_msg(const struct va_format *message,
  29. struct string_stream *stream)
  30. {
  31. if (message->fmt)
  32. string_stream_add(stream, "\n%pV", message);
  33. }
  34. void kunit_fail_assert_format(const struct kunit_assert *assert,
  35. const struct va_format *message,
  36. struct string_stream *stream)
  37. {
  38. string_stream_add(stream, "%pV", message);
  39. }
  40. EXPORT_SYMBOL_GPL(kunit_fail_assert_format);
  41. void kunit_unary_assert_format(const struct kunit_assert *assert,
  42. const struct va_format *message,
  43. struct string_stream *stream)
  44. {
  45. struct kunit_unary_assert *unary_assert;
  46. unary_assert = container_of(assert, struct kunit_unary_assert, assert);
  47. if (unary_assert->expected_true)
  48. string_stream_add(stream,
  49. KUNIT_SUBTEST_INDENT "Expected %s to be true, but is false\n",
  50. unary_assert->condition);
  51. else
  52. string_stream_add(stream,
  53. KUNIT_SUBTEST_INDENT "Expected %s to be false, but is true\n",
  54. unary_assert->condition);
  55. kunit_assert_print_msg(message, stream);
  56. }
  57. EXPORT_SYMBOL_GPL(kunit_unary_assert_format);
  58. void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
  59. const struct va_format *message,
  60. struct string_stream *stream)
  61. {
  62. struct kunit_ptr_not_err_assert *ptr_assert;
  63. ptr_assert = container_of(assert, struct kunit_ptr_not_err_assert,
  64. assert);
  65. if (!ptr_assert->value) {
  66. string_stream_add(stream,
  67. KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n",
  68. ptr_assert->text);
  69. } else if (IS_ERR(ptr_assert->value)) {
  70. string_stream_add(stream,
  71. KUNIT_SUBTEST_INDENT "Expected %s is not error, but is: %ld\n",
  72. ptr_assert->text,
  73. PTR_ERR(ptr_assert->value));
  74. }
  75. kunit_assert_print_msg(message, stream);
  76. }
  77. EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format);
  78. /* Checks if `text` is a literal representing `value`, e.g. "5" and 5 */
  79. static bool is_literal(struct kunit *test, const char *text, long long value,
  80. gfp_t gfp)
  81. {
  82. char *buffer;
  83. int len;
  84. bool ret;
  85. len = snprintf(NULL, 0, "%lld", value);
  86. if (strlen(text) != len)
  87. return false;
  88. buffer = kunit_kmalloc(test, len+1, gfp);
  89. if (!buffer)
  90. return false;
  91. snprintf(buffer, len+1, "%lld", value);
  92. ret = strncmp(buffer, text, len) == 0;
  93. kunit_kfree(test, buffer);
  94. return ret;
  95. }
  96. void kunit_binary_assert_format(const struct kunit_assert *assert,
  97. const struct va_format *message,
  98. struct string_stream *stream)
  99. {
  100. struct kunit_binary_assert *binary_assert;
  101. binary_assert = container_of(assert, struct kunit_binary_assert,
  102. assert);
  103. string_stream_add(stream,
  104. KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
  105. binary_assert->text->left_text,
  106. binary_assert->text->operation,
  107. binary_assert->text->right_text);
  108. if (!is_literal(stream->test, binary_assert->text->left_text,
  109. binary_assert->left_value, stream->gfp))
  110. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld\n",
  111. binary_assert->text->left_text,
  112. binary_assert->left_value);
  113. if (!is_literal(stream->test, binary_assert->text->right_text,
  114. binary_assert->right_value, stream->gfp))
  115. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld",
  116. binary_assert->text->right_text,
  117. binary_assert->right_value);
  118. kunit_assert_print_msg(message, stream);
  119. }
  120. EXPORT_SYMBOL_GPL(kunit_binary_assert_format);
  121. void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
  122. const struct va_format *message,
  123. struct string_stream *stream)
  124. {
  125. struct kunit_binary_ptr_assert *binary_assert;
  126. binary_assert = container_of(assert, struct kunit_binary_ptr_assert,
  127. assert);
  128. string_stream_add(stream,
  129. KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
  130. binary_assert->text->left_text,
  131. binary_assert->text->operation,
  132. binary_assert->text->right_text);
  133. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px\n",
  134. binary_assert->text->left_text,
  135. binary_assert->left_value);
  136. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px",
  137. binary_assert->text->right_text,
  138. binary_assert->right_value);
  139. kunit_assert_print_msg(message, stream);
  140. }
  141. EXPORT_SYMBOL_GPL(kunit_binary_ptr_assert_format);
  142. /* Checks if KUNIT_EXPECT_STREQ() args were string literals.
  143. * Note: `text` will have ""s where as `value` will not.
  144. */
  145. static bool is_str_literal(const char *text, const char *value)
  146. {
  147. int len;
  148. len = strlen(text);
  149. if (len < 2)
  150. return false;
  151. if (text[0] != '\"' || text[len - 1] != '\"')
  152. return false;
  153. return strncmp(text + 1, value, len - 2) == 0;
  154. }
  155. void kunit_binary_str_assert_format(const struct kunit_assert *assert,
  156. const struct va_format *message,
  157. struct string_stream *stream)
  158. {
  159. struct kunit_binary_str_assert *binary_assert;
  160. binary_assert = container_of(assert, struct kunit_binary_str_assert,
  161. assert);
  162. string_stream_add(stream,
  163. KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
  164. binary_assert->text->left_text,
  165. binary_assert->text->operation,
  166. binary_assert->text->right_text);
  167. if (!is_str_literal(binary_assert->text->left_text, binary_assert->left_value))
  168. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"\n",
  169. binary_assert->text->left_text,
  170. binary_assert->left_value);
  171. if (!is_str_literal(binary_assert->text->right_text, binary_assert->right_value))
  172. string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"",
  173. binary_assert->text->right_text,
  174. binary_assert->right_value);
  175. kunit_assert_print_msg(message, stream);
  176. }
  177. EXPORT_SYMBOL_GPL(kunit_binary_str_assert_format);