xref: /kernel/linux/linux-5.10/lib/kunit/test.c (revision 8c2ecf20)
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 <linux/kernel.h>
11#include <linux/kref.h>
12#include <linux/sched/debug.h>
13#include <linux/sched.h>
14
15#include "debugfs.h"
16#include "string-stream.h"
17#include "try-catch-impl.h"
18
19/*
20 * Append formatted message to log, size of which is limited to
21 * KUNIT_LOG_SIZE bytes (including null terminating byte).
22 */
23void kunit_log_append(char *log, const char *fmt, ...)
24{
25	char line[KUNIT_LOG_SIZE];
26	va_list args;
27	int len_left;
28
29	if (!log)
30		return;
31
32	len_left = KUNIT_LOG_SIZE - strlen(log) - 1;
33	if (len_left <= 0)
34		return;
35
36	va_start(args, fmt);
37	vsnprintf(line, sizeof(line), fmt, args);
38	va_end(args);
39
40	strncat(log, line, len_left);
41}
42EXPORT_SYMBOL_GPL(kunit_log_append);
43
44size_t kunit_suite_num_test_cases(struct kunit_suite *suite)
45{
46	struct kunit_case *test_case;
47	size_t len = 0;
48
49	kunit_suite_for_each_test_case(suite, test_case)
50		len++;
51
52	return len;
53}
54EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
55
56static void kunit_print_subtest_start(struct kunit_suite *suite)
57{
58	kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "# Subtest: %s",
59		  suite->name);
60	kunit_log(KERN_INFO, suite, KUNIT_SUBTEST_INDENT "1..%zd",
61		  kunit_suite_num_test_cases(suite));
62}
63
64static void kunit_print_ok_not_ok(void *test_or_suite,
65				  bool is_test,
66				  bool is_ok,
67				  size_t test_number,
68				  const char *description)
69{
70	struct kunit_suite *suite = is_test ? NULL : test_or_suite;
71	struct kunit *test = is_test ? test_or_suite : NULL;
72
73	/*
74	 * We do not log the test suite results as doing so would
75	 * mean debugfs display would consist of the test suite
76	 * description and status prior to individual test results.
77	 * Hence directly printk the suite status, and we will
78	 * separately seq_printf() the suite status for the debugfs
79	 * representation.
80	 */
81	if (suite)
82		pr_info("%s %zd - %s\n",
83			kunit_status_to_string(is_ok),
84			test_number, description);
85	else
86		kunit_log(KERN_INFO, test, KUNIT_SUBTEST_INDENT "%s %zd - %s",
87			  kunit_status_to_string(is_ok),
88			  test_number, description);
89}
90
91bool kunit_suite_has_succeeded(struct kunit_suite *suite)
92{
93	const struct kunit_case *test_case;
94
95	kunit_suite_for_each_test_case(suite, test_case) {
96		if (!test_case->success)
97			return false;
98	}
99
100	return true;
101}
102EXPORT_SYMBOL_GPL(kunit_suite_has_succeeded);
103
104static void kunit_print_subtest_end(struct kunit_suite *suite)
105{
106	static size_t kunit_suite_counter = 1;
107
108	kunit_print_ok_not_ok((void *)suite, false,
109			      kunit_suite_has_succeeded(suite),
110			      kunit_suite_counter++,
111			      suite->name);
112}
113
114unsigned int kunit_test_case_num(struct kunit_suite *suite,
115				 struct kunit_case *test_case)
116{
117	struct kunit_case *tc;
118	unsigned int i = 1;
119
120	kunit_suite_for_each_test_case(suite, tc) {
121		if (tc == test_case)
122			return i;
123		i++;
124	}
125
126	return 0;
127}
128EXPORT_SYMBOL_GPL(kunit_test_case_num);
129
130static void kunit_print_string_stream(struct kunit *test,
131				      struct string_stream *stream)
132{
133	struct string_stream_fragment *fragment;
134	char *buf;
135
136	if (string_stream_is_empty(stream))
137		return;
138
139	buf = string_stream_get_string(stream);
140	if (!buf) {
141		kunit_err(test,
142			  "Could not allocate buffer, dumping stream:\n");
143		list_for_each_entry(fragment, &stream->fragments, node) {
144			kunit_err(test, "%s", fragment->fragment);
145		}
146		kunit_err(test, "\n");
147	} else {
148		kunit_err(test, "%s", buf);
149		kunit_kfree(test, buf);
150	}
151}
152
153static void kunit_fail(struct kunit *test, struct kunit_assert *assert)
154{
155	struct string_stream *stream;
156
157	kunit_set_failure(test);
158
159	stream = alloc_string_stream(test, GFP_KERNEL);
160	if (!stream) {
161		WARN(true,
162		     "Could not allocate stream to print failed assertion in %s:%d\n",
163		     assert->file,
164		     assert->line);
165		return;
166	}
167
168	assert->format(assert, stream);
169
170	kunit_print_string_stream(test, stream);
171
172	WARN_ON(string_stream_destroy(stream));
173}
174
175static void __noreturn kunit_abort(struct kunit *test)
176{
177	kunit_try_catch_throw(&test->try_catch); /* Does not return. */
178
179	/*
180	 * Throw could not abort from test.
181	 *
182	 * XXX: we should never reach this line! As kunit_try_catch_throw is
183	 * marked __noreturn.
184	 */
185	WARN_ONCE(true, "Throw could not abort from test!\n");
186}
187
188void kunit_do_assertion(struct kunit *test,
189			struct kunit_assert *assert,
190			bool pass,
191			const char *fmt, ...)
192{
193	va_list args;
194
195	if (pass)
196		return;
197
198	va_start(args, fmt);
199
200	assert->message.fmt = fmt;
201	assert->message.va = &args;
202
203	kunit_fail(test, assert);
204
205	va_end(args);
206
207	if (assert->type == KUNIT_ASSERTION)
208		kunit_abort(test);
209}
210EXPORT_SYMBOL_GPL(kunit_do_assertion);
211
212void kunit_init_test(struct kunit *test, const char *name, char *log)
213{
214	spin_lock_init(&test->lock);
215	INIT_LIST_HEAD(&test->resources);
216	test->name = name;
217	test->log = log;
218	if (test->log)
219		test->log[0] = '\0';
220	test->success = true;
221}
222EXPORT_SYMBOL_GPL(kunit_init_test);
223
224/*
225 * Initializes and runs test case. Does not clean up or do post validations.
226 */
227static void kunit_run_case_internal(struct kunit *test,
228				    struct kunit_suite *suite,
229				    struct kunit_case *test_case)
230{
231	if (suite->init) {
232		int ret;
233
234		ret = suite->init(test);
235		if (ret) {
236			kunit_err(test, "failed to initialize: %d\n", ret);
237			kunit_set_failure(test);
238			return;
239		}
240	}
241
242	test_case->run_case(test);
243}
244
245static void kunit_case_internal_cleanup(struct kunit *test)
246{
247	kunit_cleanup(test);
248}
249
250/*
251 * Performs post validations and cleanup after a test case was run.
252 * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!
253 */
254static void kunit_run_case_cleanup(struct kunit *test,
255				   struct kunit_suite *suite)
256{
257	if (suite->exit)
258		suite->exit(test);
259
260	kunit_case_internal_cleanup(test);
261}
262
263struct kunit_try_catch_context {
264	struct kunit *test;
265	struct kunit_suite *suite;
266	struct kunit_case *test_case;
267};
268
269static void kunit_try_run_case(void *data)
270{
271	struct kunit_try_catch_context *ctx = data;
272	struct kunit *test = ctx->test;
273	struct kunit_suite *suite = ctx->suite;
274	struct kunit_case *test_case = ctx->test_case;
275
276#if (IS_ENABLED(CONFIG_KASAN) && IS_ENABLED(CONFIG_KUNIT))
277	current->kunit_test = test;
278#endif /* IS_ENABLED(CONFIG_KASAN) && IS_ENABLED(CONFIG_KUNIT) */
279
280	/*
281	 * kunit_run_case_internal may encounter a fatal error; if it does,
282	 * abort will be called, this thread will exit, and finally the parent
283	 * thread will resume control and handle any necessary clean up.
284	 */
285	kunit_run_case_internal(test, suite, test_case);
286	/* This line may never be reached. */
287	kunit_run_case_cleanup(test, suite);
288}
289
290static void kunit_catch_run_case(void *data)
291{
292	struct kunit_try_catch_context *ctx = data;
293	struct kunit *test = ctx->test;
294	struct kunit_suite *suite = ctx->suite;
295	int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
296
297	if (try_exit_code) {
298		kunit_set_failure(test);
299		/*
300		 * Test case could not finish, we have no idea what state it is
301		 * in, so don't do clean up.
302		 */
303		if (try_exit_code == -ETIMEDOUT) {
304			kunit_err(test, "test case timed out\n");
305		/*
306		 * Unknown internal error occurred preventing test case from
307		 * running, so there is nothing to clean up.
308		 */
309		} else {
310			kunit_err(test, "internal error occurred preventing test case from running: %d\n",
311				  try_exit_code);
312		}
313		return;
314	}
315
316	/*
317	 * Test case was run, but aborted. It is the test case's business as to
318	 * whether it failed or not, we just need to clean up.
319	 */
320	kunit_run_case_cleanup(test, suite);
321}
322
323/*
324 * Performs all logic to run a test case. It also catches most errors that
325 * occur in a test case and reports them as failures.
326 */
327static void kunit_run_case_catch_errors(struct kunit_suite *suite,
328					struct kunit_case *test_case)
329{
330	struct kunit_try_catch_context context;
331	struct kunit_try_catch *try_catch;
332	struct kunit test;
333
334	kunit_init_test(&test, test_case->name, test_case->log);
335	try_catch = &test.try_catch;
336
337	kunit_try_catch_init(try_catch,
338			     &test,
339			     kunit_try_run_case,
340			     kunit_catch_run_case);
341	context.test = &test;
342	context.suite = suite;
343	context.test_case = test_case;
344	kunit_try_catch_run(try_catch, &context);
345
346	test_case->success = test.success;
347
348	kunit_print_ok_not_ok(&test, true, test_case->success,
349			      kunit_test_case_num(suite, test_case),
350			      test_case->name);
351}
352
353int kunit_run_tests(struct kunit_suite *suite)
354{
355	struct kunit_case *test_case;
356
357	kunit_print_subtest_start(suite);
358
359	kunit_suite_for_each_test_case(suite, test_case)
360		kunit_run_case_catch_errors(suite, test_case);
361
362	kunit_print_subtest_end(suite);
363
364	return 0;
365}
366EXPORT_SYMBOL_GPL(kunit_run_tests);
367
368static void kunit_init_suite(struct kunit_suite *suite)
369{
370	kunit_debugfs_create_suite(suite);
371}
372
373int __kunit_test_suites_init(struct kunit_suite * const * const suites)
374{
375	unsigned int i;
376
377	for (i = 0; suites[i] != NULL; i++) {
378		kunit_init_suite(suites[i]);
379		kunit_run_tests(suites[i]);
380	}
381	return 0;
382}
383EXPORT_SYMBOL_GPL(__kunit_test_suites_init);
384
385static void kunit_exit_suite(struct kunit_suite *suite)
386{
387	kunit_debugfs_destroy_suite(suite);
388}
389
390void __kunit_test_suites_exit(struct kunit_suite **suites)
391{
392	unsigned int i;
393
394	for (i = 0; suites[i] != NULL; i++)
395		kunit_exit_suite(suites[i]);
396}
397EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
398
399/*
400 * Used for static resources and when a kunit_resource * has been created by
401 * kunit_alloc_resource().  When an init function is supplied, @data is passed
402 * into the init function; otherwise, we simply set the resource data field to
403 * the data value passed in.
404 */
405int kunit_add_resource(struct kunit *test,
406		       kunit_resource_init_t init,
407		       kunit_resource_free_t free,
408		       struct kunit_resource *res,
409		       void *data)
410{
411	int ret = 0;
412
413	res->free = free;
414	kref_init(&res->refcount);
415
416	if (init) {
417		ret = init(res, data);
418		if (ret)
419			return ret;
420	} else {
421		res->data = data;
422	}
423
424	spin_lock(&test->lock);
425	list_add_tail(&res->node, &test->resources);
426	/* refcount for list is established by kref_init() */
427	spin_unlock(&test->lock);
428
429	return ret;
430}
431EXPORT_SYMBOL_GPL(kunit_add_resource);
432
433int kunit_add_named_resource(struct kunit *test,
434			     kunit_resource_init_t init,
435			     kunit_resource_free_t free,
436			     struct kunit_resource *res,
437			     const char *name,
438			     void *data)
439{
440	struct kunit_resource *existing;
441
442	if (!name)
443		return -EINVAL;
444
445	existing = kunit_find_named_resource(test, name);
446	if (existing) {
447		kunit_put_resource(existing);
448		return -EEXIST;
449	}
450
451	res->name = name;
452
453	return kunit_add_resource(test, init, free, res, data);
454}
455EXPORT_SYMBOL_GPL(kunit_add_named_resource);
456
457struct kunit_resource *kunit_alloc_and_get_resource(struct kunit *test,
458						    kunit_resource_init_t init,
459						    kunit_resource_free_t free,
460						    gfp_t internal_gfp,
461						    void *data)
462{
463	struct kunit_resource *res;
464	int ret;
465
466	res = kzalloc(sizeof(*res), internal_gfp);
467	if (!res)
468		return NULL;
469
470	ret = kunit_add_resource(test, init, free, res, data);
471	if (!ret) {
472		/*
473		 * bump refcount for get; kunit_resource_put() should be called
474		 * when done.
475		 */
476		kunit_get_resource(res);
477		return res;
478	}
479	return NULL;
480}
481EXPORT_SYMBOL_GPL(kunit_alloc_and_get_resource);
482
483void kunit_remove_resource(struct kunit *test, struct kunit_resource *res)
484{
485	spin_lock(&test->lock);
486	list_del(&res->node);
487	spin_unlock(&test->lock);
488	kunit_put_resource(res);
489}
490EXPORT_SYMBOL_GPL(kunit_remove_resource);
491
492int kunit_destroy_resource(struct kunit *test, kunit_resource_match_t match,
493			   void *match_data)
494{
495	struct kunit_resource *res = kunit_find_resource(test, match,
496							 match_data);
497
498	if (!res)
499		return -ENOENT;
500
501	kunit_remove_resource(test, res);
502
503	/* We have a reference also via _find(); drop it. */
504	kunit_put_resource(res);
505
506	return 0;
507}
508EXPORT_SYMBOL_GPL(kunit_destroy_resource);
509
510struct kunit_kmalloc_params {
511	size_t size;
512	gfp_t gfp;
513};
514
515static int kunit_kmalloc_init(struct kunit_resource *res, void *context)
516{
517	struct kunit_kmalloc_params *params = context;
518
519	res->data = kmalloc(params->size, params->gfp);
520	if (!res->data)
521		return -ENOMEM;
522
523	return 0;
524}
525
526static void kunit_kmalloc_free(struct kunit_resource *res)
527{
528	kfree(res->data);
529}
530
531void *kunit_kmalloc(struct kunit *test, size_t size, gfp_t gfp)
532{
533	struct kunit_kmalloc_params params = {
534		.size = size,
535		.gfp = gfp
536	};
537
538	return kunit_alloc_resource(test,
539				    kunit_kmalloc_init,
540				    kunit_kmalloc_free,
541				    gfp,
542				    &params);
543}
544EXPORT_SYMBOL_GPL(kunit_kmalloc);
545
546void kunit_kfree(struct kunit *test, const void *ptr)
547{
548	struct kunit_resource *res;
549
550	res = kunit_find_resource(test, kunit_resource_instance_match,
551				  (void *)ptr);
552
553	/*
554	 * Removing the resource from the list of resources drops the
555	 * reference count to 1; the final put will trigger the free.
556	 */
557	kunit_remove_resource(test, res);
558
559	kunit_put_resource(res);
560
561}
562EXPORT_SYMBOL_GPL(kunit_kfree);
563
564void kunit_cleanup(struct kunit *test)
565{
566	struct kunit_resource *res;
567
568	/*
569	 * test->resources is a stack - each allocation must be freed in the
570	 * reverse order from which it was added since one resource may depend
571	 * on another for its entire lifetime.
572	 * Also, we cannot use the normal list_for_each constructs, even the
573	 * safe ones because *arbitrary* nodes may be deleted when
574	 * kunit_resource_free is called; the list_for_each_safe variants only
575	 * protect against the current node being deleted, not the next.
576	 */
577	while (true) {
578		spin_lock(&test->lock);
579		if (list_empty(&test->resources)) {
580			spin_unlock(&test->lock);
581			break;
582		}
583		res = list_last_entry(&test->resources,
584				      struct kunit_resource,
585				      node);
586		/*
587		 * Need to unlock here as a resource may remove another
588		 * resource, and this can't happen if the test->lock
589		 * is held.
590		 */
591		spin_unlock(&test->lock);
592		kunit_remove_resource(test, res);
593	}
594#if (IS_ENABLED(CONFIG_KASAN) && IS_ENABLED(CONFIG_KUNIT))
595	current->kunit_test = NULL;
596#endif /* IS_ENABLED(CONFIG_KASAN) && IS_ENABLED(CONFIG_KUNIT)*/
597}
598EXPORT_SYMBOL_GPL(kunit_cleanup);
599
600static int __init kunit_init(void)
601{
602	kunit_debugfs_init();
603
604	return 0;
605}
606late_initcall(kunit_init);
607
608static void __exit kunit_exit(void)
609{
610	kunit_debugfs_cleanup();
611}
612module_exit(kunit_exit);
613
614MODULE_LICENSE("GPL v2");
615