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