linux/sound/soc/soc-topology-test.c

// 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();