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