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