Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scanf: convert self-test to KUnit

Convert the scanf() self-test to a KUnit test.

In the interest of keeping the patch reasonably-sized this doesn't
refactor the tests into proper parameterized tests - it's all one big
test case.

Reviewed-by: David Gow <davidgow@google.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Tested-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Link: https://lore.kernel.org/r/20250307-scanf-kunit-convert-v9-3-b98820fa39ff@gmail.com
Signed-off-by: Kees Cook <kees@kernel.org>

authored by

Tamir Duberstein and committed by
Kees Cook
97c1f302 6340d61b

+134 -141
+1 -1
MAINTAINERS
··· 25411 25411 S: Maintained 25412 25412 T: git git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git 25413 25413 F: Documentation/core-api/printk-formats.rst 25414 - F: lib/test_scanf.c 25415 25414 F: lib/tests/printf_kunit.c 25415 + F: lib/tests/scanf_kunit.c 25416 25416 F: lib/vsprintf.c 25417 25417 25418 25418 VT1211 HARDWARE MONITOR DRIVER
+9 -3
lib/Kconfig.debug
··· 2436 2436 2437 2437 If unsure, say N. 2438 2438 2439 + config SCANF_KUNIT_TEST 2440 + tristate "KUnit test scanf() family of functions at runtime" if !KUNIT_ALL_TESTS 2441 + depends on KUNIT 2442 + default KUNIT_ALL_TESTS 2443 + help 2444 + Enable this option to test the scanf functions at runtime. 2445 + 2446 + If unsure, say N. 2447 + 2439 2448 config STRING_KUNIT_TEST 2440 2449 tristate "KUnit test string functions at runtime" if !KUNIT_ALL_TESTS 2441 2450 depends on KUNIT ··· 2457 2448 2458 2449 config TEST_KSTRTOX 2459 2450 tristate "Test kstrto*() family of functions at runtime" 2460 - 2461 - config TEST_SCANF 2462 - tristate "Test scanf() family of functions at runtime" 2463 2451 2464 2452 config TEST_BITMAP 2465 2453 tristate "Test bitmap_*() family of functions at runtime"
-1
lib/Makefile
··· 77 77 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o 78 78 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o 79 79 obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o 80 - obj-$(CONFIG_TEST_SCANF) += test_scanf.o 81 80 82 81 obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o 83 82 ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_KASAN),yy)
+122 -130
lib/test_scanf.c lib/tests/scanf_kunit.c
··· 3 3 * Test cases for sscanf facility. 4 4 */ 5 5 6 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 - 6 + #include <kunit/test.h> 8 7 #include <linux/bitops.h> 9 - #include <linux/init.h> 10 8 #include <linux/kernel.h> 11 9 #include <linux/module.h> 12 10 #include <linux/overflow.h> 13 - #include <linux/printk.h> 14 11 #include <linux/prandom.h> 15 12 #include <linux/slab.h> 16 13 #include <linux/string.h> 17 14 18 - #include "../tools/testing/selftests/kselftest_module.h" 19 - 20 15 #define BUF_SIZE 1024 21 16 22 - KSTM_MODULE_GLOBALS(); 23 - static char *test_buffer __initdata; 24 - static char *fmt_buffer __initdata; 25 - static struct rnd_state rnd_state __initdata; 17 + static char *test_buffer; 18 + static char *fmt_buffer; 19 + static struct rnd_state rnd_state; 26 20 27 - typedef int (*check_fn)(const char *file, const int line, const void *check_data, 28 - const char *string, const char *fmt, int n_args, va_list ap); 21 + typedef void (*check_fn)(struct kunit *test, const char *file, const int line, 22 + const void *check_data, const char *string, const char *fmt, int n_args, 23 + va_list ap); 29 24 30 - static void __scanf(6, 8) __init 31 - _test(const char *file, const int line, check_fn fn, const void *check_data, const char *string, 32 - const char *fmt, int n_args, ...) 25 + static void __scanf(7, 9) 26 + _test(struct kunit *test, const char *file, const int line, check_fn fn, const void *check_data, 27 + const char *string, const char *fmt, int n_args, ...) 33 28 { 34 29 va_list ap, ap_copy; 35 30 int ret; 36 - 37 - total_tests++; 38 31 39 32 va_start(ap, n_args); 40 33 va_copy(ap_copy, ap); ··· 35 42 va_end(ap_copy); 36 43 37 44 if (ret != n_args) { 38 - pr_warn("%s:%d: vsscanf(\"%s\", \"%s\", ...) returned %d expected %d\n", 39 - file, line, string, fmt, ret, n_args); 40 - goto fail; 45 + KUNIT_FAIL(test, "%s:%d: vsscanf(\"%s\", \"%s\", ...) returned %d expected %d", 46 + file, line, string, fmt, ret, n_args); 47 + } else { 48 + (*fn)(test, file, line, check_data, string, fmt, n_args, ap); 41 49 } 42 50 43 - ret = (*fn)(file, line, check_data, string, fmt, n_args, ap); 44 - if (ret) 45 - goto fail; 46 - 47 - va_end(ap); 48 - 49 - return; 50 - 51 - fail: 52 - failed_tests++; 53 51 va_end(ap); 54 52 } 55 53 ··· 49 65 for (; n_args > 0; n_args--, expect++) { \ 50 66 typeof(*expect) got = *va_arg(ap, typeof(expect)); \ 51 67 if (got != *expect) { \ 52 - pr_warn("%s:%d, vsscanf(\"%s\", \"%s\", ...) expected " arg_fmt " got " arg_fmt "\n", \ 53 - file, line, str, fmt, *expect, got); \ 54 - return 1; \ 68 + KUNIT_FAIL(test, \ 69 + "%s:%d: vsscanf(\"%s\", \"%s\", ...) expected " arg_fmt " got " arg_fmt, \ 70 + file, line, str, fmt, *expect, got); \ 71 + return; \ 55 72 } \ 56 73 } \ 57 - return 0; \ 58 74 } while (0) 59 75 60 - static int __init check_ull(const char *file, const int line, const void *check_data, 61 - const char *string, const char *fmt, int n_args, va_list ap) 76 + static void check_ull(struct kunit *test, const char *file, const int line, const void *check_data, 77 + const char *string, const char *fmt, int n_args, va_list ap) 62 78 { 63 79 const unsigned long long *pval = check_data; 64 80 65 81 _check_numbers_template("%llu", pval, string, fmt, n_args, ap); 66 82 } 67 83 68 - static int __init check_ll(const char *file, const int line, const void *check_data, 69 - const char *string, const char *fmt, int n_args, va_list ap) 84 + static void check_ll(struct kunit *test, const char *file, const int line, const void *check_data, 85 + const char *string, const char *fmt, int n_args, va_list ap) 70 86 { 71 87 const long long *pval = check_data; 72 88 73 89 _check_numbers_template("%lld", pval, string, fmt, n_args, ap); 74 90 } 75 91 76 - static int __init check_ulong(const char *file, const int line, const void *check_data, 77 - const char *string, const char *fmt, int n_args, va_list ap) 92 + static void check_ulong(struct kunit *test, const char *file, const int line, 93 + const void *check_data, const char *string, const char *fmt, int n_args, 94 + va_list ap) 78 95 { 79 96 const unsigned long *pval = check_data; 80 97 81 98 _check_numbers_template("%lu", pval, string, fmt, n_args, ap); 82 99 } 83 100 84 - static int __init check_long(const char *file, const int line, const void *check_data, 85 - const char *string, const char *fmt, int n_args, va_list ap) 101 + static void check_long(struct kunit *test, const char *file, const int line, const void *check_data, 102 + const char *string, const char *fmt, int n_args, va_list ap) 86 103 { 87 104 const long *pval = check_data; 88 105 89 106 _check_numbers_template("%ld", pval, string, fmt, n_args, ap); 90 107 } 91 108 92 - static int __init check_uint(const char *file, const int line, const void *check_data, 93 - const char *string, const char *fmt, int n_args, va_list ap) 109 + static void check_uint(struct kunit *test, const char *file, const int line, const void *check_data, 110 + const char *string, const char *fmt, int n_args, va_list ap) 94 111 { 95 112 const unsigned int *pval = check_data; 96 113 97 114 _check_numbers_template("%u", pval, string, fmt, n_args, ap); 98 115 } 99 116 100 - static int __init check_int(const char *file, const int line, const void *check_data, 101 - const char *string, const char *fmt, int n_args, va_list ap) 117 + static void check_int(struct kunit *test, const char *file, const int line, const void *check_data, 118 + const char *string, const char *fmt, int n_args, va_list ap) 102 119 { 103 120 const int *pval = check_data; 104 121 105 122 _check_numbers_template("%d", pval, string, fmt, n_args, ap); 106 123 } 107 124 108 - static int __init check_ushort(const char *file, const int line, const void *check_data, 109 - const char *string, const char *fmt, int n_args, va_list ap) 125 + static void check_ushort(struct kunit *test, const char *file, const int line, 126 + const void *check_data, const char *string, const char *fmt, int n_args, 127 + va_list ap) 110 128 { 111 129 const unsigned short *pval = check_data; 112 130 113 131 _check_numbers_template("%hu", pval, string, fmt, n_args, ap); 114 132 } 115 133 116 - static int __init check_short(const char *file, const int line, const void *check_data, 117 - const char *string, const char *fmt, int n_args, va_list ap) 134 + static void check_short(struct kunit *test, const char *file, const int line, 135 + const void *check_data, const char *string, const char *fmt, int n_args, 136 + va_list ap) 118 137 { 119 138 const short *pval = check_data; 120 139 121 140 _check_numbers_template("%hd", pval, string, fmt, n_args, ap); 122 141 } 123 142 124 - static int __init check_uchar(const char *file, const int line, const void *check_data, 125 - const char *string, const char *fmt, int n_args, va_list ap) 143 + static void check_uchar(struct kunit *test, const char *file, const int line, 144 + const void *check_data, const char *string, const char *fmt, int n_args, 145 + va_list ap) 126 146 { 127 147 const unsigned char *pval = check_data; 128 148 129 149 _check_numbers_template("%hhu", pval, string, fmt, n_args, ap); 130 150 } 131 151 132 - static int __init check_char(const char *file, const int line, const void *check_data, 133 - const char *string, const char *fmt, int n_args, va_list ap) 152 + static void check_char(struct kunit *test, const char *file, const int line, const void *check_data, 153 + const char *string, const char *fmt, int n_args, va_list ap) 134 154 { 135 155 const signed char *pval = check_data; 136 156 ··· 142 154 } 143 155 144 156 /* Selection of interesting numbers to test, copied from test-kstrtox.c */ 145 - static const unsigned long long numbers[] __initconst = { 157 + static const unsigned long long numbers[] = { 146 158 0x0ULL, 147 159 0x1ULL, 148 160 0x7fULL, ··· 182 194 T result = ~expect_val; /* should be overwritten */ \ 183 195 \ 184 196 snprintf(test_buffer, BUF_SIZE, gen_fmt, expect_val); \ 185 - _test(__FILE__, __LINE__, fn, &expect_val, test_buffer, "%" scan_fmt, 1, &result); \ 197 + _test(test, __FILE__, __LINE__, fn, &expect_val, test_buffer, "%" scan_fmt, 1, &result);\ 186 198 } while (0) 187 199 188 200 #define simple_numbers_loop(T, gen_fmt, scan_fmt, fn) \ ··· 200 212 } \ 201 213 } while (0) 202 214 203 - static void __init numbers_simple(void) 215 + static void numbers_simple(struct kunit *test) 204 216 { 205 217 simple_numbers_loop(unsigned long long, "%llu", "llu", check_ull); 206 218 simple_numbers_loop(long long, "%lld", "lld", check_ll); ··· 253 265 * the raw prandom*() functions (Not mathematically rigorous!!). 254 266 * Variabilty of length and value is more important than perfect randomness. 255 267 */ 256 - static u32 __init next_test_random(u32 max_bits) 268 + static u32 next_test_random(u32 max_bits) 257 269 { 258 270 u32 n_bits = hweight32(prandom_u32_state(&rnd_state)) % (max_bits + 1); 259 271 260 272 return prandom_u32_state(&rnd_state) & GENMASK(n_bits, 0); 261 273 } 262 274 263 - static unsigned long long __init next_test_random_ull(void) 275 + static unsigned long long next_test_random_ull(void) 264 276 { 265 277 u32 rand1 = prandom_u32_state(&rnd_state); 266 278 u32 n_bits = (hweight32(rand1) * 3) % 64; ··· 297 309 * updating buf_pos and returning the number of characters appended. 298 310 * On error buf_pos is not changed and return value is 0. 299 311 */ 300 - static int __init __printf(4, 5) 312 + static int __printf(4, 5) 301 313 append_fmt(char *buf, int *buf_pos, int buf_len, const char *val_fmt, ...) 302 314 { 303 315 va_list ap; ··· 319 331 * Convenience function to append the field delimiter string 320 332 * to both the value string and format string buffers. 321 333 */ 322 - static void __init append_delim(char *str_buf, int *str_buf_pos, int str_buf_len, 334 + static void append_delim(char *str_buf, int *str_buf_pos, int str_buf_len, 323 335 char *fmt_buf, int *fmt_buf_pos, int fmt_buf_len, 324 336 const char *delim_str) 325 337 { ··· 330 342 #define test_array_8(fn, check_data, string, fmt, arr) \ 331 343 do { \ 332 344 BUILD_BUG_ON(ARRAY_SIZE(arr) != 8); \ 333 - _test(__FILE__, __LINE__, fn, check_data, string, fmt, 8, \ 345 + _test(test, __FILE__, __LINE__, fn, check_data, string, fmt, 8, \ 334 346 &(arr)[0], &(arr)[1], &(arr)[2], &(arr)[3], \ 335 347 &(arr)[4], &(arr)[5], &(arr)[6], &(arr)[7]); \ 336 348 } while (0) ··· 384 396 test_array_8(fn, expect, test_buffer, fmt_buffer, result); \ 385 397 } while (0) 386 398 387 - static void __init numbers_list_ll(const char *delim) 399 + static void numbers_list_ll(struct kunit *test, const char *delim) 388 400 { 389 401 numbers_list_8(unsigned long long, "%llu", delim, "llu", check_ull); 390 402 numbers_list_8(long long, "%lld", delim, "lld", check_ll); ··· 394 406 numbers_list_8(long long, "0x%llx", delim, "lli", check_ll); 395 407 } 396 408 397 - static void __init numbers_list_l(const char *delim) 409 + static void numbers_list_l(struct kunit *test, const char *delim) 398 410 { 399 411 numbers_list_8(unsigned long, "%lu", delim, "lu", check_ulong); 400 412 numbers_list_8(long, "%ld", delim, "ld", check_long); ··· 404 416 numbers_list_8(long, "0x%lx", delim, "li", check_long); 405 417 } 406 418 407 - static void __init numbers_list_d(const char *delim) 419 + static void numbers_list_d(struct kunit *test, const char *delim) 408 420 { 409 421 numbers_list_8(unsigned int, "%u", delim, "u", check_uint); 410 422 numbers_list_8(int, "%d", delim, "d", check_int); ··· 414 426 numbers_list_8(int, "0x%x", delim, "i", check_int); 415 427 } 416 428 417 - static void __init numbers_list_h(const char *delim) 429 + static void numbers_list_h(struct kunit *test, const char *delim) 418 430 { 419 431 numbers_list_8(unsigned short, "%hu", delim, "hu", check_ushort); 420 432 numbers_list_8(short, "%hd", delim, "hd", check_short); ··· 424 436 numbers_list_8(short, "0x%hx", delim, "hi", check_short); 425 437 } 426 438 427 - static void __init numbers_list_hh(const char *delim) 439 + static void numbers_list_hh(struct kunit *test, const char *delim) 428 440 { 429 441 numbers_list_8(unsigned char, "%hhu", delim, "hhu", check_uchar); 430 442 numbers_list_8(signed char, "%hhd", delim, "hhd", check_char); ··· 434 446 numbers_list_8(signed char, "0x%hhx", delim, "hhi", check_char); 435 447 } 436 448 437 - static void __init numbers_list(const char *delim) 449 + static void numbers_list(struct kunit *test, const char *delim) 438 450 { 439 - numbers_list_ll(delim); 440 - numbers_list_l(delim); 441 - numbers_list_d(delim); 442 - numbers_list_h(delim); 443 - numbers_list_hh(delim); 451 + numbers_list_ll(test, delim); 452 + numbers_list_l(test, delim); 453 + numbers_list_d(test, delim); 454 + numbers_list_h(test, delim); 455 + numbers_list_hh(test, delim); 444 456 } 445 457 446 - static void __init numbers_list_field_width_ll(const char *delim) 458 + static void numbers_list_field_width_ll(struct kunit *test, const char *delim) 447 459 { 448 460 numbers_list_fix_width(unsigned long long, "%llu", delim, 20, "llu", check_ull); 449 461 numbers_list_fix_width(long long, "%lld", delim, 20, "lld", check_ll); ··· 453 465 numbers_list_fix_width(long long, "0x%llx", delim, 18, "lli", check_ll); 454 466 } 455 467 456 - static void __init numbers_list_field_width_l(const char *delim) 468 + static void numbers_list_field_width_l(struct kunit *test, const char *delim) 457 469 { 458 470 #if BITS_PER_LONG == 64 459 471 numbers_list_fix_width(unsigned long, "%lu", delim, 20, "lu", check_ulong); ··· 472 484 #endif 473 485 } 474 486 475 - static void __init numbers_list_field_width_d(const char *delim) 487 + static void numbers_list_field_width_d(struct kunit *test, const char *delim) 476 488 { 477 489 numbers_list_fix_width(unsigned int, "%u", delim, 10, "u", check_uint); 478 490 numbers_list_fix_width(int, "%d", delim, 11, "d", check_int); ··· 482 494 numbers_list_fix_width(int, "0x%x", delim, 10, "i", check_int); 483 495 } 484 496 485 - static void __init numbers_list_field_width_h(const char *delim) 497 + static void numbers_list_field_width_h(struct kunit *test, const char *delim) 486 498 { 487 499 numbers_list_fix_width(unsigned short, "%hu", delim, 5, "hu", check_ushort); 488 500 numbers_list_fix_width(short, "%hd", delim, 6, "hd", check_short); ··· 492 504 numbers_list_fix_width(short, "0x%hx", delim, 6, "hi", check_short); 493 505 } 494 506 495 - static void __init numbers_list_field_width_hh(const char *delim) 507 + static void numbers_list_field_width_hh(struct kunit *test, const char *delim) 496 508 { 497 509 numbers_list_fix_width(unsigned char, "%hhu", delim, 3, "hhu", check_uchar); 498 510 numbers_list_fix_width(signed char, "%hhd", delim, 4, "hhd", check_char); ··· 506 518 * List of numbers separated by delim. Each field width specifier is the 507 519 * maximum possible digits for the given type and base. 508 520 */ 509 - static void __init numbers_list_field_width_typemax(const char *delim) 521 + static void numbers_list_field_width_typemax(struct kunit *test, const char *delim) 510 522 { 511 - numbers_list_field_width_ll(delim); 512 - numbers_list_field_width_l(delim); 513 - numbers_list_field_width_d(delim); 514 - numbers_list_field_width_h(delim); 515 - numbers_list_field_width_hh(delim); 523 + numbers_list_field_width_ll(test, delim); 524 + numbers_list_field_width_l(test, delim); 525 + numbers_list_field_width_d(test, delim); 526 + numbers_list_field_width_h(test, delim); 527 + numbers_list_field_width_hh(test, delim); 516 528 } 517 529 518 - static void __init numbers_list_field_width_val_ll(const char *delim) 530 + static void numbers_list_field_width_val_ll(struct kunit *test, const char *delim) 519 531 { 520 532 numbers_list_val_width(unsigned long long, "%llu", delim, "llu", check_ull); 521 533 numbers_list_val_width(long long, "%lld", delim, "lld", check_ll); ··· 525 537 numbers_list_val_width(long long, "0x%llx", delim, "lli", check_ll); 526 538 } 527 539 528 - static void __init numbers_list_field_width_val_l(const char *delim) 540 + static void numbers_list_field_width_val_l(struct kunit *test, const char *delim) 529 541 { 530 542 numbers_list_val_width(unsigned long, "%lu", delim, "lu", check_ulong); 531 543 numbers_list_val_width(long, "%ld", delim, "ld", check_long); ··· 535 547 numbers_list_val_width(long, "0x%lx", delim, "li", check_long); 536 548 } 537 549 538 - static void __init numbers_list_field_width_val_d(const char *delim) 550 + static void numbers_list_field_width_val_d(struct kunit *test, const char *delim) 539 551 { 540 552 numbers_list_val_width(unsigned int, "%u", delim, "u", check_uint); 541 553 numbers_list_val_width(int, "%d", delim, "d", check_int); ··· 545 557 numbers_list_val_width(int, "0x%x", delim, "i", check_int); 546 558 } 547 559 548 - static void __init numbers_list_field_width_val_h(const char *delim) 560 + static void numbers_list_field_width_val_h(struct kunit *test, const char *delim) 549 561 { 550 562 numbers_list_val_width(unsigned short, "%hu", delim, "hu", check_ushort); 551 563 numbers_list_val_width(short, "%hd", delim, "hd", check_short); ··· 555 567 numbers_list_val_width(short, "0x%hx", delim, "hi", check_short); 556 568 } 557 569 558 - static void __init numbers_list_field_width_val_hh(const char *delim) 570 + static void numbers_list_field_width_val_hh(struct kunit *test, const char *delim) 559 571 { 560 572 numbers_list_val_width(unsigned char, "%hhu", delim, "hhu", check_uchar); 561 573 numbers_list_val_width(signed char, "%hhd", delim, "hhd", check_char); ··· 569 581 * List of numbers separated by delim. Each field width specifier is the 570 582 * exact length of the corresponding value digits in the string being scanned. 571 583 */ 572 - static void __init numbers_list_field_width_val_width(const char *delim) 584 + static void numbers_list_field_width_val_width(struct kunit *test, const char *delim) 573 585 { 574 - numbers_list_field_width_val_ll(delim); 575 - numbers_list_field_width_val_l(delim); 576 - numbers_list_field_width_val_d(delim); 577 - numbers_list_field_width_val_h(delim); 578 - numbers_list_field_width_val_hh(delim); 586 + numbers_list_field_width_val_ll(test, delim); 587 + numbers_list_field_width_val_l(test, delim); 588 + numbers_list_field_width_val_d(test, delim); 589 + numbers_list_field_width_val_h(test, delim); 590 + numbers_list_field_width_val_hh(test, delim); 579 591 } 580 592 581 593 /* ··· 584 596 * of digits. For example the hex values c0,3,bf01,303 would have a 585 597 * string representation of "c03bf01303" and extracted with "%2x%1x%4x%3x". 586 598 */ 587 - static void __init numbers_slice(void) 599 + static void numbers_slice(struct kunit *test) 588 600 { 589 - numbers_list_field_width_val_width(""); 601 + numbers_list_field_width_val_width(test, ""); 590 602 } 591 603 592 604 #define test_number_prefix(T, str, scan_fmt, expect0, expect1, n_args, fn) \ ··· 594 606 const T expect[2] = { expect0, expect1 }; \ 595 607 T result[2] = { (T)~expect[0], (T)~expect[1] }; \ 596 608 \ 597 - _test(__FILE__, __LINE__, fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]); \ 609 + _test(test, __FILE__, __LINE__, fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]);\ 598 610 } while (0) 599 611 600 612 /* 601 613 * Number prefix is >= field width. 602 614 * Expected behaviour is derived from testing userland sscanf. 603 615 */ 604 - static void __init numbers_prefix_overflow(void) 616 + static void numbers_prefix_overflow(struct kunit *test) 605 617 { 606 618 /* 607 619 * Negative decimal with a field of width 1, should quit scanning ··· 670 682 T got; \ 671 683 char *endp; \ 672 684 int len; \ 673 - bool fail = false; \ 674 685 \ 675 - total_tests++; \ 676 686 len = snprintf(test_buffer, BUF_SIZE, gen_fmt, expect); \ 677 687 got = (fn)(test_buffer, &endp, base); \ 678 688 if (got != (expect)) { \ 679 - fail = true; \ 680 - pr_warn(#fn "(\"%s\", %d): got " gen_fmt " expected " gen_fmt "\n", \ 681 - test_buffer, base, got, expect); \ 689 + KUNIT_FAIL(test, #fn "(\"%s\", %d): got " gen_fmt " expected " gen_fmt, \ 690 + test_buffer, base, got, expect); \ 682 691 } else if (endp != test_buffer + len) { \ 683 - fail = true; \ 684 - pr_warn(#fn "(\"%s\", %d) startp=0x%px got endp=0x%px expected 0x%px\n", \ 685 - test_buffer, base, test_buffer, \ 686 - test_buffer + len, endp); \ 692 + KUNIT_FAIL(test, #fn "(\"%s\", %d) startp=0x%px got endp=0x%px expected 0x%px", \ 693 + test_buffer, base, test_buffer, \ 694 + test_buffer + len, endp); \ 687 695 } \ 688 - \ 689 - if (fail) \ 690 - failed_tests++; \ 691 696 } while (0) 692 697 693 698 #define test_simple_strtoxx(T, fn, gen_fmt, base) \ ··· 696 715 } \ 697 716 } while (0) 698 717 699 - static void __init test_simple_strtoull(void) 718 + static void test_simple_strtoull(struct kunit *test) 700 719 { 701 720 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 10); 702 721 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 0); ··· 705 724 test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 0); 706 725 } 707 726 708 - static void __init test_simple_strtoll(void) 727 + static void test_simple_strtoll(struct kunit *test) 709 728 { 710 729 test_simple_strtoxx(long long, simple_strtoll, "%lld", 10); 711 730 test_simple_strtoxx(long long, simple_strtoll, "%lld", 0); ··· 714 733 test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 0); 715 734 } 716 735 717 - static void __init test_simple_strtoul(void) 736 + static void test_simple_strtoul(struct kunit *test) 718 737 { 719 738 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 10); 720 739 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 0); ··· 723 742 test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 0); 724 743 } 725 744 726 - static void __init test_simple_strtol(void) 745 + static void test_simple_strtol(struct kunit *test) 727 746 { 728 747 test_simple_strtoxx(long, simple_strtol, "%ld", 10); 729 748 test_simple_strtoxx(long, simple_strtol, "%ld", 0); ··· 733 752 } 734 753 735 754 /* Selection of common delimiters/separators between numbers in a string. */ 736 - static const char * const number_delimiters[] __initconst = { 755 + static const char * const number_delimiters[] = { 737 756 " ", ":", ",", "-", "/", 738 757 }; 739 758 740 - static void __init test_numbers(void) 759 + static void test_numbers(struct kunit *test) 741 760 { 742 761 int i; 743 762 744 763 /* String containing only one number. */ 745 - numbers_simple(); 764 + numbers_simple(test); 746 765 747 766 /* String with multiple numbers separated by delimiter. */ 748 767 for (i = 0; i < ARRAY_SIZE(number_delimiters); i++) { 749 - numbers_list(number_delimiters[i]); 768 + numbers_list(test, number_delimiters[i]); 750 769 751 770 /* Field width may be longer than actual field digits. */ 752 - numbers_list_field_width_typemax(number_delimiters[i]); 771 + numbers_list_field_width_typemax(test, number_delimiters[i]); 753 772 754 773 /* Each field width exactly length of actual field digits. */ 755 - numbers_list_field_width_val_width(number_delimiters[i]); 774 + numbers_list_field_width_val_width(test, number_delimiters[i]); 756 775 } 757 776 758 777 /* Slice continuous sequence of digits using field widths. */ 759 - numbers_slice(); 778 + numbers_slice(test); 760 779 761 - numbers_prefix_overflow(); 780 + numbers_prefix_overflow(test); 762 781 } 763 782 764 - static void __init selftest(void) 783 + static void scanf_test(struct kunit *test) 765 784 { 766 785 test_buffer = kmalloc(BUF_SIZE, GFP_KERNEL); 767 786 if (!test_buffer) ··· 775 794 776 795 prandom_seed_state(&rnd_state, 3141592653589793238ULL); 777 796 778 - test_numbers(); 797 + test_numbers(test); 779 798 780 - test_simple_strtoull(); 781 - test_simple_strtoll(); 782 - test_simple_strtoul(); 783 - test_simple_strtol(); 799 + test_simple_strtoull(test); 800 + test_simple_strtoll(test); 801 + test_simple_strtoul(test); 802 + test_simple_strtol(test); 784 803 785 804 kfree(fmt_buffer); 786 805 kfree(test_buffer); 787 806 } 788 807 789 - KSTM_MODULE_LOADERS(test_scanf); 808 + static struct kunit_case scanf_test_cases[] = { 809 + KUNIT_CASE(scanf_test), 810 + {} 811 + }; 812 + 813 + static struct kunit_suite scanf_test_suite = { 814 + .name = "scanf", 815 + .test_cases = scanf_test_cases, 816 + }; 817 + 818 + kunit_test_suite(scanf_test_suite); 819 + 790 820 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); 791 821 MODULE_DESCRIPTION("Test cases for sscanf facility"); 792 822 MODULE_LICENSE("GPL v2");
+1
lib/tests/Makefile
··· 30 30 CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare) 31 31 obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o 32 32 obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o 33 + obj-$(CONFIG_SCANF_KUNIT_TEST) += scanf_kunit.o 33 34 obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o 34 35 obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o 35 36 obj-$(CONFIG_TEST_SORT) += test_sort.o
+1 -1
tools/testing/selftests/lib/Makefile
··· 4 4 # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 5 5 all: 6 6 7 - TEST_PROGS := bitmap.sh scanf.sh 7 + TEST_PROGS := bitmap.sh 8 8 include ../lib.mk
-1
tools/testing/selftests/lib/config
··· 1 - CONFIG_TEST_SCANF=m 2 1 CONFIG_TEST_BITMAP=m 3 2 CONFIG_TEST_BITOPS=m
-4
tools/testing/selftests/lib/scanf.sh
··· 1 - #!/bin/sh 2 - # SPDX-License-Identifier: GPL-2.0 3 - # Tests the scanf infrastructure using test_scanf kernel module. 4 - $(dirname $0)/../kselftest/module.sh "scanf" test_scanf