1// SPDX-License-Identifier: GPL-2.0
2/*
3 * KUnit test for core test infrastructure.
4 *
5 * Copyright (C) 2019, Google LLC.
6 * Author: Brendan Higgins <brendanhiggins@google.com>
7 */
8#include "linux/gfp_types.h"
9#include <kunit/test.h>
10#include <kunit/test-bug.h>
11
12#include <linux/device.h>
13#include <kunit/device.h>
14
15#include "string-stream.h"
16#include "try-catch-impl.h"
17
18struct kunit_try_catch_test_context {
19	struct kunit_try_catch *try_catch;
20	bool function_called;
21};
22
23static void kunit_test_successful_try(void *data)
24{
25	struct kunit *test = data;
26	struct kunit_try_catch_test_context *ctx = test->priv;
27
28	ctx->function_called = true;
29}
30
31static void kunit_test_no_catch(void *data)
32{
33	struct kunit *test = data;
34
35	KUNIT_FAIL(test, "Catch should not be called\n");
36}
37
38static void kunit_test_try_catch_successful_try_no_catch(struct kunit *test)
39{
40	struct kunit_try_catch_test_context *ctx = test->priv;
41	struct kunit_try_catch *try_catch = ctx->try_catch;
42
43	kunit_try_catch_init(try_catch,
44			     test,
45			     kunit_test_successful_try,
46			     kunit_test_no_catch);
47	kunit_try_catch_run(try_catch, test);
48
49	KUNIT_EXPECT_TRUE(test, ctx->function_called);
50}
51
52static void kunit_test_unsuccessful_try(void *data)
53{
54	struct kunit *test = data;
55	struct kunit_try_catch_test_context *ctx = test->priv;
56	struct kunit_try_catch *try_catch = ctx->try_catch;
57
58	kunit_try_catch_throw(try_catch);
59	KUNIT_FAIL(test, "This line should never be reached\n");
60}
61
62static void kunit_test_catch(void *data)
63{
64	struct kunit *test = data;
65	struct kunit_try_catch_test_context *ctx = test->priv;
66
67	ctx->function_called = true;
68}
69
70static void kunit_test_try_catch_unsuccessful_try_does_catch(struct kunit *test)
71{
72	struct kunit_try_catch_test_context *ctx = test->priv;
73	struct kunit_try_catch *try_catch = ctx->try_catch;
74
75	kunit_try_catch_init(try_catch,
76			     test,
77			     kunit_test_unsuccessful_try,
78			     kunit_test_catch);
79	kunit_try_catch_run(try_catch, test);
80
81	KUNIT_EXPECT_TRUE(test, ctx->function_called);
82}
83
84static int kunit_try_catch_test_init(struct kunit *test)
85{
86	struct kunit_try_catch_test_context *ctx;
87
88	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
89	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
90	test->priv = ctx;
91
92	ctx->try_catch = kunit_kmalloc(test,
93				       sizeof(*ctx->try_catch),
94				       GFP_KERNEL);
95	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->try_catch);
96
97	return 0;
98}
99
100static struct kunit_case kunit_try_catch_test_cases[] = {
101	KUNIT_CASE(kunit_test_try_catch_successful_try_no_catch),
102	KUNIT_CASE(kunit_test_try_catch_unsuccessful_try_does_catch),
103	{}
104};
105
106static struct kunit_suite kunit_try_catch_test_suite = {
107	.name = "kunit-try-catch-test",
108	.init = kunit_try_catch_test_init,
109	.test_cases = kunit_try_catch_test_cases,
110};
111
112/*
113 * Context for testing test managed resources
114 * is_resource_initialized is used to test arbitrary resources
115 */
116struct kunit_test_resource_context {
117	struct kunit test;
118	bool is_resource_initialized;
119	int allocate_order[2];
120	int free_order[4];
121};
122
123static int fake_resource_init(struct kunit_resource *res, void *context)
124{
125	struct kunit_test_resource_context *ctx = context;
126
127	res->data = &ctx->is_resource_initialized;
128	ctx->is_resource_initialized = true;
129	return 0;
130}
131
132static void fake_resource_free(struct kunit_resource *res)
133{
134	bool *is_resource_initialized = res->data;
135
136	*is_resource_initialized = false;
137}
138
139static void kunit_resource_test_init_resources(struct kunit *test)
140{
141	struct kunit_test_resource_context *ctx = test->priv;
142
143	kunit_init_test(&ctx->test, "testing_test_init_test", NULL);
144
145	KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources));
146}
147
148static void kunit_resource_test_alloc_resource(struct kunit *test)
149{
150	struct kunit_test_resource_context *ctx = test->priv;
151	struct kunit_resource *res;
152	kunit_resource_free_t free = fake_resource_free;
153
154	res = kunit_alloc_and_get_resource(&ctx->test,
155					   fake_resource_init,
156					   fake_resource_free,
157					   GFP_KERNEL,
158					   ctx);
159
160	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res);
161	KUNIT_EXPECT_PTR_EQ(test,
162			    &ctx->is_resource_initialized,
163			    (bool *)res->data);
164	KUNIT_EXPECT_TRUE(test, list_is_last(&res->node, &ctx->test.resources));
165	KUNIT_EXPECT_PTR_EQ(test, free, res->free);
166
167	kunit_put_resource(res);
168}
169
170static inline bool kunit_resource_instance_match(struct kunit *test,
171						 struct kunit_resource *res,
172						 void *match_data)
173{
174	return res->data == match_data;
175}
176
177/*
178 * Note: tests below use kunit_alloc_and_get_resource(), so as a consequence
179 * they have a reference to the associated resource that they must release
180 * via kunit_put_resource().  In normal operation, users will only
181 * have to do this for cases where they use kunit_find_resource(), and the
182 * kunit_alloc_resource() function will be used (which does not take a
183 * resource reference).
184 */
185static void kunit_resource_test_destroy_resource(struct kunit *test)
186{
187	struct kunit_test_resource_context *ctx = test->priv;
188	struct kunit_resource *res = kunit_alloc_and_get_resource(
189			&ctx->test,
190			fake_resource_init,
191			fake_resource_free,
192			GFP_KERNEL,
193			ctx);
194
195	kunit_put_resource(res);
196
197	KUNIT_ASSERT_FALSE(test,
198			   kunit_destroy_resource(&ctx->test,
199						  kunit_resource_instance_match,
200						  res->data));
201
202	KUNIT_EXPECT_FALSE(test, ctx->is_resource_initialized);
203	KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources));
204}
205
206static void kunit_resource_test_remove_resource(struct kunit *test)
207{
208	struct kunit_test_resource_context *ctx = test->priv;
209	struct kunit_resource *res = kunit_alloc_and_get_resource(
210			&ctx->test,
211			fake_resource_init,
212			fake_resource_free,
213			GFP_KERNEL,
214			ctx);
215
216	/* The resource is in the list */
217	KUNIT_EXPECT_FALSE(test, list_empty(&ctx->test.resources));
218
219	/* Remove the resource. The pointer is still valid, but it can't be
220	 * found.
221	 */
222	kunit_remove_resource(test, res);
223	KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources));
224	/* We haven't been freed yet. */
225	KUNIT_EXPECT_TRUE(test, ctx->is_resource_initialized);
226
227	/* Removing the resource multiple times is valid. */
228	kunit_remove_resource(test, res);
229	KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources));
230	/* Despite having been removed twice (from only one reference), the
231	 * resource still has not been freed.
232	 */
233	KUNIT_EXPECT_TRUE(test, ctx->is_resource_initialized);
234
235	/* Free the resource. */
236	kunit_put_resource(res);
237	KUNIT_EXPECT_FALSE(test, ctx->is_resource_initialized);
238}
239
240static void kunit_resource_test_cleanup_resources(struct kunit *test)
241{
242	int i;
243	struct kunit_test_resource_context *ctx = test->priv;
244	struct kunit_resource *resources[5];
245
246	for (i = 0; i < ARRAY_SIZE(resources); i++) {
247		resources[i] = kunit_alloc_and_get_resource(&ctx->test,
248							    fake_resource_init,
249							    fake_resource_free,
250							    GFP_KERNEL,
251							    ctx);
252		kunit_put_resource(resources[i]);
253	}
254
255	kunit_cleanup(&ctx->test);
256
257	KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources));
258}
259
260static void kunit_resource_test_mark_order(int order_array[],
261					   size_t order_size,
262					   int key)
263{
264	int i;
265
266	for (i = 0; i < order_size && order_array[i]; i++)
267		;
268
269	order_array[i] = key;
270}
271
272#define KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, order_field, key)		       \
273		kunit_resource_test_mark_order(ctx->order_field,	       \
274					       ARRAY_SIZE(ctx->order_field),   \
275					       key)
276
277static int fake_resource_2_init(struct kunit_resource *res, void *context)
278{
279	struct kunit_test_resource_context *ctx = context;
280
281	KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, allocate_order, 2);
282
283	res->data = ctx;
284
285	return 0;
286}
287
288static void fake_resource_2_free(struct kunit_resource *res)
289{
290	struct kunit_test_resource_context *ctx = res->data;
291
292	KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, free_order, 2);
293}
294
295static int fake_resource_1_init(struct kunit_resource *res, void *context)
296{
297	struct kunit_test_resource_context *ctx = context;
298	struct kunit_resource *res2;
299
300	res2 = kunit_alloc_and_get_resource(&ctx->test,
301					    fake_resource_2_init,
302					    fake_resource_2_free,
303					    GFP_KERNEL,
304					    ctx);
305
306	KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, allocate_order, 1);
307
308	res->data = ctx;
309
310	kunit_put_resource(res2);
311
312	return 0;
313}
314
315static void fake_resource_1_free(struct kunit_resource *res)
316{
317	struct kunit_test_resource_context *ctx = res->data;
318
319	KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, free_order, 1);
320}
321
322/*
323 * TODO(brendanhiggins@google.com): replace the arrays that keep track of the
324 * order of allocation and freeing with strict mocks using the IN_SEQUENCE macro
325 * to assert allocation and freeing order when the feature becomes available.
326 */
327static void kunit_resource_test_proper_free_ordering(struct kunit *test)
328{
329	struct kunit_test_resource_context *ctx = test->priv;
330	struct kunit_resource *res;
331
332	/* fake_resource_1 allocates a fake_resource_2 in its init. */
333	res = kunit_alloc_and_get_resource(&ctx->test,
334					   fake_resource_1_init,
335					   fake_resource_1_free,
336					   GFP_KERNEL,
337					   ctx);
338
339	/*
340	 * Since fake_resource_2_init calls KUNIT_RESOURCE_TEST_MARK_ORDER
341	 * before returning to fake_resource_1_init, it should be the first to
342	 * put its key in the allocate_order array.
343	 */
344	KUNIT_EXPECT_EQ(test, ctx->allocate_order[0], 2);
345	KUNIT_EXPECT_EQ(test, ctx->allocate_order[1], 1);
346
347	kunit_put_resource(res);
348
349	kunit_cleanup(&ctx->test);
350
351	/*
352	 * Because fake_resource_2 finishes allocation before fake_resource_1,
353	 * fake_resource_1 should be freed first since it could depend on
354	 * fake_resource_2.
355	 */
356	KUNIT_EXPECT_EQ(test, ctx->free_order[0], 1);
357	KUNIT_EXPECT_EQ(test, ctx->free_order[1], 2);
358}
359
360static void kunit_resource_test_static(struct kunit *test)
361{
362	struct kunit_test_resource_context ctx;
363	struct kunit_resource res;
364
365	KUNIT_EXPECT_EQ(test, kunit_add_resource(test, NULL, NULL, &res, &ctx),
366			0);
367
368	KUNIT_EXPECT_PTR_EQ(test, res.data, (void *)&ctx);
369
370	kunit_cleanup(test);
371
372	KUNIT_EXPECT_TRUE(test, list_empty(&test->resources));
373}
374
375static void kunit_resource_test_named(struct kunit *test)
376{
377	struct kunit_resource res1, res2, *found = NULL;
378	struct kunit_test_resource_context ctx;
379
380	KUNIT_EXPECT_EQ(test,
381			kunit_add_named_resource(test, NULL, NULL, &res1,
382						 "resource_1", &ctx),
383			0);
384	KUNIT_EXPECT_PTR_EQ(test, res1.data, (void *)&ctx);
385
386	KUNIT_EXPECT_EQ(test,
387			kunit_add_named_resource(test, NULL, NULL, &res1,
388						 "resource_1", &ctx),
389			-EEXIST);
390
391	KUNIT_EXPECT_EQ(test,
392			kunit_add_named_resource(test, NULL, NULL, &res2,
393						 "resource_2", &ctx),
394			0);
395
396	found = kunit_find_named_resource(test, "resource_1");
397
398	KUNIT_EXPECT_PTR_EQ(test, found, &res1);
399
400	if (found)
401		kunit_put_resource(&res1);
402
403	KUNIT_EXPECT_EQ(test, kunit_destroy_named_resource(test, "resource_2"),
404			0);
405
406	kunit_cleanup(test);
407
408	KUNIT_EXPECT_TRUE(test, list_empty(&test->resources));
409}
410
411static void increment_int(void *ctx)
412{
413	int *i = (int *)ctx;
414	(*i)++;
415}
416
417static void kunit_resource_test_action(struct kunit *test)
418{
419	int num_actions = 0;
420
421	kunit_add_action(test, increment_int, &num_actions);
422	KUNIT_EXPECT_EQ(test, num_actions, 0);
423	kunit_cleanup(test);
424	KUNIT_EXPECT_EQ(test, num_actions, 1);
425
426	/* Once we've cleaned up, the action queue is empty. */
427	kunit_cleanup(test);
428	KUNIT_EXPECT_EQ(test, num_actions, 1);
429
430	/* Check the same function can be deferred multiple times. */
431	kunit_add_action(test, increment_int, &num_actions);
432	kunit_add_action(test, increment_int, &num_actions);
433	kunit_cleanup(test);
434	KUNIT_EXPECT_EQ(test, num_actions, 3);
435}
436static void kunit_resource_test_remove_action(struct kunit *test)
437{
438	int num_actions = 0;
439
440	kunit_add_action(test, increment_int, &num_actions);
441	KUNIT_EXPECT_EQ(test, num_actions, 0);
442
443	kunit_remove_action(test, increment_int, &num_actions);
444	kunit_cleanup(test);
445	KUNIT_EXPECT_EQ(test, num_actions, 0);
446}
447static void kunit_resource_test_release_action(struct kunit *test)
448{
449	int num_actions = 0;
450
451	kunit_add_action(test, increment_int, &num_actions);
452	KUNIT_EXPECT_EQ(test, num_actions, 0);
453	/* Runs immediately on trigger. */
454	kunit_release_action(test, increment_int, &num_actions);
455	KUNIT_EXPECT_EQ(test, num_actions, 1);
456
457	/* Doesn't run again on test exit. */
458	kunit_cleanup(test);
459	KUNIT_EXPECT_EQ(test, num_actions, 1);
460}
461static void action_order_1(void *ctx)
462{
463	struct kunit_test_resource_context *res_ctx = (struct kunit_test_resource_context *)ctx;
464
465	KUNIT_RESOURCE_TEST_MARK_ORDER(res_ctx, free_order, 1);
466	kunit_log(KERN_INFO, current->kunit_test, "action_order_1");
467}
468static void action_order_2(void *ctx)
469{
470	struct kunit_test_resource_context *res_ctx = (struct kunit_test_resource_context *)ctx;
471
472	KUNIT_RESOURCE_TEST_MARK_ORDER(res_ctx, free_order, 2);
473	kunit_log(KERN_INFO, current->kunit_test, "action_order_2");
474}
475static void kunit_resource_test_action_ordering(struct kunit *test)
476{
477	struct kunit_test_resource_context *ctx = test->priv;
478
479	kunit_add_action(test, action_order_1, ctx);
480	kunit_add_action(test, action_order_2, ctx);
481	kunit_add_action(test, action_order_1, ctx);
482	kunit_add_action(test, action_order_2, ctx);
483	kunit_remove_action(test, action_order_1, ctx);
484	kunit_release_action(test, action_order_2, ctx);
485	kunit_cleanup(test);
486
487	/* [2 is triggered] [2], [(1 is cancelled)] [1] */
488	KUNIT_EXPECT_EQ(test, ctx->free_order[0], 2);
489	KUNIT_EXPECT_EQ(test, ctx->free_order[1], 2);
490	KUNIT_EXPECT_EQ(test, ctx->free_order[2], 1);
491}
492
493static int kunit_resource_test_init(struct kunit *test)
494{
495	struct kunit_test_resource_context *ctx =
496			kzalloc(sizeof(*ctx), GFP_KERNEL);
497
498	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
499
500	test->priv = ctx;
501
502	kunit_init_test(&ctx->test, "test_test_context", NULL);
503
504	return 0;
505}
506
507static void kunit_resource_test_exit(struct kunit *test)
508{
509	struct kunit_test_resource_context *ctx = test->priv;
510
511	kunit_cleanup(&ctx->test);
512	kfree(ctx);
513}
514
515static struct kunit_case kunit_resource_test_cases[] = {
516	KUNIT_CASE(kunit_resource_test_init_resources),
517	KUNIT_CASE(kunit_resource_test_alloc_resource),
518	KUNIT_CASE(kunit_resource_test_destroy_resource),
519	KUNIT_CASE(kunit_resource_test_remove_resource),
520	KUNIT_CASE(kunit_resource_test_cleanup_resources),
521	KUNIT_CASE(kunit_resource_test_proper_free_ordering),
522	KUNIT_CASE(kunit_resource_test_static),
523	KUNIT_CASE(kunit_resource_test_named),
524	KUNIT_CASE(kunit_resource_test_action),
525	KUNIT_CASE(kunit_resource_test_remove_action),
526	KUNIT_CASE(kunit_resource_test_release_action),
527	KUNIT_CASE(kunit_resource_test_action_ordering),
528	{}
529};
530
531static struct kunit_suite kunit_resource_test_suite = {
532	.name = "kunit-resource-test",
533	.init = kunit_resource_test_init,
534	.exit = kunit_resource_test_exit,
535	.test_cases = kunit_resource_test_cases,
536};
537
538/*
539 * Log tests call string_stream functions, which aren't exported. So only
540 * build this code if this test is built-in.
541 */
542#if IS_BUILTIN(CONFIG_KUNIT_TEST)
543
544/* This avoids a cast warning if kfree() is passed direct to kunit_add_action(). */
545KUNIT_DEFINE_ACTION_WRAPPER(kfree_wrapper, kfree, const void *);
546
547static void kunit_log_test(struct kunit *test)
548{
549	struct kunit_suite suite;
550#ifdef CONFIG_KUNIT_DEBUGFS
551	char *full_log;
552#endif
553	suite.log = kunit_alloc_string_stream(test, GFP_KERNEL);
554	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, suite.log);
555	string_stream_set_append_newlines(suite.log, true);
556
557	kunit_log(KERN_INFO, test, "put this in log.");
558	kunit_log(KERN_INFO, test, "this too.");
559	kunit_log(KERN_INFO, &suite, "add to suite log.");
560	kunit_log(KERN_INFO, &suite, "along with this.");
561
562#ifdef CONFIG_KUNIT_DEBUGFS
563	KUNIT_EXPECT_TRUE(test, test->log->append_newlines);
564
565	full_log = string_stream_get_string(test->log);
566	kunit_add_action(test, kfree_wrapper, full_log);
567	KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
568				     strstr(full_log, "put this in log."));
569	KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
570				     strstr(full_log, "this too."));
571
572	full_log = string_stream_get_string(suite.log);
573	kunit_add_action(test, kfree_wrapper, full_log);
574	KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
575				     strstr(full_log, "add to suite log."));
576	KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
577				     strstr(full_log, "along with this."));
578#else
579	KUNIT_EXPECT_NULL(test, test->log);
580#endif
581}
582
583static void kunit_log_newline_test(struct kunit *test)
584{
585	char *full_log;
586
587	kunit_info(test, "Add newline\n");
588	if (test->log) {
589		full_log = string_stream_get_string(test->log);
590		kunit_add_action(test, kfree_wrapper, full_log);
591		KUNIT_ASSERT_NOT_NULL_MSG(test, strstr(full_log, "Add newline\n"),
592			"Missing log line, full log:\n%s", full_log);
593		KUNIT_EXPECT_NULL(test, strstr(full_log, "Add newline\n\n"));
594	} else {
595		kunit_skip(test, "only useful when debugfs is enabled");
596	}
597}
598#else
599static void kunit_log_test(struct kunit *test)
600{
601	kunit_skip(test, "Log tests only run when built-in");
602}
603
604static void kunit_log_newline_test(struct kunit *test)
605{
606	kunit_skip(test, "Log tests only run when built-in");
607}
608#endif /* IS_BUILTIN(CONFIG_KUNIT_TEST) */
609
610static struct kunit_case kunit_log_test_cases[] = {
611	KUNIT_CASE(kunit_log_test),
612	KUNIT_CASE(kunit_log_newline_test),
613	{}
614};
615
616static struct kunit_suite kunit_log_test_suite = {
617	.name = "kunit-log-test",
618	.test_cases = kunit_log_test_cases,
619};
620
621static void kunit_status_set_failure_test(struct kunit *test)
622{
623	struct kunit fake;
624
625	kunit_init_test(&fake, "fake test", NULL);
626
627	KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_SUCCESS);
628	kunit_set_failure(&fake);
629	KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_FAILURE);
630}
631
632static void kunit_status_mark_skipped_test(struct kunit *test)
633{
634	struct kunit fake;
635
636	kunit_init_test(&fake, "fake test", NULL);
637
638	/* Before: Should be SUCCESS with no comment. */
639	KUNIT_EXPECT_EQ(test, fake.status, KUNIT_SUCCESS);
640	KUNIT_EXPECT_STREQ(test, fake.status_comment, "");
641
642	/* Mark the test as skipped. */
643	kunit_mark_skipped(&fake, "Accepts format string: %s", "YES");
644
645	/* After: Should be SKIPPED with our comment. */
646	KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_SKIPPED);
647	KUNIT_EXPECT_STREQ(test, fake.status_comment, "Accepts format string: YES");
648}
649
650static struct kunit_case kunit_status_test_cases[] = {
651	KUNIT_CASE(kunit_status_set_failure_test),
652	KUNIT_CASE(kunit_status_mark_skipped_test),
653	{}
654};
655
656static struct kunit_suite kunit_status_test_suite = {
657	.name = "kunit_status",
658	.test_cases = kunit_status_test_cases,
659};
660
661static void kunit_current_test(struct kunit *test)
662{
663	/* Check results of both current->kunit_test and
664	 * kunit_get_current_test() are equivalent to current test.
665	 */
666	KUNIT_EXPECT_PTR_EQ(test, test, current->kunit_test);
667	KUNIT_EXPECT_PTR_EQ(test, test, kunit_get_current_test());
668}
669
670static void kunit_current_fail_test(struct kunit *test)
671{
672	struct kunit fake;
673
674	kunit_init_test(&fake, "fake test", NULL);
675	KUNIT_EXPECT_EQ(test, fake.status, KUNIT_SUCCESS);
676
677	/* Set current->kunit_test to fake test. */
678	current->kunit_test = &fake;
679
680	kunit_fail_current_test("This should make `fake` test fail.");
681	KUNIT_EXPECT_EQ(test, fake.status, (enum kunit_status)KUNIT_FAILURE);
682	kunit_cleanup(&fake);
683
684	/* Reset current->kunit_test to current test. */
685	current->kunit_test = test;
686}
687
688static struct kunit_case kunit_current_test_cases[] = {
689	KUNIT_CASE(kunit_current_test),
690	KUNIT_CASE(kunit_current_fail_test),
691	{}
692};
693
694static void test_dev_action(void *priv)
695{
696	*(void **)priv = (void *)1;
697}
698
699static void kunit_device_test(struct kunit *test)
700{
701	struct device *test_device;
702	long action_was_run = 0;
703
704	test_device = kunit_device_register(test, "my_device");
705	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_device);
706
707	// Add an action to verify cleanup.
708	devm_add_action(test_device, test_dev_action, &action_was_run);
709
710	KUNIT_EXPECT_EQ(test, action_was_run, 0);
711
712	kunit_device_unregister(test, test_device);
713
714	KUNIT_EXPECT_EQ(test, action_was_run, 1);
715}
716
717static void kunit_device_cleanup_test(struct kunit *test)
718{
719	struct device *test_device;
720	long action_was_run = 0;
721
722	test_device = kunit_device_register(test, "my_device");
723	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_device);
724
725	/* Add an action to verify cleanup. */
726	devm_add_action(test_device, test_dev_action, &action_was_run);
727
728	KUNIT_EXPECT_EQ(test, action_was_run, 0);
729
730	/* Force KUnit to run cleanup early. */
731	kunit_cleanup(test);
732
733	KUNIT_EXPECT_EQ(test, action_was_run, 1);
734}
735
736struct driver_test_state {
737	bool driver_device_probed;
738	bool driver_device_removed;
739	long action_was_run;
740};
741
742static int driver_probe_hook(struct device *dev)
743{
744	struct kunit *test = kunit_get_current_test();
745	struct driver_test_state *state = (struct driver_test_state *)test->priv;
746
747	state->driver_device_probed = true;
748	return 0;
749}
750
751static int driver_remove_hook(struct device *dev)
752{
753	struct kunit *test = kunit_get_current_test();
754	struct driver_test_state *state = (struct driver_test_state *)test->priv;
755
756	state->driver_device_removed = true;
757	return 0;
758}
759
760static void kunit_device_driver_test(struct kunit *test)
761{
762	struct device_driver *test_driver;
763	struct device *test_device;
764	struct driver_test_state *test_state = kunit_kzalloc(test, sizeof(*test_state), GFP_KERNEL);
765
766	test->priv = test_state;
767	test_driver = kunit_driver_create(test, "my_driver");
768
769	// This can fail with an error pointer.
770	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_driver);
771
772	test_driver->probe = driver_probe_hook;
773	test_driver->remove = driver_remove_hook;
774
775	test_device = kunit_device_register_with_driver(test, "my_device", test_driver);
776
777	// This can fail with an error pointer.
778	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_device);
779
780	// Make sure the probe function was called.
781	KUNIT_ASSERT_TRUE(test, test_state->driver_device_probed);
782
783	// Add an action to verify cleanup.
784	devm_add_action(test_device, test_dev_action, &test_state->action_was_run);
785
786	KUNIT_EXPECT_EQ(test, test_state->action_was_run, 0);
787
788	kunit_device_unregister(test, test_device);
789	test_device = NULL;
790
791	// Make sure the remove hook was called.
792	KUNIT_ASSERT_TRUE(test, test_state->driver_device_removed);
793
794	// We're going to test this again.
795	test_state->driver_device_probed = false;
796
797	// The driver should not automatically be destroyed by
798	// kunit_device_unregister, so we can re-use it.
799	test_device = kunit_device_register_with_driver(test, "my_device", test_driver);
800
801	// This can fail with an error pointer.
802	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_device);
803
804	// Probe was called again.
805	KUNIT_ASSERT_TRUE(test, test_state->driver_device_probed);
806
807	// Everything is automatically freed here.
808}
809
810static struct kunit_case kunit_device_test_cases[] = {
811	KUNIT_CASE(kunit_device_test),
812	KUNIT_CASE(kunit_device_cleanup_test),
813	KUNIT_CASE(kunit_device_driver_test),
814	{}
815};
816
817static struct kunit_suite kunit_device_test_suite = {
818	.name = "kunit_device",
819	.test_cases = kunit_device_test_cases,
820};
821
822static struct kunit_suite kunit_current_test_suite = {
823	.name = "kunit_current",
824	.test_cases = kunit_current_test_cases,
825};
826
827kunit_test_suites(&kunit_try_catch_test_suite, &kunit_resource_test_suite,
828		  &kunit_log_test_suite, &kunit_status_test_suite,
829		  &kunit_current_test_suite, &kunit_device_test_suite);
830
831MODULE_LICENSE("GPL v2");
832