linux/sound/soc/soc-topology-test.c
<<
>>
Prefs
   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");
 822