1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * KUnit test for the assertion formatting functions. 4 * Author: Ivan Orlov <ivan.orlov0322@gmail.com> 5 */ 6 #include <kunit/test.h> 7 #include "string-stream.h" 8 9 #define TEST_PTR_EXPECTED_BUF_SIZE 32 10 #define HEXDUMP_TEST_BUF_LEN 5 11 #define ASSERT_TEST_EXPECT_CONTAIN(test, str, substr) KUNIT_EXPECT_TRUE(test, strstr(str, substr)) 12 #define ASSERT_TEST_EXPECT_NCONTAIN(test, str, substr) KUNIT_EXPECT_FALSE(test, strstr(str, substr)) 13 14 static void kunit_test_is_literal(struct kunit *test) 15 { 16 KUNIT_EXPECT_TRUE(test, is_literal("5", 5)); 17 KUNIT_EXPECT_TRUE(test, is_literal("", 0)); 18 KUNIT_EXPECT_TRUE(test, is_literal("1234567890", 1234567890)); 19 KUNIT_EXPECT_TRUE(test, is_literal("-1234567890", -1234567890)); 20 KUNIT_EXPECT_FALSE(test, is_literal("05", 5)); 21 KUNIT_EXPECT_FALSE(test, is_literal("", 0)); 22 KUNIT_EXPECT_FALSE(test, is_literal("-0", 0)); 23 KUNIT_EXPECT_FALSE(test, is_literal("12#45", 1245)); 24 } 25 26 static void kunit_test_is_str_literal(struct kunit *test) 27 { 28 KUNIT_EXPECT_TRUE(test, is_str_literal("\"Hello, World!\"", "Hello, World!")); 29 KUNIT_EXPECT_TRUE(test, is_str_literal("\"\"", "")); 30 KUNIT_EXPECT_TRUE(test, is_str_literal("\"\"\"", "\"")); 31 KUNIT_EXPECT_FALSE(test, is_str_literal("", "")); 32 KUNIT_EXPECT_FALSE(test, is_str_literal("\"", "\"")); 33 KUNIT_EXPECT_FALSE(test, is_str_literal("\"Abacaba", "Abacaba")); 34 KUNIT_EXPECT_FALSE(test, is_str_literal("Abacaba\"", "Abacaba")); 35 KUNIT_EXPECT_FALSE(test, is_str_literal("\"Abacaba\"", "\"Abacaba\"")); 36 } 37 38 KUNIT_DEFINE_ACTION_WRAPPER(kfree_wrapper, kfree, const void *); 39 40 /* this function is used to get a "char *" string from the string stream and defer its cleanup */ 41 static char *get_str_from_stream(struct kunit *test, struct string_stream *stream) 42 { 43 char *str = string_stream_get_string(stream); 44 45 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, str); 46 kunit_add_action(test, kfree_wrapper, (void *)str); 47 48 return str; 49 } 50 51 static void kunit_test_assert_prologue(struct kunit *test) 52 { 53 struct string_stream *stream; 54 char *str; 55 const struct kunit_loc location = { 56 .file = "testfile.c", 57 .line = 1337, 58 }; 59 60 stream = kunit_alloc_string_stream(test, GFP_KERNEL); 61 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream); 62 63 /* Test an expectation fail prologue */ 64 kunit_assert_prologue(&location, KUNIT_EXPECTATION, stream); 65 str = get_str_from_stream(test, stream); 66 ASSERT_TEST_EXPECT_CONTAIN(test, str, "EXPECTATION"); 67 ASSERT_TEST_EXPECT_CONTAIN(test, str, "testfile.c"); 68 ASSERT_TEST_EXPECT_CONTAIN(test, str, "1337"); 69 70 /* Test an assertion fail prologue */ 71 string_stream_clear(stream); 72 kunit_assert_prologue(&location, KUNIT_ASSERTION, stream); 73 str = get_str_from_stream(test, stream); 74 ASSERT_TEST_EXPECT_CONTAIN(test, str, "ASSERTION"); 75 ASSERT_TEST_EXPECT_CONTAIN(test, str, "testfile.c"); 76 ASSERT_TEST_EXPECT_CONTAIN(test, str, "1337"); 77 } 78 79 /* 80 * This function accepts an arbitrary count of parameters and generates a va_format struct, 81 * which can be used to validate kunit_assert_print_msg function 82 */ 83 static void verify_assert_print_msg(struct kunit *test, 84 struct string_stream *stream, 85 char *expected, const char *format, ...) 86 { 87 va_list list; 88 const struct va_format vformat = { 89 .fmt = format, 90 .va = &list, 91 }; 92 93 va_start(list, format); 94 string_stream_clear(stream); 95 kunit_assert_print_msg(&vformat, stream); 96 KUNIT_EXPECT_STREQ(test, get_str_from_stream(test, stream), expected); 97 } 98 99 static void kunit_test_assert_print_msg(struct kunit *test) 100 { 101 struct string_stream *stream; 102 103 stream = kunit_alloc_string_stream(test, GFP_KERNEL); 104 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream); 105 106 verify_assert_print_msg(test, stream, "\nTest", "Test"); 107 verify_assert_print_msg(test, stream, "\nAbacaba -123 234", "%s %d %u", 108 "Abacaba", -123, 234U); 109 verify_assert_print_msg(test, stream, "", NULL); 110 } 111 112 /* 113 * Further code contains the tests for different assert format functions. 114 * This helper function accepts the assert format function, executes it and 115 * validates the result string from the stream by checking that all of the 116 * substrings exist in the output. 117 */ 118 static void validate_assert(assert_format_t format_func, struct kunit *test, 119 const struct kunit_assert *assert, 120 struct string_stream *stream, int num_checks, ...) 121 { 122 size_t i; 123 va_list checks; 124 char *cur_substr_exp; 125 struct va_format message = { NULL, NULL }; 126 127 va_start(checks, num_checks); 128 string_stream_clear(stream); 129 format_func(assert, &message, stream); 130 131 for (i = 0; i < num_checks; i++) { 132 cur_substr_exp = va_arg(checks, char *); 133 ASSERT_TEST_EXPECT_CONTAIN(test, get_str_from_stream(test, stream), cur_substr_exp); 134 } 135 } 136 137 static void kunit_test_unary_assert_format(struct kunit *test) 138 { 139 struct string_stream *stream; 140 struct kunit_assert assert = {}; 141 struct kunit_unary_assert un_assert = { 142 .assert = assert, 143 .condition = "expr", 144 .expected_true = true, 145 }; 146 147 stream = kunit_alloc_string_stream(test, GFP_KERNEL); 148 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream); 149 150 validate_assert(kunit_unary_assert_format, test, &un_assert.assert, 151 stream, 2, "true", "is false"); 152 153 un_assert.expected_true = false; 154 validate_assert(kunit_unary_assert_format, test, &un_assert.assert, 155 stream, 2, "false", "is true"); 156 } 157 158 static void kunit_test_ptr_not_err_assert_format(struct kunit *test) 159 { 160 struct string_stream *stream; 161 struct kunit_assert assert = {}; 162 struct kunit_ptr_not_err_assert not_err_assert = { 163 .assert = assert, 164 .text = "expr", 165 .value = NULL, 166 }; 167 168 stream = kunit_alloc_string_stream(test, GFP_KERNEL); 169 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream); 170 171 /* Value is NULL. The corresponding message should be printed out */ 172 validate_assert(kunit_ptr_not_err_assert_format, test, 173 ¬_err_assert.assert, 174 stream, 1, "null"); 175 176 /* Value is not NULL, but looks like an error pointer. Error should be printed out */ 177 not_err_assert.value = (void *)-12; 178 validate_assert(kunit_ptr_not_err_assert_format, test, 179 ¬_err_assert.assert, stream, 2, 180 "error", "-12"); 181 } 182 183 static void kunit_test_binary_assert_format(struct kunit *test) 184 { 185 struct string_stream *stream; 186 struct kunit_assert assert = {}; 187 struct kunit_binary_assert_text text = { 188 .left_text = "1 + 2", 189 .operation = "==", 190 .right_text = "2", 191 }; 192 const struct kunit_binary_assert binary_assert = { 193 .assert = assert, 194 .text = &text, 195 .left_value = 3, 196 .right_value = 2, 197 }; 198 199 stream = kunit_alloc_string_stream(test, GFP_KERNEL); 200 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream); 201 202 /* 203 * Printed values should depend on the input we provide: the left text, right text, left 204 * value and the right value. 205 */ 206 validate_assert(kunit_binary_assert_format, test, &binary_assert.assert, 207 stream, 4, "1 + 2", "2", "3", "=="); 208 209 text.right_text = "4 - 2"; 210 validate_assert(kunit_binary_assert_format, test, &binary_assert.assert, 211 stream, 3, "==", "1 + 2", "4 - 2"); 212 213 text.left_text = "3"; 214 validate_assert(kunit_binary_assert_format, test, &binary_assert.assert, 215 stream, 4, "3", "4 - 2", "2", "=="); 216 217 text.right_text = "2"; 218 validate_assert(kunit_binary_assert_format, test, &binary_assert.assert, 219 stream, 3, "3", "2", "=="); 220 } 221 222 static void kunit_test_binary_ptr_assert_format(struct kunit *test) 223 { 224 struct string_stream *stream; 225 struct kunit_assert assert = {}; 226 char *addr_var_a, *addr_var_b; 227 static const void *var_a = (void *)0xDEADBEEF; 228 static const void *var_b = (void *)0xBADDCAFE; 229 struct kunit_binary_assert_text text = { 230 .left_text = "var_a", 231 .operation = "==", 232 .right_text = "var_b", 233 }; 234 struct kunit_binary_ptr_assert binary_ptr_assert = { 235 .assert = assert, 236 .text = &text, 237 .left_value = var_a, 238 .right_value = var_b, 239 }; 240 241 addr_var_a = kunit_kzalloc(test, TEST_PTR_EXPECTED_BUF_SIZE, GFP_KERNEL); 242 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, addr_var_a); 243 addr_var_b = kunit_kzalloc(test, TEST_PTR_EXPECTED_BUF_SIZE, GFP_KERNEL); 244 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, addr_var_b); 245 /* 246 * Print the addresses to the buffers first. 247 * This is necessary as we may have different count of leading zeros in the pointer 248 * on different architectures. 249 */ 250 snprintf(addr_var_a, TEST_PTR_EXPECTED_BUF_SIZE, "%px", var_a); 251 snprintf(addr_var_b, TEST_PTR_EXPECTED_BUF_SIZE, "%px", var_b); 252 253 stream = kunit_alloc_string_stream(test, GFP_KERNEL); 254 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream); 255 validate_assert(kunit_binary_ptr_assert_format, test, &binary_ptr_assert.assert, 256 stream, 3, addr_var_a, addr_var_b, "=="); 257 } 258 259 static void kunit_test_binary_str_assert_format(struct kunit *test) 260 { 261 struct string_stream *stream; 262 struct kunit_assert assert = {}; 263 static const char *var_a = "abacaba"; 264 static const char *var_b = "kernel"; 265 struct kunit_binary_assert_text text = { 266 .left_text = "var_a", 267 .operation = "==", 268 .right_text = "var_b", 269 }; 270 struct kunit_binary_str_assert binary_str_assert = { 271 .assert = assert, 272 .text = &text, 273 .left_value = var_a, 274 .right_value = var_b, 275 }; 276 277 stream = kunit_alloc_string_stream(test, GFP_KERNEL); 278 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream); 279 280 validate_assert(kunit_binary_str_assert_format, test, 281 &binary_str_assert.assert, 282 stream, 5, "var_a", "var_b", "\"abacaba\"", 283 "\"kernel\"", "=="); 284 285 text.left_text = "\"abacaba\""; 286 validate_assert(kunit_binary_str_assert_format, test, &binary_str_assert.assert, 287 stream, 4, "\"abacaba\"", "var_b", "\"kernel\"", "=="); 288 289 text.right_text = "\"kernel\""; 290 validate_assert(kunit_binary_str_assert_format, test, &binary_str_assert.assert, 291 stream, 3, "\"abacaba\"", "\"kernel\"", "=="); 292 } 293 294 static const u8 hex_testbuf1[] = { 0x26, 0x74, 0x6b, 0x9c, 0x55, 295 0x45, 0x9d, 0x47, 0xd6, 0x47, 296 0x2, 0x89, 0x8c, 0x81, 0x94, 297 0x12, 0xfe, 0x01 }; 298 static const u8 hex_testbuf2[] = { 0x26, 0x74, 0x6b, 0x9c, 0x55, 299 0x45, 0x9d, 0x47, 0x21, 0x47, 300 0xcd, 0x89, 0x24, 0x50, 0x94, 301 0x12, 0xba, 0x01 }; 302 static void kunit_test_assert_hexdump(struct kunit *test) 303 { 304 struct string_stream *stream; 305 char *str; 306 size_t i; 307 char buf[HEXDUMP_TEST_BUF_LEN]; 308 309 stream = kunit_alloc_string_stream(test, GFP_KERNEL); 310 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream); 311 /* Check that we are getting output like <xx> for non-matching numbers. */ 312 kunit_assert_hexdump(stream, hex_testbuf1, hex_testbuf2, sizeof(hex_testbuf1)); 313 str = get_str_from_stream(test, stream); 314 for (i = 0; i < sizeof(hex_testbuf1); i++) { 315 snprintf(buf, HEXDUMP_TEST_BUF_LEN, "<%02x>", hex_testbuf1[i]); 316 if (hex_testbuf1[i] != hex_testbuf2[i]) 317 ASSERT_TEST_EXPECT_CONTAIN(test, str, buf); 318 } 319 /* We shouldn't get any <xx> numbers when comparing the buffer with itself. */ 320 string_stream_clear(stream); 321 kunit_assert_hexdump(stream, hex_testbuf1, hex_testbuf1, sizeof(hex_testbuf1)); 322 str = get_str_from_stream(test, stream); 323 ASSERT_TEST_EXPECT_NCONTAIN(test, str, "<"); 324 ASSERT_TEST_EXPECT_NCONTAIN(test, str, ">"); 325 } 326 327 static void kunit_test_mem_assert_format(struct kunit *test) 328 { 329 struct string_stream *stream; 330 struct string_stream *expected_stream; 331 struct kunit_assert assert = {}; 332 static const struct kunit_binary_assert_text text = { 333 .left_text = "hex_testbuf1", 334 .operation = "==", 335 .right_text = "hex_testbuf2", 336 }; 337 struct kunit_mem_assert mem_assert = { 338 .assert = assert, 339 .text = &text, 340 .left_value = NULL, 341 .right_value = hex_testbuf2, 342 .size = sizeof(hex_testbuf1), 343 }; 344 345 expected_stream = kunit_alloc_string_stream(test, GFP_KERNEL); 346 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected_stream); 347 stream = kunit_alloc_string_stream(test, GFP_KERNEL); 348 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream); 349 350 /* The left value is NULL */ 351 validate_assert(kunit_mem_assert_format, test, &mem_assert.assert, 352 stream, 2, "hex_testbuf1", "is not null"); 353 354 /* The right value is NULL, the left value is not NULL */ 355 mem_assert.left_value = hex_testbuf1; 356 mem_assert.right_value = NULL; 357 validate_assert(kunit_mem_assert_format, test, &mem_assert.assert, 358 stream, 2, "hex_testbuf2", "is not null"); 359 360 /* Both arguments are not null */ 361 mem_assert.left_value = hex_testbuf1; 362 mem_assert.right_value = hex_testbuf2; 363 364 validate_assert(kunit_mem_assert_format, test, &mem_assert.assert, 365 stream, 3, "hex_testbuf1", "hex_testbuf2", "=="); 366 } 367 368 static struct kunit_case assert_test_cases[] = { 369 KUNIT_CASE(kunit_test_is_literal), 370 KUNIT_CASE(kunit_test_is_str_literal), 371 KUNIT_CASE(kunit_test_assert_prologue), 372 KUNIT_CASE(kunit_test_assert_print_msg), 373 KUNIT_CASE(kunit_test_unary_assert_format), 374 KUNIT_CASE(kunit_test_ptr_not_err_assert_format), 375 KUNIT_CASE(kunit_test_binary_assert_format), 376 KUNIT_CASE(kunit_test_binary_ptr_assert_format), 377 KUNIT_CASE(kunit_test_binary_str_assert_format), 378 KUNIT_CASE(kunit_test_assert_hexdump), 379 KUNIT_CASE(kunit_test_mem_assert_format), 380 {} 381 }; 382 383 static struct kunit_suite assert_test_suite = { 384 .name = "kunit-assert", 385 .test_cases = assert_test_cases, 386 }; 387 388 kunit_test_suites(&assert_test_suite); 389
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.