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