1// Copyright 2020 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package main 16 17import ( 18 "bytes" 19 "fmt" 20 "reflect" 21 "testing" 22 23 "google.golang.org/protobuf/encoding/prototext" 24 25 bp "android/soong/cmd/extract_apks/bundle_proto" 26 "android/soong/third_party/zip" 27) 28 29type testConfigDesc struct { 30 name string 31 targetConfig TargetConfig 32 expected SelectionResult 33} 34 35type testDesc struct { 36 protoText string 37 configs []testConfigDesc 38} 39 40func TestSelectApks_ApkSet(t *testing.T) { 41 testCases := []testDesc{ 42 { 43 protoText: ` 44variant { 45 targeting { 46 sdk_version_targeting { 47 value { min { value: 29 } } } } 48 apk_set { 49 module_metadata { 50 name: "base" targeting {} delivery_type: INSTALL_TIME } 51 apk_description { 52 targeting { 53 screen_density_targeting { 54 value { density_alias: LDPI } } 55 sdk_version_targeting { 56 value { min { value: 21 } } } } 57 path: "splits/base-ldpi.apk" 58 split_apk_metadata { split_id: "config.ldpi" } } 59 apk_description { 60 targeting { 61 screen_density_targeting { 62 value { density_alias: MDPI } } 63 sdk_version_targeting { 64 value { min { value: 21 } } } } 65 path: "splits/base-mdpi.apk" 66 split_apk_metadata { split_id: "config.mdpi" } } 67 apk_description { 68 targeting { 69 sdk_version_targeting { 70 value { min { value: 21 } } } } 71 path: "splits/base-master.apk" 72 split_apk_metadata { is_master_split: true } } 73 apk_description { 74 targeting { 75 abi_targeting { 76 value { alias: ARMEABI_V7A } 77 alternatives { alias: ARM64_V8A } 78 alternatives { alias: X86 } 79 alternatives { alias: X86_64 } } 80 sdk_version_targeting { 81 value { min { value: 21 } } } } 82 path: "splits/base-armeabi_v7a.apk" 83 split_apk_metadata { split_id: "config.armeabi_v7a" } } 84 apk_description { 85 targeting { 86 abi_targeting { 87 value { alias: ARM64_V8A } 88 alternatives { alias: ARMEABI_V7A } 89 alternatives { alias: X86 } 90 alternatives { alias: X86_64 } } 91 sdk_version_targeting { 92 value { min { value: 21 } } } } 93 path: "splits/base-arm64_v8a.apk" 94 split_apk_metadata { split_id: "config.arm64_v8a" } } 95 apk_description { 96 targeting { 97 abi_targeting { 98 value { alias: X86 } 99 alternatives { alias: ARMEABI_V7A } 100 alternatives { alias: ARM64_V8A } 101 alternatives { alias: X86_64 } } 102 sdk_version_targeting { 103 value { min { value: 21 } } } } 104 path: "splits/base-x86.apk" 105 split_apk_metadata { split_id: "config.x86" } } 106 apk_description { 107 targeting { 108 abi_targeting { 109 value { alias: X86_64 } 110 alternatives { alias: ARMEABI_V7A } 111 alternatives { alias: ARM64_V8A } 112 alternatives { alias: X86 } } 113 sdk_version_targeting { 114 value { min { value: 21 } } } } 115 path: "splits/base-x86_64.apk" 116 split_apk_metadata { split_id: "config.x86_64" } } } 117} 118bundletool { 119 version: "0.10.3" } 120 121`, 122 configs: []testConfigDesc{ 123 { 124 name: "one", 125 targetConfig: TargetConfig{ 126 sdkVersion: 29, 127 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 128 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 129 }, 130 abis: map[bp.Abi_AbiAlias]int{ 131 bp.Abi_ARMEABI_V7A: 0, 132 bp.Abi_ARM64_V8A: 1, 133 }, 134 }, 135 expected: SelectionResult{ 136 "base", 137 []string{ 138 "splits/base-ldpi.apk", 139 "splits/base-mdpi.apk", 140 "splits/base-master.apk", 141 "splits/base-armeabi_v7a.apk", 142 }, 143 }, 144 }, 145 { 146 name: "two", 147 targetConfig: TargetConfig{ 148 sdkVersion: 29, 149 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 150 bp.ScreenDensity_LDPI: true, 151 }, 152 abis: map[bp.Abi_AbiAlias]int{}, 153 }, 154 expected: SelectionResult{ 155 "base", 156 []string{ 157 "splits/base-ldpi.apk", 158 "splits/base-master.apk", 159 }, 160 }, 161 }, 162 { 163 name: "three", 164 targetConfig: TargetConfig{ 165 sdkVersion: 20, 166 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 167 bp.ScreenDensity_LDPI: true, 168 }, 169 abis: map[bp.Abi_AbiAlias]int{}, 170 }, 171 expected: SelectionResult{ 172 "", 173 nil, 174 }, 175 }, 176 { 177 name: "four", 178 targetConfig: TargetConfig{ 179 sdkVersion: 29, 180 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 181 bp.ScreenDensity_MDPI: true, 182 }, 183 abis: map[bp.Abi_AbiAlias]int{ 184 bp.Abi_ARM64_V8A: 0, 185 bp.Abi_ARMEABI_V7A: 1, 186 }, 187 }, 188 expected: SelectionResult{ 189 "base", 190 []string{ 191 "splits/base-mdpi.apk", 192 "splits/base-master.apk", 193 "splits/base-arm64_v8a.apk", 194 }, 195 }, 196 }, 197 }, 198 }, 199 { 200 protoText: ` 201variant { 202 targeting { 203 sdk_version_targeting { 204 value { min { value: 10000 } } } } 205 apk_set { 206 module_metadata { 207 name: "base" targeting {} delivery_type: INSTALL_TIME } 208 apk_description { 209 targeting { 210 sdk_version_targeting { 211 value { min { value: 21 } } } } 212 path: "splits/base-master.apk" 213 split_apk_metadata { is_master_split: true } } } }`, 214 configs: []testConfigDesc{ 215 { 216 name: "Prerelease", 217 targetConfig: TargetConfig{ 218 sdkVersion: 30, 219 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{}, 220 abis: map[bp.Abi_AbiAlias]int{}, 221 allowPrereleased: true, 222 }, 223 expected: SelectionResult{ 224 "base", 225 []string{"splits/base-master.apk"}, 226 }, 227 }, 228 }, 229 }, 230 { 231 protoText: ` 232variant { 233 targeting { 234 sdk_version_targeting { 235 value { min { value: 29 } } } } 236 apk_set { 237 module_metadata { 238 name: "base" targeting {} delivery_type: INSTALL_TIME } 239 apk_description { 240 targeting {} 241 path: "universal.apk" 242 standalone_apk_metadata { fused_module_name: "base" } } } }`, 243 configs: []testConfigDesc{ 244 { 245 name: "Universal", 246 targetConfig: TargetConfig{sdkVersion: 30}, 247 expected: SelectionResult{ 248 "base", 249 []string{"universal.apk"}, 250 }, 251 }, 252 }, 253 }, 254 } 255 for _, testCase := range testCases { 256 var toc bp.BuildApksResult 257 if err := prototext.Unmarshal([]byte(testCase.protoText), &toc); err != nil { 258 t.Fatal(err) 259 } 260 for _, config := range testCase.configs { 261 actual := selectApks(&toc, config.targetConfig) 262 if !reflect.DeepEqual(config.expected, actual) { 263 t.Errorf("%s: expected %v, got %v", config.name, config.expected, actual) 264 } 265 } 266 } 267} 268 269func TestSelectApks_ApexSet(t *testing.T) { 270 testCases := []testDesc{ 271 { 272 protoText: ` 273variant { 274 targeting { 275 sdk_version_targeting { 276 value { min { value: 29 } } } } 277 apk_set { 278 module_metadata { 279 name: "base" targeting {} delivery_type: INSTALL_TIME } 280 apk_description { 281 targeting { 282 multi_abi_targeting { 283 value { abi { alias: ARMEABI_V7A } } 284 alternatives { abi { alias: ARM64_V8A } } 285 alternatives { abi { alias: X86 } } 286 alternatives { abi { alias: X86_64 } } } 287 sdk_version_targeting { 288 value { min { value: 21 } } } } 289 path: "standalones/standalone-armeabi_v7a.apex" 290 apex_apk_metadata { } } 291 apk_description { 292 targeting { 293 multi_abi_targeting { 294 value { abi { alias: ARM64_V8A } } 295 alternatives { abi { alias: ARMEABI_V7A } } 296 alternatives { abi { alias: X86 } } 297 alternatives { abi { alias: X86_64 } } } 298 sdk_version_targeting { 299 value { min { value: 21 } } } } 300 path: "standalones/standalone-arm64_v8a.apex" 301 apex_apk_metadata { } } 302 apk_description { 303 targeting { 304 multi_abi_targeting { 305 value { abi { alias: X86 } } 306 alternatives { abi { alias: ARMEABI_V7A } } 307 alternatives { abi { alias: ARM64_V8A } } 308 alternatives { abi { alias: X86_64 } } } 309 sdk_version_targeting { 310 value { min { value: 21 } } } } 311 path: "standalones/standalone-x86.apex" 312 apex_apk_metadata { } } 313 apk_description { 314 targeting { 315 multi_abi_targeting { 316 value { abi { alias: X86_64 } } 317 alternatives { abi { alias: ARMEABI_V7A } } 318 alternatives { abi { alias: ARM64_V8A } } 319 alternatives { abi { alias: X86 } } } 320 sdk_version_targeting { 321 value { min { value: 21 } } } } 322 path: "standalones/standalone-x86_64.apex" 323 apex_apk_metadata { } } } 324} 325bundletool { 326 version: "0.10.3" } 327 328`, 329 configs: []testConfigDesc{ 330 { 331 name: "order matches priorities", 332 targetConfig: TargetConfig{ 333 sdkVersion: 29, 334 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 335 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 336 }, 337 abis: map[bp.Abi_AbiAlias]int{ 338 bp.Abi_ARM64_V8A: 0, 339 bp.Abi_ARMEABI_V7A: 1, 340 }, 341 }, 342 expected: SelectionResult{ 343 "base", 344 []string{ 345 "standalones/standalone-arm64_v8a.apex", 346 }, 347 }, 348 }, 349 { 350 name: "order doesn't match priorities", 351 targetConfig: TargetConfig{ 352 sdkVersion: 29, 353 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 354 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 355 }, 356 abis: map[bp.Abi_AbiAlias]int{ 357 bp.Abi_ARMEABI_V7A: 0, 358 bp.Abi_ARM64_V8A: 1, 359 }, 360 }, 361 expected: SelectionResult{ 362 "base", 363 []string{ 364 "standalones/standalone-arm64_v8a.apex", 365 }, 366 }, 367 }, 368 { 369 name: "single choice", 370 targetConfig: TargetConfig{ 371 sdkVersion: 29, 372 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 373 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 374 }, 375 abis: map[bp.Abi_AbiAlias]int{ 376 bp.Abi_ARMEABI_V7A: 0, 377 }, 378 }, 379 expected: SelectionResult{ 380 "base", 381 []string{ 382 "standalones/standalone-armeabi_v7a.apex", 383 }, 384 }, 385 }, 386 { 387 name: "cross platform", 388 targetConfig: TargetConfig{ 389 sdkVersion: 29, 390 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 391 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 392 }, 393 abis: map[bp.Abi_AbiAlias]int{ 394 bp.Abi_ARM64_V8A: 0, 395 bp.Abi_MIPS64: 1, 396 bp.Abi_X86: 2, 397 }, 398 }, 399 expected: SelectionResult{ 400 "base", 401 []string{ 402 "standalones/standalone-x86.apex", 403 }, 404 }, 405 }, 406 }, 407 }, 408 } 409 for _, testCase := range testCases { 410 var toc bp.BuildApksResult 411 if err := prototext.Unmarshal([]byte(testCase.protoText), &toc); err != nil { 412 t.Fatal(err) 413 } 414 for _, config := range testCase.configs { 415 actual := selectApks(&toc, config.targetConfig) 416 if !reflect.DeepEqual(config.expected, actual) { 417 t.Errorf("%s: expected %v, got %v", config.name, config.expected, actual) 418 } 419 } 420 } 421} 422 423func TestSelectApks_ApexSet_Variants(t *testing.T) { 424 testCases := []testDesc{ 425 { 426 protoText: ` 427variant { 428 targeting { 429 sdk_version_targeting {value {min {value: 29}}} 430 multi_abi_targeting { 431 value {abi {alias: ARMEABI_V7A}} 432 alternatives { 433 abi {alias: ARMEABI_V7A} 434 abi {alias: ARM64_V8A} 435 } 436 alternatives {abi {alias: ARM64_V8A}} 437 alternatives {abi {alias: X86}} 438 alternatives { 439 abi {alias: X86} 440 abi {alias: X86_64} 441 } 442 } 443 } 444 apk_set { 445 module_metadata { 446 name: "base" 447 delivery_type: INSTALL_TIME 448 } 449 apk_description { 450 targeting { 451 multi_abi_targeting { 452 value {abi {alias: ARMEABI_V7A}} 453 alternatives { 454 abi {alias: ARMEABI_V7A} 455 abi {alias: ARM64_V8A} 456 } 457 alternatives {abi {alias: ARM64_V8A}} 458 alternatives {abi {alias: X86}} 459 alternatives { 460 abi {alias: X86} 461 abi {alias: X86_64} 462 } 463 } 464 } 465 path: "standalones/standalone-armeabi_v7a.apex" 466 } 467 } 468 variant_number: 0 469} 470variant { 471 targeting { 472 sdk_version_targeting {value {min {value: 29}}} 473 multi_abi_targeting { 474 value {abi {alias: ARM64_V8A}} 475 alternatives {abi {alias: ARMEABI_V7A}} 476 alternatives { 477 abi {alias: ARMEABI_V7A} 478 abi {alias: ARM64_V8A} 479 } 480 alternatives {abi {alias: X86}} 481 alternatives { 482 abi {alias: X86} 483 abi {alias: X86_64} 484 } 485 } 486 } 487 apk_set { 488 module_metadata { 489 name: "base" 490 delivery_type: INSTALL_TIME 491 } 492 apk_description { 493 targeting { 494 multi_abi_targeting { 495 value {abi {alias: ARM64_V8A}} 496 alternatives {abi {alias: ARMEABI_V7A}} 497 alternatives { 498 abi {alias: ARMEABI_V7A} 499 abi {alias: ARM64_V8A} 500 } 501 alternatives {abi {alias: X86}} 502 alternatives { 503 abi {alias: X86} 504 abi {alias: X86_64} 505 } 506 } 507 } 508 path: "standalones/standalone-arm64_v8a.apex" 509 } 510 } 511 variant_number: 1 512} 513variant { 514 targeting { 515 sdk_version_targeting {value {min {value: 29}}} 516 multi_abi_targeting { 517 value { 518 abi {alias: ARMEABI_V7A} 519 abi {alias: ARM64_V8A} 520 } 521 alternatives {abi {alias: ARMEABI_V7A}} 522 alternatives {abi {alias: ARM64_V8A}} 523 alternatives {abi {alias: X86}} 524 alternatives { 525 abi {alias: X86} 526 abi {alias: X86_64} 527 } 528 } 529 } 530 apk_set { 531 module_metadata { 532 name: "base" 533 delivery_type: INSTALL_TIME 534 } 535 apk_description { 536 targeting { 537 multi_abi_targeting { 538 value { 539 abi {alias: ARMEABI_V7A} 540 abi {alias: ARM64_V8A} 541 } 542 alternatives {abi {alias: ARMEABI_V7A}} 543 alternatives {abi {alias: ARM64_V8A}} 544 alternatives {abi {alias: X86}} 545 alternatives { 546 abi {alias: X86} 547 abi {alias: X86_64} 548 } 549 } 550 } 551 path: "standalones/standalone-armeabi_v7a.arm64_v8a.apex" 552 } 553 } 554 variant_number: 2 555} 556variant { 557 targeting { 558 sdk_version_targeting {value {min {value: 29}}} 559 multi_abi_targeting { 560 value {abi {alias: X86}} 561 alternatives {abi {alias: ARMEABI_V7A}} 562 alternatives { 563 abi {alias: ARMEABI_V7A} 564 abi {alias: ARM64_V8A} 565 } 566 alternatives {abi {alias: ARM64_V8A}} 567 alternatives { 568 abi {alias: X86} 569 abi {alias: X86_64} 570 } 571 } 572 } 573 apk_set { 574 module_metadata { 575 name: "base" 576 delivery_type: INSTALL_TIME 577 } 578 apk_description { 579 targeting { 580 multi_abi_targeting { 581 value {abi {alias: X86}} 582 alternatives {abi {alias: ARMEABI_V7A}} 583 alternatives { 584 abi {alias: ARMEABI_V7A} 585 abi {alias: ARM64_V8A} 586 } 587 alternatives {abi {alias: ARM64_V8A}} 588 alternatives { 589 abi {alias: X86} 590 abi {alias: X86_64} 591 } 592 } 593 } 594 path: "standalones/standalone-x86.apex" 595 } 596 } 597 variant_number: 3 598} 599variant { 600 targeting { 601 sdk_version_targeting {value {min {value: 29}}} 602 multi_abi_targeting { 603 value { 604 abi {alias: X86} 605 abi {alias: X86_64} 606 } 607 alternatives {abi {alias: ARMEABI_V7A}} 608 alternatives { 609 abi {alias: ARMEABI_V7A} 610 abi {alias: ARM64_V8A} 611 } 612 alternatives {abi {alias: ARM64_V8A}} 613 alternatives {abi {alias: X86}} 614 } 615 } 616 apk_set { 617 module_metadata { 618 name: "base" 619 delivery_type: INSTALL_TIME 620 } 621 apk_description { 622 targeting { 623 multi_abi_targeting { 624 value { 625 abi {alias: X86} 626 abi {alias: X86_64} 627 } 628 alternatives {abi {alias: ARMEABI_V7A}} 629 alternatives { 630 abi {alias: ARMEABI_V7A} 631 abi {alias: ARM64_V8A} 632 } 633 alternatives {abi {alias: ARM64_V8A}} 634 alternatives {abi {alias: X86}} 635 } 636 } 637 path: "standalones/standalone-x86.x86_64.apex" 638 } 639 } 640 variant_number: 4 641} 642`, 643 configs: []testConfigDesc{ 644 { 645 name: "multi-variant multi-target ARM", 646 targetConfig: TargetConfig{ 647 sdkVersion: 33, 648 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 649 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 650 }, 651 abis: map[bp.Abi_AbiAlias]int{ 652 bp.Abi_ARM64_V8A: 0, 653 bp.Abi_ARMEABI_V7A: 1, 654 }, 655 }, 656 expected: SelectionResult{ 657 "base", 658 []string{ 659 "standalones/standalone-armeabi_v7a.arm64_v8a.apex", 660 }, 661 }, 662 }, 663 { 664 name: "multi-variant single-target arm", 665 targetConfig: TargetConfig{ 666 sdkVersion: 33, 667 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 668 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 669 }, 670 abis: map[bp.Abi_AbiAlias]int{ 671 bp.Abi_ARMEABI_V7A: 0, 672 }, 673 }, 674 expected: SelectionResult{ 675 "base", 676 []string{ 677 "standalones/standalone-armeabi_v7a.apex", 678 }, 679 }, 680 }, 681 { 682 name: "multi-variant single-target arm64", 683 targetConfig: TargetConfig{ 684 sdkVersion: 33, 685 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 686 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 687 }, 688 abis: map[bp.Abi_AbiAlias]int{ 689 bp.Abi_ARM64_V8A: 0, 690 }, 691 }, 692 expected: SelectionResult{ 693 "base", 694 []string{ 695 "standalones/standalone-arm64_v8a.apex", 696 }, 697 }, 698 }, 699 { 700 name: "multi-variant multi-target x86", 701 targetConfig: TargetConfig{ 702 sdkVersion: 33, 703 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 704 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 705 }, 706 abis: map[bp.Abi_AbiAlias]int{ 707 bp.Abi_X86: 0, 708 bp.Abi_X86_64: 1, 709 }, 710 }, 711 expected: SelectionResult{ 712 "base", 713 []string{ 714 "standalones/standalone-x86.x86_64.apex", 715 }, 716 }, 717 }, 718 { 719 name: "multi-variant single-target x86", 720 targetConfig: TargetConfig{ 721 sdkVersion: 33, 722 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 723 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 724 }, 725 abis: map[bp.Abi_AbiAlias]int{ 726 bp.Abi_X86: 0, 727 }, 728 }, 729 expected: SelectionResult{ 730 "base", 731 []string{ 732 "standalones/standalone-x86.apex", 733 }, 734 }, 735 }, 736 { 737 name: "multi-variant single-target x86_64", 738 targetConfig: TargetConfig{ 739 sdkVersion: 33, 740 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 741 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 742 }, 743 abis: map[bp.Abi_AbiAlias]int{ 744 bp.Abi_X86_64: 0, 745 }, 746 }, 747 expected: SelectionResult{ 748 "base", 749 []string{ 750 "standalones/standalone-x86.x86_64.apex", 751 }}, 752 }, 753 { 754 name: "multi-variant multi-target cross-target", 755 targetConfig: TargetConfig{ 756 sdkVersion: 33, 757 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ 758 bp.ScreenDensity_DENSITY_UNSPECIFIED: true, 759 }, 760 abis: map[bp.Abi_AbiAlias]int{ 761 bp.Abi_ARM64_V8A: 0, 762 bp.Abi_X86_64: 1, 763 }, 764 }, 765 expected: SelectionResult{ 766 "base", 767 []string{ 768 "standalones/standalone-arm64_v8a.apex", 769 }, 770 }, 771 }, 772 }, 773 }, 774 } 775 for _, testCase := range testCases { 776 var toc bp.BuildApksResult 777 if err := prototext.Unmarshal([]byte(testCase.protoText), &toc); err != nil { 778 t.Fatal(err) 779 } 780 for _, config := range testCase.configs { 781 t.Run(config.name, func(t *testing.T) { 782 actual := selectApks(&toc, config.targetConfig) 783 if !reflect.DeepEqual(config.expected, actual) { 784 t.Errorf("expected %v, got %v", config.expected, actual) 785 } 786 }) 787 } 788 } 789} 790 791type testZip2ZipWriter struct { 792 entries map[string]string 793} 794 795func (w testZip2ZipWriter) CopyFrom(file *zip.File, out string) error { 796 if x, ok := w.entries[out]; ok { 797 return fmt.Errorf("%s and %s both write to %s", x, file.Name, out) 798 } 799 w.entries[out] = file.Name 800 return nil 801} 802 803type testCaseWriteApks struct { 804 name string 805 moduleName string 806 stem string 807 partition string 808 // what we write from what 809 zipEntries map[string]string 810 expectedApkcerts []string 811} 812 813func TestWriteApks(t *testing.T) { 814 testCases := []testCaseWriteApks{ 815 { 816 name: "splits", 817 moduleName: "mybase", 818 stem: "Foo", 819 partition: "system", 820 zipEntries: map[string]string{ 821 "Foo.apk": "splits/mybase-master.apk", 822 "Foo-xhdpi.apk": "splits/mybase-xhdpi.apk", 823 }, 824 expectedApkcerts: []string{ 825 `name="Foo-xhdpi.apk" certificate="PRESIGNED" private_key="" partition="system"`, 826 `name="Foo.apk" certificate="PRESIGNED" private_key="" partition="system"`, 827 }, 828 }, 829 { 830 name: "universal", 831 moduleName: "base", 832 stem: "Bar", 833 partition: "product", 834 zipEntries: map[string]string{ 835 "Bar.apk": "universal.apk", 836 }, 837 expectedApkcerts: []string{ 838 `name="Bar.apk" certificate="PRESIGNED" private_key="" partition="product"`, 839 }, 840 }, 841 } 842 for _, testCase := range testCases { 843 t.Run(testCase.name, func(t *testing.T) { 844 testZipBuf := &bytes.Buffer{} 845 testZip := zip.NewWriter(testZipBuf) 846 for _, in := range testCase.zipEntries { 847 f, _ := testZip.Create(in) 848 f.Write([]byte(in)) 849 } 850 testZip.Close() 851 852 zipReader, _ := zip.NewReader(bytes.NewReader(testZipBuf.Bytes()), int64(testZipBuf.Len())) 853 854 apkSet := ApkSet{entries: make(map[string]*zip.File)} 855 sel := SelectionResult{moduleName: testCase.moduleName} 856 for _, f := range zipReader.File { 857 apkSet.entries[f.Name] = f 858 sel.entries = append(sel.entries, f.Name) 859 } 860 861 zipWriter := testZip2ZipWriter{make(map[string]string)} 862 outWriter := &bytes.Buffer{} 863 config := TargetConfig{stem: testCase.stem} 864 apkcerts, err := apkSet.writeApks(sel, config, outWriter, zipWriter, testCase.partition) 865 if err != nil { 866 t.Error(err) 867 } 868 expectedZipEntries := make(map[string]string) 869 for k, v := range testCase.zipEntries { 870 if k != testCase.stem+".apk" { 871 expectedZipEntries[k] = v 872 } 873 } 874 if !reflect.DeepEqual(expectedZipEntries, zipWriter.entries) { 875 t.Errorf("expected zip entries %v, got %v", testCase.zipEntries, zipWriter.entries) 876 } 877 if !reflect.DeepEqual(testCase.expectedApkcerts, apkcerts) { 878 t.Errorf("expected apkcerts %v, got %v", testCase.expectedApkcerts, apkcerts) 879 } 880 if g, w := outWriter.String(), testCase.zipEntries[testCase.stem+".apk"]; !reflect.DeepEqual(g, w) { 881 t.Errorf("expected output file contents %q, got %q", testCase.stem+".apk", outWriter.String()) 882 } 883 }) 884 } 885} 886