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