Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * soc-topology-test.c  --  ALSA SoC Topology Kernel Unit Tests
0004  *
0005  * Copyright(c) 2021 Intel Corporation. All rights reserved.
0006  */
0007 
0008 #include <linux/firmware.h>
0009 #include <sound/core.h>
0010 #include <sound/soc.h>
0011 #include <sound/soc-topology.h>
0012 #include <kunit/test.h>
0013 
0014 /* ===== HELPER FUNCTIONS =================================================== */
0015 
0016 /*
0017  * snd_soc_component needs device to operate on (primarily for prints), create
0018  * fake one, as we don't register with PCI or anything else
0019  * device_driver name is used in some of the prints (fmt_single_name) so
0020  * we also mock up minimal one
0021  */
0022 static struct device *test_dev;
0023 
0024 static struct device_driver test_drv = {
0025     .name = "sound-soc-topology-test-driver",
0026 };
0027 
0028 static int snd_soc_tplg_test_init(struct kunit *test)
0029 {
0030     test_dev = root_device_register("sound-soc-topology-test");
0031     test_dev = get_device(test_dev);
0032     if (!test_dev)
0033         return -ENODEV;
0034 
0035     test_dev->driver = &test_drv;
0036 
0037     return 0;
0038 }
0039 
0040 static void snd_soc_tplg_test_exit(struct kunit *test)
0041 {
0042     put_device(test_dev);
0043     root_device_unregister(test_dev);
0044 }
0045 
0046 /*
0047  * helper struct we use when registering component, as we load topology during
0048  * component probe, we need to pass struct kunit somehow to probe function, so
0049  * we can report test result
0050  */
0051 struct kunit_soc_component {
0052     struct kunit *kunit;
0053     int expect; /* what result we expect when loading topology */
0054     struct snd_soc_component comp;
0055     struct snd_soc_card card;
0056     struct firmware fw;
0057 };
0058 
0059 static int d_probe(struct snd_soc_component *component)
0060 {
0061     struct kunit_soc_component *kunit_comp =
0062             container_of(component, struct kunit_soc_component, comp);
0063     int ret;
0064 
0065     ret = snd_soc_tplg_component_load(component, NULL, &kunit_comp->fw);
0066     KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
0067                 "Failed topology load");
0068 
0069     return 0;
0070 }
0071 
0072 static void d_remove(struct snd_soc_component *component)
0073 {
0074     struct kunit_soc_component *kunit_comp =
0075             container_of(component, struct kunit_soc_component, comp);
0076     int ret;
0077 
0078     ret = snd_soc_tplg_component_remove(component);
0079     KUNIT_EXPECT_EQ(kunit_comp->kunit, 0, ret);
0080 }
0081 
0082 /*
0083  * ASoC minimal boiler plate
0084  */
0085 SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY()));
0086 
0087 SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("sound-soc-topology-test")));
0088 
0089 static struct snd_soc_dai_link kunit_dai_links[] = {
0090     {
0091         .name = "KUNIT Audio Port",
0092         .id = 0,
0093         .stream_name = "Audio Playback/Capture",
0094         .nonatomic = 1,
0095         .dynamic = 1,
0096         .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
0097         .dpcm_playback = 1,
0098         .dpcm_capture = 1,
0099         SND_SOC_DAILINK_REG(dummy, dummy, platform),
0100     },
0101 };
0102 
0103 static const struct snd_soc_component_driver test_component = {
0104     .name = "sound-soc-topology-test",
0105     .probe = d_probe,
0106     .remove = d_remove,
0107 };
0108 
0109 /* ===== TOPOLOGY TEMPLATES ================================================= */
0110 
0111 // Structural representation of topology which can be generated with:
0112 // $ touch empty
0113 // $ alsatplg -c empty -o empty.tplg
0114 // $ xxd -i empty.tplg
0115 
0116 struct tplg_tmpl_001 {
0117     struct snd_soc_tplg_hdr header;
0118     struct snd_soc_tplg_manifest manifest;
0119 } __packed;
0120 
0121 static struct tplg_tmpl_001 tplg_tmpl_empty = {
0122     .header = {
0123         .magic = cpu_to_le32(SND_SOC_TPLG_MAGIC),
0124         .abi = cpu_to_le32(5),
0125         .version = 0,
0126         .type = cpu_to_le32(SND_SOC_TPLG_TYPE_MANIFEST),
0127         .size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)),
0128         .vendor_type = 0,
0129         .payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
0130         .index = 0,
0131         .count = cpu_to_le32(1),
0132     },
0133 
0134     .manifest = {
0135         .size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
0136         /* rest of fields is 0 */
0137     },
0138 };
0139 
0140 // Structural representation of topology containing SectionPCM
0141 
0142 struct tplg_tmpl_002 {
0143     struct snd_soc_tplg_hdr header;
0144     struct snd_soc_tplg_manifest manifest;
0145     struct snd_soc_tplg_hdr pcm_header;
0146     struct snd_soc_tplg_pcm pcm;
0147 } __packed;
0148 
0149 static struct tplg_tmpl_002 tplg_tmpl_with_pcm = {
0150     .header = {
0151         .magic = cpu_to_le32(SND_SOC_TPLG_MAGIC),
0152         .abi = cpu_to_le32(5),
0153         .version = 0,
0154         .type = cpu_to_le32(SND_SOC_TPLG_TYPE_MANIFEST),
0155         .size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)),
0156         .vendor_type = 0,
0157         .payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
0158         .index = 0,
0159         .count = cpu_to_le32(1),
0160     },
0161     .manifest = {
0162         .size = cpu_to_le32(sizeof(struct snd_soc_tplg_manifest)),
0163         .pcm_elems = cpu_to_le32(1),
0164         /* rest of fields is 0 */
0165     },
0166     .pcm_header = {
0167         .magic = cpu_to_le32(SND_SOC_TPLG_MAGIC),
0168         .abi = cpu_to_le32(5),
0169         .version = 0,
0170         .type = cpu_to_le32(SND_SOC_TPLG_TYPE_PCM),
0171         .size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr)),
0172         .vendor_type = 0,
0173         .payload_size = cpu_to_le32(sizeof(struct snd_soc_tplg_pcm)),
0174         .index = 0,
0175         .count = cpu_to_le32(1),
0176     },
0177     .pcm = {
0178         .size = cpu_to_le32(sizeof(struct snd_soc_tplg_pcm)),
0179         .pcm_name = "KUNIT Audio",
0180         .dai_name = "kunit-audio-dai",
0181         .pcm_id = 0,
0182         .dai_id = 0,
0183         .playback = cpu_to_le32(1),
0184         .capture = cpu_to_le32(1),
0185         .compress = 0,
0186         .stream = {
0187             [0] = {
0188                 .channels = cpu_to_le32(2),
0189             },
0190             [1] = {
0191                 .channels = cpu_to_le32(2),
0192             },
0193         },
0194         .num_streams = 0,
0195         .caps = {
0196             [0] = {
0197                 .name = "kunit-audio-playback",
0198                 .channels_min = cpu_to_le32(2),
0199                 .channels_max = cpu_to_le32(2),
0200             },
0201             [1] = {
0202                 .name = "kunit-audio-capture",
0203                 .channels_min = cpu_to_le32(2),
0204                 .channels_max = cpu_to_le32(2),
0205             },
0206         },
0207         .flag_mask = 0,
0208         .flags = 0,
0209         .priv = { 0 },
0210     },
0211 };
0212 
0213 /* ===== TEST CASES ========================================================= */
0214 
0215 // TEST CASE
0216 // Test passing NULL component as parameter to snd_soc_tplg_component_load
0217 
0218 /*
0219  * need to override generic probe function with one using NULL when calling
0220  * topology load during component initialization, we don't need .remove
0221  * handler as load should fail
0222  */
0223 static int d_probe_null_comp(struct snd_soc_component *component)
0224 {
0225     struct kunit_soc_component *kunit_comp =
0226             container_of(component, struct kunit_soc_component, comp);
0227     int ret;
0228 
0229     /* instead of passing component pointer as first argument, pass NULL here */
0230     ret = snd_soc_tplg_component_load(NULL, NULL, &kunit_comp->fw);
0231     KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
0232                 "Failed topology load");
0233 
0234     return 0;
0235 }
0236 
0237 static const struct snd_soc_component_driver test_component_null_comp = {
0238     .name = "sound-soc-topology-test",
0239     .probe = d_probe_null_comp,
0240 };
0241 
0242 static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test)
0243 {
0244     struct kunit_soc_component *kunit_comp;
0245     int ret;
0246 
0247     /* prepare */
0248     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0249     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0250     kunit_comp->kunit = test;
0251     kunit_comp->expect = -EINVAL; /* expect failure */
0252 
0253     kunit_comp->card.dev = test_dev,
0254     kunit_comp->card.name = "kunit-card",
0255     kunit_comp->card.owner = THIS_MODULE,
0256     kunit_comp->card.dai_link = kunit_dai_links,
0257     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0258     kunit_comp->card.fully_routed = true,
0259 
0260     /* run test */
0261     ret = snd_soc_register_card(&kunit_comp->card);
0262     if (ret != 0 && ret != -EPROBE_DEFER)
0263         KUNIT_FAIL(test, "Failed to register card");
0264 
0265     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_comp, test_dev);
0266     KUNIT_EXPECT_EQ(test, 0, ret);
0267 
0268     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0269     KUNIT_EXPECT_EQ(test, 0, ret);
0270 
0271     /* cleanup */
0272     snd_soc_unregister_card(&kunit_comp->card);
0273     snd_soc_unregister_component(test_dev);
0274 }
0275 
0276 // TEST CASE
0277 // Test passing NULL ops as parameter to snd_soc_tplg_component_load
0278 
0279 /*
0280  * NULL ops is default case, we pass empty topology (fw), so we don't have
0281  * anything to parse and just do nothing, which results in return 0; from
0282  * calling soc_tplg_dapm_complete in soc_tplg_process_headers
0283  */
0284 static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test)
0285 {
0286     struct kunit_soc_component *kunit_comp;
0287     int ret;
0288 
0289     /* prepare */
0290     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0291     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0292     kunit_comp->kunit = test;
0293     kunit_comp->expect = 0; /* expect success */
0294 
0295     kunit_comp->card.dev = test_dev,
0296     kunit_comp->card.name = "kunit-card",
0297     kunit_comp->card.owner = THIS_MODULE,
0298     kunit_comp->card.dai_link = kunit_dai_links,
0299     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0300     kunit_comp->card.fully_routed = true,
0301 
0302     /* run test */
0303     ret = snd_soc_register_card(&kunit_comp->card);
0304     if (ret != 0 && ret != -EPROBE_DEFER)
0305         KUNIT_FAIL(test, "Failed to register card");
0306 
0307     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
0308     KUNIT_EXPECT_EQ(test, 0, ret);
0309 
0310     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0311     KUNIT_EXPECT_EQ(test, 0, ret);
0312 
0313     /* cleanup */
0314     snd_soc_unregister_card(&kunit_comp->card);
0315 
0316     snd_soc_unregister_component(test_dev);
0317 }
0318 
0319 // TEST CASE
0320 // Test passing NULL fw as parameter to snd_soc_tplg_component_load
0321 
0322 /*
0323  * need to override generic probe function with one using NULL pointer to fw
0324  * when calling topology load during component initialization, we don't need
0325  * .remove handler as load should fail
0326  */
0327 static int d_probe_null_fw(struct snd_soc_component *component)
0328 {
0329     struct kunit_soc_component *kunit_comp =
0330             container_of(component, struct kunit_soc_component, comp);
0331     int ret;
0332 
0333     /* instead of passing fw pointer as third argument, pass NULL here */
0334     ret = snd_soc_tplg_component_load(component, NULL, NULL);
0335     KUNIT_EXPECT_EQ_MSG(kunit_comp->kunit, kunit_comp->expect, ret,
0336                 "Failed topology load");
0337 
0338     return 0;
0339 }
0340 
0341 static const struct snd_soc_component_driver test_component_null_fw = {
0342     .name = "sound-soc-topology-test",
0343     .probe = d_probe_null_fw,
0344 };
0345 
0346 static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test)
0347 {
0348     struct kunit_soc_component *kunit_comp;
0349     int ret;
0350 
0351     /* prepare */
0352     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0353     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0354     kunit_comp->kunit = test;
0355     kunit_comp->expect = -EINVAL; /* expect failure */
0356 
0357     kunit_comp->card.dev = test_dev,
0358     kunit_comp->card.name = "kunit-card",
0359     kunit_comp->card.owner = THIS_MODULE,
0360     kunit_comp->card.dai_link = kunit_dai_links,
0361     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0362     kunit_comp->card.fully_routed = true,
0363 
0364     /* run test */
0365     ret = snd_soc_register_card(&kunit_comp->card);
0366     if (ret != 0 && ret != -EPROBE_DEFER)
0367         KUNIT_FAIL(test, "Failed to register card");
0368 
0369     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component_null_fw, test_dev);
0370     KUNIT_EXPECT_EQ(test, 0, ret);
0371 
0372     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0373     KUNIT_EXPECT_EQ(test, 0, ret);
0374 
0375     /* cleanup */
0376     snd_soc_unregister_card(&kunit_comp->card);
0377 
0378     snd_soc_unregister_component(test_dev);
0379 }
0380 
0381 // TEST CASE
0382 // Test passing "empty" topology file
0383 static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test)
0384 {
0385     struct kunit_soc_component *kunit_comp;
0386     struct tplg_tmpl_001 *data;
0387     int size;
0388     int ret;
0389 
0390     /* prepare */
0391     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0392     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0393     kunit_comp->kunit = test;
0394     kunit_comp->expect = 0; /* expect success */
0395 
0396     size = sizeof(tplg_tmpl_empty);
0397     data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
0398     KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
0399 
0400     memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
0401 
0402     kunit_comp->fw.data = (u8 *)data;
0403     kunit_comp->fw.size = size;
0404 
0405     kunit_comp->card.dev = test_dev,
0406     kunit_comp->card.name = "kunit-card",
0407     kunit_comp->card.owner = THIS_MODULE,
0408     kunit_comp->card.dai_link = kunit_dai_links,
0409     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0410     kunit_comp->card.fully_routed = true,
0411 
0412     /* run test */
0413     ret = snd_soc_register_card(&kunit_comp->card);
0414     if (ret != 0 && ret != -EPROBE_DEFER)
0415         KUNIT_FAIL(test, "Failed to register card");
0416 
0417     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
0418     KUNIT_EXPECT_EQ(test, 0, ret);
0419 
0420     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0421     KUNIT_EXPECT_EQ(test, 0, ret);
0422 
0423     /* cleanup */
0424     snd_soc_unregister_card(&kunit_comp->card);
0425 
0426     snd_soc_unregister_component(test_dev);
0427 }
0428 
0429 // TEST CASE
0430 // Test "empty" topology file, but with bad "magic"
0431 // In theory we could loop through all possible bad values, but it takes too
0432 // long, so just use SND_SOC_TPLG_MAGIC + 1
0433 static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test)
0434 {
0435     struct kunit_soc_component *kunit_comp;
0436     struct tplg_tmpl_001 *data;
0437     int size;
0438     int ret;
0439 
0440     /* prepare */
0441     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0442     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0443     kunit_comp->kunit = test;
0444     kunit_comp->expect = -EINVAL; /* expect failure */
0445 
0446     size = sizeof(tplg_tmpl_empty);
0447     data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
0448     KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
0449 
0450     memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
0451     /*
0452      * override abi
0453      * any value != magic number is wrong
0454      */
0455     data->header.magic = cpu_to_le32(SND_SOC_TPLG_MAGIC + 1);
0456 
0457     kunit_comp->fw.data = (u8 *)data;
0458     kunit_comp->fw.size = size;
0459 
0460     kunit_comp->card.dev = test_dev,
0461     kunit_comp->card.name = "kunit-card",
0462     kunit_comp->card.owner = THIS_MODULE,
0463     kunit_comp->card.dai_link = kunit_dai_links,
0464     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0465     kunit_comp->card.fully_routed = true,
0466 
0467     /* run test */
0468     ret = snd_soc_register_card(&kunit_comp->card);
0469     if (ret != 0 && ret != -EPROBE_DEFER)
0470         KUNIT_FAIL(test, "Failed to register card");
0471 
0472     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
0473     KUNIT_EXPECT_EQ(test, 0, ret);
0474 
0475     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0476     KUNIT_EXPECT_EQ(test, 0, ret);
0477 
0478     /* cleanup */
0479     snd_soc_unregister_card(&kunit_comp->card);
0480 
0481     snd_soc_unregister_component(test_dev);
0482 }
0483 
0484 // TEST CASE
0485 // Test "empty" topology file, but with bad "abi"
0486 // In theory we could loop through all possible bad values, but it takes too
0487 // long, so just use SND_SOC_TPLG_ABI_VERSION + 1
0488 static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test)
0489 {
0490     struct kunit_soc_component *kunit_comp;
0491     struct tplg_tmpl_001 *data;
0492     int size;
0493     int ret;
0494 
0495     /* prepare */
0496     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0497     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0498     kunit_comp->kunit = test;
0499     kunit_comp->expect = -EINVAL; /* expect failure */
0500 
0501     size = sizeof(tplg_tmpl_empty);
0502     data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
0503     KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
0504 
0505     memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
0506     /*
0507      * override abi
0508      * any value != accepted range is wrong
0509      */
0510     data->header.abi = cpu_to_le32(SND_SOC_TPLG_ABI_VERSION + 1);
0511 
0512     kunit_comp->fw.data = (u8 *)data;
0513     kunit_comp->fw.size = size;
0514 
0515     kunit_comp->card.dev = test_dev,
0516     kunit_comp->card.name = "kunit-card",
0517     kunit_comp->card.owner = THIS_MODULE,
0518     kunit_comp->card.dai_link = kunit_dai_links,
0519     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0520     kunit_comp->card.fully_routed = true,
0521 
0522     /* run test */
0523     ret = snd_soc_register_card(&kunit_comp->card);
0524     if (ret != 0 && ret != -EPROBE_DEFER)
0525         KUNIT_FAIL(test, "Failed to register card");
0526 
0527     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
0528     KUNIT_EXPECT_EQ(test, 0, ret);
0529 
0530     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0531     KUNIT_EXPECT_EQ(test, 0, ret);
0532 
0533     /* cleanup */
0534     snd_soc_unregister_card(&kunit_comp->card);
0535 
0536     snd_soc_unregister_component(test_dev);
0537 }
0538 
0539 // TEST CASE
0540 // Test "empty" topology file, but with bad "size"
0541 // In theory we could loop through all possible bad values, but it takes too
0542 // long, so just use sizeof(struct snd_soc_tplg_hdr) + 1
0543 static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test)
0544 {
0545     struct kunit_soc_component *kunit_comp;
0546     struct tplg_tmpl_001 *data;
0547     int size;
0548     int ret;
0549 
0550     /* prepare */
0551     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0552     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0553     kunit_comp->kunit = test;
0554     kunit_comp->expect = -EINVAL; /* expect failure */
0555 
0556     size = sizeof(tplg_tmpl_empty);
0557     data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
0558     KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
0559 
0560     memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
0561     /*
0562      * override size
0563      * any value != struct size is wrong
0564      */
0565     data->header.size = cpu_to_le32(sizeof(struct snd_soc_tplg_hdr) + 1);
0566 
0567     kunit_comp->fw.data = (u8 *)data;
0568     kunit_comp->fw.size = size;
0569 
0570     kunit_comp->card.dev = test_dev,
0571     kunit_comp->card.name = "kunit-card",
0572     kunit_comp->card.owner = THIS_MODULE,
0573     kunit_comp->card.dai_link = kunit_dai_links,
0574     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0575     kunit_comp->card.fully_routed = true,
0576 
0577     /* run test */
0578     ret = snd_soc_register_card(&kunit_comp->card);
0579     if (ret != 0 && ret != -EPROBE_DEFER)
0580         KUNIT_FAIL(test, "Failed to register card");
0581 
0582     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
0583     KUNIT_EXPECT_EQ(test, 0, ret);
0584 
0585     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0586     KUNIT_EXPECT_EQ(test, 0, ret);
0587 
0588     /* cleanup */
0589     snd_soc_unregister_card(&kunit_comp->card);
0590 
0591     snd_soc_unregister_component(test_dev);
0592 }
0593 
0594 // TEST CASE
0595 // Test "empty" topology file, but with bad "payload_size"
0596 // In theory we could loop through all possible bad values, but it takes too
0597 // long, so just use the known wrong one
0598 static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *test)
0599 {
0600     struct kunit_soc_component *kunit_comp;
0601     struct tplg_tmpl_001 *data;
0602     int size;
0603     int ret;
0604 
0605     /* prepare */
0606     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0607     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0608     kunit_comp->kunit = test;
0609     kunit_comp->expect = -EINVAL; /* expect failure */
0610 
0611     size = sizeof(tplg_tmpl_empty);
0612     data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
0613     KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
0614 
0615     memcpy(data, &tplg_tmpl_empty, sizeof(tplg_tmpl_empty));
0616     /*
0617      * override payload size
0618      * there is only explicit check for 0, so check with it, other values
0619      * are handled by just not reading behind EOF
0620      */
0621     data->header.payload_size = 0;
0622 
0623     kunit_comp->fw.data = (u8 *)data;
0624     kunit_comp->fw.size = size;
0625 
0626     kunit_comp->card.dev = test_dev,
0627     kunit_comp->card.name = "kunit-card",
0628     kunit_comp->card.owner = THIS_MODULE,
0629     kunit_comp->card.dai_link = kunit_dai_links,
0630     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0631     kunit_comp->card.fully_routed = true,
0632 
0633     /* run test */
0634     ret = snd_soc_register_card(&kunit_comp->card);
0635     if (ret != 0 && ret != -EPROBE_DEFER)
0636         KUNIT_FAIL(test, "Failed to register card");
0637 
0638     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
0639     KUNIT_EXPECT_EQ(test, 0, ret);
0640 
0641     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0642     KUNIT_EXPECT_EQ(test, 0, ret);
0643 
0644     /* cleanup */
0645     snd_soc_unregister_component(test_dev);
0646 
0647     snd_soc_unregister_card(&kunit_comp->card);
0648 }
0649 
0650 // TEST CASE
0651 // Test passing topology file with PCM definition
0652 static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test)
0653 {
0654     struct kunit_soc_component *kunit_comp;
0655     u8 *data;
0656     int size;
0657     int ret;
0658 
0659     /* prepare */
0660     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0661     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0662     kunit_comp->kunit = test;
0663     kunit_comp->expect = 0; /* expect success */
0664 
0665     size = sizeof(tplg_tmpl_with_pcm);
0666     data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
0667     KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
0668 
0669     memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
0670 
0671     kunit_comp->fw.data = data;
0672     kunit_comp->fw.size = size;
0673 
0674     kunit_comp->card.dev = test_dev,
0675     kunit_comp->card.name = "kunit-card",
0676     kunit_comp->card.owner = THIS_MODULE,
0677     kunit_comp->card.dai_link = kunit_dai_links,
0678     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0679     kunit_comp->card.fully_routed = true,
0680 
0681     /* run test */
0682     ret = snd_soc_register_card(&kunit_comp->card);
0683     if (ret != 0 && ret != -EPROBE_DEFER)
0684         KUNIT_FAIL(test, "Failed to register card");
0685 
0686     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
0687     KUNIT_EXPECT_EQ(test, 0, ret);
0688 
0689     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0690     KUNIT_EXPECT_EQ(test, 0, ret);
0691 
0692     snd_soc_unregister_component(test_dev);
0693 
0694     /* cleanup */
0695     snd_soc_unregister_card(&kunit_comp->card);
0696 }
0697 
0698 // TEST CASE
0699 // Test passing topology file with PCM definition
0700 // with component reload
0701 static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test)
0702 {
0703     struct kunit_soc_component *kunit_comp;
0704     u8 *data;
0705     int size;
0706     int ret;
0707     int i;
0708 
0709     /* prepare */
0710     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0711     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0712     kunit_comp->kunit = test;
0713     kunit_comp->expect = 0; /* expect success */
0714 
0715     size = sizeof(tplg_tmpl_with_pcm);
0716     data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
0717     KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
0718 
0719     memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
0720 
0721     kunit_comp->fw.data = data;
0722     kunit_comp->fw.size = size;
0723 
0724     kunit_comp->card.dev = test_dev,
0725     kunit_comp->card.name = "kunit-card",
0726     kunit_comp->card.owner = THIS_MODULE,
0727     kunit_comp->card.dai_link = kunit_dai_links,
0728     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0729     kunit_comp->card.fully_routed = true,
0730 
0731     /* run test */
0732     ret = snd_soc_register_card(&kunit_comp->card);
0733     if (ret != 0 && ret != -EPROBE_DEFER)
0734         KUNIT_FAIL(test, "Failed to register card");
0735 
0736     for (i = 0; i < 100; i++) {
0737         ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
0738         KUNIT_EXPECT_EQ(test, 0, ret);
0739 
0740         ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0741         KUNIT_EXPECT_EQ(test, 0, ret);
0742 
0743         snd_soc_unregister_component(test_dev);
0744     }
0745 
0746     /* cleanup */
0747     snd_soc_unregister_card(&kunit_comp->card);
0748 }
0749 
0750 // TEST CASE
0751 // Test passing topology file with PCM definition
0752 // with card reload
0753 static void snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit *test)
0754 {
0755     struct kunit_soc_component *kunit_comp;
0756     u8 *data;
0757     int size;
0758     int ret;
0759     int i;
0760 
0761     /* prepare */
0762     kunit_comp = kunit_kzalloc(test, sizeof(*kunit_comp), GFP_KERNEL);
0763     KUNIT_EXPECT_NOT_ERR_OR_NULL(test, kunit_comp);
0764     kunit_comp->kunit = test;
0765     kunit_comp->expect = 0; /* expect success */
0766 
0767     size = sizeof(tplg_tmpl_with_pcm);
0768     data = kunit_kzalloc(kunit_comp->kunit, size, GFP_KERNEL);
0769     KUNIT_EXPECT_NOT_ERR_OR_NULL(kunit_comp->kunit, data);
0770 
0771     memcpy(data, &tplg_tmpl_with_pcm, sizeof(tplg_tmpl_with_pcm));
0772 
0773     kunit_comp->fw.data = data;
0774     kunit_comp->fw.size = size;
0775 
0776     kunit_comp->card.dev = test_dev,
0777     kunit_comp->card.name = "kunit-card",
0778     kunit_comp->card.owner = THIS_MODULE,
0779     kunit_comp->card.dai_link = kunit_dai_links,
0780     kunit_comp->card.num_links = ARRAY_SIZE(kunit_dai_links),
0781     kunit_comp->card.fully_routed = true,
0782 
0783     /* run test */
0784     ret = snd_soc_component_initialize(&kunit_comp->comp, &test_component, test_dev);
0785     KUNIT_EXPECT_EQ(test, 0, ret);
0786 
0787     ret = snd_soc_add_component(&kunit_comp->comp, NULL, 0);
0788     KUNIT_EXPECT_EQ(test, 0, ret);
0789 
0790     for (i = 0; i < 100; i++) {
0791         ret = snd_soc_register_card(&kunit_comp->card);
0792         if (ret != 0 && ret != -EPROBE_DEFER)
0793             KUNIT_FAIL(test, "Failed to register card");
0794 
0795         snd_soc_unregister_card(&kunit_comp->card);
0796     }
0797 
0798     /* cleanup */
0799     snd_soc_unregister_component(test_dev);
0800 }
0801 
0802 /* ===== KUNIT MODULE DEFINITIONS =========================================== */
0803 
0804 static struct kunit_case snd_soc_tplg_test_cases[] = {
0805     KUNIT_CASE(snd_soc_tplg_test_load_with_null_comp),
0806     KUNIT_CASE(snd_soc_tplg_test_load_with_null_ops),
0807     KUNIT_CASE(snd_soc_tplg_test_load_with_null_fw),
0808     KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg),
0809     KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_magic),
0810     KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_abi),
0811     KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_size),
0812     KUNIT_CASE(snd_soc_tplg_test_load_empty_tplg_bad_payload_size),
0813     KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg),
0814     KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_comp),
0815     KUNIT_CASE(snd_soc_tplg_test_load_pcm_tplg_reload_card),
0816     {}
0817 };
0818 
0819 static struct kunit_suite snd_soc_tplg_test_suite = {
0820     .name = "snd_soc_tplg_test",
0821     .init = snd_soc_tplg_test_init,
0822     .exit = snd_soc_tplg_test_exit,
0823     .test_cases = snd_soc_tplg_test_cases,
0824 };
0825 
0826 kunit_test_suites(&snd_soc_tplg_test_suite);
0827 
0828 MODULE_LICENSE("GPL");