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