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