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