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 */ 22 static struct device *test_dev; 23 24 static struct device_driver test_drv = { 25 .name = "sound-soc-topology-test-driver", 26 }; 27 28 static 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 40 static 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 */ 51 struct 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 59 static 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 72 static 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 */ 85 SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); 86 87 SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("sound-soc-topology-test"))); 88 89 static 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 103 static 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 117 struct tplg_tmpl_001 { 118 struct snd_soc_tplg_hdr header; 119 struct snd_soc_tplg_manifest manifest; 120 } __packed; 121 122 static 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 143 struct 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 150 static 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 */ 224 static 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 238 static 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 244 static 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 */ 288 static 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 */ 332 static 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 346 static 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 352 static 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 390 static 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 441 static 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 497 static 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 553 static 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 609 static 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 664 static 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 714 static 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 767 static 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 819 static 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 834 static 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 841 kunit_test_suites(&snd_soc_tplg_test_suite); 842 843 MODULE_LICENSE("GPL"); 844