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