File Index
Files and directories
Sign in
FILE

test.c

File preview with syntax highlighting.

linux-6.19.14/lib/kunit/test.c 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/resource.h>
  10#include <kunit/test.h>
  11#include <kunit/test-bug.h>
  12#include <kunit/attributes.h>
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/moduleparam.h>
  16#include <linux/mutex.h>
  17#include <linux/panic.h>
  18#include <linux/sched/debug.h>
  19#include <linux/sched.h>
  20#include <linux/mm.h>
  21
  22#include "debugfs.h"
  23#include "device-impl.h"
  24#include "hooks-impl.h"
  25#include "string-stream.h"
  26#include "try-catch-impl.h"
  27
  28static DEFINE_MUTEX(kunit_run_lock);
  29
  30/*
  31 * Hook to fail the current test and print an error message to the log.
  32 */
  33void __printf(3, 4) __kunit_fail_current_test_impl(const char *file, int line, const char *fmt, ...)
  34{
  35	va_list args;
  36	int len;
  37	char *buffer;
  38
  39	if (!current->kunit_test)
  40		return;
  41
  42	kunit_set_failure(current->kunit_test);
  43
  44	/* kunit_err() only accepts literals, so evaluate the args first. */
  45	va_start(args, fmt);
  46	len = vsnprintf(NULL, 0, fmt, args) + 1;
  47	va_end(args);
  48
  49	buffer = kunit_kmalloc(current->kunit_test, len, GFP_KERNEL);
  50	if (!buffer)
  51		return;
  52
  53	va_start(args, fmt);
  54	vsnprintf(buffer, len, fmt, args);
  55	va_end(args);
  56
  57	kunit_err(current->kunit_test, "%s:%d: %s", file, line, buffer);
  58	kunit_kfree(current->kunit_test, buffer);
  59}
  60
  61/*
  62 * Enable KUnit tests to run.
  63 */
  64#ifdef CONFIG_KUNIT_DEFAULT_ENABLED
  65static bool enable_param = true;
  66#else
  67static bool enable_param;
  68#endif
  69module_param_named(enable, enable_param, bool, 0);
  70MODULE_PARM_DESC(enable, "Enable KUnit tests");
  71
  72/*
  73 * Configure the base timeout.
  74 */
  75static unsigned long kunit_base_timeout = CONFIG_KUNIT_DEFAULT_TIMEOUT;
  76module_param_named(timeout, kunit_base_timeout, ulong, 0644);
  77MODULE_PARM_DESC(timeout, "Set the base timeout for Kunit test cases");
  78
  79/*
  80 * KUnit statistic mode:
  81 * 0 - disabled
  82 * 1 - only when there is more than one subtest
  83 * 2 - enabled
  84 */
  85static int kunit_stats_enabled = 1;
  86module_param_named(stats_enabled, kunit_stats_enabled, int, 0644);
  87MODULE_PARM_DESC(stats_enabled,
  88		  "Print test stats: never (0), only for multiple subtests (1), or always (2)");
  89
  90struct kunit_result_stats {
  91	unsigned long passed;
  92	unsigned long skipped;
  93	unsigned long failed;
  94	unsigned long total;
  95};
  96
  97static bool kunit_should_print_stats(struct kunit_result_stats stats)
  98{
  99	if (kunit_stats_enabled == 0)
 100		return false;
 101
 102	if (kunit_stats_enabled == 2)
 103		return true;
 104
 105	return (stats.total > 1);
 106}
 107
 108static void kunit_print_test_stats(struct kunit *test,
 109				   struct kunit_result_stats stats)
 110{
 111	if (!kunit_should_print_stats(stats))
 112		return;
 113
 114	kunit_log(KERN_INFO, test,
 115		  KUNIT_SUBTEST_INDENT
 116		  "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
 117		  test->name,
 118		  stats.passed,
 119		  stats.failed,
 120		  stats.skipped,
 121		  stats.total);
 122}
 123
 124/* Append formatted message to log. */
 125void kunit_log_append(struct string_stream *log, const char *fmt, ...)
 126{
 127	va_list args;
 128
 129	if (!log)
 130		return;
 131
 132	va_start(args, fmt);
 133	string_stream_vadd(log, fmt, args);
 134	va_end(args);
 135}
 136EXPORT_SYMBOL_GPL(kunit_log_append);
 137
 138size_t kunit_suite_num_test_cases(struct kunit_suite *suite)
 139{
 140	struct kunit_case *test_case;
 141	size_t len = 0;
 142
 143	kunit_suite_for_each_test_case(suite, test_case)
 144		len++;
 145
 146	return len;
 147}
 148EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
 149
 150/* Currently supported test levels */
 151enum {
 152	KUNIT_LEVEL_SUITE = 0,
 153	KUNIT_LEVEL_CASE,
 154	KUNIT_LEVEL_CASE_PARAM,
 155};
 156
 157static void kunit_print_suite_start(struct kunit_suite *suite)
 158{
 159	/*
 160	 * We do not log the test suite header as doing so would
 161	 * mean debugfs display would consist of the test suite
 162	 * header prior to individual test results.
 163	 * Hence directly printk the suite status, and we will
 164	 * separately seq_printf() the suite header for the debugfs
 165	 * representation.
 166	 */
 167	pr_info(KUNIT_SUBTEST_INDENT "KTAP version 1\n");
 168	pr_info(KUNIT_SUBTEST_INDENT "# Subtest: %s\n",
 169		  suite->name);
 170	kunit_print_attr((void *)suite, false, KUNIT_LEVEL_CASE);
 171	pr_info(KUNIT_SUBTEST_INDENT "1..%zd\n",
 172		  kunit_suite_num_test_cases(suite));
 173}
 174
 175static void kunit_print_ok_not_ok(struct kunit *test,
 176				  unsigned int test_level,
 177				  enum kunit_status status,
 178				  size_t test_number,
 179				  const char *description,
 180				  const char *directive)
 181{
 182	const char *directive_header = (status == KUNIT_SKIPPED) ? " # SKIP " : "";
 183	const char *directive_body = (status == KUNIT_SKIPPED) ? directive : "";
 184
 185	/*
 186	 * When test is NULL assume that results are from the suite
 187	 * and today suite results are expected at level 0 only.
 188	 */
 189	WARN(!test && test_level, "suite test level can't be %u!\n", test_level);
 190
 191	/*
 192	 * We do not log the test suite results as doing so would
 193	 * mean debugfs display would consist of an incorrect test
 194	 * number. Hence directly printk the suite result, and we will
 195	 * separately seq_printf() the suite results for the debugfs
 196	 * representation.
 197	 */
 198	if (!test)
 199		pr_info("%s %zd %s%s%s\n",
 200			kunit_status_to_ok_not_ok(status),
 201			test_number, description, directive_header,
 202			directive_body);
 203	else
 204		kunit_log(KERN_INFO, test,
 205			  "%*s%s %zd %s%s%s",
 206			  KUNIT_INDENT_LEN * test_level, "",
 207			  kunit_status_to_ok_not_ok(status),
 208			  test_number, description, directive_header,
 209			  directive_body);
 210}
 211
 212enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite)
 213{
 214	const struct kunit_case *test_case;
 215	enum kunit_status status = KUNIT_SKIPPED;
 216
 217	if (suite->suite_init_err)
 218		return KUNIT_FAILURE;
 219
 220	kunit_suite_for_each_test_case(suite, test_case) {
 221		if (test_case->status == KUNIT_FAILURE)
 222			return KUNIT_FAILURE;
 223		else if (test_case->status == KUNIT_SUCCESS)
 224			status = KUNIT_SUCCESS;
 225	}
 226
 227	return status;
 228}
 229EXPORT_SYMBOL_GPL(kunit_suite_has_succeeded);
 230
 231static size_t kunit_suite_counter = 1;
 232
 233static void kunit_print_suite_end(struct kunit_suite *suite)
 234{
 235	kunit_print_ok_not_ok(NULL, KUNIT_LEVEL_SUITE,
 236			      kunit_suite_has_succeeded(suite),
 237			      kunit_suite_counter++,
 238			      suite->name,
 239			      suite->status_comment);
 240}
 241
 242unsigned int kunit_test_case_num(struct kunit_suite *suite,
 243				 struct kunit_case *test_case)
 244{
 245	struct kunit_case *tc;
 246	unsigned int i = 1;
 247
 248	kunit_suite_for_each_test_case(suite, tc) {
 249		if (tc == test_case)
 250			return i;
 251		i++;
 252	}
 253
 254	return 0;
 255}
 256EXPORT_SYMBOL_GPL(kunit_test_case_num);
 257
 258static void kunit_print_string_stream(struct kunit *test,
 259				      struct string_stream *stream)
 260{
 261	struct string_stream_fragment *fragment;
 262	char *buf;
 263
 264	if (string_stream_is_empty(stream))
 265		return;
 266
 267	buf = string_stream_get_string(stream);
 268	if (!buf) {
 269		kunit_err(test,
 270			  "Could not allocate buffer, dumping stream:\n");
 271		list_for_each_entry(fragment, &stream->fragments, node) {
 272			kunit_err(test, "%s", fragment->fragment);
 273		}
 274		kunit_err(test, "\n");
 275	} else {
 276		kunit_err(test, "%s", buf);
 277		kfree(buf);
 278	}
 279}
 280
 281static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,
 282		       enum kunit_assert_type type, const struct kunit_assert *assert,
 283		       assert_format_t assert_format, const struct va_format *message)
 284{
 285	struct string_stream *stream;
 286
 287	kunit_set_failure(test);
 288
 289	stream = kunit_alloc_string_stream(test, GFP_KERNEL);
 290	if (IS_ERR(stream)) {
 291		WARN(true,
 292		     "Could not allocate stream to print failed assertion in %s:%d\n",
 293		     loc->file,
 294		     loc->line);
 295		return;
 296	}
 297
 298	kunit_assert_prologue(loc, type, stream);
 299	assert_format(assert, message, stream);
 300
 301	kunit_print_string_stream(test, stream);
 302
 303	kunit_free_string_stream(test, stream);
 304}
 305
 306void __noreturn __kunit_abort(struct kunit *test)
 307{
 308	kunit_try_catch_throw(&test->try_catch); /* Does not return. */
 309
 310	/*
 311	 * Throw could not abort from test.
 312	 *
 313	 * XXX: we should never reach this line! As kunit_try_catch_throw is
 314	 * marked __noreturn.
 315	 */
 316	WARN_ONCE(true, "Throw could not abort from test!\n");
 317}
 318EXPORT_SYMBOL_GPL(__kunit_abort);
 319
 320void __kunit_do_failed_assertion(struct kunit *test,
 321			       const struct kunit_loc *loc,
 322			       enum kunit_assert_type type,
 323			       const struct kunit_assert *assert,
 324			       assert_format_t assert_format,
 325			       const char *fmt, ...)
 326{
 327	va_list args;
 328	struct va_format message;
 329	va_start(args, fmt);
 330
 331	message.fmt = fmt;
 332	message.va = &args;
 333
 334	kunit_fail(test, loc, type, assert, assert_format, &message);
 335
 336	va_end(args);
 337}
 338EXPORT_SYMBOL_GPL(__kunit_do_failed_assertion);
 339
 340static void kunit_init_params(struct kunit *test)
 341{
 342	test->params_array.params = NULL;
 343	test->params_array.get_description = NULL;
 344	test->params_array.num_params = 0;
 345	test->params_array.elem_size = 0;
 346}
 347
 348void kunit_init_test(struct kunit *test, const char *name, struct string_stream *log)
 349{
 350	spin_lock_init(&test->lock);
 351	INIT_LIST_HEAD(&test->resources);
 352	test->name = name;
 353	test->log = log;
 354	if (test->log)
 355		string_stream_clear(log);
 356	test->status = KUNIT_SUCCESS;
 357	test->status_comment[0] = '\0';
 358	kunit_init_params(test);
 359}
 360EXPORT_SYMBOL_GPL(kunit_init_test);
 361
 362/* Only warn when a test takes more than twice the threshold */
 363#define KUNIT_SPEED_WARNING_MULTIPLIER	2
 364
 365/* Slow tests are defined as taking more than 1s */
 366#define KUNIT_SPEED_SLOW_THRESHOLD_S	1
 367
 368#define KUNIT_SPEED_SLOW_WARNING_THRESHOLD_S	\
 369	(KUNIT_SPEED_WARNING_MULTIPLIER * KUNIT_SPEED_SLOW_THRESHOLD_S)
 370
 371#define s_to_timespec64(s) ns_to_timespec64((s) * NSEC_PER_SEC)
 372
 373static void kunit_run_case_check_speed(struct kunit *test,
 374				       struct kunit_case *test_case,
 375				       struct timespec64 duration)
 376{
 377	struct timespec64 slow_thr =
 378		s_to_timespec64(KUNIT_SPEED_SLOW_WARNING_THRESHOLD_S);
 379	enum kunit_speed speed = test_case->attr.speed;
 380
 381	if (timespec64_compare(&duration, &slow_thr) < 0)
 382		return;
 383
 384	if (speed == KUNIT_SPEED_VERY_SLOW || speed == KUNIT_SPEED_SLOW)
 385		return;
 386
 387	kunit_warn(test,
 388		   "Test should be marked slow (runtime: %lld.%09lds)",
 389		   duration.tv_sec, duration.tv_nsec);
 390}
 391
 392/* Returns timeout multiplier based on speed.
 393 * DEFAULT:		    1
 394 * KUNIT_SPEED_SLOW:        3
 395 * KUNIT_SPEED_VERY_SLOW:   12
 396 */
 397static int kunit_timeout_mult(enum kunit_speed speed)
 398{
 399	switch (speed) {
 400	case KUNIT_SPEED_SLOW:
 401		return 3;
 402	case KUNIT_SPEED_VERY_SLOW:
 403		return 12;
 404	default:
 405		return 1;
 406	}
 407}
 408
 409static unsigned long kunit_test_timeout(struct kunit_suite *suite, struct kunit_case *test_case)
 410{
 411	int mult = 1;
 412
 413	/*
 414	 * The default test timeout is 300 seconds and will be adjusted by mult
 415	 * based on the test speed. The test speed will be overridden by the
 416	 * innermost test component.
 417	 */
 418	if (suite->attr.speed != KUNIT_SPEED_UNSET)
 419		mult = kunit_timeout_mult(suite->attr.speed);
 420	if (test_case->attr.speed != KUNIT_SPEED_UNSET)
 421		mult = kunit_timeout_mult(test_case->attr.speed);
 422	return mult * kunit_base_timeout * msecs_to_jiffies(MSEC_PER_SEC);
 423}
 424
 425
 426/*
 427 * Initializes and runs test case. Does not clean up or do post validations.
 428 */
 429static void kunit_run_case_internal(struct kunit *test,
 430				    struct kunit_suite *suite,
 431				    struct kunit_case *test_case)
 432{
 433	struct timespec64 start, end;
 434
 435	if (suite->init) {
 436		int ret;
 437
 438		ret = suite->init(test);
 439		if (ret) {
 440			kunit_err(test, "failed to initialize: %d\n", ret);
 441			kunit_set_failure(test);
 442			return;
 443		}
 444	}
 445
 446	ktime_get_ts64(&start);
 447
 448	test_case->run_case(test);
 449
 450	ktime_get_ts64(&end);
 451
 452	kunit_run_case_check_speed(test, test_case, timespec64_sub(end, start));
 453}
 454
 455static void kunit_case_internal_cleanup(struct kunit *test)
 456{
 457	kunit_cleanup(test);
 458}
 459
 460/*
 461 * Performs post validations and cleanup after a test case was run.
 462 * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!
 463 */
 464static void kunit_run_case_cleanup(struct kunit *test,
 465				   struct kunit_suite *suite)
 466{
 467	if (suite->exit)
 468		suite->exit(test);
 469
 470	kunit_case_internal_cleanup(test);
 471}
 472
 473struct kunit_try_catch_context {
 474	struct kunit *test;
 475	struct kunit_suite *suite;
 476	struct kunit_case *test_case;
 477};
 478
 479static void kunit_try_run_case(void *data)
 480{
 481	struct kunit_try_catch_context *ctx = data;
 482	struct kunit *test = ctx->test;
 483	struct kunit_suite *suite = ctx->suite;
 484	struct kunit_case *test_case = ctx->test_case;
 485
 486	current->kunit_test = test;
 487
 488	/*
 489	 * kunit_run_case_internal may encounter a fatal error; if it does,
 490	 * abort will be called, this thread will exit, and finally the parent
 491	 * thread will resume control and handle any necessary clean up.
 492	 */
 493	kunit_run_case_internal(test, suite, test_case);
 494}
 495
 496static void kunit_try_run_case_cleanup(void *data)
 497{
 498	struct kunit_try_catch_context *ctx = data;
 499	struct kunit *test = ctx->test;
 500	struct kunit_suite *suite = ctx->suite;
 501
 502	current->kunit_test = test;
 503
 504	kunit_run_case_cleanup(test, suite);
 505}
 506
 507static void kunit_catch_run_case_cleanup(void *data)
 508{
 509	struct kunit_try_catch_context *ctx = data;
 510	struct kunit *test = ctx->test;
 511	int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
 512
 513	/* It is always a failure if cleanup aborts. */
 514	kunit_set_failure(test);
 515
 516	if (try_exit_code) {
 517		/*
 518		 * Test case could not finish, we have no idea what state it is
 519		 * in, so don't do clean up.
 520		 */
 521		if (try_exit_code == -ETIMEDOUT) {
 522			kunit_err(test, "test case cleanup timed out\n");
 523		/*
 524		 * Unknown internal error occurred preventing test case from
 525		 * running, so there is nothing to clean up.
 526		 */
 527		} else {
 528			kunit_err(test, "internal error occurred during test case cleanup: %d\n",
 529				  try_exit_code);
 530		}
 531		return;
 532	}
 533
 534	kunit_err(test, "test aborted during cleanup. continuing without cleaning up\n");
 535}
 536
 537
 538static void kunit_catch_run_case(void *data)
 539{
 540	struct kunit_try_catch_context *ctx = data;
 541	struct kunit *test = ctx->test;
 542	int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
 543
 544	if (try_exit_code) {
 545		kunit_set_failure(test);
 546		/*
 547		 * Test case could not finish, we have no idea what state it is
 548		 * in, so don't do clean up.
 549		 */
 550		if (try_exit_code == -ETIMEDOUT) {
 551			kunit_err(test, "test case timed out\n");
 552		/*
 553		 * Unknown internal error occurred preventing test case from
 554		 * running, so there is nothing to clean up.
 555		 */
 556		} else {
 557			kunit_err(test, "internal error occurred preventing test case from running: %d\n",
 558				  try_exit_code);
 559		}
 560		return;
 561	}
 562}
 563
 564/*
 565 * Performs all logic to run a test case. It also catches most errors that
 566 * occur in a test case and reports them as failures.
 567 */
 568static void kunit_run_case_catch_errors(struct kunit_suite *suite,
 569					struct kunit_case *test_case,
 570					struct kunit *test)
 571{
 572	struct kunit_try_catch_context context;
 573	struct kunit_try_catch *try_catch;
 574
 575	try_catch = &test->try_catch;
 576
 577	kunit_try_catch_init(try_catch,
 578			     test,
 579			     kunit_try_run_case,
 580			     kunit_catch_run_case,
 581			     kunit_test_timeout(suite, test_case));
 582	context.test = test;
 583	context.suite = suite;
 584	context.test_case = test_case;
 585	kunit_try_catch_run(try_catch, &context);
 586
 587	/* Now run the cleanup */
 588	kunit_try_catch_init(try_catch,
 589			     test,
 590			     kunit_try_run_case_cleanup,
 591			     kunit_catch_run_case_cleanup,
 592			     kunit_test_timeout(suite, test_case));
 593	kunit_try_catch_run(try_catch, &context);
 594
 595	/* Propagate the parameter result to the test case. */
 596	if (test->status == KUNIT_FAILURE)
 597		test_case->status = KUNIT_FAILURE;
 598	else if (test_case->status != KUNIT_FAILURE && test->status == KUNIT_SUCCESS)
 599		test_case->status = KUNIT_SUCCESS;
 600}
 601
 602static void kunit_print_suite_stats(struct kunit_suite *suite,
 603				    struct kunit_result_stats suite_stats,
 604				    struct kunit_result_stats param_stats)
 605{
 606	if (kunit_should_print_stats(suite_stats)) {
 607		kunit_log(KERN_INFO, suite,
 608			  "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
 609			  suite->name,
 610			  suite_stats.passed,
 611			  suite_stats.failed,
 612			  suite_stats.skipped,
 613			  suite_stats.total);
 614	}
 615
 616	if (kunit_should_print_stats(param_stats)) {
 617		kunit_log(KERN_INFO, suite,
 618			  "# Totals: pass:%lu fail:%lu skip:%lu total:%lu",
 619			  param_stats.passed,
 620			  param_stats.failed,
 621			  param_stats.skipped,
 622			  param_stats.total);
 623	}
 624}
 625
 626static void kunit_update_stats(struct kunit_result_stats *stats,
 627			       enum kunit_status status)
 628{
 629	switch (status) {
 630	case KUNIT_SUCCESS:
 631		stats->passed++;
 632		break;
 633	case KUNIT_SKIPPED:
 634		stats->skipped++;
 635		break;
 636	case KUNIT_FAILURE:
 637		stats->failed++;
 638		break;
 639	}
 640
 641	stats->total++;
 642}
 643
 644static void kunit_accumulate_stats(struct kunit_result_stats *total,
 645				   struct kunit_result_stats add)
 646{
 647	total->passed += add.passed;
 648	total->skipped += add.skipped;
 649	total->failed += add.failed;
 650	total->total += add.total;
 651}
 652
 653const void *kunit_array_gen_params(struct kunit *test, const void *prev, char *desc)
 654{
 655	struct kunit_params *params_arr = &test->params_array;
 656	const void *param;
 657
 658	if (test->param_index < params_arr->num_params) {
 659		param = (char *)params_arr->params
 660			+ test->param_index * params_arr->elem_size;
 661
 662		if (params_arr->get_description)
 663			params_arr->get_description(test, param, desc);
 664		return param;
 665	}
 666	return NULL;
 667}
 668EXPORT_SYMBOL_GPL(kunit_array_gen_params);
 669
 670static void kunit_init_parent_param_test(struct kunit_case *test_case, struct kunit *test)
 671{
 672	if (test_case->param_init) {
 673		int err = test_case->param_init(test);
 674
 675		if (err) {
 676			kunit_err(test_case, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
 677				"# failed to initialize parent parameter test (%d)", err);
 678			test->status = KUNIT_FAILURE;
 679			test_case->status = KUNIT_FAILURE;
 680		}
 681	}
 682}
 683
 684int kunit_run_tests(struct kunit_suite *suite)
 685{
 686	char param_desc[KUNIT_PARAM_DESC_SIZE];
 687	struct kunit_case *test_case;
 688	struct kunit_result_stats suite_stats = { 0 };
 689	struct kunit_result_stats total_stats = { 0 };
 690	const void *curr_param;
 691
 692	/* Taint the kernel so we know we've run tests. */
 693	add_taint(TAINT_TEST, LOCKDEP_STILL_OK);
 694
 695	if (suite->suite_init) {
 696		suite->suite_init_err = suite->suite_init(suite);
 697		if (suite->suite_init_err) {
 698			kunit_err(suite, KUNIT_SUBTEST_INDENT
 699				  "# failed to initialize (%d)", suite->suite_init_err);
 700			goto suite_end;
 701		}
 702	}
 703
 704	kunit_print_suite_start(suite);
 705
 706	kunit_suite_for_each_test_case(suite, test_case) {
 707		struct kunit test = { .param_value = NULL, .param_index = 0 };
 708		struct kunit_result_stats param_stats = { 0 };
 709
 710		kunit_init_test(&test, test_case->name, test_case->log);
 711		if (test_case->status == KUNIT_SKIPPED) {
 712			/* Test marked as skip */
 713			test.status = KUNIT_SKIPPED;
 714			kunit_update_stats(&param_stats, test.status);
 715		} else if (!test_case->generate_params) {
 716			/* Non-parameterised test. */
 717			test_case->status = KUNIT_SKIPPED;
 718			kunit_run_case_catch_errors(suite, test_case, &test);
 719			kunit_update_stats(&param_stats, test.status);
 720		} else {
 721			kunit_init_parent_param_test(test_case, &test);
 722			if (test_case->status == KUNIT_FAILURE) {
 723				kunit_update_stats(&param_stats, test.status);
 724				goto test_case_end;
 725			}
 726			/* Get initial param. */
 727			param_desc[0] = '\0';
 728			/* TODO: Make generate_params try-catch */
 729			curr_param = test_case->generate_params(&test, NULL, param_desc);
 730			test_case->status = KUNIT_SKIPPED;
 731			kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
 732				  "KTAP version 1\n");
 733			kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
 734				  "# Subtest: %s", test_case->name);
 735			if (test.params_array.params &&
 736			    test_case->generate_params == kunit_array_gen_params) {
 737				kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT
 738					  KUNIT_SUBTEST_INDENT "1..%zd\n",
 739					  test.params_array.num_params);
 740			}
 741
 742			while (curr_param) {
 743				struct kunit param_test = {
 744					.param_value = curr_param,
 745					.param_index = ++test.param_index,
 746					.parent = &test,
 747				};
 748				kunit_init_test(&param_test, test_case->name, NULL);
 749				param_test.log = test_case->log;
 750				kunit_run_case_catch_errors(suite, test_case, &param_test);
 751
 752				if (param_desc[0] == '\0') {
 753					snprintf(param_desc, sizeof(param_desc),
 754						 "param-%d", param_test.param_index);
 755				}
 756
 757				kunit_print_ok_not_ok(&param_test, KUNIT_LEVEL_CASE_PARAM,
 758						      param_test.status,
 759						      param_test.param_index,
 760						      param_desc,
 761						      param_test.status_comment);
 762
 763				kunit_update_stats(&param_stats, param_test.status);
 764
 765				/* Get next param. */
 766				param_desc[0] = '\0';
 767				curr_param = test_case->generate_params(&test, curr_param,
 768									param_desc);
 769			}
 770			/*
 771			 * TODO: Put into a try catch. Since we don't need suite->exit
 772			 * for it we can't reuse kunit_try_run_cleanup for this yet.
 773			 */
 774			if (test_case->param_exit)
 775				test_case->param_exit(&test);
 776			/* TODO: Put this kunit_cleanup into a try-catch. */
 777			kunit_cleanup(&test);
 778		}
 779test_case_end:
 780		kunit_print_attr((void *)test_case, true, KUNIT_LEVEL_CASE);
 781
 782		kunit_print_test_stats(&test, param_stats);
 783
 784		kunit_print_ok_not_ok(&test, KUNIT_LEVEL_CASE, test_case->status,
 785				      kunit_test_case_num(suite, test_case),
 786				      test_case->name,
 787				      test.status_comment);
 788
 789		kunit_update_stats(&suite_stats, test_case->status);
 790		kunit_accumulate_stats(&total_stats, param_stats);
 791	}
 792
 793	if (suite->suite_exit)
 794		suite->suite_exit(suite);
 795
 796	kunit_print_suite_stats(suite, suite_stats, total_stats);
 797suite_end:
 798	kunit_print_suite_end(suite);
 799
 800	return 0;
 801}
 802EXPORT_SYMBOL_GPL(kunit_run_tests);
 803
 804static void kunit_init_suite(struct kunit_suite *suite)
 805{
 806	kunit_debugfs_create_suite(suite);
 807	suite->status_comment[0] = '\0';
 808	suite->suite_init_err = 0;
 809
 810	if (suite->log)
 811		string_stream_clear(suite->log);
 812}
 813
 814bool kunit_enabled(void)
 815{
 816	return enable_param;
 817}
 818
 819int __kunit_test_suites_init(struct kunit_suite * const * const suites, int num_suites,
 820			     bool run_tests)
 821{
 822	unsigned int i;
 823
 824	if (num_suites == 0)
 825		return 0;
 826
 827	if (!kunit_enabled() && num_suites > 0) {
 828		pr_info("kunit: disabled\n");
 829		return 0;
 830	}
 831
 832	kunit_suite_counter = 1;
 833
 834	/* Use mutex lock to guard against running tests concurrently. */
 835	if (mutex_lock_interruptible(&kunit_run_lock)) {
 836		pr_err("kunit: test interrupted\n");
 837		return -EINTR;
 838	}
 839	static_branch_inc(&kunit_running);
 840
 841	for (i = 0; i < num_suites; i++) {
 842		kunit_init_suite(suites[i]);
 843		if (run_tests)
 844			kunit_run_tests(suites[i]);
 845	}
 846
 847	static_branch_dec(&kunit_running);
 848	mutex_unlock(&kunit_run_lock);
 849	return 0;
 850}
 851EXPORT_SYMBOL_GPL(__kunit_test_suites_init);
 852
 853static void kunit_exit_suite(struct kunit_suite *suite)
 854{
 855	kunit_debugfs_destroy_suite(suite);
 856}
 857
 858void __kunit_test_suites_exit(struct kunit_suite **suites, int num_suites)
 859{
 860	unsigned int i;
 861
 862	if (!kunit_enabled())
 863		return;
 864
 865	for (i = 0; i < num_suites; i++)
 866		kunit_exit_suite(suites[i]);
 867}
 868EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
 869
 870static void kunit_module_init(struct module *mod)
 871{
 872	struct kunit_suite_set suite_set, filtered_set;
 873	struct kunit_suite_set normal_suite_set = {
 874		mod->kunit_suites, mod->kunit_suites + mod->num_kunit_suites,
 875	};
 876	struct kunit_suite_set init_suite_set = {
 877		mod->kunit_init_suites, mod->kunit_init_suites + mod->num_kunit_init_suites,
 878	};
 879	const char *action = kunit_action();
 880	int err = 0;
 881
 882	if (mod->num_kunit_init_suites > 0)
 883		suite_set = kunit_merge_suite_sets(init_suite_set, normal_suite_set);
 884	else
 885		suite_set = normal_suite_set;
 886
 887	filtered_set = kunit_filter_suites(&suite_set,
 888					kunit_filter_glob() ?: "*.*",
 889					kunit_filter(), kunit_filter_action(),
 890					&err);
 891	if (err)
 892		pr_err("kunit module: error filtering suites: %d\n", err);
 893
 894	mod->kunit_suites = (struct kunit_suite **)filtered_set.start;
 895	mod->num_kunit_suites = filtered_set.end - filtered_set.start;
 896
 897	if (mod->num_kunit_init_suites > 0)
 898		kfree(suite_set.start);
 899
 900	if (!action)
 901		kunit_exec_run_tests(&filtered_set, false);
 902	else if (!strcmp(action, "list"))
 903		kunit_exec_list_tests(&filtered_set, false);
 904	else if (!strcmp(action, "list_attr"))
 905		kunit_exec_list_tests(&filtered_set, true);
 906	else
 907		pr_err("kunit: unknown action '%s'\n", action);
 908}
 909
 910static void kunit_module_exit(struct module *mod)
 911{
 912	struct kunit_suite_set suite_set = {
 913		mod->kunit_suites, mod->kunit_suites + mod->num_kunit_suites,
 914	};
 915	const char *action = kunit_action();
 916
 917	/*
 918	 * Check if the start address is a valid virtual address to detect
 919	 * if the module load sequence has failed and the suite set has not
 920	 * been initialized and filtered.
 921	 */
 922	if (!suite_set.start || !virt_addr_valid(suite_set.start))
 923		return;
 924
 925	if (!action)
 926		__kunit_test_suites_exit(mod->kunit_suites,
 927					 mod->num_kunit_suites);
 928
 929	kunit_free_suite_set(suite_set);
 930}
 931
 932static int kunit_module_notify(struct notifier_block *nb, unsigned long val,
 933			       void *data)
 934{
 935	struct module *mod = data;
 936
 937	switch (val) {
 938	case MODULE_STATE_LIVE:
 939		kunit_module_init(mod);
 940		break;
 941	case MODULE_STATE_GOING:
 942		kunit_module_exit(mod);
 943		break;
 944	case MODULE_STATE_COMING:
 945		break;
 946	case MODULE_STATE_UNFORMED:
 947		break;
 948	}
 949
 950	return 0;
 951}
 952
 953static struct notifier_block kunit_mod_nb = {
 954	.notifier_call = kunit_module_notify,
 955	.priority = 0,
 956};
 957
 958KUNIT_DEFINE_ACTION_WRAPPER(kfree_action_wrapper, kfree, const void *)
 959
 960void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)
 961{
 962	void *data;
 963
 964	data = kmalloc_array(n, size, gfp);
 965
 966	if (!data)
 967		return NULL;
 968
 969	if (kunit_add_action_or_reset(test, kfree_action_wrapper, data) != 0)
 970		return NULL;
 971
 972	return data;
 973}
 974EXPORT_SYMBOL_GPL(kunit_kmalloc_array);
 975
 976void kunit_kfree(struct kunit *test, const void *ptr)
 977{
 978	if (!ptr)
 979		return;
 980
 981	kunit_release_action(test, kfree_action_wrapper, (void *)ptr);
 982}
 983EXPORT_SYMBOL_GPL(kunit_kfree);
 984
 985void kunit_kfree_const(struct kunit *test, const void *x)
 986{
 987#if !IS_MODULE(CONFIG_KUNIT)
 988	if (!is_kernel_rodata((unsigned long)x))
 989#endif
 990		kunit_kfree(test, x);
 991}
 992EXPORT_SYMBOL_GPL(kunit_kfree_const);
 993
 994const char *kunit_kstrdup_const(struct kunit *test, const char *str, gfp_t gfp)
 995{
 996#if !IS_MODULE(CONFIG_KUNIT)
 997	if (is_kernel_rodata((unsigned long)str))
 998		return str;
 999#endif
1000	return kunit_kstrdup(test, str, gfp);
1001}
1002EXPORT_SYMBOL_GPL(kunit_kstrdup_const);
1003
1004void kunit_cleanup(struct kunit *test)
1005{
1006	struct kunit_resource *res;
1007	unsigned long flags;
1008
1009	/*
1010	 * test->resources is a stack - each allocation must be freed in the
1011	 * reverse order from which it was added since one resource may depend
1012	 * on another for its entire lifetime.
1013	 * Also, we cannot use the normal list_for_each constructs, even the
1014	 * safe ones because *arbitrary* nodes may be deleted when
1015	 * kunit_resource_free is called; the list_for_each_safe variants only
1016	 * protect against the current node being deleted, not the next.
1017	 */
1018	while (true) {
1019		spin_lock_irqsave(&test->lock, flags);
1020		if (list_empty(&test->resources)) {
1021			spin_unlock_irqrestore(&test->lock, flags);
1022			break;
1023		}
1024		res = list_last_entry(&test->resources,
1025				      struct kunit_resource,
1026				      node);
1027		/*
1028		 * Need to unlock here as a resource may remove another
1029		 * resource, and this can't happen if the test->lock
1030		 * is held.
1031		 */
1032		spin_unlock_irqrestore(&test->lock, flags);
1033		kunit_remove_resource(test, res);
1034	}
1035	current->kunit_test = NULL;
1036}
1037EXPORT_SYMBOL_GPL(kunit_cleanup);
1038
1039static int __init kunit_init(void)
1040{
1041	/* Install the KUnit hook functions. */
1042	kunit_install_hooks();
1043
1044	kunit_debugfs_init();
1045
1046	kunit_bus_init();
1047	return register_module_notifier(&kunit_mod_nb);
1048}
1049late_initcall(kunit_init);
1050
1051static void __exit kunit_exit(void)
1052{
1053	memset(&kunit_hooks, 0, sizeof(kunit_hooks));
1054	unregister_module_notifier(&kunit_mod_nb);
1055
1056	kunit_bus_shutdown();
1057
1058	kunit_debugfs_cleanup();
1059}
1060module_exit(kunit_exit);
1061
1062MODULE_DESCRIPTION("Base unit test (KUnit) API");
1063MODULE_LICENSE("GPL v2");
~/ Read-only file preview.