Linux Audio

Check our new training course

Loading...
v5.9
  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
 
 
 
 
 10#include "try-catch-impl.h"
 11
 12struct kunit_try_catch_test_context {
 13	struct kunit_try_catch *try_catch;
 14	bool function_called;
 15};
 16
 17static void kunit_test_successful_try(void *data)
 18{
 19	struct kunit *test = data;
 20	struct kunit_try_catch_test_context *ctx = test->priv;
 21
 22	ctx->function_called = true;
 23}
 24
 25static void kunit_test_no_catch(void *data)
 26{
 27	struct kunit *test = data;
 28
 29	KUNIT_FAIL(test, "Catch should not be called\n");
 30}
 31
 32static void kunit_test_try_catch_successful_try_no_catch(struct kunit *test)
 33{
 34	struct kunit_try_catch_test_context *ctx = test->priv;
 35	struct kunit_try_catch *try_catch = ctx->try_catch;
 36
 37	kunit_try_catch_init(try_catch,
 38			     test,
 39			     kunit_test_successful_try,
 40			     kunit_test_no_catch);
 41	kunit_try_catch_run(try_catch, test);
 42
 43	KUNIT_EXPECT_TRUE(test, ctx->function_called);
 44}
 45
 46static void kunit_test_unsuccessful_try(void *data)
 47{
 48	struct kunit *test = data;
 49	struct kunit_try_catch_test_context *ctx = test->priv;
 50	struct kunit_try_catch *try_catch = ctx->try_catch;
 51
 52	kunit_try_catch_throw(try_catch);
 53	KUNIT_FAIL(test, "This line should never be reached\n");
 54}
 55
 56static void kunit_test_catch(void *data)
 57{
 58	struct kunit *test = data;
 59	struct kunit_try_catch_test_context *ctx = test->priv;
 60
 61	ctx->function_called = true;
 62}
 63
 64static void kunit_test_try_catch_unsuccessful_try_does_catch(struct kunit *test)
 65{
 66	struct kunit_try_catch_test_context *ctx = test->priv;
 67	struct kunit_try_catch *try_catch = ctx->try_catch;
 68
 69	kunit_try_catch_init(try_catch,
 70			     test,
 71			     kunit_test_unsuccessful_try,
 72			     kunit_test_catch);
 73	kunit_try_catch_run(try_catch, test);
 74
 75	KUNIT_EXPECT_TRUE(test, ctx->function_called);
 76}
 77
 78static int kunit_try_catch_test_init(struct kunit *test)
 79{
 80	struct kunit_try_catch_test_context *ctx;
 81
 82	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
 83	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 84	test->priv = ctx;
 85
 86	ctx->try_catch = kunit_kmalloc(test,
 87				       sizeof(*ctx->try_catch),
 88				       GFP_KERNEL);
 89	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->try_catch);
 90
 91	return 0;
 92}
 93
 94static struct kunit_case kunit_try_catch_test_cases[] = {
 95	KUNIT_CASE(kunit_test_try_catch_successful_try_no_catch),
 96	KUNIT_CASE(kunit_test_try_catch_unsuccessful_try_does_catch),
 97	{}
 98};
 99
100static struct kunit_suite kunit_try_catch_test_suite = {
101	.name = "kunit-try-catch-test",
102	.init = kunit_try_catch_test_init,
103	.test_cases = kunit_try_catch_test_cases,
104};
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106/*
107 * Context for testing test managed resources
108 * is_resource_initialized is used to test arbitrary resources
109 */
110struct kunit_test_resource_context {
111	struct kunit test;
112	bool is_resource_initialized;
113	int allocate_order[2];
114	int free_order[2];
115};
116
117static int fake_resource_init(struct kunit_resource *res, void *context)
118{
119	struct kunit_test_resource_context *ctx = context;
120
121	res->data = &ctx->is_resource_initialized;
122	ctx->is_resource_initialized = true;
123	return 0;
124}
125
126static void fake_resource_free(struct kunit_resource *res)
127{
128	bool *is_resource_initialized = res->data;
129
130	*is_resource_initialized = false;
131}
132
133static void kunit_resource_test_init_resources(struct kunit *test)
134{
135	struct kunit_test_resource_context *ctx = test->priv;
136
137	kunit_init_test(&ctx->test, "testing_test_init_test", NULL);
138
139	KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources));
140}
141
142static void kunit_resource_test_alloc_resource(struct kunit *test)
143{
144	struct kunit_test_resource_context *ctx = test->priv;
145	struct kunit_resource *res;
146	kunit_resource_free_t free = fake_resource_free;
147
148	res = kunit_alloc_and_get_resource(&ctx->test,
149					   fake_resource_init,
150					   fake_resource_free,
151					   GFP_KERNEL,
152					   ctx);
153
154	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res);
155	KUNIT_EXPECT_PTR_EQ(test,
156			    &ctx->is_resource_initialized,
157			    (bool *)res->data);
158	KUNIT_EXPECT_TRUE(test, list_is_last(&res->node, &ctx->test.resources));
159	KUNIT_EXPECT_PTR_EQ(test, free, res->free);
160
161	kunit_put_resource(res);
162}
163
 
 
 
 
 
 
 
164/*
165 * Note: tests below use kunit_alloc_and_get_resource(), so as a consequence
166 * they have a reference to the associated resource that they must release
167 * via kunit_put_resource().  In normal operation, users will only
168 * have to do this for cases where they use kunit_find_resource(), and the
169 * kunit_alloc_resource() function will be used (which does not take a
170 * resource reference).
171 */
172static void kunit_resource_test_destroy_resource(struct kunit *test)
173{
174	struct kunit_test_resource_context *ctx = test->priv;
175	struct kunit_resource *res = kunit_alloc_and_get_resource(
176			&ctx->test,
177			fake_resource_init,
178			fake_resource_free,
179			GFP_KERNEL,
180			ctx);
181
182	kunit_put_resource(res);
183
184	KUNIT_ASSERT_FALSE(test,
185			   kunit_destroy_resource(&ctx->test,
186						  kunit_resource_instance_match,
187						  res->data));
188
189	KUNIT_EXPECT_FALSE(test, ctx->is_resource_initialized);
190	KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources));
191}
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193static void kunit_resource_test_cleanup_resources(struct kunit *test)
194{
195	int i;
196	struct kunit_test_resource_context *ctx = test->priv;
197	struct kunit_resource *resources[5];
198
199	for (i = 0; i < ARRAY_SIZE(resources); i++) {
200		resources[i] = kunit_alloc_and_get_resource(&ctx->test,
201							    fake_resource_init,
202							    fake_resource_free,
203							    GFP_KERNEL,
204							    ctx);
205		kunit_put_resource(resources[i]);
206	}
207
208	kunit_cleanup(&ctx->test);
209
210	KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources));
211}
212
213static void kunit_resource_test_mark_order(int order_array[],
214					   size_t order_size,
215					   int key)
216{
217	int i;
218
219	for (i = 0; i < order_size && order_array[i]; i++)
220		;
221
222	order_array[i] = key;
223}
224
225#define KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, order_field, key)		       \
226		kunit_resource_test_mark_order(ctx->order_field,	       \
227					       ARRAY_SIZE(ctx->order_field),   \
228					       key)
229
230static int fake_resource_2_init(struct kunit_resource *res, void *context)
231{
232	struct kunit_test_resource_context *ctx = context;
233
234	KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, allocate_order, 2);
235
236	res->data = ctx;
237
238	return 0;
239}
240
241static void fake_resource_2_free(struct kunit_resource *res)
242{
243	struct kunit_test_resource_context *ctx = res->data;
244
245	KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, free_order, 2);
246}
247
248static int fake_resource_1_init(struct kunit_resource *res, void *context)
249{
250	struct kunit_test_resource_context *ctx = context;
251	struct kunit_resource *res2;
252
253	res2 = kunit_alloc_and_get_resource(&ctx->test,
254					    fake_resource_2_init,
255					    fake_resource_2_free,
256					    GFP_KERNEL,
257					    ctx);
258
259	KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, allocate_order, 1);
260
261	res->data = ctx;
262
263	kunit_put_resource(res2);
264
265	return 0;
266}
267
268static void fake_resource_1_free(struct kunit_resource *res)
269{
270	struct kunit_test_resource_context *ctx = res->data;
271
272	KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, free_order, 1);
273}
274
275/*
276 * TODO(brendanhiggins@google.com): replace the arrays that keep track of the
277 * order of allocation and freeing with strict mocks using the IN_SEQUENCE macro
278 * to assert allocation and freeing order when the feature becomes available.
279 */
280static void kunit_resource_test_proper_free_ordering(struct kunit *test)
281{
282	struct kunit_test_resource_context *ctx = test->priv;
283	struct kunit_resource *res;
284
285	/* fake_resource_1 allocates a fake_resource_2 in its init. */
286	res = kunit_alloc_and_get_resource(&ctx->test,
287					   fake_resource_1_init,
288					   fake_resource_1_free,
289					   GFP_KERNEL,
290					   ctx);
291
292	/*
293	 * Since fake_resource_2_init calls KUNIT_RESOURCE_TEST_MARK_ORDER
294	 * before returning to fake_resource_1_init, it should be the first to
295	 * put its key in the allocate_order array.
296	 */
297	KUNIT_EXPECT_EQ(test, ctx->allocate_order[0], 2);
298	KUNIT_EXPECT_EQ(test, ctx->allocate_order[1], 1);
299
300	kunit_put_resource(res);
301
302	kunit_cleanup(&ctx->test);
303
304	/*
305	 * Because fake_resource_2 finishes allocation before fake_resource_1,
306	 * fake_resource_1 should be freed first since it could depend on
307	 * fake_resource_2.
308	 */
309	KUNIT_EXPECT_EQ(test, ctx->free_order[0], 1);
310	KUNIT_EXPECT_EQ(test, ctx->free_order[1], 2);
311}
312
313static void kunit_resource_test_static(struct kunit *test)
314{
315	struct kunit_test_resource_context ctx;
316	struct kunit_resource res;
317
318	KUNIT_EXPECT_EQ(test, kunit_add_resource(test, NULL, NULL, &res, &ctx),
319			0);
320
321	KUNIT_EXPECT_PTR_EQ(test, res.data, (void *)&ctx);
322
323	kunit_cleanup(test);
324
325	KUNIT_EXPECT_TRUE(test, list_empty(&test->resources));
326}
327
328static void kunit_resource_test_named(struct kunit *test)
329{
330	struct kunit_resource res1, res2, *found = NULL;
331	struct kunit_test_resource_context ctx;
332
333	KUNIT_EXPECT_EQ(test,
334			kunit_add_named_resource(test, NULL, NULL, &res1,
335						 "resource_1", &ctx),
336			0);
337	KUNIT_EXPECT_PTR_EQ(test, res1.data, (void *)&ctx);
338
339	KUNIT_EXPECT_EQ(test,
340			kunit_add_named_resource(test, NULL, NULL, &res1,
341						 "resource_1", &ctx),
342			-EEXIST);
343
344	KUNIT_EXPECT_EQ(test,
345			kunit_add_named_resource(test, NULL, NULL, &res2,
346						 "resource_2", &ctx),
347			0);
348
349	found = kunit_find_named_resource(test, "resource_1");
350
351	KUNIT_EXPECT_PTR_EQ(test, found, &res1);
352
353	if (found)
354		kunit_put_resource(&res1);
355
356	KUNIT_EXPECT_EQ(test, kunit_destroy_named_resource(test, "resource_2"),
357			0);
358
359	kunit_cleanup(test);
360
361	KUNIT_EXPECT_TRUE(test, list_empty(&test->resources));
362}
363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364static int kunit_resource_test_init(struct kunit *test)
365{
366	struct kunit_test_resource_context *ctx =
367			kzalloc(sizeof(*ctx), GFP_KERNEL);
368
369	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
370
371	test->priv = ctx;
372
373	kunit_init_test(&ctx->test, "test_test_context", NULL);
374
375	return 0;
376}
377
378static void kunit_resource_test_exit(struct kunit *test)
379{
380	struct kunit_test_resource_context *ctx = test->priv;
381
382	kunit_cleanup(&ctx->test);
383	kfree(ctx);
384}
385
386static struct kunit_case kunit_resource_test_cases[] = {
387	KUNIT_CASE(kunit_resource_test_init_resources),
388	KUNIT_CASE(kunit_resource_test_alloc_resource),
389	KUNIT_CASE(kunit_resource_test_destroy_resource),
 
390	KUNIT_CASE(kunit_resource_test_cleanup_resources),
391	KUNIT_CASE(kunit_resource_test_proper_free_ordering),
392	KUNIT_CASE(kunit_resource_test_static),
393	KUNIT_CASE(kunit_resource_test_named),
 
 
 
 
394	{}
395};
396
397static struct kunit_suite kunit_resource_test_suite = {
398	.name = "kunit-resource-test",
399	.init = kunit_resource_test_init,
400	.exit = kunit_resource_test_exit,
401	.test_cases = kunit_resource_test_cases,
402};
403
404static void kunit_log_test(struct kunit *test);
405
406static struct kunit_case kunit_log_test_cases[] = {
407	KUNIT_CASE(kunit_log_test),
408	{}
409};
410
411static struct kunit_suite kunit_log_test_suite = {
412	.name = "kunit-log-test",
413	.test_cases = kunit_log_test_cases,
414};
415
416static void kunit_log_test(struct kunit *test)
417{
418	struct kunit_suite *suite = &kunit_log_test_suite;
 
 
 
 
 
 
419
420	kunit_log(KERN_INFO, test, "put this in log.");
421	kunit_log(KERN_INFO, test, "this too.");
422	kunit_log(KERN_INFO, suite, "add to suite log.");
423	kunit_log(KERN_INFO, suite, "along with this.");
424
425#ifdef CONFIG_KUNIT_DEBUGFS
 
 
 
 
426	KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
427				     strstr(test->log, "put this in log."));
428	KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
429				     strstr(test->log, "this too."));
 
 
 
430	KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
431				     strstr(suite->log, "add to suite log."));
432	KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
433				     strstr(suite->log, "along with this."));
434#else
435	KUNIT_EXPECT_PTR_EQ(test, test->log, (char *)NULL);
436	KUNIT_EXPECT_PTR_EQ(test, suite->log, (char *)NULL);
437#endif
438}
439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440kunit_test_suites(&kunit_try_catch_test_suite, &kunit_resource_test_suite,
441		  &kunit_log_test_suite);
 
 
442
 
443MODULE_LICENSE("GPL v2");
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * KUnit test for core test infrastructure.
  4 *
  5 * Copyright (C) 2019, Google LLC.
  6 * Author: Brendan Higgins <brendanhiggins@google.com>
  7 */
  8#include "linux/gfp_types.h"
  9#include <kunit/test.h>
 10#include <kunit/test-bug.h>
 11
 12#include <linux/device.h>
 13#include <kunit/device.h>
 14
 15#include "string-stream.h"
 16#include "try-catch-impl.h"
 17
 18struct kunit_try_catch_test_context {
 19	struct kunit_try_catch *try_catch;
 20	bool function_called;
 21};
 22
 23static void kunit_test_successful_try(void *data)
 24{
 25	struct kunit *test = data;
 26	struct kunit_try_catch_test_context *ctx = test->priv;
 27
 28	ctx->function_called = true;
 29}
 30
 31static void kunit_test_no_catch(void *data)
 32{
 33	struct kunit *test = data;
 34
 35	KUNIT_FAIL(test, "Catch should not be called\n");
 36}
 37
 38static void kunit_test_try_catch_successful_try_no_catch(struct kunit *test)
 39{
 40	struct kunit_try_catch_test_context *ctx = test->priv;
 41	struct kunit_try_catch *try_catch = ctx->try_catch;
 42
 43	kunit_try_catch_init(try_catch,
 44			     test,
 45			     kunit_test_successful_try,
 46			     kunit_test_no_catch);
 47	kunit_try_catch_run(try_catch, test);
 48
 49	KUNIT_EXPECT_TRUE(test, ctx->function_called);
 50}
 51
 52static void kunit_test_unsuccessful_try(void *data)
 53{
 54	struct kunit *test = data;
 55	struct kunit_try_catch_test_context *ctx = test->priv;
 56	struct kunit_try_catch *try_catch = ctx->try_catch;
 57
 58	kunit_try_catch_throw(try_catch);
 59	KUNIT_FAIL(test, "This line should never be reached\n");
 60}
 61
 62static void kunit_test_catch(void *data)
 63{
 64	struct kunit *test = data;
 65	struct kunit_try_catch_test_context *ctx = test->priv;
 66
 67	ctx->function_called = true;
 68}
 69
 70static void kunit_test_try_catch_unsuccessful_try_does_catch(struct kunit *test)
 71{
 72	struct kunit_try_catch_test_context *ctx = test->priv;
 73	struct kunit_try_catch *try_catch = ctx->try_catch;
 74
 75	kunit_try_catch_init(try_catch,
 76			     test,
 77			     kunit_test_unsuccessful_try,
 78			     kunit_test_catch);
 79	kunit_try_catch_run(try_catch, test);
 80
 81	KUNIT_EXPECT_TRUE(test, ctx->function_called);
 82}
 83
 84static int kunit_try_catch_test_init(struct kunit *test)
 85{
 86	struct kunit_try_catch_test_context *ctx;
 87
 88	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
 89	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
 90	test->priv = ctx;
 91
 92	ctx->try_catch = kunit_kmalloc(test,
 93				       sizeof(*ctx->try_catch),
 94				       GFP_KERNEL);
 95	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->try_catch);
 96
 97	return 0;
 98}
 99
100static struct kunit_case kunit_try_catch_test_cases[] = {
101	KUNIT_CASE(kunit_test_try_catch_successful_try_no_catch),
102	KUNIT_CASE(kunit_test_try_catch_unsuccessful_try_does_catch),
103	{}
104};
105
106static struct kunit_suite kunit_try_catch_test_suite = {
107	.name = "kunit-try-catch-test",
108	.init = kunit_try_catch_test_init,
109	.test_cases = kunit_try_catch_test_cases,
110};
111
112#if IS_ENABLED(CONFIG_KUNIT_FAULT_TEST)
113
114static 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
124static 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
141static 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
148static 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 */
158struct 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
165static 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
174static void fake_resource_free(struct kunit_resource *res)
175{
176	bool *is_resource_initialized = res->data;
177
178	*is_resource_initialized = false;
179}
180
181static 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
190static 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
212static 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 */
227static 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
248static 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
282static 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
302static 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
319static 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
330static 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
337static 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
357static 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 */
369static 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
402static 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
417static 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
453static void increment_int(void *ctx)
454{
455	int *i = (int *)ctx;
456	(*i)++;
457}
458
459static 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}
478static 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}
489static 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}
503static 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}
510static 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}
517static 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
535static 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
549static 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
557static 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
573static 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(). */
587KUNIT_DEFINE_ACTION_WRAPPER(kfree_wrapper, kfree, const void *);
 
 
588
589static 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
625static 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
641static void kunit_log_test(struct kunit *test)
642{
643	kunit_skip(test, "Log tests only run when built-in");
644}
645
646static 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
652static struct kunit_case kunit_log_test_cases[] = {
653	KUNIT_CASE(kunit_log_test),
654	KUNIT_CASE(kunit_log_newline_test),
655	{}
656};
657
658static struct kunit_suite kunit_log_test_suite = {
659	.name = "kunit-log-test",
660	.test_cases = kunit_log_test_cases,
661};
662
663static 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
674static 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
692static 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
698static struct kunit_suite kunit_status_test_suite = {
699	.name = "kunit_status",
700	.test_cases = kunit_status_test_cases,
701};
702
703static 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
712static 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
730static struct kunit_case kunit_current_test_cases[] = {
731	KUNIT_CASE(kunit_current_test),
732	KUNIT_CASE(kunit_current_fail_test),
733	{}
734};
735
736static void test_dev_action(void *priv)
737{
738	*(void **)priv = (void *)1;
739}
740
741static 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
759static 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
778struct driver_test_state {
779	bool driver_device_probed;
780	bool driver_device_removed;
781	long action_was_run;
782};
783
784static 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
793static 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
802static 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
854static 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
861static struct kunit_suite kunit_device_test_suite = {
862	.name = "kunit_device",
863	.test_cases = kunit_device_test_cases,
864};
865
866static struct kunit_suite kunit_current_test_suite = {
867	.name = "kunit_current",
868	.test_cases = kunit_current_test_cases,
869};
870
871kunit_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
876MODULE_DESCRIPTION("KUnit test for core test infrastructure");
877MODULE_LICENSE("GPL v2");