// SPDX-License-Identifier: GPL-2.0-only /* * soc-topology-test.c -- ALSA SoC Topology Kernel Unit Tests * * Copyright(c) 2021 Intel Corporation. */ #include <linux/firmware.h> #include <sound/core.h> #include <sound/soc.h> #include <sound/soc-topology.h> #include <kunit/device.h> #include <kunit/test.h> /* ===== HELPER FUNCTIONS =================================================== */ /* * snd_soc_component needs device to operate on (primarily for prints), create * fake one, as we don't register with PCI or anything else * device_driver name is used in some of the prints (fmt_single_name) so * we also mock up minimal one */ static struct device *test_dev; static int snd_soc_tplg_test_init(struct kunit *test) { … } static void snd_soc_tplg_test_exit(struct kunit *test) { … } /* * helper struct we use when registering component, as we load topology during * component probe, we need to pass struct kunit somehow to probe function, so * we can report test result */ struct kunit_soc_component { … }; static int d_probe(struct snd_soc_component *component) { … } static void d_remove(struct snd_soc_component *component) { … } /* * ASoC minimal boiler plate */ SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("sound-soc-topology-test"))); static struct snd_soc_dai_link kunit_dai_links[] = …; static const struct snd_soc_component_driver test_component = …; /* ===== TOPOLOGY TEMPLATES ================================================= */ // Structural representation of topology which can be generated with: // $ touch empty // $ alsatplg -c empty -o empty.tplg // $ xxd -i empty.tplg struct tplg_tmpl_001 { … } __packed; static struct tplg_tmpl_001 tplg_tmpl_empty = …; // Structural representation of topology containing SectionPCM struct tplg_tmpl_002 { … } __packed; static struct tplg_tmpl_002 tplg_tmpl_with_pcm = …; /* ===== TEST CASES ========================================================= */ // TEST CASE // Test passing NULL component as parameter to snd_soc_tplg_component_load /* * need to override generic probe function with one using NULL when calling * topology load during component initialization, we don't need .remove * handler as load should fail */ static int d_probe_null_comp(struct snd_soc_component *component) { … } static const struct snd_soc_component_driver test_component_null_comp = …; static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test) { … } // TEST CASE // Test passing NULL ops as parameter to snd_soc_tplg_component_load /* * NULL ops is default case, we pass empty topology (fw), so we don't have * anything to parse and just do nothing, which results in return 0; from * calling soc_tplg_dapm_complete in soc_tplg_process_headers */ static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test) { … } // TEST CASE // Test passing NULL fw as parameter to snd_soc_tplg_component_load /* * need to override generic probe function with one using NULL pointer to fw * when calling topology load during component initialization, we don't need * .remove handler as load should fail */ static int d_probe_null_fw(struct snd_soc_component *component) { … } static const struct snd_soc_component_driver test_component_null_fw = …; static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test) { … } // TEST CASE // Test passing "empty" topology file static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test) { … } // TEST CASE // Test "empty" topology file, but with bad "magic" // In theory we could loop through all possible bad values, but it takes too // long, so just use SND_SOC_TPLG_MAGIC + 1 static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test) { … } // TEST CASE // Test "empty" topology file, but with bad "abi" // In theory we could loop through all possible bad values, but it takes too // long, so just use SND_SOC_TPLG_ABI_VERSION + 1 static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test) { … } // TEST CASE // Test "empty" topology file, but with bad "size" // In theory we could loop through all possible bad values, but it takes too // long, so just use sizeof(struct snd_soc_tplg_hdr) + 1 static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test) { … } // TEST CASE // Test "empty" topology file, but with bad "payload_size" // In theory we could loop through all possible bad values, but it takes too // long, so just use the known wrong one static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *test) { … } // TEST CASE // Test passing topology file with PCM definition static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test) { … } // TEST CASE // Test passing topology file with PCM definition // with component reload static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test) { … } // TEST CASE // Test passing topology file with PCM definition // with card reload static void snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit *test) { … } /* ===== KUNIT MODULE DEFINITIONS =========================================== */ static struct kunit_case snd_soc_tplg_test_cases[] = …; static struct kunit_suite snd_soc_tplg_test_suite = …; kunit_test_suites(…); MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;