Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Base unit test (KUnit) API.
0004  *
0005  * Copyright (C) 2019, Google LLC.
0006  * Author: Brendan Higgins <brendanhiggins@google.com>
0007  */
0008 
0009 #include <kunit/resource.h>
0010 #include <kunit/test.h>
0011 #include <kunit/test-bug.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/moduleparam.h>
0015 #include <linux/panic.h>
0016 #include <linux/sched/debug.h>
0017 #include <linux/sched.h>
0018 
0019 #include "debugfs.h"
0020 #include "string-stream.h"
0021 #include "try-catch-impl.h"
0022 
0023 #if IS_BUILTIN(CONFIG_KUNIT)
0024 /*
0025  * Fail the current test and print an error message to the log.
0026  */
0027 void __kunit_fail_current_test(const char *file, int line, const char *fmt, ...)
0028 {
0029     va_list args;
0030     int len;
0031     char *buffer;
0032 
0033     if (!current->kunit_test)
0034         return;
0035 
0036     kunit_set_failure(current->kunit_test);
0037 
0038     /* kunit_err() only accepts literals, so evaluate the args first. */
0039     va_start(args, fmt);
0040     len = vsnprintf(NULL, 0, fmt, args) + 1;
0041     va_end(args);
0042 
0043     buffer = kunit_kmalloc(current->kunit_test, len, GFP_KERNEL);
0044     if (!buffer)
0045         return;
0046 
0047     va_start(args, fmt);
0048     vsnprintf(buffer, len, fmt, args);
0049     va_end(args);
0050 
0051     kunit_err(current->kunit_test, "%s:%d: %s", file, line, buffer);
0052     kunit_kfree(current->kunit_test, buffer);
0053 }
0054 EXPORT_SYMBOL_GPL(__kunit_fail_current_test);
0055 #endif
0056 
0057 /*
0058  * KUnit statistic mode:
0059  * 0 - disabled
0060  * 1 - only when there is more than one subtest
0061  * 2 - enabled
0062  */
0063 static int kunit_stats_enabled = 1;
0064 module_param_named(stats_enabled, kunit_stats_enabled, int, 0644);
0065 MODULE_PARM_DESC(stats_enabled,
0066           "Print test stats: never (0), only for multiple subtests (1), or always (2)");
0067 
0068 struct kunit_result_stats {
0069     unsigned long passed;
0070     unsigned long skipped;
0071     unsigned long failed;
0072     unsigned long total;
0073 };
0074 
0075 static bool kunit_should_print_stats(struct kunit_result_stats stats)
0076 {
0077     if (kunit_stats_enabled == 0)
0078         return false;
0079 
0080     if (kunit_stats_enabled == 2)
0081         return true;
0082 
0083     return (stats.total > 1);
0084 }
0085 
0086 static void kunit_print_test_stats(struct kunit *test,
0087                    struct kunit_result_stats stats)
0088 {
0089     if (!kunit_should_print_stats(stats))
0090         return;
0091 
0092     kunit_log(KERN_INFO, test,
0093           KUNIT_SUBTEST_INDENT
0094           "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
0095           test->name,
0096           stats.passed,
0097           stats.failed,
0098           stats.skipped,
0099           stats.total);
0100 }
0101 
0102 /*
0103  * Append formatted message to log, size of which is limited to
0104  * KUNIT_LOG_SIZE bytes (including null terminating byte).
0105  */
0106 void kunit_log_append(char *log, const char *fmt, ...)
0107 {
0108     char line[KUNIT_LOG_SIZE];
0109     va_list args;
0110     int len_left;
0111 
0112     if (!log)
0113         return;
0114 
0115     len_left = KUNIT_LOG_SIZE - strlen(log) - 1;
0116     if (len_left <= 0)
0117         return;
0118 
0119     va_start(args, fmt);
0120     vsnprintf(line, sizeof(line), fmt, args);
0121     va_end(args);
0122 
0123     strncat(log, line, len_left);
0124 }
0125 EXPORT_SYMBOL_GPL(kunit_log_append);
0126 
0127 size_t kunit_suite_num_test_cases(struct kunit_suite *suite)
0128 {
0129     struct kunit_case *test_case;
0130     size_t len = 0;
0131 
0132     kunit_suite_for_each_test_case(suite, test_case)
0133         len++;
0134 
0135     return len;
0136 }
0137 EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
0138 
0139 static void kunit_print_suite_start(struct kunit_suite *suite)
0140 {
0141     kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "# Subtest: %s",
0142           suite->name);
0143     kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "1..%zd",
0144           kunit_suite_num_test_cases(suite));
0145 }
0146 
0147 static void kunit_print_ok_not_ok(void *test_or_suite,
0148                   bool is_test,
0149                   enum kunit_status status,
0150                   size_t test_number,
0151                   const char *description,
0152                   const char *directive)
0153 {
0154     struct kunit_suite *suite = is_test ? NULL : test_or_suite;
0155     struct kunit *test = is_test ? test_or_suite : NULL;
0156     const char *directive_header = (status == KUNIT_SKIPPED) ? " # SKIP " : "";
0157 
0158     /*
0159      * We do not log the test suite results as doing so would
0160      * mean debugfs display would consist of the test suite
0161      * description and status prior to individual test results.
0162      * Hence directly printk the suite status, and we will
0163      * separately seq_printf() the suite status for the debugfs
0164      * representation.
0165      */
0166     if (suite)
0167         pr_info("%s %zd - %s%s%s\n",
0168             kunit_status_to_ok_not_ok(status),
0169             test_number, description, directive_header,
0170             (status == KUNIT_SKIPPED) ? directive : "");
0171     else
0172         kunit_log(KERN_INFO, test,
0173               KUNIT_SUBTEST_INDENT "%s %zd - %s%s%s",
0174               kunit_status_to_ok_not_ok(status),
0175               test_number, description, directive_header,
0176               (status == KUNIT_SKIPPED) ? directive : "");
0177 }
0178 
0179 enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite)
0180 {
0181     const struct kunit_case *test_case;
0182     enum kunit_status status = KUNIT_SKIPPED;
0183 
0184     if (suite->suite_init_err)
0185         return KUNIT_FAILURE;
0186 
0187     kunit_suite_for_each_test_case(suite, test_case) {
0188         if (test_case->status == KUNIT_FAILURE)
0189             return KUNIT_FAILURE;
0190         else if (test_case->status == KUNIT_SUCCESS)
0191             status = KUNIT_SUCCESS;
0192     }
0193 
0194     return status;
0195 }
0196 EXPORT_SYMBOL_GPL(kunit_suite_has_succeeded);
0197 
0198 static size_t kunit_suite_counter = 1;
0199 
0200 static void kunit_print_suite_end(struct kunit_suite *suite)
0201 {
0202     kunit_print_ok_not_ok((void *)suite, false,
0203                   kunit_suite_has_succeeded(suite),
0204                   kunit_suite_counter++,
0205                   suite->name,
0206                   suite->status_comment);
0207 }
0208 
0209 unsigned int kunit_test_case_num(struct kunit_suite *suite,
0210                  struct kunit_case *test_case)
0211 {
0212     struct kunit_case *tc;
0213     unsigned int i = 1;
0214 
0215     kunit_suite_for_each_test_case(suite, tc) {
0216         if (tc == test_case)
0217             return i;
0218         i++;
0219     }
0220 
0221     return 0;
0222 }
0223 EXPORT_SYMBOL_GPL(kunit_test_case_num);
0224 
0225 static void kunit_print_string_stream(struct kunit *test,
0226                       struct string_stream *stream)
0227 {
0228     struct string_stream_fragment *fragment;
0229     char *buf;
0230 
0231     if (string_stream_is_empty(stream))
0232         return;
0233 
0234     buf = string_stream_get_string(stream);
0235     if (!buf) {
0236         kunit_err(test,
0237               "Could not allocate buffer, dumping stream:\n");
0238         list_for_each_entry(fragment, &stream->fragments, node) {
0239             kunit_err(test, "%s", fragment->fragment);
0240         }
0241         kunit_err(test, "\n");
0242     } else {
0243         kunit_err(test, "%s", buf);
0244         kunit_kfree(test, buf);
0245     }
0246 }
0247 
0248 static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,
0249                enum kunit_assert_type type, const struct kunit_assert *assert,
0250                const struct va_format *message)
0251 {
0252     struct string_stream *stream;
0253 
0254     kunit_set_failure(test);
0255 
0256     stream = alloc_string_stream(test, GFP_KERNEL);
0257     if (!stream) {
0258         WARN(true,
0259              "Could not allocate stream to print failed assertion in %s:%d\n",
0260              loc->file,
0261              loc->line);
0262         return;
0263     }
0264 
0265     kunit_assert_prologue(loc, type, stream);
0266     assert->format(assert, message, stream);
0267 
0268     kunit_print_string_stream(test, stream);
0269 
0270     WARN_ON(string_stream_destroy(stream));
0271 }
0272 
0273 static void __noreturn kunit_abort(struct kunit *test)
0274 {
0275     kunit_try_catch_throw(&test->try_catch); /* Does not return. */
0276 
0277     /*
0278      * Throw could not abort from test.
0279      *
0280      * XXX: we should never reach this line! As kunit_try_catch_throw is
0281      * marked __noreturn.
0282      */
0283     WARN_ONCE(true, "Throw could not abort from test!\n");
0284 }
0285 
0286 void kunit_do_failed_assertion(struct kunit *test,
0287                    const struct kunit_loc *loc,
0288                    enum kunit_assert_type type,
0289                    const struct kunit_assert *assert,
0290                    const char *fmt, ...)
0291 {
0292     va_list args;
0293     struct va_format message;
0294     va_start(args, fmt);
0295 
0296     message.fmt = fmt;
0297     message.va = &args;
0298 
0299     kunit_fail(test, loc, type, assert, &message);
0300 
0301     va_end(args);
0302 
0303     if (type == KUNIT_ASSERTION)
0304         kunit_abort(test);
0305 }
0306 EXPORT_SYMBOL_GPL(kunit_do_failed_assertion);
0307 
0308 void kunit_init_test(struct kunit *test, const char *name, char *log)
0309 {
0310     spin_lock_init(&test->lock);
0311     INIT_LIST_HEAD(&test->resources);
0312     test->name = name;
0313     test->log = log;
0314     if (test->log)
0315         test->log[0] = '\0';
0316     test->status = KUNIT_SUCCESS;
0317     test->status_comment[0] = '\0';
0318 }
0319 EXPORT_SYMBOL_GPL(kunit_init_test);
0320 
0321 /*
0322  * Initializes and runs test case. Does not clean up or do post validations.
0323  */
0324 static void kunit_run_case_internal(struct kunit *test,
0325                     struct kunit_suite *suite,
0326                     struct kunit_case *test_case)
0327 {
0328     if (suite->init) {
0329         int ret;
0330 
0331         ret = suite->init(test);
0332         if (ret) {
0333             kunit_err(test, "failed to initialize: %d\n", ret);
0334             kunit_set_failure(test);
0335             return;
0336         }
0337     }
0338 
0339     test_case->run_case(test);
0340 }
0341 
0342 static void kunit_case_internal_cleanup(struct kunit *test)
0343 {
0344     kunit_cleanup(test);
0345 }
0346 
0347 /*
0348  * Performs post validations and cleanup after a test case was run.
0349  * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!
0350  */
0351 static void kunit_run_case_cleanup(struct kunit *test,
0352                    struct kunit_suite *suite)
0353 {
0354     if (suite->exit)
0355         suite->exit(test);
0356 
0357     kunit_case_internal_cleanup(test);
0358 }
0359 
0360 struct kunit_try_catch_context {
0361     struct kunit *test;
0362     struct kunit_suite *suite;
0363     struct kunit_case *test_case;
0364 };
0365 
0366 static void kunit_try_run_case(void *data)
0367 {
0368     struct kunit_try_catch_context *ctx = data;
0369     struct kunit *test = ctx->test;
0370     struct kunit_suite *suite = ctx->suite;
0371     struct kunit_case *test_case = ctx->test_case;
0372 
0373     current->kunit_test = test;
0374 
0375     /*
0376      * kunit_run_case_internal may encounter a fatal error; if it does,
0377      * abort will be called, this thread will exit, and finally the parent
0378      * thread will resume control and handle any necessary clean up.
0379      */
0380     kunit_run_case_internal(test, suite, test_case);
0381     /* This line may never be reached. */
0382     kunit_run_case_cleanup(test, suite);
0383 }
0384 
0385 static void kunit_catch_run_case(void *data)
0386 {
0387     struct kunit_try_catch_context *ctx = data;
0388     struct kunit *test = ctx->test;
0389     struct kunit_suite *suite = ctx->suite;
0390     int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
0391 
0392     if (try_exit_code) {
0393         kunit_set_failure(test);
0394         /*
0395          * Test case could not finish, we have no idea what state it is
0396          * in, so don't do clean up.
0397          */
0398         if (try_exit_code == -ETIMEDOUT) {
0399             kunit_err(test, "test case timed out\n");
0400         /*
0401          * Unknown internal error occurred preventing test case from
0402          * running, so there is nothing to clean up.
0403          */
0404         } else {
0405             kunit_err(test, "internal error occurred preventing test case from running: %d\n",
0406                   try_exit_code);
0407         }
0408         return;
0409     }
0410 
0411     /*
0412      * Test case was run, but aborted. It is the test case's business as to
0413      * whether it failed or not, we just need to clean up.
0414      */
0415     kunit_run_case_cleanup(test, suite);
0416 }
0417 
0418 /*
0419  * Performs all logic to run a test case. It also catches most errors that
0420  * occur in a test case and reports them as failures.
0421  */
0422 static void kunit_run_case_catch_errors(struct kunit_suite *suite,
0423                     struct kunit_case *test_case,
0424                     struct kunit *test)
0425 {
0426     struct kunit_try_catch_context context;
0427     struct kunit_try_catch *try_catch;
0428 
0429     kunit_init_test(test, test_case->name, test_case->log);
0430     try_catch = &test->try_catch;
0431 
0432     kunit_try_catch_init(try_catch,
0433                  test,
0434                  kunit_try_run_case,
0435                  kunit_catch_run_case);
0436     context.test = test;
0437     context.suite = suite;
0438     context.test_case = test_case;
0439     kunit_try_catch_run(try_catch, &context);
0440 
0441     /* Propagate the parameter result to the test case. */
0442     if (test->status == KUNIT_FAILURE)
0443         test_case->status = KUNIT_FAILURE;
0444     else if (test_case->status != KUNIT_FAILURE && test->status == KUNIT_SUCCESS)
0445         test_case->status = KUNIT_SUCCESS;
0446 }
0447 
0448 static void kunit_print_suite_stats(struct kunit_suite *suite,
0449                     struct kunit_result_stats suite_stats,
0450                     struct kunit_result_stats param_stats)
0451 {
0452     if (kunit_should_print_stats(suite_stats)) {
0453         kunit_log(KERN_INFO, suite,
0454               "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
0455               suite->name,
0456               suite_stats.passed,
0457               suite_stats.failed,
0458               suite_stats.skipped,
0459               suite_stats.total);
0460     }
0461 
0462     if (kunit_should_print_stats(param_stats)) {
0463         kunit_log(KERN_INFO, suite,
0464               "# Totals: pass:%lu fail:%lu skip:%lu total:%lu",
0465               param_stats.passed,
0466               param_stats.failed,
0467               param_stats.skipped,
0468               param_stats.total);
0469     }
0470 }
0471 
0472 static void kunit_update_stats(struct kunit_result_stats *stats,
0473                    enum kunit_status status)
0474 {
0475     switch (status) {
0476     case KUNIT_SUCCESS:
0477         stats->passed++;
0478         break;
0479     case KUNIT_SKIPPED:
0480         stats->skipped++;
0481         break;
0482     case KUNIT_FAILURE:
0483         stats->failed++;
0484         break;
0485     }
0486 
0487     stats->total++;
0488 }
0489 
0490 static void kunit_accumulate_stats(struct kunit_result_stats *total,
0491                    struct kunit_result_stats add)
0492 {
0493     total->passed += add.passed;
0494     total->skipped += add.skipped;
0495     total->failed += add.failed;
0496     total->total += add.total;
0497 }
0498 
0499 int kunit_run_tests(struct kunit_suite *suite)
0500 {
0501     char param_desc[KUNIT_PARAM_DESC_SIZE];
0502     struct kunit_case *test_case;
0503     struct kunit_result_stats suite_stats = { 0 };
0504     struct kunit_result_stats total_stats = { 0 };
0505 
0506     /* Taint the kernel so we know we've run tests. */
0507     add_taint(TAINT_TEST, LOCKDEP_STILL_OK);
0508 
0509     if (suite->suite_init) {
0510         suite->suite_init_err = suite->suite_init(suite);
0511         if (suite->suite_init_err) {
0512             kunit_err(suite, KUNIT_SUBTEST_INDENT
0513                   "# failed to initialize (%d)", suite->suite_init_err);
0514             goto suite_end;
0515         }
0516     }
0517 
0518     kunit_print_suite_start(suite);
0519 
0520     kunit_suite_for_each_test_case(suite, test_case) {
0521         struct kunit test = { .param_value = NULL, .param_index = 0 };
0522         struct kunit_result_stats param_stats = { 0 };
0523         test_case->status = KUNIT_SKIPPED;
0524 
0525         if (!test_case->generate_params) {
0526             /* Non-parameterised test. */
0527             kunit_run_case_catch_errors(suite, test_case, &test);
0528             kunit_update_stats(&param_stats, test.status);
0529         } else {
0530             /* Get initial param. */
0531             param_desc[0] = '\0';
0532             test.param_value = test_case->generate_params(NULL, param_desc);
0533             kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
0534                   "# Subtest: %s", test_case->name);
0535 
0536             while (test.param_value) {
0537                 kunit_run_case_catch_errors(suite, test_case, &test);
0538 
0539                 if (param_desc[0] == '\0') {
0540                     snprintf(param_desc, sizeof(param_desc),
0541                          "param-%d", test.param_index);
0542                 }
0543 
0544                 kunit_log(KERN_INFO, &test,
0545                       KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
0546                       "%s %d - %s",
0547                       kunit_status_to_ok_not_ok(test.status),
0548                       test.param_index + 1, param_desc);
0549 
0550                 /* Get next param. */
0551                 param_desc[0] = '\0';
0552                 test.param_value = test_case->generate_params(test.param_value, param_desc);
0553                 test.param_index++;
0554 
0555                 kunit_update_stats(&param_stats, test.status);
0556             }
0557         }
0558 
0559 
0560         kunit_print_test_stats(&test, param_stats);
0561 
0562         kunit_print_ok_not_ok(&test, true, test_case->status,
0563                       kunit_test_case_num(suite, test_case),
0564                       test_case->name,
0565                       test.status_comment);
0566 
0567         kunit_update_stats(&suite_stats, test_case->status);
0568         kunit_accumulate_stats(&total_stats, param_stats);
0569     }
0570 
0571     if (suite->suite_exit)
0572         suite->suite_exit(suite);
0573 
0574     kunit_print_suite_stats(suite, suite_stats, total_stats);
0575 suite_end:
0576     kunit_print_suite_end(suite);
0577 
0578     return 0;
0579 }
0580 EXPORT_SYMBOL_GPL(kunit_run_tests);
0581 
0582 static void kunit_init_suite(struct kunit_suite *suite)
0583 {
0584     kunit_debugfs_create_suite(suite);
0585     suite->status_comment[0] = '\0';
0586     suite->suite_init_err = 0;
0587 }
0588 
0589 int __kunit_test_suites_init(struct kunit_suite * const * const suites, int num_suites)
0590 {
0591     unsigned int i;
0592 
0593     for (i = 0; i < num_suites; i++) {
0594         kunit_init_suite(suites[i]);
0595         kunit_run_tests(suites[i]);
0596     }
0597     return 0;
0598 }
0599 EXPORT_SYMBOL_GPL(__kunit_test_suites_init);
0600 
0601 static void kunit_exit_suite(struct kunit_suite *suite)
0602 {
0603     kunit_debugfs_destroy_suite(suite);
0604 }
0605 
0606 void __kunit_test_suites_exit(struct kunit_suite **suites, int num_suites)
0607 {
0608     unsigned int i;
0609 
0610     for (i = 0; i < num_suites; i++)
0611         kunit_exit_suite(suites[i]);
0612 
0613     kunit_suite_counter = 1;
0614 }
0615 EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
0616 
0617 #ifdef CONFIG_MODULES
0618 static void kunit_module_init(struct module *mod)
0619 {
0620     __kunit_test_suites_init(mod->kunit_suites, mod->num_kunit_suites);
0621 }
0622 
0623 static void kunit_module_exit(struct module *mod)
0624 {
0625     __kunit_test_suites_exit(mod->kunit_suites, mod->num_kunit_suites);
0626 }
0627 
0628 static int kunit_module_notify(struct notifier_block *nb, unsigned long val,
0629                    void *data)
0630 {
0631     struct module *mod = data;
0632 
0633     switch (val) {
0634     case MODULE_STATE_LIVE:
0635         kunit_module_init(mod);
0636         break;
0637     case MODULE_STATE_GOING:
0638         kunit_module_exit(mod);
0639         break;
0640     case MODULE_STATE_COMING:
0641     case MODULE_STATE_UNFORMED:
0642         break;
0643     }
0644 
0645     return 0;
0646 }
0647 
0648 static struct notifier_block kunit_mod_nb = {
0649     .notifier_call = kunit_module_notify,
0650     .priority = 0,
0651 };
0652 #endif
0653 
0654 struct kunit_kmalloc_array_params {
0655     size_t n;
0656     size_t size;
0657     gfp_t gfp;
0658 };
0659 
0660 static int kunit_kmalloc_array_init(struct kunit_resource *res, void *context)
0661 {
0662     struct kunit_kmalloc_array_params *params = context;
0663 
0664     res->data = kmalloc_array(params->n, params->size, params->gfp);
0665     if (!res->data)
0666         return -ENOMEM;
0667 
0668     return 0;
0669 }
0670 
0671 static void kunit_kmalloc_array_free(struct kunit_resource *res)
0672 {
0673     kfree(res->data);
0674 }
0675 
0676 void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)
0677 {
0678     struct kunit_kmalloc_array_params params = {
0679         .size = size,
0680         .n = n,
0681         .gfp = gfp
0682     };
0683 
0684     return kunit_alloc_resource(test,
0685                     kunit_kmalloc_array_init,
0686                     kunit_kmalloc_array_free,
0687                     gfp,
0688                     &params);
0689 }
0690 EXPORT_SYMBOL_GPL(kunit_kmalloc_array);
0691 
0692 void kunit_kfree(struct kunit *test, const void *ptr)
0693 {
0694     struct kunit_resource *res;
0695 
0696     res = kunit_find_resource(test, kunit_resource_instance_match,
0697                   (void *)ptr);
0698 
0699     /*
0700      * Removing the resource from the list of resources drops the
0701      * reference count to 1; the final put will trigger the free.
0702      */
0703     kunit_remove_resource(test, res);
0704 
0705     kunit_put_resource(res);
0706 
0707 }
0708 EXPORT_SYMBOL_GPL(kunit_kfree);
0709 
0710 void kunit_cleanup(struct kunit *test)
0711 {
0712     struct kunit_resource *res;
0713     unsigned long flags;
0714 
0715     /*
0716      * test->resources is a stack - each allocation must be freed in the
0717      * reverse order from which it was added since one resource may depend
0718      * on another for its entire lifetime.
0719      * Also, we cannot use the normal list_for_each constructs, even the
0720      * safe ones because *arbitrary* nodes may be deleted when
0721      * kunit_resource_free is called; the list_for_each_safe variants only
0722      * protect against the current node being deleted, not the next.
0723      */
0724     while (true) {
0725         spin_lock_irqsave(&test->lock, flags);
0726         if (list_empty(&test->resources)) {
0727             spin_unlock_irqrestore(&test->lock, flags);
0728             break;
0729         }
0730         res = list_last_entry(&test->resources,
0731                       struct kunit_resource,
0732                       node);
0733         /*
0734          * Need to unlock here as a resource may remove another
0735          * resource, and this can't happen if the test->lock
0736          * is held.
0737          */
0738         spin_unlock_irqrestore(&test->lock, flags);
0739         kunit_remove_resource(test, res);
0740     }
0741     current->kunit_test = NULL;
0742 }
0743 EXPORT_SYMBOL_GPL(kunit_cleanup);
0744 
0745 static int __init kunit_init(void)
0746 {
0747     kunit_debugfs_init();
0748 #ifdef CONFIG_MODULES
0749     return register_module_notifier(&kunit_mod_nb);
0750 #else
0751     return 0;
0752 #endif
0753 }
0754 late_initcall(kunit_init);
0755 
0756 static void __exit kunit_exit(void)
0757 {
0758 #ifdef CONFIG_MODULES
0759     unregister_module_notifier(&kunit_mod_nb);
0760 #endif
0761     kunit_debugfs_cleanup();
0762 }
0763 module_exit(kunit_exit);
0764 
0765 MODULE_LICENSE("GPL v2");