ALSA: usb-audio: Validate MS endpoint descriptors
[linux-2.6-microblaze.git] / sound / soc / soc-topology-test.c
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");