Merge tag 'microblaze-v5.15' of git://git.monstr.eu/linux-2.6-microblaze
[platform/kernel/linux-rpi.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                         /* Get initial param. */
509                         param_desc[0] = '\0';
510                         test.param_value = test_case->generate_params(NULL, param_desc);
511                 }
512
513                 do {
514                         kunit_run_case_catch_errors(suite, test_case, &test);
515
516                         if (test_case->generate_params) {
517                                 if (param_desc[0] == '\0') {
518                                         snprintf(param_desc, sizeof(param_desc),
519                                                  "param-%d", test.param_index);
520                                 }
521
522                                 kunit_log(KERN_INFO, &test,
523                                           KUNIT_SUBTEST_INDENT
524                                           "# %s: %s %d - %s",
525                                           test_case->name,
526                                           kunit_status_to_ok_not_ok(test.status),
527                                           test.param_index + 1, param_desc);
528
529                                 /* Get next param. */
530                                 param_desc[0] = '\0';
531                                 test.param_value = test_case->generate_params(test.param_value, param_desc);
532                                 test.param_index++;
533                         }
534
535                         kunit_update_stats(&param_stats, test.status);
536
537                 } while (test.param_value);
538
539                 kunit_print_test_stats(&test, param_stats);
540
541                 kunit_print_ok_not_ok(&test, true, test_case->status,
542                                       kunit_test_case_num(suite, test_case),
543                                       test_case->name,
544                                       test.status_comment);
545
546                 kunit_update_stats(&suite_stats, test_case->status);
547                 kunit_accumulate_stats(&total_stats, param_stats);
548         }
549
550         kunit_print_suite_stats(suite, suite_stats, total_stats);
551         kunit_print_subtest_end(suite);
552
553         return 0;
554 }
555 EXPORT_SYMBOL_GPL(kunit_run_tests);
556
557 static void kunit_init_suite(struct kunit_suite *suite)
558 {
559         kunit_debugfs_create_suite(suite);
560         suite->status_comment[0] = '\0';
561 }
562
563 int __kunit_test_suites_init(struct kunit_suite * const * const suites)
564 {
565         unsigned int i;
566
567         for (i = 0; suites[i] != NULL; i++) {
568                 kunit_init_suite(suites[i]);
569                 kunit_run_tests(suites[i]);
570         }
571         return 0;
572 }
573 EXPORT_SYMBOL_GPL(__kunit_test_suites_init);
574
575 static void kunit_exit_suite(struct kunit_suite *suite)
576 {
577         kunit_debugfs_destroy_suite(suite);
578 }
579
580 void __kunit_test_suites_exit(struct kunit_suite **suites)
581 {
582         unsigned int i;
583
584         for (i = 0; suites[i] != NULL; i++)
585                 kunit_exit_suite(suites[i]);
586 }
587 EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
588
589 /*
590  * Used for static resources and when a kunit_resource * has been created by
591  * kunit_alloc_resource().  When an init function is supplied, @data is passed
592  * into the init function; otherwise, we simply set the resource data field to
593  * the data value passed in.
594  */
595 int kunit_add_resource(struct kunit *test,
596                        kunit_resource_init_t init,
597                        kunit_resource_free_t free,
598                        struct kunit_resource *res,
599                        void *data)
600 {
601         int ret = 0;
602         unsigned long flags;
603
604         res->free = free;
605         kref_init(&res->refcount);
606
607         if (init) {
608                 ret = init(res, data);
609                 if (ret)
610                         return ret;
611         } else {
612                 res->data = data;
613         }
614
615         spin_lock_irqsave(&test->lock, flags);
616         list_add_tail(&res->node, &test->resources);
617         /* refcount for list is established by kref_init() */
618         spin_unlock_irqrestore(&test->lock, flags);
619
620         return ret;
621 }
622 EXPORT_SYMBOL_GPL(kunit_add_resource);
623
624 int kunit_add_named_resource(struct kunit *test,
625                              kunit_resource_init_t init,
626                              kunit_resource_free_t free,
627                              struct kunit_resource *res,
628                              const char *name,
629                              void *data)
630 {
631         struct kunit_resource *existing;
632
633         if (!name)
634                 return -EINVAL;
635
636         existing = kunit_find_named_resource(test, name);
637         if (existing) {
638                 kunit_put_resource(existing);
639                 return -EEXIST;
640         }
641
642         res->name = name;
643
644         return kunit_add_resource(test, init, free, res, data);
645 }
646 EXPORT_SYMBOL_GPL(kunit_add_named_resource);
647
648 struct kunit_resource *kunit_alloc_and_get_resource(struct kunit *test,
649                                                     kunit_resource_init_t init,
650                                                     kunit_resource_free_t free,
651                                                     gfp_t internal_gfp,
652                                                     void *data)
653 {
654         struct kunit_resource *res;
655         int ret;
656
657         res = kzalloc(sizeof(*res), internal_gfp);
658         if (!res)
659                 return NULL;
660
661         ret = kunit_add_resource(test, init, free, res, data);
662         if (!ret) {
663                 /*
664                  * bump refcount for get; kunit_resource_put() should be called
665                  * when done.
666                  */
667                 kunit_get_resource(res);
668                 return res;
669         }
670         return NULL;
671 }
672 EXPORT_SYMBOL_GPL(kunit_alloc_and_get_resource);
673
674 void kunit_remove_resource(struct kunit *test, struct kunit_resource *res)
675 {
676         unsigned long flags;
677
678         spin_lock_irqsave(&test->lock, flags);
679         list_del(&res->node);
680         spin_unlock_irqrestore(&test->lock, flags);
681         kunit_put_resource(res);
682 }
683 EXPORT_SYMBOL_GPL(kunit_remove_resource);
684
685 int kunit_destroy_resource(struct kunit *test, kunit_resource_match_t match,
686                            void *match_data)
687 {
688         struct kunit_resource *res = kunit_find_resource(test, match,
689                                                          match_data);
690
691         if (!res)
692                 return -ENOENT;
693
694         kunit_remove_resource(test, res);
695
696         /* We have a reference also via _find(); drop it. */
697         kunit_put_resource(res);
698
699         return 0;
700 }
701 EXPORT_SYMBOL_GPL(kunit_destroy_resource);
702
703 struct kunit_kmalloc_array_params {
704         size_t n;
705         size_t size;
706         gfp_t gfp;
707 };
708
709 static int kunit_kmalloc_array_init(struct kunit_resource *res, void *context)
710 {
711         struct kunit_kmalloc_array_params *params = context;
712
713         res->data = kmalloc_array(params->n, params->size, params->gfp);
714         if (!res->data)
715                 return -ENOMEM;
716
717         return 0;
718 }
719
720 static void kunit_kmalloc_array_free(struct kunit_resource *res)
721 {
722         kfree(res->data);
723 }
724
725 void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)
726 {
727         struct kunit_kmalloc_array_params params = {
728                 .size = size,
729                 .n = n,
730                 .gfp = gfp
731         };
732
733         return kunit_alloc_resource(test,
734                                     kunit_kmalloc_array_init,
735                                     kunit_kmalloc_array_free,
736                                     gfp,
737                                     &params);
738 }
739 EXPORT_SYMBOL_GPL(kunit_kmalloc_array);
740
741 void kunit_kfree(struct kunit *test, const void *ptr)
742 {
743         struct kunit_resource *res;
744
745         res = kunit_find_resource(test, kunit_resource_instance_match,
746                                   (void *)ptr);
747
748         /*
749          * Removing the resource from the list of resources drops the
750          * reference count to 1; the final put will trigger the free.
751          */
752         kunit_remove_resource(test, res);
753
754         kunit_put_resource(res);
755
756 }
757 EXPORT_SYMBOL_GPL(kunit_kfree);
758
759 void kunit_cleanup(struct kunit *test)
760 {
761         struct kunit_resource *res;
762         unsigned long flags;
763
764         /*
765          * test->resources is a stack - each allocation must be freed in the
766          * reverse order from which it was added since one resource may depend
767          * on another for its entire lifetime.
768          * Also, we cannot use the normal list_for_each constructs, even the
769          * safe ones because *arbitrary* nodes may be deleted when
770          * kunit_resource_free is called; the list_for_each_safe variants only
771          * protect against the current node being deleted, not the next.
772          */
773         while (true) {
774                 spin_lock_irqsave(&test->lock, flags);
775                 if (list_empty(&test->resources)) {
776                         spin_unlock_irqrestore(&test->lock, flags);
777                         break;
778                 }
779                 res = list_last_entry(&test->resources,
780                                       struct kunit_resource,
781                                       node);
782                 /*
783                  * Need to unlock here as a resource may remove another
784                  * resource, and this can't happen if the test->lock
785                  * is held.
786                  */
787                 spin_unlock_irqrestore(&test->lock, flags);
788                 kunit_remove_resource(test, res);
789         }
790         current->kunit_test = NULL;
791 }
792 EXPORT_SYMBOL_GPL(kunit_cleanup);
793
794 static int __init kunit_init(void)
795 {
796         kunit_debugfs_init();
797
798         return 0;
799 }
800 late_initcall(kunit_init);
801
802 static void __exit kunit_exit(void)
803 {
804         kunit_debugfs_cleanup();
805 }
806 module_exit(kunit_exit);
807
808 MODULE_LICENSE("GPL v2");