xref: /openbmc/linux/lib/kunit/test.c (revision acf50233)
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/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_suite_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 	if (suite->suite_init_err)
183 		return KUNIT_FAILURE;
184 
185 	kunit_suite_for_each_test_case(suite, test_case) {
186 		if (test_case->status == KUNIT_FAILURE)
187 			return KUNIT_FAILURE;
188 		else if (test_case->status == KUNIT_SUCCESS)
189 			status = KUNIT_SUCCESS;
190 	}
191 
192 	return status;
193 }
194 EXPORT_SYMBOL_GPL(kunit_suite_has_succeeded);
195 
196 static size_t kunit_suite_counter = 1;
197 
198 static void kunit_print_suite_end(struct kunit_suite *suite)
199 {
200 	kunit_print_ok_not_ok((void *)suite, false,
201 			      kunit_suite_has_succeeded(suite),
202 			      kunit_suite_counter++,
203 			      suite->name,
204 			      suite->status_comment);
205 }
206 
207 unsigned int kunit_test_case_num(struct kunit_suite *suite,
208 				 struct kunit_case *test_case)
209 {
210 	struct kunit_case *tc;
211 	unsigned int i = 1;
212 
213 	kunit_suite_for_each_test_case(suite, tc) {
214 		if (tc == test_case)
215 			return i;
216 		i++;
217 	}
218 
219 	return 0;
220 }
221 EXPORT_SYMBOL_GPL(kunit_test_case_num);
222 
223 static void kunit_print_string_stream(struct kunit *test,
224 				      struct string_stream *stream)
225 {
226 	struct string_stream_fragment *fragment;
227 	char *buf;
228 
229 	if (string_stream_is_empty(stream))
230 		return;
231 
232 	buf = string_stream_get_string(stream);
233 	if (!buf) {
234 		kunit_err(test,
235 			  "Could not allocate buffer, dumping stream:\n");
236 		list_for_each_entry(fragment, &stream->fragments, node) {
237 			kunit_err(test, "%s", fragment->fragment);
238 		}
239 		kunit_err(test, "\n");
240 	} else {
241 		kunit_err(test, "%s", buf);
242 		kunit_kfree(test, buf);
243 	}
244 }
245 
246 static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,
247 		       enum kunit_assert_type type, const struct kunit_assert *assert,
248 		       const struct va_format *message)
249 {
250 	struct string_stream *stream;
251 
252 	kunit_set_failure(test);
253 
254 	stream = alloc_string_stream(test, GFP_KERNEL);
255 	if (!stream) {
256 		WARN(true,
257 		     "Could not allocate stream to print failed assertion in %s:%d\n",
258 		     loc->file,
259 		     loc->line);
260 		return;
261 	}
262 
263 	kunit_assert_prologue(loc, type, stream);
264 	assert->format(assert, message, stream);
265 
266 	kunit_print_string_stream(test, stream);
267 
268 	WARN_ON(string_stream_destroy(stream));
269 }
270 
271 static void __noreturn kunit_abort(struct kunit *test)
272 {
273 	kunit_try_catch_throw(&test->try_catch); /* Does not return. */
274 
275 	/*
276 	 * Throw could not abort from test.
277 	 *
278 	 * XXX: we should never reach this line! As kunit_try_catch_throw is
279 	 * marked __noreturn.
280 	 */
281 	WARN_ONCE(true, "Throw could not abort from test!\n");
282 }
283 
284 void kunit_do_failed_assertion(struct kunit *test,
285 			       const struct kunit_loc *loc,
286 			       enum kunit_assert_type type,
287 			       const struct kunit_assert *assert,
288 			       const char *fmt, ...)
289 {
290 	va_list args;
291 	struct va_format message;
292 	va_start(args, fmt);
293 
294 	message.fmt = fmt;
295 	message.va = &args;
296 
297 	kunit_fail(test, loc, type, assert, &message);
298 
299 	va_end(args);
300 
301 	if (type == KUNIT_ASSERTION)
302 		kunit_abort(test);
303 }
304 EXPORT_SYMBOL_GPL(kunit_do_failed_assertion);
305 
306 void kunit_init_test(struct kunit *test, const char *name, char *log)
307 {
308 	spin_lock_init(&test->lock);
309 	INIT_LIST_HEAD(&test->resources);
310 	test->name = name;
311 	test->log = log;
312 	if (test->log)
313 		test->log[0] = '\0';
314 	test->status = KUNIT_SUCCESS;
315 	test->status_comment[0] = '\0';
316 }
317 EXPORT_SYMBOL_GPL(kunit_init_test);
318 
319 /*
320  * Initializes and runs test case. Does not clean up or do post validations.
321  */
322 static void kunit_run_case_internal(struct kunit *test,
323 				    struct kunit_suite *suite,
324 				    struct kunit_case *test_case)
325 {
326 	if (suite->init) {
327 		int ret;
328 
329 		ret = suite->init(test);
330 		if (ret) {
331 			kunit_err(test, "failed to initialize: %d\n", ret);
332 			kunit_set_failure(test);
333 			return;
334 		}
335 	}
336 
337 	test_case->run_case(test);
338 }
339 
340 static void kunit_case_internal_cleanup(struct kunit *test)
341 {
342 	kunit_cleanup(test);
343 }
344 
345 /*
346  * Performs post validations and cleanup after a test case was run.
347  * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!
348  */
349 static void kunit_run_case_cleanup(struct kunit *test,
350 				   struct kunit_suite *suite)
351 {
352 	if (suite->exit)
353 		suite->exit(test);
354 
355 	kunit_case_internal_cleanup(test);
356 }
357 
358 struct kunit_try_catch_context {
359 	struct kunit *test;
360 	struct kunit_suite *suite;
361 	struct kunit_case *test_case;
362 };
363 
364 static void kunit_try_run_case(void *data)
365 {
366 	struct kunit_try_catch_context *ctx = data;
367 	struct kunit *test = ctx->test;
368 	struct kunit_suite *suite = ctx->suite;
369 	struct kunit_case *test_case = ctx->test_case;
370 
371 	current->kunit_test = test;
372 
373 	/*
374 	 * kunit_run_case_internal may encounter a fatal error; if it does,
375 	 * abort will be called, this thread will exit, and finally the parent
376 	 * thread will resume control and handle any necessary clean up.
377 	 */
378 	kunit_run_case_internal(test, suite, test_case);
379 	/* This line may never be reached. */
380 	kunit_run_case_cleanup(test, suite);
381 }
382 
383 static void kunit_catch_run_case(void *data)
384 {
385 	struct kunit_try_catch_context *ctx = data;
386 	struct kunit *test = ctx->test;
387 	struct kunit_suite *suite = ctx->suite;
388 	int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
389 
390 	if (try_exit_code) {
391 		kunit_set_failure(test);
392 		/*
393 		 * Test case could not finish, we have no idea what state it is
394 		 * in, so don't do clean up.
395 		 */
396 		if (try_exit_code == -ETIMEDOUT) {
397 			kunit_err(test, "test case timed out\n");
398 		/*
399 		 * Unknown internal error occurred preventing test case from
400 		 * running, so there is nothing to clean up.
401 		 */
402 		} else {
403 			kunit_err(test, "internal error occurred preventing test case from running: %d\n",
404 				  try_exit_code);
405 		}
406 		return;
407 	}
408 
409 	/*
410 	 * Test case was run, but aborted. It is the test case's business as to
411 	 * whether it failed or not, we just need to clean up.
412 	 */
413 	kunit_run_case_cleanup(test, suite);
414 }
415 
416 /*
417  * Performs all logic to run a test case. It also catches most errors that
418  * occur in a test case and reports them as failures.
419  */
420 static void kunit_run_case_catch_errors(struct kunit_suite *suite,
421 					struct kunit_case *test_case,
422 					struct kunit *test)
423 {
424 	struct kunit_try_catch_context context;
425 	struct kunit_try_catch *try_catch;
426 
427 	kunit_init_test(test, test_case->name, test_case->log);
428 	try_catch = &test->try_catch;
429 
430 	kunit_try_catch_init(try_catch,
431 			     test,
432 			     kunit_try_run_case,
433 			     kunit_catch_run_case);
434 	context.test = test;
435 	context.suite = suite;
436 	context.test_case = test_case;
437 	kunit_try_catch_run(try_catch, &context);
438 
439 	/* Propagate the parameter result to the test case. */
440 	if (test->status == KUNIT_FAILURE)
441 		test_case->status = KUNIT_FAILURE;
442 	else if (test_case->status != KUNIT_FAILURE && test->status == KUNIT_SUCCESS)
443 		test_case->status = KUNIT_SUCCESS;
444 }
445 
446 static void kunit_print_suite_stats(struct kunit_suite *suite,
447 				    struct kunit_result_stats suite_stats,
448 				    struct kunit_result_stats param_stats)
449 {
450 	if (kunit_should_print_stats(suite_stats)) {
451 		kunit_log(KERN_INFO, suite,
452 			  "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
453 			  suite->name,
454 			  suite_stats.passed,
455 			  suite_stats.failed,
456 			  suite_stats.skipped,
457 			  suite_stats.total);
458 	}
459 
460 	if (kunit_should_print_stats(param_stats)) {
461 		kunit_log(KERN_INFO, suite,
462 			  "# Totals: pass:%lu fail:%lu skip:%lu total:%lu",
463 			  param_stats.passed,
464 			  param_stats.failed,
465 			  param_stats.skipped,
466 			  param_stats.total);
467 	}
468 }
469 
470 static void kunit_update_stats(struct kunit_result_stats *stats,
471 			       enum kunit_status status)
472 {
473 	switch (status) {
474 	case KUNIT_SUCCESS:
475 		stats->passed++;
476 		break;
477 	case KUNIT_SKIPPED:
478 		stats->skipped++;
479 		break;
480 	case KUNIT_FAILURE:
481 		stats->failed++;
482 		break;
483 	}
484 
485 	stats->total++;
486 }
487 
488 static void kunit_accumulate_stats(struct kunit_result_stats *total,
489 				   struct kunit_result_stats add)
490 {
491 	total->passed += add.passed;
492 	total->skipped += add.skipped;
493 	total->failed += add.failed;
494 	total->total += add.total;
495 }
496 
497 int kunit_run_tests(struct kunit_suite *suite)
498 {
499 	char param_desc[KUNIT_PARAM_DESC_SIZE];
500 	struct kunit_case *test_case;
501 	struct kunit_result_stats suite_stats = { 0 };
502 	struct kunit_result_stats total_stats = { 0 };
503 
504 	if (suite->suite_init) {
505 		suite->suite_init_err = suite->suite_init(suite);
506 		if (suite->suite_init_err) {
507 			kunit_err(suite, KUNIT_SUBTEST_INDENT
508 				  "# failed to initialize (%d)", suite->suite_init_err);
509 			goto suite_end;
510 		}
511 	}
512 
513 	kunit_print_suite_start(suite);
514 
515 	kunit_suite_for_each_test_case(suite, test_case) {
516 		struct kunit test = { .param_value = NULL, .param_index = 0 };
517 		struct kunit_result_stats param_stats = { 0 };
518 		test_case->status = KUNIT_SKIPPED;
519 
520 		if (!test_case->generate_params) {
521 			/* Non-parameterised test. */
522 			kunit_run_case_catch_errors(suite, test_case, &test);
523 			kunit_update_stats(&param_stats, test.status);
524 		} else {
525 			/* Get initial param. */
526 			param_desc[0] = '\0';
527 			test.param_value = test_case->generate_params(NULL, param_desc);
528 			kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
529 				  "# Subtest: %s", test_case->name);
530 
531 			while (test.param_value) {
532 				kunit_run_case_catch_errors(suite, test_case, &test);
533 
534 				if (param_desc[0] == '\0') {
535 					snprintf(param_desc, sizeof(param_desc),
536 						 "param-%d", test.param_index);
537 				}
538 
539 				kunit_log(KERN_INFO, &test,
540 					  KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
541 					  "%s %d - %s",
542 					  kunit_status_to_ok_not_ok(test.status),
543 					  test.param_index + 1, param_desc);
544 
545 				/* Get next param. */
546 				param_desc[0] = '\0';
547 				test.param_value = test_case->generate_params(test.param_value, param_desc);
548 				test.param_index++;
549 
550 				kunit_update_stats(&param_stats, test.status);
551 			}
552 		}
553 
554 
555 		kunit_print_test_stats(&test, param_stats);
556 
557 		kunit_print_ok_not_ok(&test, true, test_case->status,
558 				      kunit_test_case_num(suite, test_case),
559 				      test_case->name,
560 				      test.status_comment);
561 
562 		kunit_update_stats(&suite_stats, test_case->status);
563 		kunit_accumulate_stats(&total_stats, param_stats);
564 	}
565 
566 	if (suite->suite_exit)
567 		suite->suite_exit(suite);
568 
569 	kunit_print_suite_stats(suite, suite_stats, total_stats);
570 suite_end:
571 	kunit_print_suite_end(suite);
572 
573 	return 0;
574 }
575 EXPORT_SYMBOL_GPL(kunit_run_tests);
576 
577 static void kunit_init_suite(struct kunit_suite *suite)
578 {
579 	kunit_debugfs_create_suite(suite);
580 	suite->status_comment[0] = '\0';
581 	suite->suite_init_err = 0;
582 }
583 
584 int __kunit_test_suites_init(struct kunit_suite * const * const suites)
585 {
586 	unsigned int i;
587 
588 	for (i = 0; suites[i] != NULL; i++) {
589 		kunit_init_suite(suites[i]);
590 		kunit_run_tests(suites[i]);
591 	}
592 	return 0;
593 }
594 EXPORT_SYMBOL_GPL(__kunit_test_suites_init);
595 
596 static void kunit_exit_suite(struct kunit_suite *suite)
597 {
598 	kunit_debugfs_destroy_suite(suite);
599 }
600 
601 void __kunit_test_suites_exit(struct kunit_suite **suites)
602 {
603 	unsigned int i;
604 
605 	for (i = 0; suites[i] != NULL; i++)
606 		kunit_exit_suite(suites[i]);
607 
608 	kunit_suite_counter = 1;
609 }
610 EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
611 
612 struct kunit_kmalloc_array_params {
613 	size_t n;
614 	size_t size;
615 	gfp_t gfp;
616 };
617 
618 static int kunit_kmalloc_array_init(struct kunit_resource *res, void *context)
619 {
620 	struct kunit_kmalloc_array_params *params = context;
621 
622 	res->data = kmalloc_array(params->n, params->size, params->gfp);
623 	if (!res->data)
624 		return -ENOMEM;
625 
626 	return 0;
627 }
628 
629 static void kunit_kmalloc_array_free(struct kunit_resource *res)
630 {
631 	kfree(res->data);
632 }
633 
634 void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)
635 {
636 	struct kunit_kmalloc_array_params params = {
637 		.size = size,
638 		.n = n,
639 		.gfp = gfp
640 	};
641 
642 	return kunit_alloc_resource(test,
643 				    kunit_kmalloc_array_init,
644 				    kunit_kmalloc_array_free,
645 				    gfp,
646 				    &params);
647 }
648 EXPORT_SYMBOL_GPL(kunit_kmalloc_array);
649 
650 void kunit_kfree(struct kunit *test, const void *ptr)
651 {
652 	struct kunit_resource *res;
653 
654 	res = kunit_find_resource(test, kunit_resource_instance_match,
655 				  (void *)ptr);
656 
657 	/*
658 	 * Removing the resource from the list of resources drops the
659 	 * reference count to 1; the final put will trigger the free.
660 	 */
661 	kunit_remove_resource(test, res);
662 
663 	kunit_put_resource(res);
664 
665 }
666 EXPORT_SYMBOL_GPL(kunit_kfree);
667 
668 void kunit_cleanup(struct kunit *test)
669 {
670 	struct kunit_resource *res;
671 	unsigned long flags;
672 
673 	/*
674 	 * test->resources is a stack - each allocation must be freed in the
675 	 * reverse order from which it was added since one resource may depend
676 	 * on another for its entire lifetime.
677 	 * Also, we cannot use the normal list_for_each constructs, even the
678 	 * safe ones because *arbitrary* nodes may be deleted when
679 	 * kunit_resource_free is called; the list_for_each_safe variants only
680 	 * protect against the current node being deleted, not the next.
681 	 */
682 	while (true) {
683 		spin_lock_irqsave(&test->lock, flags);
684 		if (list_empty(&test->resources)) {
685 			spin_unlock_irqrestore(&test->lock, flags);
686 			break;
687 		}
688 		res = list_last_entry(&test->resources,
689 				      struct kunit_resource,
690 				      node);
691 		/*
692 		 * Need to unlock here as a resource may remove another
693 		 * resource, and this can't happen if the test->lock
694 		 * is held.
695 		 */
696 		spin_unlock_irqrestore(&test->lock, flags);
697 		kunit_remove_resource(test, res);
698 	}
699 	current->kunit_test = NULL;
700 }
701 EXPORT_SYMBOL_GPL(kunit_cleanup);
702 
703 static int __init kunit_init(void)
704 {
705 	kunit_debugfs_init();
706 
707 	return 0;
708 }
709 late_initcall(kunit_init);
710 
711 static void __exit kunit_exit(void)
712 {
713 	kunit_debugfs_cleanup();
714 }
715 module_exit(kunit_exit);
716 
717 MODULE_LICENSE("GPL v2");
718