blob: bc4d377c83ecd7e2c79d9290b64f52c5ed85972d [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 (
18 "fmt"
19 "github.com/golang/protobuf/proto"
20 "reflect"
21 "testing"
22
23 bp "android/soong/cmd/extract_apks/bundle_proto"
24 "android/soong/third_party/zip"
25)
26
27type TestConfigDesc struct {
28 name string
29 targetConfig TargetConfig
30 expected SelectionResult
31}
32
33type TestDesc struct {
34 protoText string
35 configs []TestConfigDesc
36}
37
Jaewoong Jungfa00c062020-05-14 14:15:24 -070038func TestSelectApks_ApkSet(t *testing.T) {
39 testCases := []TestDesc{
Sasha Smundak7a894a62020-05-06 21:23:08 -070040 {
41 protoText: `
42variant {
43 targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070044 sdk_version_targeting {
Sasha Smundak7a894a62020-05-06 21:23:08 -070045 value { min { value: 29 } } } }
46 apk_set {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070047 module_metadata {
Sasha Smundak7a894a62020-05-06 21:23:08 -070048 name: "base" targeting {} delivery_type: INSTALL_TIME }
49 apk_description {
50 targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070051 screen_density_targeting {
Sasha Smundak7a894a62020-05-06 21:23:08 -070052 value { density_alias: LDPI } }
53 sdk_version_targeting {
54 value { min { value: 21 } } } }
55 path: "splits/base-ldpi.apk"
56 split_apk_metadata { split_id: "config.ldpi" } }
57 apk_description {
58 targeting {
59 screen_density_targeting {
60 value { density_alias: MDPI } }
61 sdk_version_targeting {
62 value { min { value: 21 } } } }
63 path: "splits/base-mdpi.apk"
64 split_apk_metadata { split_id: "config.mdpi" } }
65 apk_description {
66 targeting {
67 sdk_version_targeting {
68 value { min { value: 21 } } } }
69 path: "splits/base-master.apk"
70 split_apk_metadata { is_master_split: true } }
71 apk_description {
72 targeting {
73 abi_targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070074 value { alias: ARMEABI_V7A }
75 alternatives { alias: ARM64_V8A }
76 alternatives { alias: X86 }
77 alternatives { alias: X86_64 } }
Sasha Smundak7a894a62020-05-06 21:23:08 -070078 sdk_version_targeting {
79 value { min { value: 21 } } } }
80 path: "splits/base-armeabi_v7a.apk"
81 split_apk_metadata { split_id: "config.armeabi_v7a" } }
82 apk_description {
83 targeting {
84 abi_targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070085 value { alias: ARM64_V8A }
86 alternatives { alias: ARMEABI_V7A }
87 alternatives { alias: X86 }
88 alternatives { alias: X86_64 } }
Sasha Smundak7a894a62020-05-06 21:23:08 -070089 sdk_version_targeting {
90 value { min { value: 21 } } } }
91 path: "splits/base-arm64_v8a.apk"
92 split_apk_metadata { split_id: "config.arm64_v8a" } }
93 apk_description {
94 targeting {
95 abi_targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -070096 value { alias: X86 }
97 alternatives { alias: ARMEABI_V7A }
98 alternatives { alias: ARM64_V8A }
99 alternatives { alias: X86_64 } }
Sasha Smundak7a894a62020-05-06 21:23:08 -0700100 sdk_version_targeting {
101 value { min { value: 21 } } } }
102 path: "splits/base-x86.apk"
103 split_apk_metadata { split_id: "config.x86" } }
104 apk_description {
105 targeting {
106 abi_targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700107 value { alias: X86_64 }
108 alternatives { alias: ARMEABI_V7A }
109 alternatives { alias: ARM64_V8A }
110 alternatives { alias: X86 } }
Sasha Smundak7a894a62020-05-06 21:23:08 -0700111 sdk_version_targeting {
112 value { min { value: 21 } } } }
113 path: "splits/base-x86_64.apk"
114 split_apk_metadata { split_id: "config.x86_64" } } }
115}
116bundletool {
117 version: "0.10.3" }
118
119`,
120 configs: []TestConfigDesc{
121 {
122 name: "one",
123 targetConfig: TargetConfig{
124 sdkVersion: 29,
125 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
126 bp.ScreenDensity_DENSITY_UNSPECIFIED: true,
127 },
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700128 abis: map[bp.Abi_AbiAlias]int{
129 bp.Abi_ARMEABI_V7A: 0,
130 bp.Abi_ARM64_V8A: 1,
Sasha Smundak7a894a62020-05-06 21:23:08 -0700131 },
132 },
133 expected: SelectionResult{
134 "base",
135 []string{
136 "splits/base-ldpi.apk",
137 "splits/base-mdpi.apk",
138 "splits/base-master.apk",
139 "splits/base-armeabi_v7a.apk",
Sasha Smundak7a894a62020-05-06 21:23:08 -0700140 },
141 },
142 },
143 {
144 name: "two",
145 targetConfig: TargetConfig{
146 sdkVersion: 29,
147 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
148 bp.ScreenDensity_LDPI: true,
149 },
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700150 abis: map[bp.Abi_AbiAlias]int{},
Sasha Smundak7a894a62020-05-06 21:23:08 -0700151 },
152 expected: SelectionResult{
153 "base",
154 []string{
155 "splits/base-ldpi.apk",
156 "splits/base-master.apk",
157 },
158 },
159 },
160 {
161 name: "three",
162 targetConfig: TargetConfig{
163 sdkVersion: 20,
164 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
165 bp.ScreenDensity_LDPI: true,
166 },
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700167 abis: map[bp.Abi_AbiAlias]int{},
Sasha Smundak7a894a62020-05-06 21:23:08 -0700168 },
169 expected: SelectionResult{
170 "",
171 nil,
172 },
173 },
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700174 {
175 name: "four",
176 targetConfig: TargetConfig{
177 sdkVersion: 29,
178 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
179 bp.ScreenDensity_MDPI: true,
180 },
181 abis: map[bp.Abi_AbiAlias]int{
182 bp.Abi_ARM64_V8A: 0,
183 bp.Abi_ARMEABI_V7A: 1,
184 },
185 },
186 expected: SelectionResult{
187 "base",
188 []string{
189 "splits/base-mdpi.apk",
190 "splits/base-master.apk",
191 "splits/base-arm64_v8a.apk",
192 },
193 },
194 },
Sasha Smundak7a894a62020-05-06 21:23:08 -0700195 },
196 },
197 {
198 protoText: `
199variant {
200 targeting {
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700201 sdk_version_targeting {
Sasha Smundak7a894a62020-05-06 21:23:08 -0700202 value { min { value: 10000 } } } }
203 apk_set {
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700204 module_metadata {
Sasha Smundak7a894a62020-05-06 21:23:08 -0700205 name: "base" targeting {} delivery_type: INSTALL_TIME }
206 apk_description {
207 targeting {
208 sdk_version_targeting {
209 value { min { value: 21 } } } }
210 path: "splits/base-master.apk"
211 split_apk_metadata { is_master_split: true } } } }`,
212 configs: []TestConfigDesc{
213 {
214 name: "Prerelease",
215 targetConfig: TargetConfig{
216 sdkVersion: 30,
217 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{},
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700218 abis: map[bp.Abi_AbiAlias]int{},
Sasha Smundak7a894a62020-05-06 21:23:08 -0700219 allowPrereleased: true,
220 },
221 expected: SelectionResult{
222 "base",
223 []string{"splits/base-master.apk"},
224 },
225 },
226 },
227 },
228 }
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700229 for _, testCase := range testCases {
230 var toc bp.BuildApksResult
231 if err := proto.UnmarshalText(testCase.protoText, &toc); err != nil {
232 t.Fatal(err)
233 }
234 for _, config := range testCase.configs {
235 actual := selectApks(&toc, config.targetConfig)
236 if !reflect.DeepEqual(config.expected, actual) {
237 t.Errorf("%s: expected %v, got %v", config.name, config.expected, actual)
238 }
239 }
240 }
241}
Sasha Smundak7a894a62020-05-06 21:23:08 -0700242
Jaewoong Jungfa00c062020-05-14 14:15:24 -0700243func TestSelectApks_ApexSet(t *testing.T) {
244 testCases := []TestDesc{
245 {
246 protoText: `
247variant {
248 targeting {
249 sdk_version_targeting {
250 value { min { value: 29 } } } }
251 apk_set {
252 module_metadata {
253 name: "base" targeting {} delivery_type: INSTALL_TIME }
254 apk_description {
255 targeting {
256 multi_abi_targeting {
257 value { abi { alias: ARMEABI_V7A } }
258 alternatives { abi { alias: ARM64_V8A } }
259 alternatives { abi { alias: X86 } }
260 alternatives { abi { alias: X86_64 } } }
261 sdk_version_targeting {
262 value { min { value: 21 } } } }
263 path: "standalones/standalone-armeabi_v7a.apex"
264 apex_apk_metadata { } }
265 apk_description {
266 targeting {
267 multi_abi_targeting {
268 value { abi { alias: ARM64_V8A } }
269 alternatives { abi { alias: ARMEABI_V7A } }
270 alternatives { abi { alias: X86 } }
271 alternatives { abi { alias: X86_64 } } }
272 sdk_version_targeting {
273 value { min { value: 21 } } } }
274 path: "standalones/standalone-arm64_v8a.apex"
275 apex_apk_metadata { } }
276 apk_description {
277 targeting {
278 multi_abi_targeting {
279 value { abi { alias: X86 } }
280 alternatives { abi { alias: ARMEABI_V7A } }
281 alternatives { abi { alias: ARM64_V8A } }
282 alternatives { abi { alias: X86_64 } } }
283 sdk_version_targeting {
284 value { min { value: 21 } } } }
285 path: "standalones/standalone-x86.apex"
286 apex_apk_metadata { } }
287 apk_description {
288 targeting {
289 multi_abi_targeting {
290 value { abi { alias: X86_64 } }
291 alternatives { abi { alias: ARMEABI_V7A } }
292 alternatives { abi { alias: ARM64_V8A } }
293 alternatives { abi { alias: X86 } } }
294 sdk_version_targeting {
295 value { min { value: 21 } } } }
296 path: "standalones/standalone-x86_64.apex"
297 apex_apk_metadata { } } }
298}
299bundletool {
300 version: "0.10.3" }
301
302`,
303 configs: []TestConfigDesc{
304 {
305 name: "order matches priorities",
306 targetConfig: TargetConfig{
307 sdkVersion: 29,
308 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
309 bp.ScreenDensity_DENSITY_UNSPECIFIED: true,
310 },
311 abis: map[bp.Abi_AbiAlias]int{
312 bp.Abi_ARM64_V8A: 0,
313 bp.Abi_ARMEABI_V7A: 1,
314 },
315 },
316 expected: SelectionResult{
317 "base",
318 []string{
319 "standalones/standalone-arm64_v8a.apex",
320 },
321 },
322 },
323 {
324 name: "order doesn't match priorities",
325 targetConfig: TargetConfig{
326 sdkVersion: 29,
327 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
328 bp.ScreenDensity_DENSITY_UNSPECIFIED: true,
329 },
330 abis: map[bp.Abi_AbiAlias]int{
331 bp.Abi_ARMEABI_V7A: 0,
332 bp.Abi_ARM64_V8A: 1,
333 },
334 },
335 expected: SelectionResult{
336 "base",
337 []string{
338 "standalones/standalone-arm64_v8a.apex",
339 },
340 },
341 },
342 {
343 name: "single choice",
344 targetConfig: TargetConfig{
345 sdkVersion: 29,
346 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
347 bp.ScreenDensity_DENSITY_UNSPECIFIED: true,
348 },
349 abis: map[bp.Abi_AbiAlias]int{
350 bp.Abi_ARMEABI_V7A: 0,
351 },
352 },
353 expected: SelectionResult{
354 "base",
355 []string{
356 "standalones/standalone-armeabi_v7a.apex",
357 },
358 },
359 },
360 {
361 name: "cross platform",
362 targetConfig: TargetConfig{
363 sdkVersion: 29,
364 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
365 bp.ScreenDensity_DENSITY_UNSPECIFIED: true,
366 },
367 abis: map[bp.Abi_AbiAlias]int{
368 bp.Abi_ARM64_V8A: 0,
369 bp.Abi_MIPS64: 1,
370 bp.Abi_X86: 2,
371 },
372 },
373 expected: SelectionResult{
374 "base",
375 []string{
376 "standalones/standalone-x86.apex",
377 },
378 },
379 },
380 },
381 },
382 }
Sasha Smundak7a894a62020-05-06 21:23:08 -0700383 for _, testCase := range testCases {
384 var toc bp.BuildApksResult
385 if err := proto.UnmarshalText(testCase.protoText, &toc); err != nil {
386 t.Fatal(err)
387 }
388 for _, config := range testCase.configs {
389 actual := selectApks(&toc, config.targetConfig)
390 if !reflect.DeepEqual(config.expected, actual) {
391 t.Errorf("%s: expected %v, got %v", config.name, config.expected, actual)
392 }
393 }
394 }
395}
396
397type testZip2ZipWriter struct {
398 entries map[string]string
399}
400
401func (w testZip2ZipWriter) CopyFrom(file *zip.File, out string) error {
402 if x, ok := w.entries[out]; ok {
403 return fmt.Errorf("%s and %s both write to %s", x, file.Name, out)
404 }
405 w.entries[out] = file.Name
406 return nil
407}
408
409func TestWriteZip(t *testing.T) {
410 // what we write from what
411 expected := map[string]string{
412 "Foo.apk": "splits/mybase-master.apk",
413 "Foo-xhdpi.apk": "splits/mybase-xhdpi.apk",
414 }
415 apkSet := ApkSet{entries: make(map[string]*zip.File)}
416 sel := SelectionResult{moduleName: "mybase"}
417 for _, in := range expected {
418 apkSet.entries[in] = &zip.File{FileHeader: zip.FileHeader{Name: in}}
419 sel.entries = append(sel.entries, in)
420 }
421 writer := testZip2ZipWriter{make(map[string]string)}
422 config := TargetConfig{stem: "Foo"}
423 if err := apkSet.writeApks(sel, config, writer); err != nil {
424 t.Error(err)
425 }
426 if !reflect.DeepEqual(expected, writer.entries) {
427 t.Errorf("expected %v, got %v", expected, writer.entries)
428 }
429}