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