blob: 9f52877c9290029532407c314b5dce25794233ad [file] [log] [blame]
Sasha Smundak7a894a62020-05-06 21:23:08 -07001// 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 (
Colin Crossffbcd1d2021-11-12 12:19:42 -080018 "bytes"
Sasha Smundak7a894a62020-05-06 21:23:08 -070019 "fmt"
Sasha Smundak7a894a62020-05-06 21:23:08 -070020 "reflect"
21 "testing"
22
Dan Willemsen4591b642021-05-24 14:24:12 -070023 "google.golang.org/protobuf/encoding/prototext"
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -070024
Sasha Smundak7a894a62020-05-06 21:23:08 -070025 bp "android/soong/cmd/extract_apks/bundle_proto"
26 "android/soong/third_party/zip"
27)
28
Sasha Smundak827c55f2020-05-20 13:10:59 -070029type testConfigDesc struct {
Sasha Smundak7a894a62020-05-06 21:23:08 -070030 name string
31 targetConfig TargetConfig
32 expected SelectionResult
33}
34
Sasha Smundak827c55f2020-05-20 13:10:59 -070035type testDesc struct {
Sasha Smundak7a894a62020-05-06 21:23:08 -070036 protoText string
Sasha Smundak827c55f2020-05-20 13:10:59 -070037 configs []testConfigDesc
Sasha Smundak7a894a62020-05-06 21:23:08 -070038}
39
Jaewoong Jungfa00c062020-05-14 14:15:24 -070040func TestSelectApks_ApkSet(t *testing.T) {
Sasha Smundak827c55f2020-05-20 13:10:59 -070041 testCases := []testDesc{
Sasha Smundak7a894a62020-05-06 21:23:08 -070042 {
43 protoText: `
44variant {
45 targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070046 sdk_version_targeting {
Sasha Smundak7a894a62020-05-06 21:23:08 -070047 value { min { value: 29 } } } }
48 apk_set {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070049 module_metadata {
Sasha Smundak7a894a62020-05-06 21:23:08 -070050 name: "base" targeting {} delivery_type: INSTALL_TIME }
51 apk_description {
52 targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070053 screen_density_targeting {
Sasha Smundak7a894a62020-05-06 21:23:08 -070054 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 {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070076 value { alias: ARMEABI_V7A }
77 alternatives { alias: ARM64_V8A }
78 alternatives { alias: X86 }
79 alternatives { alias: X86_64 } }
Sasha Smundak7a894a62020-05-06 21:23:08 -070080 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 {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070087 value { alias: ARM64_V8A }
88 alternatives { alias: ARMEABI_V7A }
89 alternatives { alias: X86 }
90 alternatives { alias: X86_64 } }
Sasha Smundak7a894a62020-05-06 21:23:08 -070091 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 {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070098 value { alias: X86 }
99 alternatives { alias: ARMEABI_V7A }
100 alternatives { alias: ARM64_V8A }
101 alternatives { alias: X86_64 } }
Sasha Smundak7a894a62020-05-06 21:23:08 -0700102 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 {
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700109 value { alias: X86_64 }
110 alternatives { alias: ARMEABI_V7A }
111 alternatives { alias: ARM64_V8A }
112 alternatives { alias: X86 } }
Sasha Smundak7a894a62020-05-06 21:23:08 -0700113 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`,
Sasha Smundak827c55f2020-05-20 13:10:59 -0700122 configs: []testConfigDesc{
Sasha Smundak7a894a62020-05-06 21:23:08 -0700123 {
124 name: "one",
125 targetConfig: TargetConfig{
126 sdkVersion: 29,
127 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
128 bp.ScreenDensity_DENSITY_UNSPECIFIED: true,
129 },
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700130 abis: map[bp.Abi_AbiAlias]int{
131 bp.Abi_ARMEABI_V7A: 0,
132 bp.Abi_ARM64_V8A: 1,
Sasha Smundak7a894a62020-05-06 21:23:08 -0700133 },
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",
Sasha Smundak7a894a62020-05-06 21:23:08 -0700142 },
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 },
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700152 abis: map[bp.Abi_AbiAlias]int{},
Sasha Smundak7a894a62020-05-06 21:23:08 -0700153 },
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 },
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700169 abis: map[bp.Abi_AbiAlias]int{},
Sasha Smundak7a894a62020-05-06 21:23:08 -0700170 },
171 expected: SelectionResult{
172 "",
173 nil,
174 },
175 },
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700176 {
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 },
Sasha Smundak7a894a62020-05-06 21:23:08 -0700197 },
198 },
199 {
200 protoText: `
201variant {
202 targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700203 sdk_version_targeting {
Sasha Smundak7a894a62020-05-06 21:23:08 -0700204 value { min { value: 10000 } } } }
205 apk_set {
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700206 module_metadata {
Sasha Smundak7a894a62020-05-06 21:23:08 -0700207 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 } } } }`,
Sasha Smundak827c55f2020-05-20 13:10:59 -0700214 configs: []testConfigDesc{
Sasha Smundak7a894a62020-05-06 21:23:08 -0700215 {
216 name: "Prerelease",
217 targetConfig: TargetConfig{
218 sdkVersion: 30,
219 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{},
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700220 abis: map[bp.Abi_AbiAlias]int{},
Sasha Smundak7a894a62020-05-06 21:23:08 -0700221 allowPrereleased: true,
222 },
223 expected: SelectionResult{
224 "base",
225 []string{"splits/base-master.apk"},
226 },
227 },
228 },
229 },
Sasha Smundak827c55f2020-05-20 13:10:59 -0700230 {
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 },
Sasha Smundak7a894a62020-05-06 21:23:08 -0700254 }
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700255 for _, testCase := range testCases {
256 var toc bp.BuildApksResult
Dan Willemsen4591b642021-05-24 14:24:12 -0700257 if err := prototext.Unmarshal([]byte(testCase.protoText), &toc); err != nil {
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700258 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}
Sasha Smundak7a894a62020-05-06 21:23:08 -0700268
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700269func TestSelectApks_ApexSet(t *testing.T) {
Sasha Smundak827c55f2020-05-20 13:10:59 -0700270 testCases := []testDesc{
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700271 {
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`,
Sasha Smundak827c55f2020-05-20 13:10:59 -0700329 configs: []testConfigDesc{
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700330 {
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 }
Sasha Smundak7a894a62020-05-06 21:23:08 -0700409 for _, testCase := range testCases {
410 var toc bp.BuildApksResult
Dan Willemsen4591b642021-05-24 14:24:12 -0700411 if err := prototext.Unmarshal([]byte(testCase.protoText), &toc); err != nil {
Sasha Smundak7a894a62020-05-06 21:23:08 -0700412 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
Sam Delmericob74f0a02022-09-16 11:59:56 -0400423func 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 },
Sam Delmericob48d57b2022-11-22 17:47:59 -0500747 expected: SelectionResult{
748 "base",
749 []string{
750 "standalones/standalone-x86.x86_64.apex",
751 }},
Sam Delmericob74f0a02022-09-16 11:59:56 -0400752 },
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
Sasha Smundak7a894a62020-05-06 21:23:08 -0700791type 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
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -0700803type testCaseWriteApks struct {
Sasha Smundak827c55f2020-05-20 13:10:59 -0700804 name string
805 moduleName string
806 stem string
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -0700807 partition string
Sasha Smundak7a894a62020-05-06 21:23:08 -0700808 // what we write from what
Colin Crossffbcd1d2021-11-12 12:19:42 -0800809 zipEntries map[string]string
810 expectedApkcerts []string
Sasha Smundak827c55f2020-05-20 13:10:59 -0700811}
812
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -0700813func TestWriteApks(t *testing.T) {
814 testCases := []testCaseWriteApks{
Sasha Smundak827c55f2020-05-20 13:10:59 -0700815 {
816 name: "splits",
817 moduleName: "mybase",
818 stem: "Foo",
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -0700819 partition: "system",
Colin Crossffbcd1d2021-11-12 12:19:42 -0800820 zipEntries: map[string]string{
Sasha Smundak827c55f2020-05-20 13:10:59 -0700821 "Foo.apk": "splits/mybase-master.apk",
822 "Foo-xhdpi.apk": "splits/mybase-xhdpi.apk",
823 },
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -0700824 expectedApkcerts: []string{
825 `name="Foo-xhdpi.apk" certificate="PRESIGNED" private_key="" partition="system"`,
826 `name="Foo.apk" certificate="PRESIGNED" private_key="" partition="system"`,
827 },
Sasha Smundak827c55f2020-05-20 13:10:59 -0700828 },
829 {
830 name: "universal",
831 moduleName: "base",
832 stem: "Bar",
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -0700833 partition: "product",
Colin Crossffbcd1d2021-11-12 12:19:42 -0800834 zipEntries: map[string]string{
Sasha Smundak827c55f2020-05-20 13:10:59 -0700835 "Bar.apk": "universal.apk",
836 },
Jaewoong Jung11c1e0f2020-06-29 19:18:44 -0700837 expectedApkcerts: []string{
838 `name="Bar.apk" certificate="PRESIGNED" private_key="" partition="product"`,
839 },
Sasha Smundak827c55f2020-05-20 13:10:59 -0700840 },
Sasha Smundak7a894a62020-05-06 21:23:08 -0700841 }
Sasha Smundak827c55f2020-05-20 13:10:59 -0700842 for _, testCase := range testCases {
Colin Crossffbcd1d2021-11-12 12:19:42 -0800843 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 })
Sasha Smundak7a894a62020-05-06 21:23:08 -0700884 }
885}