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