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