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
snd_soc_tplg_test_init(struct kunit * test)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
snd_soc_tplg_test_exit(struct kunit * test)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
d_probe(struct snd_soc_component * component)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
d_remove(struct snd_soc_component * component)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 */
d_probe_null_comp(struct snd_soc_component * component)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
snd_soc_tplg_test_load_with_null_comp(struct kunit * test)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 */
snd_soc_tplg_test_load_with_null_ops(struct kunit * test)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 */
d_probe_null_fw(struct snd_soc_component * component)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
snd_soc_tplg_test_load_with_null_fw(struct kunit * test)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
snd_soc_tplg_test_load_empty_tplg(struct kunit * test)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
snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit * test)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
snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit * test)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
snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit * test)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
snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit * test)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
snd_soc_tplg_test_load_pcm_tplg(struct kunit * test)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
snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit * test)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
snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit * test)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