GNU Linux-libre 5.15.137-gnu
[releases.git] / lib / kunit / test.c
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 <kunit/test-bug.h>
11 #include <linux/kernel.h>
12 #include <linux/kref.h>
13 #include <linux/moduleparam.h>
14 #include <linux/sched/debug.h>
15 #include <linux/sched.h>
16
17 #include "debugfs.h"
18 #include "string-stream.h"
19 #include "try-catch-impl.h"
20
21 #if IS_BUILTIN(CONFIG_KUNIT)
22 /*
23  * Fail the current test and print an error message to the log.
24  */
25 void __kunit_fail_current_test(const char *file, int line, const char *fmt, ...)
26 {
27         va_list args;
28         int len;
29         char *buffer;
30
31         if (!current->kunit_test)
32                 return;
33
34         kunit_set_failure(current->kunit_test);
35
36         /* kunit_err() only accepts literals, so evaluate the args first. */
37         va_start(args, fmt);
38         len = vsnprintf(NULL, 0, fmt, args) + 1;
39         va_end(args);
40
41         buffer = kunit_kmalloc(current->kunit_test, len, GFP_KERNEL);
42         if (!buffer)
43                 return;
44
45         va_start(args, fmt);
46         vsnprintf(buffer, len, fmt, args);
47         va_end(args);
48
49         kunit_err(current->kunit_test, "%s:%d: %s", file, line, buffer);
50         kunit_kfree(current->kunit_test, buffer);
51 }
52 EXPORT_SYMBOL_GPL(__kunit_fail_current_test);
53 #endif
54
55 /*
56  * KUnit statistic mode:
57  * 0 - disabled
58  * 1 - only when there is more than one subtest
59  * 2 - enabled
60  */
61 static int kunit_stats_enabled = 1;
62 module_param_named(stats_enabled, kunit_stats_enabled, int, 0644);
63 MODULE_PARM_DESC(stats_enabled,
64                   "Print test stats: never (0), only for multiple subtests (1), or always (2)");
65
66 struct kunit_result_stats {
67         unsigned long passed;
68         unsigned long skipped;
69         unsigned long failed;
70         unsigned long total;
71 };
72
73 static bool kunit_should_print_stats(struct kunit_result_stats stats)
74 {
75         if (kunit_stats_enabled == 0)
76                 return false;
77
78         if (kunit_stats_enabled == 2)
79                 return true;
80
81         return (stats.total > 1);
82 }
83
84 static void kunit_print_test_stats(struct kunit *test,
85                                    struct kunit_result_stats stats)
86 {
87         if (!kunit_should_print_stats(stats))
88                 return;
89
90         kunit_log(KERN_INFO, test,
91                   KUNIT_SUBTEST_INDENT
92                   "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
93                   test->name,
94                   stats.passed,
95                   stats.failed,
96                   stats.skipped,
97                   stats.total);
98 }
99
100 /*
101  * Append formatted message to log, size of which is limited to
102  * KUNIT_LOG_SIZE bytes (including null terminating byte).
103  */
104 void kunit_log_append(char *log, const char *fmt, ...)
105 {
106         char line[KUNIT_LOG_SIZE];
107         va_list args;
108         int len_left;
109
110         if (!log)
111                 return;
112
113         len_left = KUNIT_LOG_SIZE - strlen(log) - 1;
114         if (len_left <= 0)
115                 return;
116
117         va_start(args, fmt);
118         vsnprintf(line, sizeof(line), fmt, args);
119         va_end(args);
120
121         strncat(log, line, len_left);
122 }
123 EXPORT_SYMBOL_GPL(kunit_log_append);
124
125 size_t kunit_suite_num_test_cases(struct kunit_suite *suite)
126 {
127         struct kunit_case *test_case;
128         size_t len = 0;
129
130         kunit_suite_for_each_test_case(suite, test_case)
131                 len++;
132
133         return len;
134 }
135 EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
136
137 static void kunit_print_subtest_start(struct kunit_suite *suite)
138 {
139         kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "# Subtest: %s",
140                   suite->name);
141         kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "1..%zd",
142                   kunit_suite_num_test_cases(suite));
143 }
144
145 static void kunit_print_ok_not_ok(void *test_or_suite,
146                                   bool is_test,
147                                   enum kunit_status status,
148                                   size_t test_number,
149                                   const char *description,
150                                   const char *directive)
151 {
152         struct kunit_suite *suite = is_test ? NULL : test_or_suite;
153         struct kunit *test = is_test ? test_or_suite : NULL;
154         const char *directive_header = (status == KUNIT_SKIPPED) ? " # SKIP " : "";
155
156         /*
157          * We do not log the test suite results as doing so would
158          * mean debugfs display would consist of the test suite
159          * description and status prior to individual test results.
160          * Hence directly printk the suite status, and we will
161          * separately seq_printf() the suite status for the debugfs
162          * representation.
163          */
164         if (suite)
165                 pr_info("%s %zd - %s%s%s\n",
166                         kunit_status_to_ok_not_ok(status),
167                         test_number, description, directive_header,
168                         (status == KUNIT_SKIPPED) ? directive : "");
169         else
170                 kunit_log(KERN_INFO, test,
171                           KUNIT_SUBTEST_INDENT "%s %zd - %s%s%s",
172                           kunit_status_to_ok_not_ok(status),
173                           test_number, description, directive_header,
174                           (status == KUNIT_SKIPPED) ? directive : "");
175 }
176
177 enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite)
178 {
179         const struct kunit_case *test_case;
180         enum kunit_status status = KUNIT_SKIPPED;
181
182         kunit_suite_for_each_test_case(suite, test_case) {
183                 if (test_case->status == KUNIT_FAILURE)
184                         return KUNIT_FAILURE;
185                 else if (test_case->status == KUNIT_SUCCESS)
186                         status = KUNIT_SUCCESS;
187         }
188
189         return status;
190 }
191 EXPORT_SYMBOL_GPL(kunit_suite_has_succeeded);
192
193 static void kunit_print_subtest_end(struct kunit_suite *suite)
194 {
195         static size_t kunit_suite_counter = 1;
196
197         kunit_print_ok_not_ok((void *)suite, false,
198                               kunit_suite_has_succeeded(suite),
199                               kunit_suite_counter++,
200                               suite->name,
201                               suite->status_comment);
202 }
203
204 unsigned int kunit_test_case_num(struct kunit_suite *suite,
205                                  struct kunit_case *test_case)
206 {
207         struct kunit_case *tc;
208         unsigned int i = 1;
209
210         kunit_suite_for_each_test_case(suite, tc) {
211                 if (tc == test_case)
212                         return i;
213                 i++;
214         }
215
216         return 0;
217 }
218 EXPORT_SYMBOL_GPL(kunit_test_case_num);
219
220 static void kunit_print_string_stream(struct kunit *test,
221                                       struct string_stream *stream)
222 {
223         struct string_stream_fragment *fragment;
224         char *buf;
225
226         if (string_stream_is_empty(stream))
227                 return;
228
229         buf = string_stream_get_string(stream);
230         if (!buf) {
231                 kunit_err(test,
232                           "Could not allocate buffer, dumping stream:\n");
233                 list_for_each_entry(fragment, &stream->fragments, node) {
234                         kunit_err(test, "%s", fragment->fragment);
235                 }
236                 kunit_err(test, "\n");
237         } else {
238                 kunit_err(test, "%s", buf);
239                 kunit_kfree(test, buf);
240         }
241 }
242
243 static void kunit_fail(struct kunit *test, struct kunit_assert *assert)
244 {
245         struct string_stream *stream;
246
247         kunit_set_failure(test);
248
249         stream = alloc_string_stream(test, GFP_KERNEL);
250         if (!stream) {
251                 WARN(true,
252                      "Could not allocate stream to print failed assertion in %s:%d\n",
253                      assert->file,
254                      assert->line);
255                 return;
256         }
257
258         assert->format(assert, stream);
259
260         kunit_print_string_stream(test, stream);
261
262         WARN_ON(string_stream_destroy(stream));
263 }
264
265 static void __noreturn kunit_abort(struct kunit *test)
266 {
267         kunit_try_catch_throw(&test->try_catch); /* Does not return. */
268
269         /*
270          * Throw could not abort from test.
271          *
272          * XXX: we should never reach this line! As kunit_try_catch_throw is
273          * marked __noreturn.
274          */
275         WARN_ONCE(true, "Throw could not abort from test!\n");
276 }
277
278 void kunit_do_assertion(struct kunit *test,
279                         struct kunit_assert *assert,
280                         bool pass,
281                         const char *fmt, ...)
282 {
283         va_list args;
284
285         if (pass)
286                 return;
287
288         va_start(args, fmt);
289
290         assert->message.fmt = fmt;
291         assert->message.va = &args;
292
293         kunit_fail(test, assert);
294
295         va_end(args);
296
297         if (assert->type == KUNIT_ASSERTION)
298                 kunit_abort(test);
299 }
300 EXPORT_SYMBOL_GPL(kunit_do_assertion);
301
302 void kunit_init_test(struct kunit *test, const char *name, char *log)
303 {
304         spin_lock_init(&test->lock);
305         INIT_LIST_HEAD(&test->resources);
306         test->name = name;
307         test->log = log;
308         if (test->log)
309                 test->log[0] = '\0';
310         test->status = KUNIT_SUCCESS;
311         test->status_comment[0] = '\0';
312 }
313 EXPORT_SYMBOL_GPL(kunit_init_test);
314
315 /*
316  * Initializes and runs test case. Does not clean up or do post validations.
317  */
318 static void kunit_run_case_internal(struct kunit *test,
319                                     struct kunit_suite *suite,
320                                     struct kunit_case *test_case)
321 {
322         if (suite->init) {
323                 int ret;
324
325                 ret = suite->init(test);
326                 if (ret) {
327                         kunit_err(test, "failed to initialize: %d\n", ret);
328                         kunit_set_failure(test);
329                         return;
330                 }
331         }
332
333         test_case->run_case(test);
334 }
335
336 static void kunit_case_internal_cleanup(struct kunit *test)
337 {
338         kunit_cleanup(test);
339 }
340
341 /*
342  * Performs post validations and cleanup after a test case was run.
343  * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!
344  */
345 static void kunit_run_case_cleanup(struct kunit *test,
346                                    struct kunit_suite *suite)
347 {
348         if (suite->exit)
349                 suite->exit(test);
350
351         kunit_case_internal_cleanup(test);
352 }
353
354 struct kunit_try_catch_context {
355         struct kunit *test;
356         struct kunit_suite *suite;
357         struct kunit_case *test_case;
358 };
359
360 static void kunit_try_run_case(void *data)
361 {
362         struct kunit_try_catch_context *ctx = data;
363         struct kunit *test = ctx->test;
364         struct kunit_suite *suite = ctx->suite;
365         struct kunit_case *test_case = ctx->test_case;
366
367         current->kunit_test = test;
368
369         /*
370          * kunit_run_case_internal may encounter a fatal error; if it does,
371          * abort will be called, this thread will exit, and finally the parent
372          * thread will resume control and handle any necessary clean up.
373          */
374         kunit_run_case_internal(test, suite, test_case);
375         /* This line may never be reached. */
376         kunit_run_case_cleanup(test, suite);
377 }
378
379 static void kunit_catch_run_case(void *data)
380 {
381         struct kunit_try_catch_context *ctx = data;
382         struct kunit *test = ctx->test;
383         struct kunit_suite *suite = ctx->suite;
384         int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
385
386         if (try_exit_code) {
387                 kunit_set_failure(test);
388                 /*
389                  * Test case could not finish, we have no idea what state it is
390                  * in, so don't do clean up.
391                  */
392                 if (try_exit_code == -ETIMEDOUT) {
393                         kunit_err(test, "test case timed out\n");
394                 /*
395                  * Unknown internal error occurred preventing test case from
396                  * running, so there is nothing to clean up.
397                  */
398                 } else {
399                         kunit_err(test, "internal error occurred preventing test case from running: %d\n",
400                                   try_exit_code);
401                 }
402                 return;
403         }
404
405         /*
406          * Test case was run, but aborted. It is the test case's business as to
407          * whether it failed or not, we just need to clean up.
408          */
409         kunit_run_case_cleanup(test, suite);
410 }
411
412 /*
413  * Performs all logic to run a test case. It also catches most errors that
414  * occur in a test case and reports them as failures.
415  */
416 static void kunit_run_case_catch_errors(struct kunit_suite *suite,
417                                         struct kunit_case *test_case,
418                                         struct kunit *test)
419 {
420         struct kunit_try_catch_context context;
421         struct kunit_try_catch *try_catch;
422
423         kunit_init_test(test, test_case->name, test_case->log);
424         try_catch = &test->try_catch;
425
426         kunit_try_catch_init(try_catch,
427                              test,
428                              kunit_try_run_case,
429                              kunit_catch_run_case);
430         context.test = test;
431         context.suite = suite;
432         context.test_case = test_case;
433         kunit_try_catch_run(try_catch, &context);
434
435         /* Propagate the parameter result to the test case. */
436         if (test->status == KUNIT_FAILURE)
437                 test_case->status = KUNIT_FAILURE;
438         else if (test_case->status != KUNIT_FAILURE && test->status == KUNIT_SUCCESS)
439                 test_case->status = KUNIT_SUCCESS;
440 }
441
442 static void kunit_print_suite_stats(struct kunit_suite *suite,
443                                     struct kunit_result_stats suite_stats,
444                                     struct kunit_result_stats param_stats)
445 {
446         if (kunit_should_print_stats(suite_stats)) {
447                 kunit_log(KERN_INFO, suite,
448                           "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
449                           suite->name,
450                           suite_stats.passed,
451                           suite_stats.failed,
452                           suite_stats.skipped,
453                           suite_stats.total);
454         }
455
456         if (kunit_should_print_stats(param_stats)) {
457                 kunit_log(KERN_INFO, suite,
458                           "# Totals: pass:%lu fail:%lu skip:%lu total:%lu",
459                           param_stats.passed,
460                           param_stats.failed,
461                           param_stats.skipped,
462                           param_stats.total);
463         }
464 }
465
466 static void kunit_update_stats(struct kunit_result_stats *stats,
467                                enum kunit_status status)
468 {
469         switch (status) {
470         case KUNIT_SUCCESS:
471                 stats->passed++;
472                 break;
473         case KUNIT_SKIPPED:
474                 stats->skipped++;
475                 break;
476         case KUNIT_FAILURE:
477                 stats->failed++;
478                 break;
479         }
480
481         stats->total++;
482 }
483
484 static void kunit_accumulate_stats(struct kunit_result_stats *total,
485                                    struct kunit_result_stats add)
486 {
487         total->passed += add.passed;
488         total->skipped += add.skipped;
489         total->failed += add.failed;
490         total->total += add.total;
491 }
492
493 int kunit_run_tests(struct kunit_suite *suite)
494 {
495         char param_desc[KUNIT_PARAM_DESC_SIZE];
496         struct kunit_case *test_case;
497         struct kunit_result_stats suite_stats = { 0 };
498         struct kunit_result_stats total_stats = { 0 };
499
500         kunit_print_subtest_start(suite);
501
502         kunit_suite_for_each_test_case(suite, test_case) {
503                 struct kunit test = { .param_value = NULL, .param_index = 0 };
504                 struct kunit_result_stats param_stats = { 0 };
505                 test_case->status = KUNIT_SKIPPED;
506
507                 if (!test_case->generate_params) {
508                         /* Non-parameterised test. */
509                         kunit_run_case_catch_errors(suite, test_case, &test);
510                         kunit_update_stats(&param_stats, test.status);
511                 } else {
512                         /* Get initial param. */
513                         param_desc[0] = '\0';
514                         test.param_value = test_case->generate_params(NULL, param_desc);
515
516                         while (test.param_value) {
517                                 kunit_run_case_catch_errors(suite, test_case, &test);
518
519                                 if (param_desc[0] == '\0') {
520                                         snprintf(param_desc, sizeof(param_desc),
521                                                  "param-%d", test.param_index);
522                                 }
523
524                                 kunit_log(KERN_INFO, &test,
525                                           KUNIT_SUBTEST_INDENT
526                                           "# %s: %s %d - %s",
527                                           test_case->name,
528                                           kunit_status_to_ok_not_ok(test.status),
529                                           test.param_index + 1, param_desc);
530
531                                 /* Get next param. */
532                                 param_desc[0] = '\0';
533                                 test.param_value = test_case->generate_params(test.param_value, param_desc);
534                                 test.param_index++;
535
536                                 kunit_update_stats(&param_stats, test.status);
537                         }
538                 }
539
540
541                 kunit_print_test_stats(&test, param_stats);
542
543                 kunit_print_ok_not_ok(&test, true, test_case->status,
544                                       kunit_test_case_num(suite, test_case),
545                                       test_case->name,
546                                       test.status_comment);
547
548                 kunit_update_stats(&suite_stats, test_case->status);
549                 kunit_accumulate_stats(&total_stats, param_stats);
550         }
551
552         kunit_print_suite_stats(suite, suite_stats, total_stats);
553         kunit_print_subtest_end(suite);
554
555         return 0;
556 }
557 EXPORT_SYMBOL_GPL(kunit_run_tests);
558
559 static void kunit_init_suite(struct kunit_suite *suite)
560 {
561         kunit_debugfs_create_suite(suite);
562         suite->status_comment[0] = '\0';
563 }
564
565 int __kunit_test_suites_init(struct kunit_suite * const * const suites)
566 {
567         unsigned int i;
568
569         for (i = 0; suites[i] != NULL; i++) {
570                 kunit_init_suite(suites[i]);
571                 kunit_run_tests(suites[i]);
572         }
573         return 0;
574 }
575 EXPORT_SYMBOL_GPL(__kunit_test_suites_init);
576
577 static void kunit_exit_suite(struct kunit_suite *suite)
578 {
579         kunit_debugfs_destroy_suite(suite);
580 }
581
582 void __kunit_test_suites_exit(struct kunit_suite **suites)
583 {
584         unsigned int i;
585
586         for (i = 0; suites[i] != NULL; i++)
587                 kunit_exit_suite(suites[i]);
588 }
589 EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
590
591 /*
592  * Used for static resources and when a kunit_resource * has been created by
593  * kunit_alloc_resource().  When an init function is supplied, @data is passed
594  * into the init function; otherwise, we simply set the resource data field to
595  * the data value passed in.
596  */
597 int kunit_add_resource(struct kunit *test,
598                        kunit_resource_init_t init,
599                        kunit_resource_free_t free,
600                        struct kunit_resource *res,
601                        void *data)
602 {
603         int ret = 0;
604         unsigned long flags;
605
606         res->free = free;
607         kref_init(&res->refcount);
608
609         if (init) {
610                 ret = init(res, data);
611                 if (ret)
612                         return ret;
613         } else {
614                 res->data = data;
615         }
616
617         spin_lock_irqsave(&test->lock, flags);
618         list_add_tail(&res->node, &test->resources);
619         /* refcount for list is established by kref_init() */
620         spin_unlock_irqrestore(&test->lock, flags);
621
622         return ret;
623 }
624 EXPORT_SYMBOL_GPL(kunit_add_resource);
625
626 int kunit_add_named_resource(struct kunit *test,
627                              kunit_resource_init_t init,
628                              kunit_resource_free_t free,
629                              struct kunit_resource *res,
630                              const char *name,
631                              void *data)
632 {
633         struct kunit_resource *existing;
634
635         if (!name)
636                 return -EINVAL;
637
638         existing = kunit_find_named_resource(test, name);
639         if (existing) {
640                 kunit_put_resource(existing);
641                 return -EEXIST;
642         }
643
644         res->name = name;
645
646         return kunit_add_resource(test, init, free, res, data);
647 }
648 EXPORT_SYMBOL_GPL(kunit_add_named_resource);
649
650 struct kunit_resource *kunit_alloc_and_get_resource(struct kunit *test,
651                                                     kunit_resource_init_t init,
652                                                     kunit_resource_free_t free,
653                                                     gfp_t internal_gfp,
654                                                     void *data)
655 {
656         struct kunit_resource *res;
657         int ret;
658
659         res = kzalloc(sizeof(*res), internal_gfp);
660         if (!res)
661                 return NULL;
662
663         ret = kunit_add_resource(test, init, free, res, data);
664         if (!ret) {
665                 /*
666                  * bump refcount for get; kunit_resource_put() should be called
667                  * when done.
668                  */
669                 kunit_get_resource(res);
670                 return res;
671         }
672         return NULL;
673 }
674 EXPORT_SYMBOL_GPL(kunit_alloc_and_get_resource);
675
676 void kunit_remove_resource(struct kunit *test, struct kunit_resource *res)
677 {
678         unsigned long flags;
679
680         spin_lock_irqsave(&test->lock, flags);
681         list_del(&res->node);
682         spin_unlock_irqrestore(&test->lock, flags);
683         kunit_put_resource(res);
684 }
685 EXPORT_SYMBOL_GPL(kunit_remove_resource);
686
687 int kunit_destroy_resource(struct kunit *test, kunit_resource_match_t match,
688                            void *match_data)
689 {
690         struct kunit_resource *res = kunit_find_resource(test, match,
691                                                          match_data);
692
693         if (!res)
694                 return -ENOENT;
695
696         kunit_remove_resource(test, res);
697
698         /* We have a reference also via _find(); drop it. */
699         kunit_put_resource(res);
700
701         return 0;
702 }
703 EXPORT_SYMBOL_GPL(kunit_destroy_resource);
704
705 struct kunit_kmalloc_array_params {
706         size_t n;
707         size_t size;
708         gfp_t gfp;
709 };
710
711 static int kunit_kmalloc_array_init(struct kunit_resource *res, void *context)
712 {
713         struct kunit_kmalloc_array_params *params = context;
714
715         res->data = kmalloc_array(params->n, params->size, params->gfp);
716         if (!res->data)
717                 return -ENOMEM;
718
719         return 0;
720 }
721
722 static void kunit_kmalloc_array_free(struct kunit_resource *res)
723 {
724         kfree(res->data);
725 }
726
727 void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)
728 {
729         struct kunit_kmalloc_array_params params = {
730                 .size = size,
731                 .n = n,
732                 .gfp = gfp
733         };
734
735         return kunit_alloc_resource(test,
736                                     kunit_kmalloc_array_init,
737                                     kunit_kmalloc_array_free,
738                                     gfp,
739                                     &params);
740 }
741 EXPORT_SYMBOL_GPL(kunit_kmalloc_array);
742
743 void kunit_kfree(struct kunit *test, const void *ptr)
744 {
745         struct kunit_resource *res;
746
747         res = kunit_find_resource(test, kunit_resource_instance_match,
748                                   (void *)ptr);
749
750         /*
751          * Removing the resource from the list of resources drops the
752          * reference count to 1; the final put will trigger the free.
753          */
754         kunit_remove_resource(test, res);
755
756         kunit_put_resource(res);
757
758 }
759 EXPORT_SYMBOL_GPL(kunit_kfree);
760
761 void kunit_cleanup(struct kunit *test)
762 {
763         struct kunit_resource *res;
764         unsigned long flags;
765
766         /*
767          * test->resources is a stack - each allocation must be freed in the
768          * reverse order from which it was added since one resource may depend
769          * on another for its entire lifetime.
770          * Also, we cannot use the normal list_for_each constructs, even the
771          * safe ones because *arbitrary* nodes may be deleted when
772          * kunit_resource_free is called; the list_for_each_safe variants only
773          * protect against the current node being deleted, not the next.
774          */
775         while (true) {
776                 spin_lock_irqsave(&test->lock, flags);
777                 if (list_empty(&test->resources)) {
778                         spin_unlock_irqrestore(&test->lock, flags);
779                         break;
780                 }
781                 res = list_last_entry(&test->resources,
782                                       struct kunit_resource,
783                                       node);
784                 /*
785                  * Need to unlock here as a resource may remove another
786                  * resource, and this can't happen if the test->lock
787                  * is held.
788                  */
789                 spin_unlock_irqrestore(&test->lock, flags);
790                 kunit_remove_resource(test, res);
791         }
792         current->kunit_test = NULL;
793 }
794 EXPORT_SYMBOL_GPL(kunit_cleanup);
795
796 static int __init kunit_init(void)
797 {
798         kunit_debugfs_init();
799
800         return 0;
801 }
802 late_initcall(kunit_init);
803
804 static void __exit kunit_exit(void)
805 {
806         kunit_debugfs_cleanup();
807 }
808 module_exit(kunit_exit);
809
810 MODULE_LICENSE("GPL v2");