Linux Audio

Check our new training course

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