1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * soc-topology-test.c  --  ALSA SoC Topology Kernel Unit Tests
4  *
5  * Copyright(c) 2021 Intel Corporation. All rights reserved.
6  */
7 
8 #include <linux/firmware.h>
9 #include <sound/core.h>
10 #include <sound/soc.h>
11 #include <sound/soc-topology.h>
12 #include <kunit/test.h>
13 
14 /* ===== HELPER FUNCTIONS =================================================== */
15 
16 /*
17  * snd_soc_component needs device to operate on (primarily for prints), create
18  * fake one, as we don't register with PCI or anything else
19  * device_driver name is used in some of the prints (fmt_single_name) so
20  * we also mock up minimal one
21  */
22 static struct device *test_dev;
23 
24 static struct device_driver test_drv = {
25 	.name = "sound-soc-topology-test-driver",
26 };
27 
snd_soc_tplg_test_init(struct kunit * test)28 static int snd_soc_tplg_test_init(struct kunit *test)
29 {
30 	test_dev = root_device_register("sound-soc-topology-test");
31 	test_dev = get_device(test_dev);
32 	if (!test_dev)
33 		return -ENODEV;
34 
35 	test_dev->driver = &test_drv;
36 
37 	return 0;
38 }
39 
snd_soc_tplg_test_exit(struct kunit * test)40 static void snd_soc_tplg_test_exit(struct kunit *test)
41 {
42 	put_device(test_dev);
43 	root_device_unregister(test_dev);
44 }
45 
46 /*
47  * helper struct we use when registering component, as we load topology during
48  * component probe, we need to pass struct kunit somehow to probe function, so
49  * we can report test result
50  */
51 struct kunit_soc_component {
52 	struct kunit *kunit;
53 	int expect; /* what result we expect when loading topology */
54 	struct snd_soc_component comp;
55 	struct snd_soc_card card;
56 	struct firmware fw;
57 };
58 
d_probe(struct snd_soc_component * component)59 static int d_probe(struct snd_soc_component *component)
60 {
61 	struct kunit_soc_component *kunit_comp =
62 			container_of(component, struct kunit_soc_component, comp);
63 	int ret;
64 
65 	ret = snd_soc_tplg_component_load(component, NULL, &kunit_comp->fw);
66 	KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
67 			    "Failed topology load");
68 
69 	return 0;
70 }
71 
d_remove(struct snd_soc_component * component)72 static void d_remove(struct snd_soc_component *component)
73 {
74 	struct kunit_soc_component *kunit_comp =
75 			container_of(component, struct kunit_soc_component, comp);
76 	int ret;
77 
78 	ret = snd_soc_tplg_component_remove(component);
79 	KUNIT_EXPECT_EQ(kunit_comp->kunit, 0, ret);
80 }
81 
82 /*
83  * ASoC minimal boiler plate
84  */
85 SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY()));
86 
87 SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("sound-soc-topology-test")));
88 
89 static struct snd_soc_dai_link kunit_dai_links[] = {
90 	{
91 		.name = "KUNIT Audio Port",
92 		.id = 0,
93 		.stream_name = "Audio Playback/Capture",
94 		.nonatomic = 1,
95 		.dynamic = 1,
96 		.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
97 		.dpcm_playback = 1,
98 		.dpcm_capture = 1,
99 		SND_SOC_DAILINK_REG(dummy, dummy, platform),
100 	},
101 };
102 
103 static const struct snd_soc_component_driver test_component = {
104 	.name = "sound-soc-topology-test",
105 	.probe = d_probe,
106 	.remove = d_remove,
107 };
108 
109 /* ===== TOPOLOGY TEMPLATES ================================================= */
110 
111 // Structural representation of topology which can be generated with:
112 // $ touch empty
113 // $ alsatplg -c empty -o empty.tplg
114 // $ xxd -i empty.tplg
115 
116 struct tplg_tmpl_001 {
117 	struct snd_soc_tplg_hdr header;
118 	struct snd_soc_tplg_manifest manifest;
119 } __packed;
120 
121 static struct tplg_tmpl_001 tplg_tmpl_empty = {
122 	.header = {
123 		.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC),
124 		.abi = cpu_to_le32(5),
125 		.version = 0,
126 		.type = cpu_to_le32(SND_SOC_TPLG_TYPE_MANIFEST),
127 		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)),
128 		.vendor_type = 0,
129 		.payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
130 		.index = 0,
131 		.count = cpu_to_le32(1),
132 	},
133 
134 	.manifest = {
135 		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
136 		/* rest of fields is 0 */
137 	},
138 };
139 
140 // Structural representation of topology containing SectionPCM
141 
142 struct tplg_tmpl_002 {
143 	struct snd_soc_tplg_hdr header;
144 	struct snd_soc_tplg_manifest manifest;
145 	struct snd_soc_tplg_hdr pcm_header;
146 	struct snd_soc_tplg_pcm pcm;
147 } __packed;
148 
149 static struct tplg_tmpl_002 tplg_tmpl_with_pcm = {
150 	.header = {
151 		.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC),
152 		.abi = cpu_to_le32(5),
153 		.version = 0,
154 		.type = cpu_to_le32(SND_SOC_TPLG_TYPE_MANIFEST),
155 		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)),
156 		.vendor_type = 0,
157 		.payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
158 		.index = 0,
159 		.count = cpu_to_le32(1),
160 	},
161 	.manifest = {
162 		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
163 		.pcm_elems = cpu_to_le32(1),
164 		/* rest of fields is 0 */
165 	},
166 	.pcm_header = {
167 		.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC),
168 		.abi = cpu_to_le32(5),
169 		.version = 0,
170 		.type = cpu_to_le32(SND_SOC_TPLG_TYPE_PCM),
171 		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)),
172 		.vendor_type = 0,
173 		.payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_pcm)),
174 		.index = 0,
175 		.count = cpu_to_le32(1),
176 	},
177 	.pcm = {
178 		.size = cpu_to_le32(sizeof(struct snd_soc_tplg_pcm)),
179 		.pcm_name = "KUNIT Audio",
180 		.dai_name = "kunit-audio-dai",
181 		.pcm_id = 0,
182 		.dai_id = 0,
183 		.playback = cpu_to_le32(1),
184 		.capture = cpu_to_le32(1),
185 		.compress = 0,
186 		.stream = {
187 			[0] = {
188 				.channels = cpu_to_le32(2),
189 			},
190 			[1] = {
191 				.channels = cpu_to_le32(2),
192 			},
193 		},
194 		.num_streams = 0,
195 		.caps = {
196 			[0] = {
197 				.name = "kunit-audio-playback",
198 				.channels_min = cpu_to_le32(2),
199 				.channels_max = cpu_to_le32(2),
200 			},
201 			[1] = {
202 				.name = "kunit-audio-capture",
203 				.channels_min = cpu_to_le32(2),
204 				.channels_max = cpu_to_le32(2),
205 			},
206 		},
207 		.flag_mask = 0,
208 		.flags = 0,
209 		.priv = { 0 },
210 	},
211 };
212 
213 /* ===== TEST CASES ========================================================= */
214 
215 // TEST CASE
216 // Test passing NULL component as parameter to snd_soc_tplg_component_load
217 
218 /*
219  * need to override generic probe function with one using NULL when calling
220  * topology load during component initialization, we don't need .remove
221  * handler as load should fail
222  */
d_probe_null_comp(struct snd_soc_component * component)223 static int d_probe_null_comp(struct snd_soc_component *component)
224 {
225 	struct kunit_soc_component *kunit_comp =
226 			container_of(component, struct kunit_soc_component, comp);
227 	int ret;
228 
229 	/* instead of passing component pointer as first argument, pass NULL here */
230 	ret = snd_soc_tplg_component_load(NULL, NULL, &kunit_comp->fw);
231 	KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
232 			    "Failed topology load");
233 
234 	return 0;
235 }
236 
237 static const struct snd_soc_component_driver test_component_null_comp = {
238 	.name = "sound-soc-topology-test",
239 	.probe = d_probe_null_comp,
240 };
241 
snd_soc_tplg_test_load_with_null_comp(struct kunit * test)242 static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test)
243 {
244 	struct kunit_soc_component *kunit_comp;
245 	int ret;
246 
247 	/* prepare */
248 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
249 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
250 	kunit_comp->kunit = test;
251 	kunit_comp->expect = -EINVAL; /* expect failure */
252 
253 	kunit_comp->card.dev = test_dev,
254 	kunit_comp->card.name = "kunit-card",
255 	kunit_comp->card.owner = THIS_MODULE,
256 	kunit_comp->card.dai_link = kunit_dai_links,
257 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
258 	kunit_comp->card.fully_routed = true,
259 
260 	/* run test */
261 	ret = snd_soc_register_card(&kunit_comp->card);
262 	if (ret != 0 && ret != -EPROBE_DEFER)
263 		KUNIT_FAIL(test, "Failed to register card");
264 
265 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_comp, test_dev);
266 	KUNIT_EXPECT_EQ(test, 0, ret);
267 
268 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
269 	KUNIT_EXPECT_EQ(test, 0, ret);
270 
271 	/* cleanup */
272 	snd_soc_unregister_card(&kunit_comp->card);
273 	snd_soc_unregister_component(test_dev);
274 }
275 
276 // TEST CASE
277 // Test passing NULL ops as parameter to snd_soc_tplg_component_load
278 
279 /*
280  * NULL ops is default case, we pass empty topology (fw), so we don't have
281  * anything to parse and just do nothing, which results in return 0; from
282  * calling soc_tplg_dapm_complete in soc_tplg_process_headers
283  */
snd_soc_tplg_test_load_with_null_ops(struct kunit * test)284 static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test)
285 {
286 	struct kunit_soc_component *kunit_comp;
287 	int ret;
288 
289 	/* prepare */
290 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
291 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
292 	kunit_comp->kunit = test;
293 	kunit_comp->expect = 0; /* expect success */
294 
295 	kunit_comp->card.dev = test_dev,
296 	kunit_comp->card.name = "kunit-card",
297 	kunit_comp->card.owner = THIS_MODULE,
298 	kunit_comp->card.dai_link = kunit_dai_links,
299 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
300 	kunit_comp->card.fully_routed = true,
301 
302 	/* run test */
303 	ret = snd_soc_register_card(&kunit_comp->card);
304 	if (ret != 0 && ret != -EPROBE_DEFER)
305 		KUNIT_FAIL(test, "Failed to register card");
306 
307 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
308 	KUNIT_EXPECT_EQ(test, 0, ret);
309 
310 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
311 	KUNIT_EXPECT_EQ(test, 0, ret);
312 
313 	/* cleanup */
314 	snd_soc_unregister_card(&kunit_comp->card);
315 
316 	snd_soc_unregister_component(test_dev);
317 }
318 
319 // TEST CASE
320 // Test passing NULL fw as parameter to snd_soc_tplg_component_load
321 
322 /*
323  * need to override generic probe function with one using NULL pointer to fw
324  * when calling topology load during component initialization, we don't need
325  * .remove handler as load should fail
326  */
d_probe_null_fw(struct snd_soc_component * component)327 static int d_probe_null_fw(struct snd_soc_component *component)
328 {
329 	struct kunit_soc_component *kunit_comp =
330 			container_of(component, struct kunit_soc_component, comp);
331 	int ret;
332 
333 	/* instead of passing fw pointer as third argument, pass NULL here */
334 	ret = snd_soc_tplg_component_load(component, NULL, NULL);
335 	KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
336 			    "Failed topology load");
337 
338 	return 0;
339 }
340 
341 static const struct snd_soc_component_driver test_component_null_fw = {
342 	.name = "sound-soc-topology-test",
343 	.probe = d_probe_null_fw,
344 };
345 
snd_soc_tplg_test_load_with_null_fw(struct kunit * test)346 static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test)
347 {
348 	struct kunit_soc_component *kunit_comp;
349 	int ret;
350 
351 	/* prepare */
352 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
353 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
354 	kunit_comp->kunit = test;
355 	kunit_comp->expect = -EINVAL; /* expect failure */
356 
357 	kunit_comp->card.dev = test_dev,
358 	kunit_comp->card.name = "kunit-card",
359 	kunit_comp->card.owner = THIS_MODULE,
360 	kunit_comp->card.dai_link = kunit_dai_links,
361 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
362 	kunit_comp->card.fully_routed = true,
363 
364 	/* run test */
365 	ret = snd_soc_register_card(&kunit_comp->card);
366 	if (ret != 0 && ret != -EPROBE_DEFER)
367 		KUNIT_FAIL(test, "Failed to register card");
368 
369 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_fw, test_dev);
370 	KUNIT_EXPECT_EQ(test, 0, ret);
371 
372 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
373 	KUNIT_EXPECT_EQ(test, 0, ret);
374 
375 	/* cleanup */
376 	snd_soc_unregister_card(&kunit_comp->card);
377 
378 	snd_soc_unregister_component(test_dev);
379 }
380 
381 // TEST CASE
382 // Test passing "empty" topology file
snd_soc_tplg_test_load_empty_tplg(struct kunit * test)383 static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test)
384 {
385 	struct kunit_soc_component *kunit_comp;
386 	struct tplg_tmpl_001 *data;
387 	int size;
388 	int ret;
389 
390 	/* prepare */
391 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
392 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
393 	kunit_comp->kunit = test;
394 	kunit_comp->expect = 0; /* expect success */
395 
396 	size = sizeof(tplg_tmpl_empty);
397 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
398 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
399 
400 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
401 
402 	kunit_comp->fw.data = (u8 *)data;
403 	kunit_comp->fw.size = size;
404 
405 	kunit_comp->card.dev = test_dev,
406 	kunit_comp->card.name = "kunit-card",
407 	kunit_comp->card.owner = THIS_MODULE,
408 	kunit_comp->card.dai_link = kunit_dai_links,
409 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
410 	kunit_comp->card.fully_routed = true,
411 
412 	/* run test */
413 	ret = snd_soc_register_card(&kunit_comp->card);
414 	if (ret != 0 && ret != -EPROBE_DEFER)
415 		KUNIT_FAIL(test, "Failed to register card");
416 
417 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
418 	KUNIT_EXPECT_EQ(test, 0, ret);
419 
420 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
421 	KUNIT_EXPECT_EQ(test, 0, ret);
422 
423 	/* cleanup */
424 	snd_soc_unregister_card(&kunit_comp->card);
425 
426 	snd_soc_unregister_component(test_dev);
427 }
428 
429 // TEST CASE
430 // Test "empty" topology file, but with bad "magic"
431 // In theory we could loop through all possible bad values, but it takes too
432 // long, so just use SND_SOC_TPLG_MAGIC + 1
snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit * test)433 static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test)
434 {
435 	struct kunit_soc_component *kunit_comp;
436 	struct tplg_tmpl_001 *data;
437 	int size;
438 	int ret;
439 
440 	/* prepare */
441 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
442 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
443 	kunit_comp->kunit = test;
444 	kunit_comp->expect = -EINVAL; /* expect failure */
445 
446 	size = sizeof(tplg_tmpl_empty);
447 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
448 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
449 
450 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
451 	/*
452 	 * override abi
453 	 * any value != magic number is wrong
454 	 */
455 	data->header.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC + 1);
456 
457 	kunit_comp->fw.data = (u8 *)data;
458 	kunit_comp->fw.size = size;
459 
460 	kunit_comp->card.dev = test_dev,
461 	kunit_comp->card.name = "kunit-card",
462 	kunit_comp->card.owner = THIS_MODULE,
463 	kunit_comp->card.dai_link = kunit_dai_links,
464 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
465 	kunit_comp->card.fully_routed = true,
466 
467 	/* run test */
468 	ret = snd_soc_register_card(&kunit_comp->card);
469 	if (ret != 0 && ret != -EPROBE_DEFER)
470 		KUNIT_FAIL(test, "Failed to register card");
471 
472 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
473 	KUNIT_EXPECT_EQ(test, 0, ret);
474 
475 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
476 	KUNIT_EXPECT_EQ(test, 0, ret);
477 
478 	/* cleanup */
479 	snd_soc_unregister_card(&kunit_comp->card);
480 
481 	snd_soc_unregister_component(test_dev);
482 }
483 
484 // TEST CASE
485 // Test "empty" topology file, but with bad "abi"
486 // In theory we could loop through all possible bad values, but it takes too
487 // long, so just use SND_SOC_TPLG_ABI_VERSION + 1
snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit * test)488 static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test)
489 {
490 	struct kunit_soc_component *kunit_comp;
491 	struct tplg_tmpl_001 *data;
492 	int size;
493 	int ret;
494 
495 	/* prepare */
496 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
497 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
498 	kunit_comp->kunit = test;
499 	kunit_comp->expect = -EINVAL; /* expect failure */
500 
501 	size = sizeof(tplg_tmpl_empty);
502 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
503 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
504 
505 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
506 	/*
507 	 * override abi
508 	 * any value != accepted range is wrong
509 	 */
510 	data->header.abi = cpu_to_le32(SND_SOC_TPLG_ABI_VERSION + 1);
511 
512 	kunit_comp->fw.data = (u8 *)data;
513 	kunit_comp->fw.size = size;
514 
515 	kunit_comp->card.dev = test_dev,
516 	kunit_comp->card.name = "kunit-card",
517 	kunit_comp->card.owner = THIS_MODULE,
518 	kunit_comp->card.dai_link = kunit_dai_links,
519 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
520 	kunit_comp->card.fully_routed = true,
521 
522 	/* run test */
523 	ret = snd_soc_register_card(&kunit_comp->card);
524 	if (ret != 0 && ret != -EPROBE_DEFER)
525 		KUNIT_FAIL(test, "Failed to register card");
526 
527 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
528 	KUNIT_EXPECT_EQ(test, 0, ret);
529 
530 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
531 	KUNIT_EXPECT_EQ(test, 0, ret);
532 
533 	/* cleanup */
534 	snd_soc_unregister_card(&kunit_comp->card);
535 
536 	snd_soc_unregister_component(test_dev);
537 }
538 
539 // TEST CASE
540 // Test "empty" topology file, but with bad "size"
541 // In theory we could loop through all possible bad values, but it takes too
542 // long, so just use sizeof(struct snd_soc_tplg_hdr) + 1
snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit * test)543 static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test)
544 {
545 	struct kunit_soc_component *kunit_comp;
546 	struct tplg_tmpl_001 *data;
547 	int size;
548 	int ret;
549 
550 	/* prepare */
551 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
552 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
553 	kunit_comp->kunit = test;
554 	kunit_comp->expect = -EINVAL; /* expect failure */
555 
556 	size = sizeof(tplg_tmpl_empty);
557 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
558 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
559 
560 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
561 	/*
562 	 * override size
563 	 * any value != struct size is wrong
564 	 */
565 	data->header.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr) + 1);
566 
567 	kunit_comp->fw.data = (u8 *)data;
568 	kunit_comp->fw.size = size;
569 
570 	kunit_comp->card.dev = test_dev,
571 	kunit_comp->card.name = "kunit-card",
572 	kunit_comp->card.owner = THIS_MODULE,
573 	kunit_comp->card.dai_link = kunit_dai_links,
574 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
575 	kunit_comp->card.fully_routed = true,
576 
577 	/* run test */
578 	ret = snd_soc_register_card(&kunit_comp->card);
579 	if (ret != 0 && ret != -EPROBE_DEFER)
580 		KUNIT_FAIL(test, "Failed to register card");
581 
582 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
583 	KUNIT_EXPECT_EQ(test, 0, ret);
584 
585 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
586 	KUNIT_EXPECT_EQ(test, 0, ret);
587 
588 	/* cleanup */
589 	snd_soc_unregister_card(&kunit_comp->card);
590 
591 	snd_soc_unregister_component(test_dev);
592 }
593 
594 // TEST CASE
595 // Test "empty" topology file, but with bad "payload_size"
596 // In theory we could loop through all possible bad values, but it takes too
597 // long, so just use the known wrong one
snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit * test)598 static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *test)
599 {
600 	struct kunit_soc_component *kunit_comp;
601 	struct tplg_tmpl_001 *data;
602 	int size;
603 	int ret;
604 
605 	/* prepare */
606 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
607 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
608 	kunit_comp->kunit = test;
609 	kunit_comp->expect = -EINVAL; /* expect failure */
610 
611 	size = sizeof(tplg_tmpl_empty);
612 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
613 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
614 
615 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
616 	/*
617 	 * override payload size
618 	 * there is only explicit check for 0, so check with it, other values
619 	 * are handled by just not reading behind EOF
620 	 */
621 	data->header.payload_size = 0;
622 
623 	kunit_comp->fw.data = (u8 *)data;
624 	kunit_comp->fw.size = size;
625 
626 	kunit_comp->card.dev = test_dev,
627 	kunit_comp->card.name = "kunit-card",
628 	kunit_comp->card.owner = THIS_MODULE,
629 	kunit_comp->card.dai_link = kunit_dai_links,
630 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
631 	kunit_comp->card.fully_routed = true,
632 
633 	/* run test */
634 	ret = snd_soc_register_card(&kunit_comp->card);
635 	if (ret != 0 && ret != -EPROBE_DEFER)
636 		KUNIT_FAIL(test, "Failed to register card");
637 
638 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
639 	KUNIT_EXPECT_EQ(test, 0, ret);
640 
641 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
642 	KUNIT_EXPECT_EQ(test, 0, ret);
643 
644 	/* cleanup */
645 	snd_soc_unregister_component(test_dev);
646 
647 	snd_soc_unregister_card(&kunit_comp->card);
648 }
649 
650 // TEST CASE
651 // Test passing topology file with PCM definition
snd_soc_tplg_test_load_pcm_tplg(struct kunit * test)652 static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test)
653 {
654 	struct kunit_soc_component *kunit_comp;
655 	u8 *data;
656 	int size;
657 	int ret;
658 
659 	/* prepare */
660 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
661 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
662 	kunit_comp->kunit = test;
663 	kunit_comp->expect = 0; /* expect success */
664 
665 	size = sizeof(tplg_tmpl_with_pcm);
666 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
667 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
668 
669 	memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
670 
671 	kunit_comp->fw.data = data;
672 	kunit_comp->fw.size = size;
673 
674 	kunit_comp->card.dev = test_dev,
675 	kunit_comp->card.name = "kunit-card",
676 	kunit_comp->card.owner = THIS_MODULE,
677 	kunit_comp->card.dai_link = kunit_dai_links,
678 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
679 	kunit_comp->card.fully_routed = true,
680 
681 	/* run test */
682 	ret = snd_soc_register_card(&kunit_comp->card);
683 	if (ret != 0 && ret != -EPROBE_DEFER)
684 		KUNIT_FAIL(test, "Failed to register card");
685 
686 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
687 	KUNIT_EXPECT_EQ(test, 0, ret);
688 
689 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
690 	KUNIT_EXPECT_EQ(test, 0, ret);
691 
692 	snd_soc_unregister_component(test_dev);
693 
694 	/* cleanup */
695 	snd_soc_unregister_card(&kunit_comp->card);
696 }
697 
698 // TEST CASE
699 // Test passing topology file with PCM definition
700 // with component reload
snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit * test)701 static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test)
702 {
703 	struct kunit_soc_component *kunit_comp;
704 	u8 *data;
705 	int size;
706 	int ret;
707 	int i;
708 
709 	/* prepare */
710 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
711 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
712 	kunit_comp->kunit = test;
713 	kunit_comp->expect = 0; /* expect success */
714 
715 	size = sizeof(tplg_tmpl_with_pcm);
716 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
717 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
718 
719 	memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
720 
721 	kunit_comp->fw.data = data;
722 	kunit_comp->fw.size = size;
723 
724 	kunit_comp->card.dev = test_dev,
725 	kunit_comp->card.name = "kunit-card",
726 	kunit_comp->card.owner = THIS_MODULE,
727 	kunit_comp->card.dai_link = kunit_dai_links,
728 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
729 	kunit_comp->card.fully_routed = true,
730 
731 	/* run test */
732 	ret = snd_soc_register_card(&kunit_comp->card);
733 	if (ret != 0 && ret != -EPROBE_DEFER)
734 		KUNIT_FAIL(test, "Failed to register card");
735 
736 	for (i = 0; i < 100; i++) {
737 		ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
738 		KUNIT_EXPECT_EQ(test, 0, ret);
739 
740 		ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
741 		KUNIT_EXPECT_EQ(test, 0, ret);
742 
743 		snd_soc_unregister_component(test_dev);
744 	}
745 
746 	/* cleanup */
747 	snd_soc_unregister_card(&kunit_comp->card);
748 }
749 
750 // TEST CASE
751 // Test passing topology file with PCM definition
752 // with card reload
snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit * test)753 static void snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit *test)
754 {
755 	struct kunit_soc_component *kunit_comp;
756 	u8 *data;
757 	int size;
758 	int ret;
759 	int i;
760 
761 	/* prepare */
762 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
763 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
764 	kunit_comp->kunit = test;
765 	kunit_comp->expect = 0; /* expect success */
766 
767 	size = sizeof(tplg_tmpl_with_pcm);
768 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
769 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
770 
771 	memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
772 
773 	kunit_comp->fw.data = data;
774 	kunit_comp->fw.size = size;
775 
776 	kunit_comp->card.dev = test_dev,
777 	kunit_comp->card.name = "kunit-card",
778 	kunit_comp->card.owner = THIS_MODULE,
779 	kunit_comp->card.dai_link = kunit_dai_links,
780 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
781 	kunit_comp->card.fully_routed = true,
782 
783 	/* run test */
784 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
785 	KUNIT_EXPECT_EQ(test, 0, ret);
786 
787 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
788 	KUNIT_EXPECT_EQ(test, 0, ret);
789 
790 	for (i = 0; i < 100; i++) {
791 		ret = snd_soc_register_card(&kunit_comp->card);
792 		if (ret != 0 && ret != -EPROBE_DEFER)
793 			KUNIT_FAIL(test, "Failed to register card");
794 
795 		snd_soc_unregister_card(&kunit_comp->card);
796 	}
797 
798 	/* cleanup */
799 	snd_soc_unregister_component(test_dev);
800 }
801 
802 /* ===== KUNIT MODULE DEFINITIONS =========================================== */
803 
804 static struct kunit_case snd_soc_tplg_test_cases[] = {
805 	KUNIT_CASE(snd_soc_tplg_test_load_with_null_comp),
806 	KUNIT_CASE(snd_soc_tplg_test_load_with_null_ops),
807 	KUNIT_CASE(snd_soc_tplg_test_load_with_null_fw),
808 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg),
809 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_magic),
810 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_abi),
811 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_size),
812 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_payload_size),
813 	KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg),
814 	KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_comp),
815 	KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_card),
816 	{}
817 };
818 
819 static struct kunit_suite snd_soc_tplg_test_suite = {
820 	.name = "snd_soc_tplg_test",
821 	.init = snd_soc_tplg_test_init,
822 	.exit = snd_soc_tplg_test_exit,
823 	.test_cases = snd_soc_tplg_test_cases,
824 };
825 
826 kunit_test_suites(&snd_soc_tplg_test_suite);
827 
828 MODULE_LICENSE("GPL");
829