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