1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Base unit test (KUnit) API. 4 * 5 * Copyright (C) 2019, Google LLC. 6 * Author: Brendan Higgins <brendanhiggins@google.com> 7 */ 8 9 #include <kunit/test.h> 10 #include <linux/kernel.h> 11 #include <linux/sched/debug.h> 12 13 #include "string-stream.h" 14 #include "try-catch-impl.h" 15 16 static void kunit_set_failure(struct kunit *test) 17 { 18 WRITE_ONCE(test->success, false); 19 } 20 21 static void kunit_print_tap_version(void) 22 { 23 static bool kunit_has_printed_tap_version; 24 25 if (!kunit_has_printed_tap_version) { 26 pr_info("TAP version 14\n"); 27 kunit_has_printed_tap_version = true; 28 } 29 } 30 31 static size_t kunit_test_cases_len(struct kunit_case *test_cases) 32 { 33 struct kunit_case *test_case; 34 size_t len = 0; 35 36 for (test_case = test_cases; test_case->run_case; test_case++) 37 len++; 38 39 return len; 40 } 41 42 static void kunit_print_subtest_start(struct kunit_suite *suite) 43 { 44 kunit_print_tap_version(); 45 pr_info("\t# Subtest: %s\n", suite->name); 46 pr_info("\t1..%zd\n", kunit_test_cases_len(suite->test_cases)); 47 } 48 49 static void kunit_print_ok_not_ok(bool should_indent, 50 bool is_ok, 51 size_t test_number, 52 const char *description) 53 { 54 const char *indent, *ok_not_ok; 55 56 if (should_indent) 57 indent = "\t"; 58 else 59 indent = ""; 60 61 if (is_ok) 62 ok_not_ok = "ok"; 63 else 64 ok_not_ok = "not ok"; 65 66 pr_info("%s%s %zd - %s\n", indent, ok_not_ok, test_number, description); 67 } 68 69 static bool kunit_suite_has_succeeded(struct kunit_suite *suite) 70 { 71 const struct kunit_case *test_case; 72 73 for (test_case = suite->test_cases; test_case->run_case; test_case++) 74 if (!test_case->success) 75 return false; 76 77 return true; 78 } 79 80 static void kunit_print_subtest_end(struct kunit_suite *suite) 81 { 82 static size_t kunit_suite_counter = 1; 83 84 kunit_print_ok_not_ok(false, 85 kunit_suite_has_succeeded(suite), 86 kunit_suite_counter++, 87 suite->name); 88 } 89 90 static void kunit_print_test_case_ok_not_ok(struct kunit_case *test_case, 91 size_t test_number) 92 { 93 kunit_print_ok_not_ok(true, 94 test_case->success, 95 test_number, 96 test_case->name); 97 } 98 99 static void kunit_print_string_stream(struct kunit *test, 100 struct string_stream *stream) 101 { 102 struct string_stream_fragment *fragment; 103 char *buf; 104 105 buf = string_stream_get_string(stream); 106 if (!buf) { 107 kunit_err(test, 108 "Could not allocate buffer, dumping stream:\n"); 109 list_for_each_entry(fragment, &stream->fragments, node) { 110 kunit_err(test, "%s", fragment->fragment); 111 } 112 kunit_err(test, "\n"); 113 } else { 114 kunit_err(test, "%s", buf); 115 kunit_kfree(test, buf); 116 } 117 } 118 119 static void kunit_fail(struct kunit *test, struct kunit_assert *assert) 120 { 121 struct string_stream *stream; 122 123 kunit_set_failure(test); 124 125 stream = alloc_string_stream(test, GFP_KERNEL); 126 if (!stream) { 127 WARN(true, 128 "Could not allocate stream to print failed assertion in %s:%d\n", 129 assert->file, 130 assert->line); 131 return; 132 } 133 134 assert->format(assert, stream); 135 136 kunit_print_string_stream(test, stream); 137 138 WARN_ON(string_stream_destroy(stream)); 139 } 140 141 static void __noreturn kunit_abort(struct kunit *test) 142 { 143 kunit_try_catch_throw(&test->try_catch); /* Does not return. */ 144 145 /* 146 * Throw could not abort from test. 147 * 148 * XXX: we should never reach this line! As kunit_try_catch_throw is 149 * marked __noreturn. 150 */ 151 WARN_ONCE(true, "Throw could not abort from test!\n"); 152 } 153 154 void kunit_do_assertion(struct kunit *test, 155 struct kunit_assert *assert, 156 bool pass, 157 const char *fmt, ...) 158 { 159 va_list args; 160 161 if (pass) 162 return; 163 164 va_start(args, fmt); 165 166 assert->message.fmt = fmt; 167 assert->message.va = &args; 168 169 kunit_fail(test, assert); 170 171 va_end(args); 172 173 if (assert->type == KUNIT_ASSERTION) 174 kunit_abort(test); 175 } 176 EXPORT_SYMBOL_GPL(kunit_do_assertion); 177 178 void kunit_init_test(struct kunit *test, const char *name) 179 { 180 spin_lock_init(&test->lock); 181 INIT_LIST_HEAD(&test->resources); 182 test->name = name; 183 test->success = true; 184 } 185 EXPORT_SYMBOL_GPL(kunit_init_test); 186 187 /* 188 * Initializes and runs test case. Does not clean up or do post validations. 189 */ 190 static void kunit_run_case_internal(struct kunit *test, 191 struct kunit_suite *suite, 192 struct kunit_case *test_case) 193 { 194 if (suite->init) { 195 int ret; 196 197 ret = suite->init(test); 198 if (ret) { 199 kunit_err(test, "failed to initialize: %d\n", ret); 200 kunit_set_failure(test); 201 return; 202 } 203 } 204 205 test_case->run_case(test); 206 } 207 208 static void kunit_case_internal_cleanup(struct kunit *test) 209 { 210 kunit_cleanup(test); 211 } 212 213 /* 214 * Performs post validations and cleanup after a test case was run. 215 * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal! 216 */ 217 static void kunit_run_case_cleanup(struct kunit *test, 218 struct kunit_suite *suite) 219 { 220 if (suite->exit) 221 suite->exit(test); 222 223 kunit_case_internal_cleanup(test); 224 } 225 226 struct kunit_try_catch_context { 227 struct kunit *test; 228 struct kunit_suite *suite; 229 struct kunit_case *test_case; 230 }; 231 232 static void kunit_try_run_case(void *data) 233 { 234 struct kunit_try_catch_context *ctx = data; 235 struct kunit *test = ctx->test; 236 struct kunit_suite *suite = ctx->suite; 237 struct kunit_case *test_case = ctx->test_case; 238 239 /* 240 * kunit_run_case_internal may encounter a fatal error; if it does, 241 * abort will be called, this thread will exit, and finally the parent 242 * thread will resume control and handle any necessary clean up. 243 */ 244 kunit_run_case_internal(test, suite, test_case); 245 /* This line may never be reached. */ 246 kunit_run_case_cleanup(test, suite); 247 } 248 249 static void kunit_catch_run_case(void *data) 250 { 251 struct kunit_try_catch_context *ctx = data; 252 struct kunit *test = ctx->test; 253 struct kunit_suite *suite = ctx->suite; 254 int try_exit_code = kunit_try_catch_get_result(&test->try_catch); 255 256 if (try_exit_code) { 257 kunit_set_failure(test); 258 /* 259 * Test case could not finish, we have no idea what state it is 260 * in, so don't do clean up. 261 */ 262 if (try_exit_code == -ETIMEDOUT) { 263 kunit_err(test, "test case timed out\n"); 264 /* 265 * Unknown internal error occurred preventing test case from 266 * running, so there is nothing to clean up. 267 */ 268 } else { 269 kunit_err(test, "internal error occurred preventing test case from running: %d\n", 270 try_exit_code); 271 } 272 return; 273 } 274 275 /* 276 * Test case was run, but aborted. It is the test case's business as to 277 * whether it failed or not, we just need to clean up. 278 */ 279 kunit_run_case_cleanup(test, suite); 280 } 281 282 /* 283 * Performs all logic to run a test case. It also catches most errors that 284 * occur in a test case and reports them as failures. 285 */ 286 static void kunit_run_case_catch_errors(struct kunit_suite *suite, 287 struct kunit_case *test_case) 288 { 289 struct kunit_try_catch_context context; 290 struct kunit_try_catch *try_catch; 291 struct kunit test; 292 293 kunit_init_test(&test, test_case->name); 294 try_catch = &test.try_catch; 295 296 kunit_try_catch_init(try_catch, 297 &test, 298 kunit_try_run_case, 299 kunit_catch_run_case); 300 context.test = &test; 301 context.suite = suite; 302 context.test_case = test_case; 303 kunit_try_catch_run(try_catch, &context); 304 305 test_case->success = test.success; 306 } 307 308 int kunit_run_tests(struct kunit_suite *suite) 309 { 310 struct kunit_case *test_case; 311 size_t test_case_count = 1; 312 313 kunit_print_subtest_start(suite); 314 315 for (test_case = suite->test_cases; test_case->run_case; test_case++) { 316 kunit_run_case_catch_errors(suite, test_case); 317 kunit_print_test_case_ok_not_ok(test_case, test_case_count++); 318 } 319 320 kunit_print_subtest_end(suite); 321 322 return 0; 323 } 324 EXPORT_SYMBOL_GPL(kunit_run_tests); 325 326 struct kunit_resource *kunit_alloc_and_get_resource(struct kunit *test, 327 kunit_resource_init_t init, 328 kunit_resource_free_t free, 329 gfp_t internal_gfp, 330 void *context) 331 { 332 struct kunit_resource *res; 333 int ret; 334 335 res = kzalloc(sizeof(*res), internal_gfp); 336 if (!res) 337 return NULL; 338 339 ret = init(res, context); 340 if (ret) 341 return NULL; 342 343 res->free = free; 344 spin_lock(&test->lock); 345 list_add_tail(&res->node, &test->resources); 346 spin_unlock(&test->lock); 347 348 return res; 349 } 350 EXPORT_SYMBOL_GPL(kunit_alloc_and_get_resource); 351 352 static void kunit_resource_free(struct kunit *test, struct kunit_resource *res) 353 { 354 res->free(res); 355 kfree(res); 356 } 357 358 static struct kunit_resource *kunit_resource_find(struct kunit *test, 359 kunit_resource_match_t match, 360 kunit_resource_free_t free, 361 void *match_data) 362 { 363 struct kunit_resource *resource; 364 365 lockdep_assert_held(&test->lock); 366 367 list_for_each_entry_reverse(resource, &test->resources, node) { 368 if (resource->free != free) 369 continue; 370 if (match(test, resource->allocation, match_data)) 371 return resource; 372 } 373 374 return NULL; 375 } 376 377 static struct kunit_resource *kunit_resource_remove( 378 struct kunit *test, 379 kunit_resource_match_t match, 380 kunit_resource_free_t free, 381 void *match_data) 382 { 383 struct kunit_resource *resource; 384 385 spin_lock(&test->lock); 386 resource = kunit_resource_find(test, match, free, match_data); 387 if (resource) 388 list_del(&resource->node); 389 spin_unlock(&test->lock); 390 391 return resource; 392 } 393 394 int kunit_resource_destroy(struct kunit *test, 395 kunit_resource_match_t match, 396 kunit_resource_free_t free, 397 void *match_data) 398 { 399 struct kunit_resource *resource; 400 401 resource = kunit_resource_remove(test, match, free, match_data); 402 403 if (!resource) 404 return -ENOENT; 405 406 kunit_resource_free(test, resource); 407 return 0; 408 } 409 EXPORT_SYMBOL_GPL(kunit_resource_destroy); 410 411 struct kunit_kmalloc_params { 412 size_t size; 413 gfp_t gfp; 414 }; 415 416 static int kunit_kmalloc_init(struct kunit_resource *res, void *context) 417 { 418 struct kunit_kmalloc_params *params = context; 419 420 res->allocation = kmalloc(params->size, params->gfp); 421 if (!res->allocation) 422 return -ENOMEM; 423 424 return 0; 425 } 426 427 static void kunit_kmalloc_free(struct kunit_resource *res) 428 { 429 kfree(res->allocation); 430 } 431 432 void *kunit_kmalloc(struct kunit *test, size_t size, gfp_t gfp) 433 { 434 struct kunit_kmalloc_params params = { 435 .size = size, 436 .gfp = gfp 437 }; 438 439 return kunit_alloc_resource(test, 440 kunit_kmalloc_init, 441 kunit_kmalloc_free, 442 gfp, 443 ¶ms); 444 } 445 EXPORT_SYMBOL_GPL(kunit_kmalloc); 446 447 void kunit_kfree(struct kunit *test, const void *ptr) 448 { 449 int rc; 450 451 rc = kunit_resource_destroy(test, 452 kunit_resource_instance_match, 453 kunit_kmalloc_free, 454 (void *)ptr); 455 456 WARN_ON(rc); 457 } 458 EXPORT_SYMBOL_GPL(kunit_kfree); 459 460 void kunit_cleanup(struct kunit *test) 461 { 462 struct kunit_resource *resource; 463 464 /* 465 * test->resources is a stack - each allocation must be freed in the 466 * reverse order from which it was added since one resource may depend 467 * on another for its entire lifetime. 468 * Also, we cannot use the normal list_for_each constructs, even the 469 * safe ones because *arbitrary* nodes may be deleted when 470 * kunit_resource_free is called; the list_for_each_safe variants only 471 * protect against the current node being deleted, not the next. 472 */ 473 while (true) { 474 spin_lock(&test->lock); 475 if (list_empty(&test->resources)) { 476 spin_unlock(&test->lock); 477 break; 478 } 479 resource = list_last_entry(&test->resources, 480 struct kunit_resource, 481 node); 482 list_del(&resource->node); 483 spin_unlock(&test->lock); 484 485 kunit_resource_free(test, resource); 486 } 487 } 488 EXPORT_SYMBOL_GPL(kunit_cleanup); 489 490 static int __init kunit_init(void) 491 { 492 return 0; 493 } 494 late_initcall(kunit_init); 495 496 static void __exit kunit_exit(void) 497 { 498 } 499 module_exit(kunit_exit); 500 501 MODULE_LICENSE("GPL v2"); 502