blob: c7c94ece6ca8f2187bda6a027204733c98efd262 [file] [log] [blame]
Colin Cross3bc7ffa2017-11-22 16:19:37 -08001// Copyright 2017 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 java
16
17import (
18 "android/soong/android"
Colin Crossd09b0b62018-04-18 11:06:47 -070019 "fmt"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080020 "reflect"
Colin Crossb69301e2017-12-01 10:48:26 -080021 "sort"
Colin Crossd09b0b62018-04-18 11:06:47 -070022 "strings"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080023 "testing"
24)
25
26var (
27 resourceFiles = []string{
28 "res/layout/layout.xml",
29 "res/values/strings.xml",
30 "res/values-en-rUS/strings.xml",
31 }
32
33 compiledResourceFiles = []string{
34 "aapt2/res/layout_layout.xml.flat",
35 "aapt2/res/values_strings.arsc.flat",
36 "aapt2/res/values-en-rUS_strings.arsc.flat",
37 }
38)
39
Colin Cross527012a2017-11-30 22:56:16 -080040func testAppContext(config android.Config, bp string, fs map[string][]byte) *android.TestContext {
41 appFS := map[string][]byte{}
42 for k, v := range fs {
43 appFS[k] = v
Colin Cross3bc7ffa2017-11-22 16:19:37 -080044 }
45
Colin Cross527012a2017-11-30 22:56:16 -080046 for _, file := range resourceFiles {
47 appFS[file] = nil
48 }
49
50 return testContext(config, bp, appFS)
51}
52
53func testApp(t *testing.T, bp string) *android.TestContext {
54 config := testConfig(nil)
55
56 ctx := testAppContext(config, bp, nil)
57
58 run(t, ctx, config)
59
60 return ctx
Colin Cross3bc7ffa2017-11-22 16:19:37 -080061}
62
63func TestApp(t *testing.T) {
Colin Crossa97c5d32018-03-28 14:58:31 -070064 for _, moduleType := range []string{"android_app", "android_library"} {
65 t.Run(moduleType, func(t *testing.T) {
66 ctx := testApp(t, moduleType+` {
67 name: "foo",
68 srcs: ["a.java"],
69 }
70 `)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080071
Colin Crossa97c5d32018-03-28 14:58:31 -070072 foo := ctx.ModuleForTests("foo", "android_common")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080073
Colin Cross31656952018-05-24 16:11:20 -070074 var expectedLinkImplicits []string
75
76 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
77 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080078
Colin Crossa97c5d32018-03-28 14:58:31 -070079 frameworkRes := ctx.ModuleForTests("framework-res", "android_common")
80 expectedLinkImplicits = append(expectedLinkImplicits,
81 frameworkRes.Output("package-res.apk").Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080082
Colin Crossa97c5d32018-03-28 14:58:31 -070083 // Test the mapping from input files to compiled output file names
84 compile := foo.Output(compiledResourceFiles[0])
85 if !reflect.DeepEqual(resourceFiles, compile.Inputs.Strings()) {
86 t.Errorf("expected aapt2 compile inputs expected:\n %#v\n got:\n %#v",
87 resourceFiles, compile.Inputs.Strings())
88 }
Colin Crossb69301e2017-12-01 10:48:26 -080089
Colin Crossa97c5d32018-03-28 14:58:31 -070090 compiledResourceOutputs := compile.Outputs.Strings()
91 sort.Strings(compiledResourceOutputs)
Colin Crossb69301e2017-12-01 10:48:26 -080092
Colin Crossa97c5d32018-03-28 14:58:31 -070093 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080094
Colin Crossa97c5d32018-03-28 14:58:31 -070095 list := foo.Output("aapt2/res.list")
96 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080097
Colin Crossa97c5d32018-03-28 14:58:31 -070098 // Check that the link rule uses
99 res := ctx.ModuleForTests("foo", "android_common").Output("package-res.apk")
100 if !reflect.DeepEqual(expectedLinkImplicits, res.Implicits.Strings()) {
101 t.Errorf("expected aapt2 link implicits expected:\n %#v\n got:\n %#v",
102 expectedLinkImplicits, res.Implicits.Strings())
103 }
104 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800105 }
106}
Colin Cross890ff552017-11-30 20:13:19 -0800107
108var testEnforceRROTests = []struct {
109 name string
110 enforceRROTargets []string
111 enforceRROExcludedOverlays []string
112 fooOverlayFiles []string
113 fooRRODirs []string
114 barOverlayFiles []string
115 barRRODirs []string
116}{
117 {
118 name: "no RRO",
119 enforceRROTargets: nil,
120 enforceRROExcludedOverlays: nil,
121 fooOverlayFiles: []string{
Colin Cross890ff552017-11-30 20:13:19 -0800122 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
Colin Cross68a70232018-01-04 14:50:13 -0800123 "device/vendor/blah/overlay/foo/res/values/strings.xml",
Colin Cross890ff552017-11-30 20:13:19 -0800124 },
125 fooRRODirs: nil,
126 barOverlayFiles: []string{
Colin Cross890ff552017-11-30 20:13:19 -0800127 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
Colin Cross68a70232018-01-04 14:50:13 -0800128 "device/vendor/blah/overlay/bar/res/values/strings.xml",
Colin Cross890ff552017-11-30 20:13:19 -0800129 },
130 barRRODirs: nil,
131 },
132 {
133 name: "enforce RRO on foo",
134 enforceRROTargets: []string{"foo"},
135 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
136 fooOverlayFiles: []string{
137 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
138 },
139 fooRRODirs: []string{
140 "device/vendor/blah/overlay/foo/res",
141 },
142 barOverlayFiles: []string{
Colin Cross890ff552017-11-30 20:13:19 -0800143 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
Colin Cross68a70232018-01-04 14:50:13 -0800144 "device/vendor/blah/overlay/bar/res/values/strings.xml",
Colin Cross890ff552017-11-30 20:13:19 -0800145 },
146 barRRODirs: nil,
147 },
148 {
149 name: "enforce RRO on all",
150 enforceRROTargets: []string{"*"},
151 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
152 fooOverlayFiles: []string{
153 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
154 },
155 fooRRODirs: []string{
156 "device/vendor/blah/overlay/foo/res",
157 },
158 barOverlayFiles: []string{
159 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
160 },
161 barRRODirs: []string{
162 "device/vendor/blah/overlay/bar/res",
163 },
164 },
165}
166
167func TestEnforceRRO(t *testing.T) {
168 resourceOverlays := []string{
169 "device/vendor/blah/overlay",
170 "device/vendor/blah/overlay2",
171 "device/vendor/blah/static_overlay",
172 }
173
174 fs := map[string][]byte{
175 "foo/res/res/values/strings.xml": nil,
176 "bar/res/res/values/strings.xml": nil,
177 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
178 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
179 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
180 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
181 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
182 }
183
184 bp := `
185 android_app {
186 name: "foo",
187 resource_dirs: ["foo/res"],
188 }
189
190 android_app {
191 name: "bar",
192 resource_dirs: ["bar/res"],
193 }
194 `
195
196 for _, testCase := range testEnforceRROTests {
197 t.Run(testCase.name, func(t *testing.T) {
198 config := testConfig(nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700199 config.TestProductVariables.ResourceOverlays = &resourceOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800200 if testCase.enforceRROTargets != nil {
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700201 config.TestProductVariables.EnforceRROTargets = &testCase.enforceRROTargets
Colin Cross890ff552017-11-30 20:13:19 -0800202 }
203 if testCase.enforceRROExcludedOverlays != nil {
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700204 config.TestProductVariables.EnforceRROExcludedOverlays = &testCase.enforceRROExcludedOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800205 }
206
207 ctx := testAppContext(config, bp, fs)
208 run(t, ctx, config)
209
210 getOverlays := func(moduleName string) ([]string, []string) {
211 module := ctx.ModuleForTests(moduleName, "android_common")
212 overlayCompiledPaths := module.Output("aapt2/overlay.list").Inputs.Strings()
213
214 var overlayFiles []string
215 for _, o := range overlayCompiledPaths {
216 overlayFiles = append(overlayFiles, module.Output(o).Inputs.Strings()...)
217 }
218
219 rroDirs := module.Module().(*AndroidApp).rroDirs.Strings()
220
221 return overlayFiles, rroDirs
222 }
223
224 fooOverlayFiles, fooRRODirs := getOverlays("foo")
225 barOverlayFiles, barRRODirs := getOverlays("bar")
226
227 if !reflect.DeepEqual(fooOverlayFiles, testCase.fooOverlayFiles) {
228 t.Errorf("expected foo overlay files:\n %#v\n got:\n %#v",
229 testCase.fooOverlayFiles, fooOverlayFiles)
230 }
231 if !reflect.DeepEqual(fooRRODirs, testCase.fooRRODirs) {
232 t.Errorf("expected foo rroDirs: %#v\n got:\n %#v",
233 testCase.fooRRODirs, fooRRODirs)
234 }
235
236 if !reflect.DeepEqual(barOverlayFiles, testCase.barOverlayFiles) {
237 t.Errorf("expected bar overlay files:\n %#v\n got:\n %#v",
238 testCase.barOverlayFiles, barOverlayFiles)
239 }
240 if !reflect.DeepEqual(barRRODirs, testCase.barRRODirs) {
241 t.Errorf("expected bar rroDirs: %#v\n got:\n %#v",
242 testCase.barRRODirs, barRRODirs)
243 }
244
245 })
246 }
247}
Colin Crossd09b0b62018-04-18 11:06:47 -0700248
249func TestAppSdkVersion(t *testing.T) {
250 testCases := []struct {
251 name string
252 sdkVersion string
253 platformSdkInt int
254 platformSdkCodename string
255 platformSdkFinal bool
256 expectedMinSdkVersion string
257 }{
258 {
259 name: "current final SDK",
260 sdkVersion: "current",
261 platformSdkInt: 27,
262 platformSdkCodename: "REL",
263 platformSdkFinal: true,
264 expectedMinSdkVersion: "27",
265 },
266 {
267 name: "current non-final SDK",
268 sdkVersion: "current",
269 platformSdkInt: 27,
270 platformSdkCodename: "OMR1",
271 platformSdkFinal: false,
272 expectedMinSdkVersion: "OMR1",
273 },
274 {
275 name: "default final SDK",
276 sdkVersion: "",
277 platformSdkInt: 27,
278 platformSdkCodename: "REL",
279 platformSdkFinal: true,
280 expectedMinSdkVersion: "27",
281 },
282 {
283 name: "default non-final SDK",
284 sdkVersion: "",
285 platformSdkInt: 27,
286 platformSdkCodename: "OMR1",
287 platformSdkFinal: false,
288 expectedMinSdkVersion: "OMR1",
289 },
290 {
291 name: "14",
292 sdkVersion: "14",
293 expectedMinSdkVersion: "14",
294 },
295 }
296
297 for _, moduleType := range []string{"android_app", "android_library"} {
298 for _, test := range testCases {
299 t.Run(moduleType+" "+test.name, func(t *testing.T) {
300 bp := fmt.Sprintf(`%s {
301 name: "foo",
302 srcs: ["a.java"],
303 sdk_version: "%s",
304 }`, moduleType, test.sdkVersion)
305
306 config := testConfig(nil)
307 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
308 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
309 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
310
311 ctx := testAppContext(config, bp, nil)
312
313 run(t, ctx, config)
314
315 foo := ctx.ModuleForTests("foo", "android_common")
316 link := foo.Output("package-res.apk")
317 linkFlags := strings.Split(link.Args["flags"], " ")
318 min := android.IndexList("--min-sdk-version", linkFlags)
319 target := android.IndexList("--target-sdk-version", linkFlags)
320
321 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
322 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
323 }
324
325 gotMinSdkVersion := linkFlags[min+1]
326 gotTargetSdkVersion := linkFlags[target+1]
327
328 if gotMinSdkVersion != test.expectedMinSdkVersion {
329 t.Errorf("incorrect --min-sdk-version, expected %q got %q",
330 test.expectedMinSdkVersion, gotMinSdkVersion)
331 }
332
333 if gotTargetSdkVersion != test.expectedMinSdkVersion {
334 t.Errorf("incorrect --target-sdk-version, expected %q got %q",
335 test.expectedMinSdkVersion, gotTargetSdkVersion)
336 }
337 })
338 }
339 }
340}