blob: 1d7726b364242a9a4ee50a737a1b2f53beb96979 [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
38var (
39 testCases = []TestDesc{
40 {
41 protoText: `
42variant {
43 targeting {
44 sdk_version_targeting {
45 value { min { value: 29 } } } }
46 apk_set {
47 module_metadata {
48 name: "base" targeting {} delivery_type: INSTALL_TIME }
49 apk_description {
50 targeting {
51 screen_density_targeting {
52 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 {
74 value { alias: ARMEABI_V7A } }
75 sdk_version_targeting {
76 value { min { value: 21 } } } }
77 path: "splits/base-armeabi_v7a.apk"
78 split_apk_metadata { split_id: "config.armeabi_v7a" } }
79 apk_description {
80 targeting {
81 abi_targeting {
82 value { alias: ARM64_V8A } }
83 sdk_version_targeting {
84 value { min { value: 21 } } } }
85 path: "splits/base-arm64_v8a.apk"
86 split_apk_metadata { split_id: "config.arm64_v8a" } }
87 apk_description {
88 targeting {
89 abi_targeting {
90 value { alias: X86 } }
91 sdk_version_targeting {
92 value { min { value: 21 } } } }
93 path: "splits/base-x86.apk"
94 split_apk_metadata { split_id: "config.x86" } }
95 apk_description {
96 targeting {
97 abi_targeting {
98 value { alias: X86_64 } }
99 sdk_version_targeting {
100 value { min { value: 21 } } } }
101 path: "splits/base-x86_64.apk"
102 split_apk_metadata { split_id: "config.x86_64" } } }
103}
104bundletool {
105 version: "0.10.3" }
106
107`,
108 configs: []TestConfigDesc{
109 {
110 name: "one",
111 targetConfig: TargetConfig{
112 sdkVersion: 29,
113 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
114 bp.ScreenDensity_DENSITY_UNSPECIFIED: true,
115 },
116 abis: map[bp.Abi_AbiAlias]bool{
117 bp.Abi_ARMEABI_V7A: true,
118 bp.Abi_ARM64_V8A: true,
119 },
120 },
121 expected: SelectionResult{
122 "base",
123 []string{
124 "splits/base-ldpi.apk",
125 "splits/base-mdpi.apk",
126 "splits/base-master.apk",
127 "splits/base-armeabi_v7a.apk",
128 "splits/base-arm64_v8a.apk",
129 },
130 },
131 },
132 {
133 name: "two",
134 targetConfig: TargetConfig{
135 sdkVersion: 29,
136 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
137 bp.ScreenDensity_LDPI: true,
138 },
139 abis: map[bp.Abi_AbiAlias]bool{},
140 },
141 expected: SelectionResult{
142 "base",
143 []string{
144 "splits/base-ldpi.apk",
145 "splits/base-master.apk",
146 },
147 },
148 },
149 {
150 name: "three",
151 targetConfig: TargetConfig{
152 sdkVersion: 20,
153 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{
154 bp.ScreenDensity_LDPI: true,
155 },
156 abis: map[bp.Abi_AbiAlias]bool{},
157 },
158 expected: SelectionResult{
159 "",
160 nil,
161 },
162 },
163 },
164 },
165 {
166 protoText: `
167variant {
168 targeting {
169 sdk_version_targeting {
170 value { min { value: 10000 } } } }
171 apk_set {
172 module_metadata {
173 name: "base" targeting {} delivery_type: INSTALL_TIME }
174 apk_description {
175 targeting {
176 sdk_version_targeting {
177 value { min { value: 21 } } } }
178 path: "splits/base-master.apk"
179 split_apk_metadata { is_master_split: true } } } }`,
180 configs: []TestConfigDesc{
181 {
182 name: "Prerelease",
183 targetConfig: TargetConfig{
184 sdkVersion: 30,
185 screenDpi: map[bp.ScreenDensity_DensityAlias]bool{},
186 abis: map[bp.Abi_AbiAlias]bool{},
187 allowPrereleased: true,
188 },
189 expected: SelectionResult{
190 "base",
191 []string{"splits/base-master.apk"},
192 },
193 },
194 },
195 },
196 }
197)
198
199func TestSelectApks(t *testing.T) {
200 for _, testCase := range testCases {
201 var toc bp.BuildApksResult
202 if err := proto.UnmarshalText(testCase.protoText, &toc); err != nil {
203 t.Fatal(err)
204 }
205 for _, config := range testCase.configs {
206 actual := selectApks(&toc, config.targetConfig)
207 if !reflect.DeepEqual(config.expected, actual) {
208 t.Errorf("%s: expected %v, got %v", config.name, config.expected, actual)
209 }
210 }
211 }
212}
213
214type testZip2ZipWriter struct {
215 entries map[string]string
216}
217
218func (w testZip2ZipWriter) CopyFrom(file *zip.File, out string) error {
219 if x, ok := w.entries[out]; ok {
220 return fmt.Errorf("%s and %s both write to %s", x, file.Name, out)
221 }
222 w.entries[out] = file.Name
223 return nil
224}
225
226func TestWriteZip(t *testing.T) {
227 // what we write from what
228 expected := map[string]string{
229 "Foo.apk": "splits/mybase-master.apk",
230 "Foo-xhdpi.apk": "splits/mybase-xhdpi.apk",
231 }
232 apkSet := ApkSet{entries: make(map[string]*zip.File)}
233 sel := SelectionResult{moduleName: "mybase"}
234 for _, in := range expected {
235 apkSet.entries[in] = &zip.File{FileHeader: zip.FileHeader{Name: in}}
236 sel.entries = append(sel.entries, in)
237 }
238 writer := testZip2ZipWriter{make(map[string]string)}
239 config := TargetConfig{stem: "Foo"}
240 if err := apkSet.writeApks(sel, config, writer); err != nil {
241 t.Error(err)
242 }
243 if !reflect.DeepEqual(expected, writer.entries) {
244 t.Errorf("expected %v, got %v", expected, writer.entries)
245 }
246}