xref: /openbmc/linux/sound/soc/soc-topology-test.c (revision fbb6b31a)
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 	ret = snd_soc_unregister_card(&kunit_comp->card);
275 	KUNIT_EXPECT_EQ(test, 0, ret);
276 
277 	snd_soc_unregister_component(test_dev);
278 }
279 
280 // TEST CASE
281 // Test passing NULL ops as parameter to snd_soc_tplg_component_load
282 
283 /*
284  * NULL ops is default case, we pass empty topology (fw), so we don't have
285  * anything to parse and just do nothing, which results in return 0; from
286  * calling soc_tplg_dapm_complete in soc_tplg_process_headers
287  */
288 static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test)
289 {
290 	struct kunit_soc_component *kunit_comp;
291 	int ret;
292 
293 	/* prepare */
294 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
295 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
296 	kunit_comp->kunit = test;
297 	kunit_comp->expect = 0; /* expect success */
298 
299 	kunit_comp->card.dev = test_dev,
300 	kunit_comp->card.name = "kunit-card",
301 	kunit_comp->card.owner = THIS_MODULE,
302 	kunit_comp->card.dai_link = kunit_dai_links,
303 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
304 	kunit_comp->card.fully_routed = true,
305 
306 	/* run test */
307 	ret = snd_soc_register_card(&kunit_comp->card);
308 	if (ret != 0 && ret != -EPROBE_DEFER)
309 		KUNIT_FAIL(test, "Failed to register card");
310 
311 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
312 	KUNIT_EXPECT_EQ(test, 0, ret);
313 
314 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
315 	KUNIT_EXPECT_EQ(test, 0, ret);
316 
317 	/* cleanup */
318 	ret = snd_soc_unregister_card(&kunit_comp->card);
319 	KUNIT_EXPECT_EQ(test, 0, ret);
320 
321 	snd_soc_unregister_component(test_dev);
322 }
323 
324 // TEST CASE
325 // Test passing NULL fw as parameter to snd_soc_tplg_component_load
326 
327 /*
328  * need to override generic probe function with one using NULL pointer to fw
329  * when calling topology load during component initialization, we don't need
330  * .remove handler as load should fail
331  */
332 static int d_probe_null_fw(struct snd_soc_component *component)
333 {
334 	struct kunit_soc_component *kunit_comp =
335 			container_of(component, struct kunit_soc_component, comp);
336 	int ret;
337 
338 	/* instead of passing fw pointer as third argument, pass NULL here */
339 	ret = snd_soc_tplg_component_load(component, NULL, NULL);
340 	KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
341 			    "Failed topology load");
342 
343 	return 0;
344 }
345 
346 static const struct snd_soc_component_driver test_component_null_fw = {
347 	.name = "sound-soc-topology-test",
348 	.probe = d_probe_null_fw,
349 	.non_legacy_dai_naming = 1,
350 };
351 
352 static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test)
353 {
354 	struct kunit_soc_component *kunit_comp;
355 	int ret;
356 
357 	/* prepare */
358 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
359 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
360 	kunit_comp->kunit = test;
361 	kunit_comp->expect = -EINVAL; /* expect failure */
362 
363 	kunit_comp->card.dev = test_dev,
364 	kunit_comp->card.name = "kunit-card",
365 	kunit_comp->card.owner = THIS_MODULE,
366 	kunit_comp->card.dai_link = kunit_dai_links,
367 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
368 	kunit_comp->card.fully_routed = true,
369 
370 	/* run test */
371 	ret = snd_soc_register_card(&kunit_comp->card);
372 	if (ret != 0 && ret != -EPROBE_DEFER)
373 		KUNIT_FAIL(test, "Failed to register card");
374 
375 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_fw, test_dev);
376 	KUNIT_EXPECT_EQ(test, 0, ret);
377 
378 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
379 	KUNIT_EXPECT_EQ(test, 0, ret);
380 
381 	/* cleanup */
382 	ret = snd_soc_unregister_card(&kunit_comp->card);
383 	KUNIT_EXPECT_EQ(test, 0, ret);
384 
385 	snd_soc_unregister_component(test_dev);
386 }
387 
388 // TEST CASE
389 // Test passing "empty" topology file
390 static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test)
391 {
392 	struct kunit_soc_component *kunit_comp;
393 	struct tplg_tmpl_001 *data;
394 	int size;
395 	int ret;
396 
397 	/* prepare */
398 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
399 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
400 	kunit_comp->kunit = test;
401 	kunit_comp->expect = 0; /* expect success */
402 
403 	size = sizeof(tplg_tmpl_empty);
404 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
405 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
406 
407 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
408 
409 	kunit_comp->fw.data = (u8 *)data;
410 	kunit_comp->fw.size = size;
411 
412 	kunit_comp->card.dev = test_dev,
413 	kunit_comp->card.name = "kunit-card",
414 	kunit_comp->card.owner = THIS_MODULE,
415 	kunit_comp->card.dai_link = kunit_dai_links,
416 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
417 	kunit_comp->card.fully_routed = true,
418 
419 	/* run test */
420 	ret = snd_soc_register_card(&kunit_comp->card);
421 	if (ret != 0 && ret != -EPROBE_DEFER)
422 		KUNIT_FAIL(test, "Failed to register card");
423 
424 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
425 	KUNIT_EXPECT_EQ(test, 0, ret);
426 
427 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
428 	KUNIT_EXPECT_EQ(test, 0, ret);
429 
430 	/* cleanup */
431 	ret = snd_soc_unregister_card(&kunit_comp->card);
432 	KUNIT_EXPECT_EQ(test, 0, ret);
433 
434 	snd_soc_unregister_component(test_dev);
435 }
436 
437 // TEST CASE
438 // Test "empty" topology file, but with bad "magic"
439 // In theory we could loop through all possible bad values, but it takes too
440 // long, so just use SND_SOC_TPLG_MAGIC + 1
441 static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test)
442 {
443 	struct kunit_soc_component *kunit_comp;
444 	struct tplg_tmpl_001 *data;
445 	int size;
446 	int ret;
447 
448 	/* prepare */
449 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
450 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
451 	kunit_comp->kunit = test;
452 	kunit_comp->expect = -EINVAL; /* expect failure */
453 
454 	size = sizeof(tplg_tmpl_empty);
455 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
456 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
457 
458 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
459 	/*
460 	 * override abi
461 	 * any value != magic number is wrong
462 	 */
463 	data->header.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC + 1);
464 
465 	kunit_comp->fw.data = (u8 *)data;
466 	kunit_comp->fw.size = size;
467 
468 	kunit_comp->card.dev = test_dev,
469 	kunit_comp->card.name = "kunit-card",
470 	kunit_comp->card.owner = THIS_MODULE,
471 	kunit_comp->card.dai_link = kunit_dai_links,
472 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
473 	kunit_comp->card.fully_routed = true,
474 
475 	/* run test */
476 	ret = snd_soc_register_card(&kunit_comp->card);
477 	if (ret != 0 && ret != -EPROBE_DEFER)
478 		KUNIT_FAIL(test, "Failed to register card");
479 
480 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
481 	KUNIT_EXPECT_EQ(test, 0, ret);
482 
483 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
484 	KUNIT_EXPECT_EQ(test, 0, ret);
485 
486 	/* cleanup */
487 	ret = snd_soc_unregister_card(&kunit_comp->card);
488 	KUNIT_EXPECT_EQ(test, 0, ret);
489 
490 	snd_soc_unregister_component(test_dev);
491 }
492 
493 // TEST CASE
494 // Test "empty" topology file, but with bad "abi"
495 // In theory we could loop through all possible bad values, but it takes too
496 // long, so just use SND_SOC_TPLG_ABI_VERSION + 1
497 static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test)
498 {
499 	struct kunit_soc_component *kunit_comp;
500 	struct tplg_tmpl_001 *data;
501 	int size;
502 	int ret;
503 
504 	/* prepare */
505 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
506 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
507 	kunit_comp->kunit = test;
508 	kunit_comp->expect = -EINVAL; /* expect failure */
509 
510 	size = sizeof(tplg_tmpl_empty);
511 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
512 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
513 
514 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
515 	/*
516 	 * override abi
517 	 * any value != accepted range is wrong
518 	 */
519 	data->header.abi = cpu_to_le32(SND_SOC_TPLG_ABI_VERSION + 1);
520 
521 	kunit_comp->fw.data = (u8 *)data;
522 	kunit_comp->fw.size = size;
523 
524 	kunit_comp->card.dev = test_dev,
525 	kunit_comp->card.name = "kunit-card",
526 	kunit_comp->card.owner = THIS_MODULE,
527 	kunit_comp->card.dai_link = kunit_dai_links,
528 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
529 	kunit_comp->card.fully_routed = true,
530 
531 	/* run test */
532 	ret = snd_soc_register_card(&kunit_comp->card);
533 	if (ret != 0 && ret != -EPROBE_DEFER)
534 		KUNIT_FAIL(test, "Failed to register card");
535 
536 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
537 	KUNIT_EXPECT_EQ(test, 0, ret);
538 
539 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
540 	KUNIT_EXPECT_EQ(test, 0, ret);
541 
542 	/* cleanup */
543 	ret = snd_soc_unregister_card(&kunit_comp->card);
544 	KUNIT_EXPECT_EQ(test, 0, ret);
545 
546 	snd_soc_unregister_component(test_dev);
547 }
548 
549 // TEST CASE
550 // Test "empty" topology file, but with bad "size"
551 // In theory we could loop through all possible bad values, but it takes too
552 // long, so just use sizeof(struct snd_soc_tplg_hdr) + 1
553 static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test)
554 {
555 	struct kunit_soc_component *kunit_comp;
556 	struct tplg_tmpl_001 *data;
557 	int size;
558 	int ret;
559 
560 	/* prepare */
561 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
562 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
563 	kunit_comp->kunit = test;
564 	kunit_comp->expect = -EINVAL; /* expect failure */
565 
566 	size = sizeof(tplg_tmpl_empty);
567 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
568 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
569 
570 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
571 	/*
572 	 * override size
573 	 * any value != struct size is wrong
574 	 */
575 	data->header.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr) + 1);
576 
577 	kunit_comp->fw.data = (u8 *)data;
578 	kunit_comp->fw.size = size;
579 
580 	kunit_comp->card.dev = test_dev,
581 	kunit_comp->card.name = "kunit-card",
582 	kunit_comp->card.owner = THIS_MODULE,
583 	kunit_comp->card.dai_link = kunit_dai_links,
584 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
585 	kunit_comp->card.fully_routed = true,
586 
587 	/* run test */
588 	ret = snd_soc_register_card(&kunit_comp->card);
589 	if (ret != 0 && ret != -EPROBE_DEFER)
590 		KUNIT_FAIL(test, "Failed to register card");
591 
592 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
593 	KUNIT_EXPECT_EQ(test, 0, ret);
594 
595 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
596 	KUNIT_EXPECT_EQ(test, 0, ret);
597 
598 	/* cleanup */
599 	ret = snd_soc_unregister_card(&kunit_comp->card);
600 	KUNIT_EXPECT_EQ(test, 0, ret);
601 
602 	snd_soc_unregister_component(test_dev);
603 }
604 
605 // TEST CASE
606 // Test "empty" topology file, but with bad "payload_size"
607 // In theory we could loop through all possible bad values, but it takes too
608 // long, so just use the known wrong one
609 static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *test)
610 {
611 	struct kunit_soc_component *kunit_comp;
612 	struct tplg_tmpl_001 *data;
613 	int size;
614 	int ret;
615 
616 	/* prepare */
617 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
618 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
619 	kunit_comp->kunit = test;
620 	kunit_comp->expect = -EINVAL; /* expect failure */
621 
622 	size = sizeof(tplg_tmpl_empty);
623 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
624 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
625 
626 	memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
627 	/*
628 	 * override payload size
629 	 * there is only explicit check for 0, so check with it, other values
630 	 * are handled by just not reading behind EOF
631 	 */
632 	data->header.payload_size = 0;
633 
634 	kunit_comp->fw.data = (u8 *)data;
635 	kunit_comp->fw.size = size;
636 
637 	kunit_comp->card.dev = test_dev,
638 	kunit_comp->card.name = "kunit-card",
639 	kunit_comp->card.owner = THIS_MODULE,
640 	kunit_comp->card.dai_link = kunit_dai_links,
641 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
642 	kunit_comp->card.fully_routed = true,
643 
644 	/* run test */
645 	ret = snd_soc_register_card(&kunit_comp->card);
646 	if (ret != 0 && ret != -EPROBE_DEFER)
647 		KUNIT_FAIL(test, "Failed to register card");
648 
649 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
650 	KUNIT_EXPECT_EQ(test, 0, ret);
651 
652 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
653 	KUNIT_EXPECT_EQ(test, 0, ret);
654 
655 	/* cleanup */
656 	snd_soc_unregister_component(test_dev);
657 
658 	ret = snd_soc_unregister_card(&kunit_comp->card);
659 	KUNIT_EXPECT_EQ(test, 0, ret);
660 }
661 
662 // TEST CASE
663 // Test passing topology file with PCM definition
664 static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test)
665 {
666 	struct kunit_soc_component *kunit_comp;
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 	/* run test */
694 	ret = snd_soc_register_card(&kunit_comp->card);
695 	if (ret != 0 && ret != -EPROBE_DEFER)
696 		KUNIT_FAIL(test, "Failed to register card");
697 
698 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
699 	KUNIT_EXPECT_EQ(test, 0, ret);
700 
701 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
702 	KUNIT_EXPECT_EQ(test, 0, ret);
703 
704 	snd_soc_unregister_component(test_dev);
705 
706 	/* cleanup */
707 	ret = snd_soc_unregister_card(&kunit_comp->card);
708 	KUNIT_EXPECT_EQ(test, 0, ret);
709 }
710 
711 // TEST CASE
712 // Test passing topology file with PCM definition
713 // with component reload
714 static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test)
715 {
716 	struct kunit_soc_component *kunit_comp;
717 	u8 *data;
718 	int size;
719 	int ret;
720 	int i;
721 
722 	/* prepare */
723 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
724 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
725 	kunit_comp->kunit = test;
726 	kunit_comp->expect = 0; /* expect success */
727 
728 	size = sizeof(tplg_tmpl_with_pcm);
729 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
730 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
731 
732 	memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
733 
734 	kunit_comp->fw.data = data;
735 	kunit_comp->fw.size = size;
736 
737 	kunit_comp->card.dev = test_dev,
738 	kunit_comp->card.name = "kunit-card",
739 	kunit_comp->card.owner = THIS_MODULE,
740 	kunit_comp->card.dai_link = kunit_dai_links,
741 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
742 	kunit_comp->card.fully_routed = true,
743 
744 	/* run test */
745 	ret = snd_soc_register_card(&kunit_comp->card);
746 	if (ret != 0 && ret != -EPROBE_DEFER)
747 		KUNIT_FAIL(test, "Failed to register card");
748 
749 	for (i = 0; i < 100; i++) {
750 		ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
751 		KUNIT_EXPECT_EQ(test, 0, ret);
752 
753 		ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
754 		KUNIT_EXPECT_EQ(test, 0, ret);
755 
756 		snd_soc_unregister_component(test_dev);
757 	}
758 
759 	/* cleanup */
760 	ret = snd_soc_unregister_card(&kunit_comp->card);
761 	KUNIT_EXPECT_EQ(test, 0, ret);
762 }
763 
764 // TEST CASE
765 // Test passing topology file with PCM definition
766 // with card reload
767 static void snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit *test)
768 {
769 	struct kunit_soc_component *kunit_comp;
770 	u8 *data;
771 	int size;
772 	int ret;
773 	int i;
774 
775 	/* prepare */
776 	kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
777 	KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
778 	kunit_comp->kunit = test;
779 	kunit_comp->expect = 0; /* expect success */
780 
781 	size = sizeof(tplg_tmpl_with_pcm);
782 	data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
783 	KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
784 
785 	memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
786 
787 	kunit_comp->fw.data = data;
788 	kunit_comp->fw.size = size;
789 
790 	kunit_comp->card.dev = test_dev,
791 	kunit_comp->card.name = "kunit-card",
792 	kunit_comp->card.owner = THIS_MODULE,
793 	kunit_comp->card.dai_link = kunit_dai_links,
794 	kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
795 	kunit_comp->card.fully_routed = true,
796 
797 	/* run test */
798 	ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
799 	KUNIT_EXPECT_EQ(test, 0, ret);
800 
801 	ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
802 	KUNIT_EXPECT_EQ(test, 0, ret);
803 
804 	for (i = 0; i < 100; i++) {
805 		ret = snd_soc_register_card(&kunit_comp->card);
806 		if (ret != 0 && ret != -EPROBE_DEFER)
807 			KUNIT_FAIL(test, "Failed to register card");
808 
809 		ret = snd_soc_unregister_card(&kunit_comp->card);
810 		KUNIT_EXPECT_EQ(test, 0, ret);
811 	}
812 
813 	/* cleanup */
814 	snd_soc_unregister_component(test_dev);
815 }
816 
817 /* ===== KUNIT MODULE DEFINITIONS =========================================== */
818 
819 static struct kunit_case snd_soc_tplg_test_cases[] = {
820 	KUNIT_CASE(snd_soc_tplg_test_load_with_null_comp),
821 	KUNIT_CASE(snd_soc_tplg_test_load_with_null_ops),
822 	KUNIT_CASE(snd_soc_tplg_test_load_with_null_fw),
823 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg),
824 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_magic),
825 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_abi),
826 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_size),
827 	KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_payload_size),
828 	KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg),
829 	KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_comp),
830 	KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_card),
831 	{}
832 };
833 
834 static struct kunit_suite snd_soc_tplg_test_suite = {
835 	.name = "snd_soc_tplg_test",
836 	.init = snd_soc_tplg_test_init,
837 	.exit = snd_soc_tplg_test_exit,
838 	.test_cases = snd_soc_tplg_test_cases,
839 };
840 
841 kunit_test_suites(&snd_soc_tplg_test_suite);
842 
843 MODULE_LICENSE("GPL");
844