xref: /openbmc/linux/lib/kunit/kunit-test.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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