1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * KUnit test for core test infrastructure. 4 * 5 * Copyright (C) 2019, Google LLC. 6 * Author: Brendan Higgins <brendanhiggins@google.com> 7 */ 8 #include "linux/gfp_types.h" 9 #include <kunit/test.h> 10 #include <kunit/test-bug.h> 11 12 #include <linux/device.h> 13 #include <kunit/device.h> 14 15 #include "string-stream.h" 16 #include "try-catch-impl.h" 17 18 struct kunit_try_catch_test_context { 19 struct kunit_try_catch *try_catch; 20 bool function_called; 21 }; 22 23 static void kunit_test_successful_try(void *data) 24 { 25 struct kunit *test = data; 26 struct kunit_try_catch_test_context *ctx = test->priv; 27 28 ctx->function_called = true; 29 } 30 31 static void kunit_test_no_catch(void *data) 32 { 33 struct kunit *test = data; 34 35 KUNIT_FAIL(test, "Catch should not be called\n"); 36 } 37 38 static void kunit_test_try_catch_successful_try_no_catch(struct kunit *test) 39 { 40 struct kunit_try_catch_test_context *ctx = test->priv; 41 struct kunit_try_catch *try_catch = ctx->try_catch; 42 43 kunit_try_catch_init(try_catch, 44 test, 45 kunit_test_successful_try, 46 kunit_test_no_catch); 47 kunit_try_catch_run(try_catch, test); 48 49 KUNIT_EXPECT_TRUE(test, ctx->function_called); 50 } 51 52 static void kunit_test_unsuccessful_try(void *data) 53 { 54 struct kunit *test = data; 55 struct kunit_try_catch_test_context *ctx = test->priv; 56 struct kunit_try_catch *try_catch = ctx->try_catch; 57 58 kunit_try_catch_throw(try_catch); 59 KUNIT_FAIL(test, "This line should never be reached\n"); 60 } 61 62 static void kunit_test_catch(void *data) 63 { 64 struct kunit *test = data; 65 struct kunit_try_catch_test_context *ctx = test->priv; 66 67 ctx->function_called = true; 68 } 69 70 static void kunit_test_try_catch_unsuccessful_try_does_catch(struct kunit *test) 71 { 72 struct kunit_try_catch_test_context *ctx = test->priv; 73 struct kunit_try_catch *try_catch = ctx->try_catch; 74 75 kunit_try_catch_init(try_catch, 76 test, 77 kunit_test_unsuccessful_try, 78 kunit_test_catch); 79 kunit_try_catch_run(try_catch, test); 80 81 KUNIT_EXPECT_TRUE(test, ctx->function_called); 82 } 83 84 static int kunit_try_catch_test_init(struct kunit *test) 85 { 86 struct kunit_try_catch_test_context *ctx; 87 88 ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); 89 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); 90 test->priv = ctx; 91 92 ctx->try_catch = kunit_kmalloc(test, 93 sizeof(*ctx->try_catch), 94 GFP_KERNEL); 95 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->try_catch); 96 97 return 0; 98 } 99 100 static struct kunit_case kunit_try_catch_test_cases[] = { 101 KUNIT_CASE(kunit_test_try_catch_successful_try_no_catch), 102 KUNIT_CASE(kunit_test_try_catch_unsuccessful_try_does_catch), 103 {} 104 }; 105 106 static struct kunit_suite kunit_try_catch_test_suite = { 107 .name = "kunit-try-catch-test", 108 .init = kunit_try_catch_test_init, 109 .test_cases = kunit_try_catch_test_cases, 110 }; 111 112 /* 113 * Context for testing test managed resources 114 * is_resource_initialized is used to test arbitrary resources 115 */ 116 struct kunit_test_resource_context { 117 struct kunit test; 118 bool is_resource_initialized; 119 int allocate_order[2]; 120 int free_order[4]; 121 }; 122 123 static int fake_resource_init(struct kunit_resource *res, void *context) 124 { 125 struct kunit_test_resource_context *ctx = context; 126 127 res->data = &ctx->is_resource_initialized; 128 ctx->is_resource_initialized = true; 129 return 0; 130 } 131 132 static void fake_resource_free(struct kunit_resource *res) 133 { 134 bool *is_resource_initialized = res->data; 135 136 *is_resource_initialized = false; 137 } 138 139 static void kunit_resource_test_init_resources(struct kunit *test) 140 { 141 struct kunit_test_resource_context *ctx = test->priv; 142 143 kunit_init_test(&ctx->test, "testing_test_init_test", NULL); 144 145 KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); 146 } 147 148 static void kunit_resource_test_alloc_resource(struct kunit *test) 149 { 150 struct kunit_test_resource_context *ctx = test->priv; 151 struct kunit_resource *res; 152 kunit_resource_free_t free = fake_resource_free; 153 154 res = kunit_alloc_and_get_resource(&ctx->test, 155 fake_resource_init, 156 fake_resource_free, 157 GFP_KERNEL, 158 ctx); 159 160 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res); 161 KUNIT_EXPECT_PTR_EQ(test, 162 &ctx->is_resource_initialized, 163 (bool *)res->data); 164 KUNIT_EXPECT_TRUE(test, list_is_last(&res->node, &ctx->test.resources)); 165 KUNIT_EXPECT_PTR_EQ(test, free, res->free); 166 167 kunit_put_resource(res); 168 } 169 170 static inline bool kunit_resource_instance_match(struct kunit *test, 171 struct kunit_resource *res, 172 void *match_data) 173 { 174 return res->data == match_data; 175 } 176 177 /* 178 * Note: tests below use kunit_alloc_and_get_resource(), so as a consequence 179 * they have a reference to the associated resource that they must release 180 * via kunit_put_resource(). In normal operation, users will only 181 * have to do this for cases where they use kunit_find_resource(), and the 182 * kunit_alloc_resource() function will be used (which does not take a 183 * resource reference). 184 */ 185 static void kunit_resource_test_destroy_resource(struct kunit *test) 186 { 187 struct kunit_test_resource_context *ctx = test->priv; 188 struct kunit_resource *res = kunit_alloc_and_get_resource( 189 &ctx->test, 190 fake_resource_init, 191 fake_resource_free, 192 GFP_KERNEL, 193 ctx); 194 195 kunit_put_resource(res); 196 197 KUNIT_ASSERT_FALSE(test, 198 kunit_destroy_resource(&ctx->test, 199 kunit_resource_instance_match, 200 res->data)); 201 202 KUNIT_EXPECT_FALSE(test, ctx->is_resource_initialized); 203 KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); 204 } 205 206 static void kunit_resource_test_remove_resource(struct kunit *test) 207 { 208 struct kunit_test_resource_context *ctx = test->priv; 209 struct kunit_resource *res = kunit_alloc_and_get_resource( 210 &ctx->test, 211 fake_resource_init, 212 fake_resource_free, 213 GFP_KERNEL, 214 ctx); 215 216 /* The resource is in the list */ 217 KUNIT_EXPECT_FALSE(test, list_empty(&ctx->test.resources)); 218 219 /* Remove the resource. The pointer is still valid, but it can't be 220 * found. 221 */ 222 kunit_remove_resource(test, res); 223 KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); 224 /* We haven't been freed yet. */ 225 KUNIT_EXPECT_TRUE(test, ctx->is_resource_initialized); 226 227 /* Removing the resource multiple times is valid. */ 228 kunit_remove_resource(test, res); 229 KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); 230 /* Despite having been removed twice (from only one reference), the 231 * resource still has not been freed. 232 */ 233 KUNIT_EXPECT_TRUE(test, ctx->is_resource_initialized); 234 235 /* Free the resource. */ 236 kunit_put_resource(res); 237 KUNIT_EXPECT_FALSE(test, ctx->is_resource_initialized); 238 } 239 240 static void kunit_resource_test_cleanup_resources(struct kunit *test) 241 { 242 int i; 243 struct kunit_test_resource_context *ctx = test->priv; 244 struct kunit_resource *resources[5]; 245 246 for (i = 0; i < ARRAY_SIZE(resources); i++) { 247 resources[i] = kunit_alloc_and_get_resource(&ctx->test, 248 fake_resource_init, 249 fake_resource_free, 250 GFP_KERNEL, 251 ctx); 252 kunit_put_resource(resources[i]); 253 } 254 255 kunit_cleanup(&ctx->test); 256 257 KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); 258 } 259 260 static void kunit_resource_test_mark_order(int order_array[], 261 size_t order_size, 262 int key) 263 { 264 int i; 265 266 for (i = 0; i < order_size && order_array[i]; i++) 267 ; 268 269 order_array[i] = key; 270 } 271 272 #define KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, order_field, key) \ 273 kunit_resource_test_mark_order(ctx->order_field, \ 274 ARRAY_SIZE(ctx->order_field), \ 275 key) 276 277 static int fake_resource_2_init(struct kunit_resource *res, void *context) 278 { 279 struct kunit_test_resource_context *ctx = context; 280 281 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, allocate_order, 2); 282 283 res->data = ctx; 284 285 return 0; 286 } 287 288 static void fake_resource_2_free(struct kunit_resource *res) 289 { 290 struct kunit_test_resource_context *ctx = res->data; 291 292 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, free_order, 2); 293 } 294 295 static int fake_resource_1_init(struct kunit_resource *res, void *context) 296 { 297 struct kunit_test_resource_context *ctx = context; 298 struct kunit_resource *res2; 299 300 res2 = kunit_alloc_and_get_resource(&ctx->test, 301 fake_resource_2_init, 302 fake_resource_2_free, 303 GFP_KERNEL, 304 ctx); 305 306 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, allocate_order, 1); 307 308 res->data = ctx; 309 310 kunit_put_resource(res2); 311 312 return 0; 313 } 314 315 static void fake_resource_1_free(struct kunit_resource *res) 316 { 317 struct kunit_test_resource_context *ctx = res->data; 318 319 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, free_order, 1); 320 } 321 322 /* 323 * TODO(brendanhiggins@google.com): replace the arrays that keep track of the 324 * order of allocation and freeing with strict mocks using the IN_SEQUENCE macro 325 * to assert allocation and freeing order when the feature becomes available. 326 */ 327 static void kunit_resource_test_proper_free_ordering(struct kunit *test) 328 { 329 struct kunit_test_resource_context *ctx = test->priv; 330 struct kunit_resource *res; 331 332 /* fake_resource_1 allocates a fake_resource_2 in its init. */ 333 res = kunit_alloc_and_get_resource(&ctx->test, 334 fake_resource_1_init, 335 fake_resource_1_free, 336 GFP_KERNEL, 337 ctx); 338 339 /* 340 * Since fake_resource_2_init calls KUNIT_RESOURCE_TEST_MARK_ORDER 341 * before returning to fake_resource_1_init, it should be the first to 342 * put its key in the allocate_order array. 343 */ 344 KUNIT_EXPECT_EQ(test, ctx->allocate_order[0], 2); 345 KUNIT_EXPECT_EQ(test, ctx->allocate_order[1], 1); 346 347 kunit_put_resource(res); 348 349 kunit_cleanup(&ctx->test); 350 351 /* 352 * Because fake_resource_2 finishes allocation before fake_resource_1, 353 * fake_resource_1 should be freed first since it could depend on 354 * fake_resource_2. 355 */ 356 KUNIT_EXPECT_EQ(test, ctx->free_order[0], 1); 357 KUNIT_EXPECT_EQ(test, ctx->free_order[1], 2); 358 } 359 360 static void kunit_resource_test_static(struct kunit *test) 361 { 362 struct kunit_test_resource_context ctx; 363 struct kunit_resource res; 364 365 KUNIT_EXPECT_EQ(test, kunit_add_resource(test, NULL, NULL, &res, &ctx), 366 0); 367 368 KUNIT_EXPECT_PTR_EQ(test, res.data, (void *)&ctx); 369 370 kunit_cleanup(test); 371 372 KUNIT_EXPECT_TRUE(test, list_empty(&test->resources)); 373 } 374 375 static void kunit_resource_test_named(struct kunit *test) 376 { 377 struct kunit_resource res1, res2, *found = NULL; 378 struct kunit_test_resource_context ctx; 379 380 KUNIT_EXPECT_EQ(test, 381 kunit_add_named_resource(test, NULL, NULL, &res1, 382 "resource_1", &ctx), 383 0); 384 KUNIT_EXPECT_PTR_EQ(test, res1.data, (void *)&ctx); 385 386 KUNIT_EXPECT_EQ(test, 387 kunit_add_named_resource(test, NULL, NULL, &res1, 388 "resource_1", &ctx), 389 -EEXIST); 390 391 KUNIT_EXPECT_EQ(test, 392 kunit_add_named_resource(test, NULL, NULL, &res2, 393 "resource_2", &ctx), 394 0); 395 396 found = kunit_find_named_resource(test, "resource_1"); 397 398 KUNIT_EXPECT_PTR_EQ(test, found, &res1); 399 400 if (found) 401 kunit_put_resource(&res1); 402 403 KUNIT_EXPECT_EQ(test, kunit_destroy_named_resource(test, "resource_2"), 404 0); 405 406 kunit_cleanup(test); 407 408 KUNIT_EXPECT_TRUE(test, list_empty(&test->resources)); 409 } 410 411 static void increment_int(void *ctx) 412 { 413 int *i = (int *)ctx; 414 (*i)++; 415 } 416 417 static void kunit_resource_test_action(struct kunit *test) 418 { 419 int num_actions = 0; 420 421 kunit_add_action(test, increment_int, &num_actions); 422 KUNIT_EXPECT_EQ(test, num_actions, 0); 423 kunit_cleanup(test); 424 KUNIT_EXPECT_EQ(test, num_actions, 1); 425 426 /* Once we've cleaned up, the action queue is empty. */ 427 kunit_cleanup(test); 428 KUNIT_EXPECT_EQ(test, num_actions, 1); 429 430 /* Check the same function can be deferred multiple times. */ 431 kunit_add_action(test, increment_int, &num_actions); 432 kunit_add_action(test, increment_int, &num_actions); 433 kunit_cleanup(test); 434 KUNIT_EXPECT_EQ(test, num_actions, 3); 435 } 436 static void kunit_resource_test_remove_action(struct kunit *test) 437 { 438 int num_actions = 0; 439 440 kunit_add_action(test, increment_int, &num_actions); 441 KUNIT_EXPECT_EQ(test, num_actions, 0); 442 443 kunit_remove_action(test, increment_int, &num_actions); 444 kunit_cleanup(test); 445 KUNIT_EXPECT_EQ(test, num_actions, 0); 446 } 447 static void kunit_resource_test_release_action(struct kunit *test) 448 { 449 int num_actions = 0; 450 451 kunit_add_action(test, increment_int, &num_actions); 452 KUNIT_EXPECT_EQ(test, num_actions, 0); 453 /* Runs immediately on trigger. */ 454 kunit_release_action(test, increment_int, &num_actions); 455 KUNIT_EXPECT_EQ(test, num_actions, 1); 456 457 /* Doesn't run again on test exit. */ 458 kunit_cleanup(test); 459 KUNIT_EXPECT_EQ(test, num_actions, 1); 460 } 461 static void action_order_1(void *ctx) 462 { 463 struct kunit_test_resource_context *res_ctx = (struct kunit_test_resource_context *)ctx; 464 465 KUNIT_RESOURCE_TEST_MARK_ORDER(res_ctx, free_order, 1); 466 kunit_log(KERN_INFO, current->kunit_test, "action_order_1"); 467 } 468 static void action_order_2(void *ctx) 469 { 470 struct kunit_test_resource_context *res_ctx = (struct kunit_test_resource_context *)ctx; 471 472 KUNIT_RESOURCE_TEST_MARK_ORDER(res_ctx, free_order, 2); 473 kunit_log(KERN_INFO, current->kunit_test, "action_order_2"); 474 } 475 static void kunit_resource_test_action_ordering(struct kunit *test) 476 { 477 struct kunit_test_resource_context *ctx = test->priv; 478 479 kunit_add_action(test, action_order_1, ctx); 480 kunit_add_action(test, action_order_2, ctx); 481 kunit_add_action(test, action_order_1, ctx); 482 kunit_add_action(test, action_order_2, ctx); 483 kunit_remove_action(test, action_order_1, ctx); 484 kunit_release_action(test, action_order_2, ctx); 485 kunit_cleanup(test); 486 487 /* [2 is triggered] [2], [(1 is cancelled)] [1] */ 488 KUNIT_EXPECT_EQ(test, ctx->free_order[0], 2); 489 KUNIT_EXPECT_EQ(test, ctx->free_order[1], 2); 490 KUNIT_EXPECT_EQ(test, ctx->free_order[2], 1); 491 } 492 493 static int kunit_resource_test_init(struct kunit *test) 494 { 495 struct kunit_test_resource_context *ctx = 496 kzalloc(sizeof(*ctx), GFP_KERNEL); 497 498 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); 499 500 test->priv = ctx; 501 502 kunit_init_test(&ctx->test, "test_test_context", NULL); 503 504 return 0; 505 } 506 507 static void kunit_resource_test_exit(struct kunit *test) 508 { 509 struct kunit_test_resource_context *ctx = test->priv; 510 511 kunit_cleanup(&ctx->test); 512 kfree(ctx); 513 } 514 515 static struct kunit_case kunit_resource_test_cases[] = { 516 KUNIT_CASE(kunit_resource_test_init_resources), 517 KUNIT_CASE(kunit_resource_test_alloc_resource), 518 KUNIT_CASE(kunit_resource_test_destroy_resource), 519 KUNIT_CASE(kunit_resource_test_remove_resource), 520 KUNIT_CASE(kunit_resource_test_cleanup_resources), 521 KUNIT_CASE(kunit_resource_test_proper_free_ordering), 522 KUNIT_CASE(kunit_resource_test_static), 523 KUNIT_CASE(kunit_resource_test_named), 524 KUNIT_CASE(kunit_resource_test_action), 525 KUNIT_CASE(kunit_resource_test_remove_action), 526 KUNIT_CASE(kunit_resource_test_release_action), 527 KUNIT_CASE(kunit_resource_test_action_ordering), 528 {} 529 }; 530 531 static struct kunit_suite kunit_resource_test_suite = { 532 .name = "kunit-resource-test", 533 .init = kunit_resource_test_init, 534 .exit = kunit_resource_test_exit, 535 .test_cases = kunit_resource_test_cases, 536 }; 537 538 /* 539 * Log tests call string_stream functions, which aren't exported. So only 540 * build this code if this test is built-in. 541 */ 542 #if IS_BUILTIN(CONFIG_KUNIT_TEST) 543 544 /* This avoids a cast warning if kfree() is passed direct to kunit_add_action(). */ 545 KUNIT_DEFINE_ACTION_WRAPPER(kfree_wrapper, kfree, const void *); 546 547 static void kunit_log_test(struct kunit *test) 548 { 549 struct kunit_suite suite; 550 #ifdef CONFIG_KUNIT_DEBUGFS 551 char *full_log; 552 #endif 553 suite.log = kunit_alloc_string_stream(test, GFP_KERNEL); 554 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, suite.log); 555 string_stream_set_append_newlines(suite.log, true); 556 557 kunit_log(KERN_INFO, test, "put this in log."); 558 kunit_log(KERN_INFO, test, "this too."); 559 kunit_log(KERN_INFO, &suite, "add to suite log."); 560 kunit_log(KERN_INFO, &suite, "along with this."); 561 562 #ifdef CONFIG_KUNIT_DEBUGFS 563 KUNIT_EXPECT_TRUE(test, test->log->append_newlines); 564 565 full_log = string_stream_get_string(test->log); 566 kunit_add_action(test, kfree_wrapper, full_log); 567 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 568 strstr(full_log, "put this in log.")); 569 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 570 strstr(full_log, "this too.")); 571 572 full_log = string_stream_get_string(suite.log); 573 kunit_add_action(test, kfree_wrapper, full_log); 574 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 575 strstr(full_log, "add to suite log.")); 576 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 577 strstr(full_log, "along with this.")); 578 #else 579 KUNIT_EXPECT_NULL(test, test->log); 580 #endif 581 } 582 583 static void kunit_log_newline_test(struct kunit *test) 584 { 585 char *full_log; 586 587 kunit_info(test, "Add newline\n"); 588 if (test->log) { 589 full_log = string_stream_get_string(test->log); 590 kunit_add_action(test, kfree_wrapper, full_log); 591 KUNIT_ASSERT_NOT_NULL_MSG(test, strstr(full_log, "Add newline\n"), 592 "Missing log line, full log:\n%s", full_log); 593 KUNIT_EXPECT_NULL(test, strstr(full_log, "Add newline\n\n")); 594 } else { 595 kunit_skip(test, "only useful when debugfs is enabled"); 596 } 597 } 598 #else 599 static void kunit_log_test(struct kunit *test) 600 { 601 kunit_skip(test, "Log tests only run when built-in"); 602 } 603 604 static void kunit_log_newline_test(struct kunit *test) 605 { 606 kunit_skip(test, "Log tests only run when built-in"); 607 } 608 #endif /* IS_BUILTIN(CONFIG_KUNIT_TEST) */ 609 610 static struct kunit_case kunit_log_test_cases[] = { 611 KUNIT_CASE(kunit_log_test), 612 KUNIT_CASE(kunit_log_newline_test), 613 {} 614 }; 615 616 static struct kunit_suite kunit_log_test_suite = { 617 .name = "kunit-log-test", 618 .test_cases = kunit_log_test_cases, 619 }; 620 621 static void kunit_status_set_failure_test(struct kunit *test) 622 { 623 struct kunit fake; 624 625 kunit_init_test(&fake, "fake test", NULL); 626 627 KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_SUCCESS); 628 kunit_set_failure(&fake); 629 KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_FAILURE); 630 } 631 632 static void kunit_status_mark_skipped_test(struct kunit *test) 633 { 634 struct kunit fake; 635 636 kunit_init_test(&fake, "fake test", NULL); 637 638 /* Before: Should be SUCCESS with no comment. */ 639 KUNIT_EXPECT_EQ(test, fake.status, KUNIT_SUCCESS); 640 KUNIT_EXPECT_STREQ(test, fake.status_comment, ""); 641 642 /* Mark the test as skipped. */ 643 kunit_mark_skipped(&fake, "Accepts format string: %s", "YES"); 644 645 /* After: Should be SKIPPED with our comment. */ 646 KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_SKIPPED); 647 KUNIT_EXPECT_STREQ(test, fake.status_comment, "Accepts format string: YES"); 648 } 649 650 static struct kunit_case kunit_status_test_cases[] = { 651 KUNIT_CASE(kunit_status_set_failure_test), 652 KUNIT_CASE(kunit_status_mark_skipped_test), 653 {} 654 }; 655 656 static struct kunit_suite kunit_status_test_suite = { 657 .name = "kunit_status", 658 .test_cases = kunit_status_test_cases, 659 }; 660 661 static void kunit_current_test(struct kunit *test) 662 { 663 /* Check results of both current->kunit_test and 664 * kunit_get_current_test() are equivalent to current test. 665 */ 666 KUNIT_EXPECT_PTR_EQ(test, test, current->kunit_test); 667 KUNIT_EXPECT_PTR_EQ(test, test, kunit_get_current_test()); 668 } 669 670 static void kunit_current_fail_test(struct kunit *test) 671 { 672 struct kunit fake; 673 674 kunit_init_test(&fake, "fake test", NULL); 675 KUNIT_EXPECT_EQ(test, fake.status, KUNIT_SUCCESS); 676 677 /* Set current->kunit_test to fake test. */ 678 current->kunit_test = &fake; 679 680 kunit_fail_current_test("This should make `fake` test fail."); 681 KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_FAILURE); 682 kunit_cleanup(&fake); 683 684 /* Reset current->kunit_test to current test. */ 685 current->kunit_test = test; 686 } 687 688 static struct kunit_case kunit_current_test_cases[] = { 689 KUNIT_CASE(kunit_current_test), 690 KUNIT_CASE(kunit_current_fail_test), 691 {} 692 }; 693 694 static void test_dev_action(void *priv) 695 { 696 *(void **)priv = (void *)1; 697 } 698 699 static void kunit_device_test(struct kunit *test) 700 { 701 struct device *test_device; 702 long action_was_run = 0; 703 704 test_device = kunit_device_register(test, "my_device"); 705 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_device); 706 707 // Add an action to verify cleanup. 708 devm_add_action(test_device, test_dev_action, &action_was_run); 709 710 KUNIT_EXPECT_EQ(test, action_was_run, 0); 711 712 kunit_device_unregister(test, test_device); 713 714 KUNIT_EXPECT_EQ(test, action_was_run, 1); 715 } 716 717 static void kunit_device_cleanup_test(struct kunit *test) 718 { 719 struct device *test_device; 720 long action_was_run = 0; 721 722 test_device = kunit_device_register(test, "my_device"); 723 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_device); 724 725 /* Add an action to verify cleanup. */ 726 devm_add_action(test_device, test_dev_action, &action_was_run); 727 728 KUNIT_EXPECT_EQ(test, action_was_run, 0); 729 730 /* Force KUnit to run cleanup early. */ 731 kunit_cleanup(test); 732 733 KUNIT_EXPECT_EQ(test, action_was_run, 1); 734 } 735 736 struct driver_test_state { 737 bool driver_device_probed; 738 bool driver_device_removed; 739 long action_was_run; 740 }; 741 742 static int driver_probe_hook(struct device *dev) 743 { 744 struct kunit *test = kunit_get_current_test(); 745 struct driver_test_state *state = (struct driver_test_state *)test->priv; 746 747 state->driver_device_probed = true; 748 return 0; 749 } 750 751 static int driver_remove_hook(struct device *dev) 752 { 753 struct kunit *test = kunit_get_current_test(); 754 struct driver_test_state *state = (struct driver_test_state *)test->priv; 755 756 state->driver_device_removed = true; 757 return 0; 758 } 759 760 static void kunit_device_driver_test(struct kunit *test) 761 { 762 struct device_driver *test_driver; 763 struct device *test_device; 764 struct driver_test_state *test_state = kunit_kzalloc(test, sizeof(*test_state), GFP_KERNEL); 765 766 test->priv = test_state; 767 test_driver = kunit_driver_create(test, "my_driver"); 768 769 // This can fail with an error pointer. 770 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_driver); 771 772 test_driver->probe = driver_probe_hook; 773 test_driver->remove = driver_remove_hook; 774 775 test_device = kunit_device_register_with_driver(test, "my_device", test_driver); 776 777 // This can fail with an error pointer. 778 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_device); 779 780 // Make sure the probe function was called. 781 KUNIT_ASSERT_TRUE(test, test_state->driver_device_probed); 782 783 // Add an action to verify cleanup. 784 devm_add_action(test_device, test_dev_action, &test_state->action_was_run); 785 786 KUNIT_EXPECT_EQ(test, test_state->action_was_run, 0); 787 788 kunit_device_unregister(test, test_device); 789 test_device = NULL; 790 791 // Make sure the remove hook was called. 792 KUNIT_ASSERT_TRUE(test, test_state->driver_device_removed); 793 794 // We're going to test this again. 795 test_state->driver_device_probed = false; 796 797 // The driver should not automatically be destroyed by 798 // kunit_device_unregister, so we can re-use it. 799 test_device = kunit_device_register_with_driver(test, "my_device", test_driver); 800 801 // This can fail with an error pointer. 802 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_device); 803 804 // Probe was called again. 805 KUNIT_ASSERT_TRUE(test, test_state->driver_device_probed); 806 807 // Everything is automatically freed here. 808 } 809 810 static struct kunit_case kunit_device_test_cases[] = { 811 KUNIT_CASE(kunit_device_test), 812 KUNIT_CASE(kunit_device_cleanup_test), 813 KUNIT_CASE(kunit_device_driver_test), 814 {} 815 }; 816 817 static struct kunit_suite kunit_device_test_suite = { 818 .name = "kunit_device", 819 .test_cases = kunit_device_test_cases, 820 }; 821 822 static struct kunit_suite kunit_current_test_suite = { 823 .name = "kunit_current", 824 .test_cases = kunit_current_test_cases, 825 }; 826 827 kunit_test_suites(&kunit_try_catch_test_suite, &kunit_resource_test_suite, 828 &kunit_log_test_suite, &kunit_status_test_suite, 829 &kunit_current_test_suite, &kunit_device_test_suite); 830 831 MODULE_LICENSE("GPL v2"); 832