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