blob: a0beaca8c5457f8681d289540b7ce30151bd7dc6 [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 (
Colin Crossd09b0b62018-04-18 11:06:47 -070018 "fmt"
Colin Crossa4f08812018-10-02 22:03:40 -070019 "path/filepath"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080020 "reflect"
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -070021/*
Jaewoong Jung9c6f3142019-04-26 14:31:50 -070022 "regexp"
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -070023*/
Colin Crossb69301e2017-12-01 10:48:26 -080024 "sort"
Colin Crossd09b0b62018-04-18 11:06:47 -070025 "strings"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080026 "testing"
Colin Cross43377ee2019-06-25 13:35:30 -070027
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -070028/*
Colin Cross43377ee2019-06-25 13:35:30 -070029 "github.com/google/blueprint/proptools"
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -070030*/
Jaewoong Jung9c6f3142019-04-26 14:31:50 -070031
32 "android/soong/android"
33 "android/soong/cc"
Colin Cross3bc7ffa2017-11-22 16:19:37 -080034)
35
36var (
37 resourceFiles = []string{
38 "res/layout/layout.xml",
39 "res/values/strings.xml",
40 "res/values-en-rUS/strings.xml",
41 }
42
43 compiledResourceFiles = []string{
44 "aapt2/res/layout_layout.xml.flat",
45 "aapt2/res/values_strings.arsc.flat",
46 "aapt2/res/values-en-rUS_strings.arsc.flat",
47 }
48)
49
Colin Cross527012a2017-11-30 22:56:16 -080050func testAppContext(config android.Config, bp string, fs map[string][]byte) *android.TestContext {
51 appFS := map[string][]byte{}
52 for k, v := range fs {
53 appFS[k] = v
Colin Cross3bc7ffa2017-11-22 16:19:37 -080054 }
55
Colin Cross527012a2017-11-30 22:56:16 -080056 for _, file := range resourceFiles {
57 appFS[file] = nil
58 }
59
60 return testContext(config, bp, appFS)
61}
62
63func testApp(t *testing.T, bp string) *android.TestContext {
64 config := testConfig(nil)
65
66 ctx := testAppContext(config, bp, nil)
67
68 run(t, ctx, config)
69
70 return ctx
Colin Cross3bc7ffa2017-11-22 16:19:37 -080071}
72
73func TestApp(t *testing.T) {
Colin Crossa97c5d32018-03-28 14:58:31 -070074 for _, moduleType := range []string{"android_app", "android_library"} {
75 t.Run(moduleType, func(t *testing.T) {
76 ctx := testApp(t, moduleType+` {
77 name: "foo",
78 srcs: ["a.java"],
79 }
80 `)
Colin Cross3bc7ffa2017-11-22 16:19:37 -080081
Colin Crossa97c5d32018-03-28 14:58:31 -070082 foo := ctx.ModuleForTests("foo", "android_common")
Colin Cross3bc7ffa2017-11-22 16:19:37 -080083
Colin Cross31656952018-05-24 16:11:20 -070084 var expectedLinkImplicits []string
85
86 manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
87 expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080088
Colin Crossa97c5d32018-03-28 14:58:31 -070089 frameworkRes := ctx.ModuleForTests("framework-res", "android_common")
Rashed Abdel-Tawab47d35aa2018-08-09 14:08:53 -070090 lineageRes := ctx.ModuleForTests("org.lineageos.platform-res", "android_common")
Colin Crossa97c5d32018-03-28 14:58:31 -070091 expectedLinkImplicits = append(expectedLinkImplicits,
92 frameworkRes.Output("package-res.apk").Output.String())
Rashed Abdel-Tawab47d35aa2018-08-09 14:08:53 -070093 expectedLinkImplicits = append(expectedLinkImplicits,
94 lineageRes.Output("package-res.apk").Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -080095
Colin Crossa97c5d32018-03-28 14:58:31 -070096 // Test the mapping from input files to compiled output file names
97 compile := foo.Output(compiledResourceFiles[0])
98 if !reflect.DeepEqual(resourceFiles, compile.Inputs.Strings()) {
99 t.Errorf("expected aapt2 compile inputs expected:\n %#v\n got:\n %#v",
100 resourceFiles, compile.Inputs.Strings())
101 }
Colin Crossb69301e2017-12-01 10:48:26 -0800102
Colin Crossa97c5d32018-03-28 14:58:31 -0700103 compiledResourceOutputs := compile.Outputs.Strings()
104 sort.Strings(compiledResourceOutputs)
Colin Crossb69301e2017-12-01 10:48:26 -0800105
Colin Crossa97c5d32018-03-28 14:58:31 -0700106 expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800107
Colin Crossa97c5d32018-03-28 14:58:31 -0700108 list := foo.Output("aapt2/res.list")
109 expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800110
Colin Crossa97c5d32018-03-28 14:58:31 -0700111 // Check that the link rule uses
112 res := ctx.ModuleForTests("foo", "android_common").Output("package-res.apk")
113 if !reflect.DeepEqual(expectedLinkImplicits, res.Implicits.Strings()) {
114 t.Errorf("expected aapt2 link implicits expected:\n %#v\n got:\n %#v",
115 expectedLinkImplicits, res.Implicits.Strings())
116 }
117 })
Colin Cross3bc7ffa2017-11-22 16:19:37 -0800118 }
119}
Colin Cross890ff552017-11-30 20:13:19 -0800120
Colin Crosse560c4a2019-03-19 16:03:11 -0700121func TestAppSplits(t *testing.T) {
122 ctx := testApp(t, `
123 android_app {
124 name: "foo",
125 srcs: ["a.java"],
126 package_splits: ["v4", "v7,hdpi"],
127 }`)
128
129 foo := ctx.ModuleForTests("foo", "android_common")
130
131 expectedOutputs := []string{
132 filepath.Join(buildDir, ".intermediates/foo/android_common/foo.apk"),
133 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v4.apk"),
134 filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v7_hdpi.apk"),
135 }
136 for _, expectedOutput := range expectedOutputs {
137 foo.Output(expectedOutput)
138 }
139
140 if g, w := foo.Module().(*AndroidApp).Srcs().Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
141 t.Errorf("want Srcs() = %q, got %q", w, g)
142 }
143}
144
Colin Cross0ddae7f2019-02-07 15:30:01 -0800145func TestResourceDirs(t *testing.T) {
146 testCases := []struct {
147 name string
148 prop string
149 resources []string
150 }{
151 {
152 name: "no resource_dirs",
153 prop: "",
154 resources: []string{"res/res/values/strings.xml"},
155 },
156 {
157 name: "resource_dirs",
158 prop: `resource_dirs: ["res"]`,
159 resources: []string{"res/res/values/strings.xml"},
160 },
161 {
162 name: "empty resource_dirs",
163 prop: `resource_dirs: []`,
164 resources: nil,
165 },
166 }
167
168 fs := map[string][]byte{
169 "res/res/values/strings.xml": nil,
170 }
171
172 bp := `
173 android_app {
174 name: "foo",
175 %s
176 }
177 `
178
179 for _, testCase := range testCases {
180 t.Run(testCase.name, func(t *testing.T) {
181 config := testConfig(nil)
182 ctx := testContext(config, fmt.Sprintf(bp, testCase.prop), fs)
183 run(t, ctx, config)
184
185 module := ctx.ModuleForTests("foo", "android_common")
186 resourceList := module.MaybeOutput("aapt2/res.list")
187
188 var resources []string
189 if resourceList.Rule != nil {
190 for _, compiledResource := range resourceList.Inputs.Strings() {
191 resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
192 }
193 }
194
195 if !reflect.DeepEqual(resources, testCase.resources) {
196 t.Errorf("expected resource files %q, got %q",
197 testCase.resources, resources)
198 }
199 })
200 }
201}
202
Colin Crossbec85302019-02-13 13:15:46 -0800203func TestAndroidResources(t *testing.T) {
Colin Cross5c4791c2019-02-01 11:44:44 -0800204 testCases := []struct {
205 name string
206 enforceRROTargets []string
207 enforceRROExcludedOverlays []string
Colin Crossbec85302019-02-13 13:15:46 -0800208 resourceFiles map[string][]string
Colin Cross5c4791c2019-02-01 11:44:44 -0800209 overlayFiles map[string][]string
210 rroDirs map[string][]string
211 }{
212 {
213 name: "no RRO",
214 enforceRROTargets: nil,
215 enforceRROExcludedOverlays: nil,
Colin Crossbec85302019-02-13 13:15:46 -0800216 resourceFiles: map[string][]string{
217 "foo": nil,
218 "bar": {"bar/res/res/values/strings.xml"},
219 "lib": nil,
220 "lib2": {"lib2/res/res/values/strings.xml"},
221 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800222 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800223 "foo": {
224 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800225 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000226 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800227 "foo/res/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800228 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
229 "device/vendor/blah/overlay/foo/res/values/strings.xml",
Anton Hansson53c88442019-03-18 15:53:16 +0000230 "product/vendor/blah/overlay/foo/res/values/strings.xml",
Colin Cross5c4791c2019-02-01 11:44:44 -0800231 },
Colin Crossbec85302019-02-13 13:15:46 -0800232 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800233 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
234 "device/vendor/blah/overlay/bar/res/values/strings.xml",
235 },
Colin Crossbec85302019-02-13 13:15:46 -0800236 "lib": {
237 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
238 "lib/res/res/values/strings.xml",
239 "device/vendor/blah/overlay/lib/res/values/strings.xml",
240 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800241 },
242 rroDirs: map[string][]string{
243 "foo": nil,
244 "bar": nil,
245 },
246 },
247 {
248 name: "enforce RRO on foo",
249 enforceRROTargets: []string{"foo"},
250 enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
Colin Crossbec85302019-02-13 13:15:46 -0800251 resourceFiles: map[string][]string{
252 "foo": nil,
253 "bar": {"bar/res/res/values/strings.xml"},
254 "lib": nil,
255 "lib2": {"lib2/res/res/values/strings.xml"},
256 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800257 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800258 "foo": {
259 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800260 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000261 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800262 "foo/res/res/values/strings.xml",
263 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
264 },
Colin Crossbec85302019-02-13 13:15:46 -0800265 "bar": {
Colin Cross5c4791c2019-02-01 11:44:44 -0800266 "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
267 "device/vendor/blah/overlay/bar/res/values/strings.xml",
268 },
Colin Crossbec85302019-02-13 13:15:46 -0800269 "lib": {
270 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
271 "lib/res/res/values/strings.xml",
272 "device/vendor/blah/overlay/lib/res/values/strings.xml",
273 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800274 },
Colin Crossc1c37552019-01-31 11:42:41 -0800275
Colin Cross5c4791c2019-02-01 11:44:44 -0800276 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800277 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000278 "device:device/vendor/blah/overlay/foo/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800279 // Enforce RRO on "foo" could imply RRO on static dependencies, but for now it doesn't.
280 // "device/vendor/blah/overlay/lib/res",
Anton Hansson53c88442019-03-18 15:53:16 +0000281 "product:product/vendor/blah/overlay/foo/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800282 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800283 "bar": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800284 "lib": nil,
Colin Cross5c4791c2019-02-01 11:44:44 -0800285 },
286 },
287 {
288 name: "enforce RRO on all",
289 enforceRROTargets: []string{"*"},
290 enforceRROExcludedOverlays: []string{
291 // Excluding specific apps/res directories also allowed.
292 "device/vendor/blah/static_overlay/foo",
293 "device/vendor/blah/static_overlay/bar/res",
294 },
Colin Crossbec85302019-02-13 13:15:46 -0800295 resourceFiles: map[string][]string{
296 "foo": nil,
297 "bar": {"bar/res/res/values/strings.xml"},
298 "lib": nil,
299 "lib2": {"lib2/res/res/values/strings.xml"},
300 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800301 overlayFiles: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800302 "foo": {
303 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800304 buildDir + "/.intermediates/lib/android_common/package-res.apk",
Anton Hansson53c88442019-03-18 15:53:16 +0000305 buildDir + "/.intermediates/lib3/android_common/package-res.apk",
Colin Cross6ed7dea2019-01-31 14:44:30 -0800306 "foo/res/res/values/strings.xml",
307 "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
308 },
Colin Crossbec85302019-02-13 13:15:46 -0800309 "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
310 "lib": {
311 buildDir + "/.intermediates/lib2/android_common/package-res.apk",
312 "lib/res/res/values/strings.xml",
313 },
Colin Cross5c4791c2019-02-01 11:44:44 -0800314 },
315 rroDirs: map[string][]string{
Colin Crossbec85302019-02-13 13:15:46 -0800316 "foo": {
Anton Hansson53c88442019-03-18 15:53:16 +0000317 "device:device/vendor/blah/overlay/foo/res",
318 "product:product/vendor/blah/overlay/foo/res",
319 // Lib dep comes after the direct deps
320 "device:device/vendor/blah/overlay/lib/res",
Colin Crossc1c37552019-01-31 11:42:41 -0800321 },
Anton Hansson53c88442019-03-18 15:53:16 +0000322 "bar": {"device:device/vendor/blah/overlay/bar/res"},
323 "lib": {"device:device/vendor/blah/overlay/lib/res"},
Colin Cross5c4791c2019-02-01 11:44:44 -0800324 },
325 },
326 }
327
Anton Hansson53c88442019-03-18 15:53:16 +0000328 deviceResourceOverlays := []string{
Colin Cross890ff552017-11-30 20:13:19 -0800329 "device/vendor/blah/overlay",
330 "device/vendor/blah/overlay2",
331 "device/vendor/blah/static_overlay",
332 }
333
Anton Hansson53c88442019-03-18 15:53:16 +0000334 productResourceOverlays := []string{
335 "product/vendor/blah/overlay",
336 }
337
Colin Cross890ff552017-11-30 20:13:19 -0800338 fs := map[string][]byte{
339 "foo/res/res/values/strings.xml": nil,
340 "bar/res/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800341 "lib/res/res/values/strings.xml": nil,
Colin Crossbec85302019-02-13 13:15:46 -0800342 "lib2/res/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800343 "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
344 "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
Colin Cross6ed7dea2019-01-31 14:44:30 -0800345 "device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800346 "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
347 "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
348 "device/vendor/blah/overlay2/res/values/strings.xml": nil,
Anton Hansson53c88442019-03-18 15:53:16 +0000349 "product/vendor/blah/overlay/foo/res/values/strings.xml": nil,
Colin Cross890ff552017-11-30 20:13:19 -0800350 }
351
352 bp := `
353 android_app {
354 name: "foo",
355 resource_dirs: ["foo/res"],
Anton Hansson53c88442019-03-18 15:53:16 +0000356 static_libs: ["lib", "lib3"],
Colin Cross890ff552017-11-30 20:13:19 -0800357 }
358
359 android_app {
360 name: "bar",
361 resource_dirs: ["bar/res"],
362 }
Colin Cross6ed7dea2019-01-31 14:44:30 -0800363
364 android_library {
365 name: "lib",
366 resource_dirs: ["lib/res"],
Colin Crossbec85302019-02-13 13:15:46 -0800367 static_libs: ["lib2"],
368 }
369
370 android_library {
371 name: "lib2",
372 resource_dirs: ["lib2/res"],
Colin Cross6ed7dea2019-01-31 14:44:30 -0800373 }
Anton Hansson53c88442019-03-18 15:53:16 +0000374
375 // This library has the same resources as lib (should not lead to dupe RROs)
376 android_library {
377 name: "lib3",
378 resource_dirs: ["lib/res"]
379 }
Colin Cross890ff552017-11-30 20:13:19 -0800380 `
381
Colin Cross5c4791c2019-02-01 11:44:44 -0800382 for _, testCase := range testCases {
Colin Cross890ff552017-11-30 20:13:19 -0800383 t.Run(testCase.name, func(t *testing.T) {
384 config := testConfig(nil)
Anton Hansson53c88442019-03-18 15:53:16 +0000385 config.TestProductVariables.DeviceResourceOverlays = deviceResourceOverlays
386 config.TestProductVariables.ProductResourceOverlays = productResourceOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800387 if testCase.enforceRROTargets != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800388 config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
Colin Cross890ff552017-11-30 20:13:19 -0800389 }
390 if testCase.enforceRROExcludedOverlays != nil {
Colin Crossa74ca042019-01-31 14:31:51 -0800391 config.TestProductVariables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
Colin Cross890ff552017-11-30 20:13:19 -0800392 }
393
394 ctx := testAppContext(config, bp, fs)
395 run(t, ctx, config)
396
Colin Crossbec85302019-02-13 13:15:46 -0800397 resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
398 for _, o := range list {
399 res := module.MaybeOutput(o)
400 if res.Rule != nil {
401 // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
402 // verify the inputs to the .arsc.flat rule.
403 files = append(files, res.Inputs.Strings()...)
404 } else {
405 // Otherwise, verify the full path to the output of the other module
406 files = append(files, o)
Anton Hansson94c93f32019-01-30 16:03:37 +0000407 }
Colin Cross890ff552017-11-30 20:13:19 -0800408 }
Colin Crossbec85302019-02-13 13:15:46 -0800409 return files
Colin Cross890ff552017-11-30 20:13:19 -0800410 }
411
Colin Crossbec85302019-02-13 13:15:46 -0800412 getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
413 module := ctx.ModuleForTests(moduleName, "android_common")
414 resourceList := module.MaybeOutput("aapt2/res.list")
415 if resourceList.Rule != nil {
416 resourceFiles = resourceListToFiles(module, resourceList.Inputs.Strings())
Anton Hansson0375a4f2019-01-24 14:39:19 +0000417 }
Colin Crossbec85302019-02-13 13:15:46 -0800418 overlayList := module.MaybeOutput("aapt2/overlay.list")
419 if overlayList.Rule != nil {
420 overlayFiles = resourceListToFiles(module, overlayList.Inputs.Strings())
421 }
422
Anton Hansson53c88442019-03-18 15:53:16 +0000423 for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() {
424 var prefix string
425 if d.overlayType == device {
426 prefix = "device:"
427 } else if d.overlayType == product {
428 prefix = "product:"
429 } else {
430 t.Fatalf("Unexpected overlayType %d", d.overlayType)
431 }
432 rroDirs = append(rroDirs, prefix+d.path.String())
433 }
Colin Crossbec85302019-02-13 13:15:46 -0800434
435 return resourceFiles, overlayFiles, rroDirs
436 }
437
438 modules := []string{"foo", "bar", "lib", "lib2"}
439 for _, module := range modules {
440 resourceFiles, overlayFiles, rroDirs := getResources(module)
441
442 if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
443 t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
444 module, testCase.resourceFiles[module], resourceFiles)
445 }
446 if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
447 t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
448 module, testCase.overlayFiles[module], overlayFiles)
449 }
450 if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
Anton Hansson0375a4f2019-01-24 14:39:19 +0000451 t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
Colin Crossbec85302019-02-13 13:15:46 -0800452 module, testCase.rroDirs[module], rroDirs)
Anton Hansson0375a4f2019-01-24 14:39:19 +0000453 }
Colin Cross890ff552017-11-30 20:13:19 -0800454 }
Colin Cross890ff552017-11-30 20:13:19 -0800455 })
456 }
457}
Colin Crossd09b0b62018-04-18 11:06:47 -0700458
459func TestAppSdkVersion(t *testing.T) {
460 testCases := []struct {
461 name string
462 sdkVersion string
463 platformSdkInt int
464 platformSdkCodename string
465 platformSdkFinal bool
466 expectedMinSdkVersion string
467 }{
468 {
469 name: "current final SDK",
470 sdkVersion: "current",
471 platformSdkInt: 27,
472 platformSdkCodename: "REL",
473 platformSdkFinal: true,
474 expectedMinSdkVersion: "27",
475 },
476 {
477 name: "current non-final SDK",
478 sdkVersion: "current",
479 platformSdkInt: 27,
480 platformSdkCodename: "OMR1",
481 platformSdkFinal: false,
482 expectedMinSdkVersion: "OMR1",
483 },
484 {
485 name: "default final SDK",
486 sdkVersion: "",
487 platformSdkInt: 27,
488 platformSdkCodename: "REL",
489 platformSdkFinal: true,
490 expectedMinSdkVersion: "27",
491 },
492 {
493 name: "default non-final SDK",
494 sdkVersion: "",
495 platformSdkInt: 27,
496 platformSdkCodename: "OMR1",
497 platformSdkFinal: false,
498 expectedMinSdkVersion: "OMR1",
499 },
500 {
501 name: "14",
502 sdkVersion: "14",
503 expectedMinSdkVersion: "14",
504 },
505 }
506
507 for _, moduleType := range []string{"android_app", "android_library"} {
508 for _, test := range testCases {
509 t.Run(moduleType+" "+test.name, func(t *testing.T) {
510 bp := fmt.Sprintf(`%s {
511 name: "foo",
512 srcs: ["a.java"],
513 sdk_version: "%s",
514 }`, moduleType, test.sdkVersion)
515
516 config := testConfig(nil)
517 config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
518 config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename
519 config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal
520
521 ctx := testAppContext(config, bp, nil)
522
523 run(t, ctx, config)
524
525 foo := ctx.ModuleForTests("foo", "android_common")
526 link := foo.Output("package-res.apk")
527 linkFlags := strings.Split(link.Args["flags"], " ")
528 min := android.IndexList("--min-sdk-version", linkFlags)
529 target := android.IndexList("--target-sdk-version", linkFlags)
530
531 if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
532 t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
533 }
534
535 gotMinSdkVersion := linkFlags[min+1]
536 gotTargetSdkVersion := linkFlags[target+1]
537
538 if gotMinSdkVersion != test.expectedMinSdkVersion {
539 t.Errorf("incorrect --min-sdk-version, expected %q got %q",
540 test.expectedMinSdkVersion, gotMinSdkVersion)
541 }
542
543 if gotTargetSdkVersion != test.expectedMinSdkVersion {
544 t.Errorf("incorrect --target-sdk-version, expected %q got %q",
545 test.expectedMinSdkVersion, gotTargetSdkVersion)
546 }
547 })
548 }
549 }
550}
Colin Crossa4f08812018-10-02 22:03:40 -0700551
Colin Cross47fa9d32019-03-26 10:51:39 -0700552func TestJNIABI(t *testing.T) {
553 ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
Colin Crossa4f08812018-10-02 22:03:40 -0700554 cc_library {
555 name: "libjni",
556 system_shared_libs: [],
557 stl: "none",
558 }
559
560 android_test {
561 name: "test",
562 no_framework_libs: true,
563 jni_libs: ["libjni"],
564 }
565
566 android_test {
567 name: "test_first",
568 no_framework_libs: true,
569 compile_multilib: "first",
570 jni_libs: ["libjni"],
571 }
572
573 android_test {
574 name: "test_both",
575 no_framework_libs: true,
576 compile_multilib: "both",
577 jni_libs: ["libjni"],
578 }
579
580 android_test {
581 name: "test_32",
582 no_framework_libs: true,
583 compile_multilib: "32",
584 jni_libs: ["libjni"],
585 }
586
587 android_test {
588 name: "test_64",
589 no_framework_libs: true,
590 compile_multilib: "64",
591 jni_libs: ["libjni"],
592 }
593 `)
594
Colin Crossa4f08812018-10-02 22:03:40 -0700595 testCases := []struct {
596 name string
597 abis []string
598 }{
599 {"test", []string{"arm64-v8a"}},
600 {"test_first", []string{"arm64-v8a"}},
601 {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
602 {"test_32", []string{"armeabi-v7a"}},
603 {"test_64", []string{"arm64-v8a"}},
604 }
605
606 for _, test := range testCases {
607 t.Run(test.name, func(t *testing.T) {
608 app := ctx.ModuleForTests(test.name, "android_common")
609 jniLibZip := app.Output("jnilibs.zip")
610 var abis []string
611 args := strings.Fields(jniLibZip.Args["jarArgs"])
612 for i := 0; i < len(args); i++ {
613 if args[i] == "-P" {
614 abis = append(abis, filepath.Base(args[i+1]))
615 i++
616 }
617 }
618 if !reflect.DeepEqual(abis, test.abis) {
619 t.Errorf("want abis %v, got %v", test.abis, abis)
620 }
621 })
622 }
623}
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800624
Colin Cross47fa9d32019-03-26 10:51:39 -0700625func TestJNIPackaging(t *testing.T) {
626 ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
627 cc_library {
628 name: "libjni",
629 system_shared_libs: [],
630 stl: "none",
631 }
632
633 android_app {
634 name: "app",
635 jni_libs: ["libjni"],
636 }
637
638 android_app {
639 name: "app_noembed",
640 jni_libs: ["libjni"],
641 use_embedded_native_libs: false,
642 }
643
644 android_app {
645 name: "app_embed",
646 jni_libs: ["libjni"],
647 use_embedded_native_libs: true,
648 }
649
650 android_test {
651 name: "test",
652 no_framework_libs: true,
653 jni_libs: ["libjni"],
654 }
655
656 android_test {
657 name: "test_noembed",
658 no_framework_libs: true,
659 jni_libs: ["libjni"],
660 use_embedded_native_libs: false,
661 }
662
663 android_test_helper_app {
664 name: "test_helper",
665 no_framework_libs: true,
666 jni_libs: ["libjni"],
667 }
668
669 android_test_helper_app {
670 name: "test_helper_noembed",
671 no_framework_libs: true,
672 jni_libs: ["libjni"],
673 use_embedded_native_libs: false,
674 }
675 `)
676
677 testCases := []struct {
678 name string
679 packaged bool
680 compressed bool
681 }{
682 {"app", false, false},
683 {"app_noembed", false, false},
684 {"app_embed", true, false},
685 {"test", true, false},
686 {"test_noembed", true, true},
687 {"test_helper", true, false},
688 {"test_helper_noembed", true, true},
689 }
690
691 for _, test := range testCases {
692 t.Run(test.name, func(t *testing.T) {
693 app := ctx.ModuleForTests(test.name, "android_common")
694 jniLibZip := app.MaybeOutput("jnilibs.zip")
695 if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
696 t.Errorf("expected jni packaged %v, got %v", w, g)
697 }
698
699 if jniLibZip.Rule != nil {
700 if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
701 t.Errorf("expected jni compressed %v, got %v", w, g)
702 }
703 }
704 })
705 }
706
707}
708
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800709func TestCertificates(t *testing.T) {
710 testCases := []struct {
711 name string
712 bp string
713 certificateOverride string
714 expected string
715 }{
716 {
717 name: "default",
718 bp: `
719 android_app {
720 name: "foo",
721 srcs: ["a.java"],
722 }
723 `,
724 certificateOverride: "",
Dan Willemsenadbfc492019-04-09 21:36:26 -0700725 expected: "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800726 },
727 {
728 name: "module certificate property",
729 bp: `
730 android_app {
731 name: "foo",
732 srcs: ["a.java"],
733 certificate: ":new_certificate"
734 }
735
736 android_app_certificate {
737 name: "new_certificate",
738 certificate: "cert/new_cert",
739 }
740 `,
741 certificateOverride: "",
742 expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
743 },
744 {
745 name: "path certificate property",
746 bp: `
747 android_app {
748 name: "foo",
749 srcs: ["a.java"],
750 certificate: "expiredkey"
751 }
752 `,
753 certificateOverride: "",
Dan Willemsenadbfc492019-04-09 21:36:26 -0700754 expected: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
Jaewoong Jung2ad817c2019-01-18 14:27:16 -0800755 },
756 {
757 name: "certificate overrides",
758 bp: `
759 android_app {
760 name: "foo",
761 srcs: ["a.java"],
762 certificate: "expiredkey"
763 }
764
765 android_app_certificate {
766 name: "new_certificate",
767 certificate: "cert/new_cert",
768 }
769 `,
770 certificateOverride: "foo:new_certificate",
771 expected: "cert/new_cert.x509.pem cert/new_cert.pk8",
772 },
773 }
774
775 for _, test := range testCases {
776 t.Run(test.name, func(t *testing.T) {
777 config := testConfig(nil)
778 if test.certificateOverride != "" {
779 config.TestProductVariables.CertificateOverrides = []string{test.certificateOverride}
780 }
781 ctx := testAppContext(config, test.bp, nil)
782
783 run(t, ctx, config)
784 foo := ctx.ModuleForTests("foo", "android_common")
785
786 signapk := foo.Output("foo.apk")
787 signFlags := signapk.Args["certificates"]
788 if test.expected != signFlags {
789 t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
790 }
791 })
792 }
793}
Jaewoong Jung9d22a912019-01-23 16:27:47 -0800794
795func TestPackageNameOverride(t *testing.T) {
796 testCases := []struct {
797 name string
798 bp string
799 packageNameOverride string
800 expected []string
801 }{
802 {
803 name: "default",
804 bp: `
805 android_app {
806 name: "foo",
807 srcs: ["a.java"],
808 }
809 `,
810 packageNameOverride: "",
811 expected: []string{
812 buildDir + "/.intermediates/foo/android_common/foo.apk",
813 buildDir + "/target/product/test_device/system/app/foo/foo.apk",
814 },
815 },
816 {
817 name: "overridden",
818 bp: `
819 android_app {
820 name: "foo",
821 srcs: ["a.java"],
822 }
823 `,
824 packageNameOverride: "foo:bar",
825 expected: []string{
826 // The package apk should be still be the original name for test dependencies.
827 buildDir + "/.intermediates/foo/android_common/foo.apk",
828 buildDir + "/target/product/test_device/system/app/bar/bar.apk",
829 },
830 },
831 }
832
833 for _, test := range testCases {
834 t.Run(test.name, func(t *testing.T) {
835 config := testConfig(nil)
836 if test.packageNameOverride != "" {
837 config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
838 }
839 ctx := testAppContext(config, test.bp, nil)
840
841 run(t, ctx, config)
842 foo := ctx.ModuleForTests("foo", "android_common")
843
844 outputs := foo.AllOutputs()
845 outputMap := make(map[string]bool)
846 for _, o := range outputs {
847 outputMap[o] = true
848 }
849 for _, e := range test.expected {
850 if _, exist := outputMap[e]; !exist {
851 t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
852 }
853 }
854 })
855 }
856}
Jaewoong Jung4102e5d2019-02-27 16:26:28 -0800857
858func TestInstrumentationTargetOverridden(t *testing.T) {
859 bp := `
860 android_app {
861 name: "foo",
862 srcs: ["a.java"],
863 }
864
865 android_test {
866 name: "bar",
867 instrumentation_for: "foo",
868 }
869 `
870 config := testConfig(nil)
871 config.TestProductVariables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
872 ctx := testAppContext(config, bp, nil)
873
874 run(t, ctx, config)
875
876 bar := ctx.ModuleForTests("bar", "android_common")
877 res := bar.Output("package-res.apk")
878 aapt2Flags := res.Args["flags"]
879 e := "--rename-instrumentation-target-package org.dandroid.bp"
880 if !strings.Contains(aapt2Flags, e) {
881 t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
882 }
883}
Jaewoong Jung525443a2019-02-28 15:35:54 -0800884
885func TestOverrideAndroidApp(t *testing.T) {
886 ctx := testJava(t, `
887 android_app {
888 name: "foo",
889 srcs: ["a.java"],
Jaewoong Junga641ee92019-03-27 11:17:14 -0700890 certificate: "expiredkey",
Jaewoong Jung525443a2019-02-28 15:35:54 -0800891 overrides: ["baz"],
892 }
893
894 override_android_app {
895 name: "bar",
896 base: "foo",
897 certificate: ":new_certificate",
898 }
899
900 android_app_certificate {
901 name: "new_certificate",
902 certificate: "cert/new_cert",
903 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700904
905 override_android_app {
906 name: "baz",
907 base: "foo",
908 package_name: "org.dandroid.bp",
909 }
Jaewoong Jung525443a2019-02-28 15:35:54 -0800910 `)
911
912 expectedVariants := []struct {
913 variantName string
914 apkName string
915 apkPath string
916 signFlag string
917 overrides []string
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700918 aaptFlag string
Jaewoong Jung525443a2019-02-28 15:35:54 -0800919 }{
920 {
921 variantName: "android_common",
922 apkPath: "/target/product/test_device/system/app/foo/foo.apk",
Dan Willemsenadbfc492019-04-09 21:36:26 -0700923 signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
Jaewoong Jung525443a2019-02-28 15:35:54 -0800924 overrides: []string{"baz"},
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700925 aaptFlag: "",
Jaewoong Jung525443a2019-02-28 15:35:54 -0800926 },
927 {
928 variantName: "bar_android_common",
929 apkPath: "/target/product/test_device/system/app/bar/bar.apk",
930 signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
931 overrides: []string{"baz", "foo"},
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700932 aaptFlag: "",
933 },
934 {
935 variantName: "baz_android_common",
936 apkPath: "/target/product/test_device/system/app/baz/baz.apk",
Dan Willemsenadbfc492019-04-09 21:36:26 -0700937 signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700938 overrides: []string{"baz", "foo"},
939 aaptFlag: "--rename-manifest-package org.dandroid.bp",
Jaewoong Jung525443a2019-02-28 15:35:54 -0800940 },
941 }
942 for _, expected := range expectedVariants {
943 variant := ctx.ModuleForTests("foo", expected.variantName)
944
945 // Check the final apk name
946 outputs := variant.AllOutputs()
947 expectedApkPath := buildDir + expected.apkPath
948 found := false
949 for _, o := range outputs {
950 if o == expectedApkPath {
951 found = true
952 break
953 }
954 }
955 if !found {
956 t.Errorf("Can't find %q in output files.\nAll outputs:%v", expectedApkPath, outputs)
957 }
958
959 // Check the certificate paths
960 signapk := variant.Output("foo.apk")
961 signFlag := signapk.Args["certificates"]
962 if expected.signFlag != signFlag {
963 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected.signFlag, signFlag)
964 }
965
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700966 // Check if the overrides field values are correctly aggregated.
Jaewoong Jung525443a2019-02-28 15:35:54 -0800967 mod := variant.Module().(*AndroidApp)
968 if !reflect.DeepEqual(expected.overrides, mod.appProperties.Overrides) {
969 t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
970 expected.overrides, mod.appProperties.Overrides)
971 }
Jaewoong Jung6f373f62019-03-13 10:13:24 -0700972
973 // Check the package renaming flag, if exists.
974 res := variant.Output("package-res.apk")
975 aapt2Flags := res.Args["flags"]
976 if !strings.Contains(aapt2Flags, expected.aaptFlag) {
977 t.Errorf("package renaming flag, %q is missing in aapt2 link flags, %q", expected.aaptFlag, aapt2Flags)
978 }
Jaewoong Jung525443a2019-02-28 15:35:54 -0800979 }
980}
Jaewoong Jung5c6572e2019-06-17 17:40:56 -0700981
982func TestEmbedNotice(t *testing.T) {
983 ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
984 android_app {
985 name: "foo",
986 srcs: ["a.java"],
987 static_libs: ["javalib"],
988 jni_libs: ["libjni"],
989 notice: "APP_NOTICE",
990 embed_notices: true,
991 }
992
993 // No embed_notice flag
994 android_app {
995 name: "bar",
996 srcs: ["a.java"],
997 jni_libs: ["libjni"],
998 notice: "APP_NOTICE",
999 }
1000
1001 // No NOTICE files
1002 android_app {
1003 name: "baz",
1004 srcs: ["a.java"],
1005 embed_notices: true,
1006 }
1007
1008 cc_library {
1009 name: "libjni",
1010 system_shared_libs: [],
1011 stl: "none",
1012 notice: "LIB_NOTICE",
1013 }
1014
1015 java_library {
1016 name: "javalib",
1017 srcs: [
1018 ":gen",
1019 ],
1020 }
1021
1022 genrule {
1023 name: "gen",
1024 tools: ["gentool"],
1025 out: ["gen.java"],
1026 notice: "GENRULE_NOTICE",
1027 }
1028
1029 java_binary_host {
1030 name: "gentool",
1031 srcs: ["b.java"],
1032 notice: "TOOL_NOTICE",
1033 }
1034 `)
1035
1036 // foo has NOTICE files to process, and embed_notices is true.
1037 foo := ctx.ModuleForTests("foo", "android_common")
1038 // verify merge notices rule.
1039 mergeNotices := foo.Rule("mergeNoticesRule")
1040 noticeInputs := mergeNotices.Inputs.Strings()
1041 // TOOL_NOTICE should be excluded as it's a host module.
1042 if len(mergeNotices.Inputs) != 3 {
1043 t.Errorf("number of input notice files: expected = 3, actual = %q", noticeInputs)
1044 }
1045 if !inList("APP_NOTICE", noticeInputs) {
1046 t.Errorf("APP_NOTICE is missing from notice files, %q", noticeInputs)
1047 }
1048 if !inList("LIB_NOTICE", noticeInputs) {
1049 t.Errorf("LIB_NOTICE is missing from notice files, %q", noticeInputs)
1050 }
1051 if !inList("GENRULE_NOTICE", noticeInputs) {
1052 t.Errorf("GENRULE_NOTICE is missing from notice files, %q", noticeInputs)
1053 }
1054 // aapt2 flags should include -A <NOTICE dir> so that its contents are put in the APK's /assets.
1055 res := foo.Output("package-res.apk")
1056 aapt2Flags := res.Args["flags"]
1057 e := "-A " + buildDir + "/.intermediates/foo/android_common/NOTICE"
1058 if !strings.Contains(aapt2Flags, e) {
1059 t.Errorf("asset dir flag for NOTICE, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
1060 }
1061
1062 // bar has NOTICE files to process, but embed_notices is not set.
1063 bar := ctx.ModuleForTests("bar", "android_common")
1064 mergeNotices = bar.MaybeRule("mergeNoticesRule")
1065 if mergeNotices.Rule != nil {
1066 t.Errorf("mergeNotices shouldn't have run for bar")
1067 }
1068
1069 // baz's embed_notice is true, but it doesn't have any NOTICE files.
1070 baz := ctx.ModuleForTests("baz", "android_common")
1071 mergeNotices = baz.MaybeRule("mergeNoticesRule")
1072 if mergeNotices.Rule != nil {
1073 t.Errorf("mergeNotices shouldn't have run for baz")
1074 }
1075}
Colin Cross43377ee2019-06-25 13:35:30 -07001076
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -07001077/*
Colin Cross43377ee2019-06-25 13:35:30 -07001078func TestUncompressDex(t *testing.T) {
1079 testCases := []struct {
1080 name string
1081 bp string
1082
1083 uncompressedPlatform bool
1084 uncompressedUnbundled bool
1085 }{
1086 {
1087 name: "normal",
1088 bp: `
1089 android_app {
1090 name: "foo",
1091 srcs: ["a.java"],
1092 }
1093 `,
1094 uncompressedPlatform: true,
1095 uncompressedUnbundled: false,
1096 },
1097 {
1098 name: "use_embedded_dex",
1099 bp: `
1100 android_app {
1101 name: "foo",
1102 use_embedded_dex: true,
1103 srcs: ["a.java"],
1104 }
1105 `,
1106 uncompressedPlatform: true,
1107 uncompressedUnbundled: true,
1108 },
1109 {
1110 name: "privileged",
1111 bp: `
1112 android_app {
1113 name: "foo",
1114 privileged: true,
1115 srcs: ["a.java"],
1116 }
1117 `,
1118 uncompressedPlatform: true,
1119 uncompressedUnbundled: true,
1120 },
1121 }
1122
1123 test := func(t *testing.T, bp string, want bool, unbundled bool) {
1124 t.Helper()
1125
1126 config := testConfig(nil)
1127 if unbundled {
1128 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
1129 }
1130
1131 ctx := testAppContext(config, bp, nil)
1132
1133 run(t, ctx, config)
1134
1135 foo := ctx.ModuleForTests("foo", "android_common")
1136 dex := foo.Rule("r8")
1137 uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
1138 aligned := foo.MaybeRule("zipalign").Rule != nil
1139
1140 if uncompressedInDexJar != want {
1141 t.Errorf("want uncompressed in dex %v, got %v", want, uncompressedInDexJar)
1142 }
1143
1144 if aligned != want {
1145 t.Errorf("want aligned %v, got %v", want, aligned)
1146 }
1147 }
1148
1149 for _, tt := range testCases {
1150 t.Run(tt.name, func(t *testing.T) {
1151 t.Run("platform", func(t *testing.T) {
1152 test(t, tt.bp, tt.uncompressedPlatform, false)
1153 })
1154 t.Run("unbundled", func(t *testing.T) {
1155 test(t, tt.bp, tt.uncompressedUnbundled, true)
1156 })
1157 })
1158 }
1159}
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -07001160*/
Jaewoong Jung33695b92019-04-15 09:48:31 -07001161
1162func TestAndroidAppImport(t *testing.T) {
1163 ctx := testJava(t, `
1164 android_app_import {
1165 name: "foo",
1166 apk: "prebuilts/apk/app.apk",
1167 certificate: "platform",
1168 dex_preopt: {
1169 enabled: true,
1170 },
1171 }
1172 `)
1173
1174 variant := ctx.ModuleForTests("foo", "android_common")
1175
1176 // Check dexpreopt outputs.
1177 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
1178 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
1179 t.Errorf("can't find dexpreopt outputs")
1180 }
1181
1182 // Check cert signing flag.
1183 signedApk := variant.Output("signed/foo.apk")
1184 signingFlag := signedApk.Args["certificates"]
1185 expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
1186 if expected != signingFlag {
1187 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
1188 }
1189}
1190
1191func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
1192 ctx := testJava(t, `
1193 android_app_import {
1194 name: "foo",
1195 apk: "prebuilts/apk/app.apk",
1196 certificate: "platform",
1197 dex_preopt: {
1198 enabled: false,
1199 },
1200 }
1201 `)
1202
1203 variant := ctx.ModuleForTests("foo", "android_common")
1204
1205 // Check dexpreopt outputs. They shouldn't exist.
1206 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule != nil ||
1207 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule != nil {
1208 t.Errorf("dexpreopt shouldn't have run.")
1209 }
1210}
1211
1212func TestAndroidAppImport_Presigned(t *testing.T) {
1213 ctx := testJava(t, `
1214 android_app_import {
1215 name: "foo",
1216 apk: "prebuilts/apk/app.apk",
1217 presigned: true,
1218 dex_preopt: {
1219 enabled: true,
1220 },
1221 }
1222 `)
1223
1224 variant := ctx.ModuleForTests("foo", "android_common")
1225
1226 // Check dexpreopt outputs.
1227 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
1228 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
1229 t.Errorf("can't find dexpreopt outputs")
1230 }
1231 // Make sure stripping wasn't done.
1232 stripRule := variant.Output("dexpreopt/foo.apk")
1233 if !strings.HasPrefix(stripRule.RuleParams.Command, "cp -f") {
1234 t.Errorf("unexpected, non-skipping strip command: %q", stripRule.RuleParams.Command)
1235 }
1236
1237 // Make sure signing was skipped and aligning was done instead.
1238 if variant.MaybeOutput("signed/foo.apk").Rule != nil {
1239 t.Errorf("signing rule shouldn't be included.")
1240 }
1241 if variant.MaybeOutput("zip-aligned/foo.apk").Rule == nil {
1242 t.Errorf("can't find aligning rule")
1243 }
1244}
Jaewoong Jung9c6f3142019-04-26 14:31:50 -07001245
Jaewoong Junga7d90022019-08-22 14:25:58 -07001246func TestAndroidAppImport_DefaultDevCert(t *testing.T) {
1247 ctx := testJava(t, `
1248 android_app_import {
1249 name: "foo",
1250 apk: "prebuilts/apk/app.apk",
1251 default_dev_cert: true,
1252 dex_preopt: {
1253 enabled: true,
1254 },
1255 }
1256 `)
1257
1258 variant := ctx.ModuleForTests("foo", "android_common")
1259
1260 // Check dexpreopt outputs.
1261 if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil ||
1262 variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil {
1263 t.Errorf("can't find dexpreopt outputs")
1264 }
1265
1266 // Check cert signing flag.
1267 signedApk := variant.Output("signed/foo.apk")
1268 signingFlag := signedApk.Args["certificates"]
1269 expected := "build/make/target/product/security/testkey.x509.pem build/make/target/product/security/testkey.pk8"
1270 if expected != signingFlag {
1271 t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
1272 }
1273}
1274
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -07001275/*
Jaewoong Jung9c6f3142019-04-26 14:31:50 -07001276func TestAndroidAppImport_DpiVariants(t *testing.T) {
1277 bp := `
1278 android_app_import {
1279 name: "foo",
1280 apk: "prebuilts/apk/app.apk",
1281 dpi_variants: {
1282 xhdpi: {
1283 apk: "prebuilts/apk/app_xhdpi.apk",
1284 },
1285 xxhdpi: {
1286 apk: "prebuilts/apk/app_xxhdpi.apk",
1287 },
1288 },
Jaewoong Junga7d90022019-08-22 14:25:58 -07001289 presigned: true,
Jaewoong Jung9c6f3142019-04-26 14:31:50 -07001290 dex_preopt: {
1291 enabled: true,
1292 },
1293 }
1294 `
1295 testCases := []struct {
1296 name string
1297 aaptPreferredConfig *string
1298 aaptPrebuiltDPI []string
1299 expected string
1300 }{
1301 {
1302 name: "no preferred",
1303 aaptPreferredConfig: nil,
1304 aaptPrebuiltDPI: []string{},
1305 expected: "prebuilts/apk/app.apk",
1306 },
1307 {
1308 name: "AAPTPreferredConfig matches",
1309 aaptPreferredConfig: proptools.StringPtr("xhdpi"),
Jaewoong Jung05d5b542019-06-11 12:25:34 -07001310 aaptPrebuiltDPI: []string{"xxhdpi", "ldpi"},
Jaewoong Jung9c6f3142019-04-26 14:31:50 -07001311 expected: "prebuilts/apk/app_xhdpi.apk",
1312 },
1313 {
1314 name: "AAPTPrebuiltDPI matches",
1315 aaptPreferredConfig: proptools.StringPtr("mdpi"),
1316 aaptPrebuiltDPI: []string{"xxhdpi", "xhdpi"},
1317 expected: "prebuilts/apk/app_xxhdpi.apk",
1318 },
1319 {
1320 name: "non-first AAPTPrebuiltDPI matches",
1321 aaptPreferredConfig: proptools.StringPtr("mdpi"),
1322 aaptPrebuiltDPI: []string{"ldpi", "xhdpi"},
1323 expected: "prebuilts/apk/app_xhdpi.apk",
1324 },
1325 {
1326 name: "no matches",
1327 aaptPreferredConfig: proptools.StringPtr("mdpi"),
1328 aaptPrebuiltDPI: []string{"ldpi", "xxxhdpi"},
1329 expected: "prebuilts/apk/app.apk",
1330 },
1331 }
1332
1333 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
1334 for _, test := range testCases {
1335 config := testConfig(nil)
1336 config.TestProductVariables.AAPTPreferredConfig = test.aaptPreferredConfig
1337 config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
1338 ctx := testAppContext(config, bp, nil)
1339
1340 run(t, ctx, config)
1341
1342 variant := ctx.ModuleForTests("foo", "android_common")
1343 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
1344 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
1345 if len(matches) != 2 {
1346 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
1347 }
1348 if test.expected != matches[1] {
1349 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
1350 }
1351 }
1352}
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -07001353*/
Jaewoong Jung9b008e42019-07-17 10:21:49 -07001354
1355func TestAndroidAppImport_Filename(t *testing.T) {
1356 config := testConfig(nil)
1357 ctx := testJava(t, `
1358 android_app_import {
1359 name: "foo",
1360 apk: "prebuilts/apk/app.apk",
1361 presigned: true,
1362 }
1363
1364 android_app_import {
1365 name: "bar",
1366 apk: "prebuilts/apk/app.apk",
1367 presigned: true,
1368 filename: "bar_sample.apk"
1369 }
1370 `)
1371
1372 testCases := []struct {
1373 name string
1374 expected string
1375 }{
1376 {
1377 name: "foo",
1378 expected: "foo.apk",
1379 },
1380 {
1381 name: "bar",
1382 expected: "bar_sample.apk",
1383 },
1384 }
1385
1386 for _, test := range testCases {
1387 variant := ctx.ModuleForTests(test.name, "android_common")
1388 if variant.MaybeOutput(test.expected).Rule == nil {
1389 t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
1390 }
1391
1392 a := variant.Module().(*AndroidAppImport)
1393 expectedValues := []string{test.expected}
1394 actualValues := android.AndroidMkEntriesForTest(
1395 t, config, "", a).EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
1396 if !reflect.DeepEqual(actualValues, expectedValues) {
1397 t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
1398 actualValues, expectedValues)
1399 }
1400 }
1401}
Jaewoong Jung9e0fbd52019-08-13 14:11:33 -07001402
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -07001403/*
Jaewoong Jung9e0fbd52019-08-13 14:11:33 -07001404func TestAndroidAppImport_ArchVariants(t *testing.T) {
1405 // The test config's target arch is ARM64.
1406 testCases := []struct {
1407 name string
1408 bp string
1409 expected string
1410 }{
1411 {
1412 name: "matching arch",
1413 bp: `
1414 android_app_import {
1415 name: "foo",
1416 apk: "prebuilts/apk/app.apk",
1417 arch: {
1418 arm64: {
1419 apk: "prebuilts/apk/app_arm64.apk",
1420 },
1421 },
Jaewoong Junga7d90022019-08-22 14:25:58 -07001422 presigned: true,
Jaewoong Jung9e0fbd52019-08-13 14:11:33 -07001423 dex_preopt: {
1424 enabled: true,
1425 },
1426 }
1427 `,
1428 expected: "prebuilts/apk/app_arm64.apk",
1429 },
1430 {
1431 name: "no matching arch",
1432 bp: `
1433 android_app_import {
1434 name: "foo",
1435 apk: "prebuilts/apk/app.apk",
1436 arch: {
1437 arm: {
1438 apk: "prebuilts/apk/app_arm.apk",
1439 },
1440 },
Jaewoong Junga7d90022019-08-22 14:25:58 -07001441 presigned: true,
Jaewoong Jung9e0fbd52019-08-13 14:11:33 -07001442 dex_preopt: {
1443 enabled: true,
1444 },
1445 }
1446 `,
1447 expected: "prebuilts/apk/app.apk",
1448 },
1449 }
1450
1451 jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
1452 for _, test := range testCases {
1453 ctx := testJava(t, test.bp)
1454
1455 variant := ctx.ModuleForTests("foo", "android_common")
1456 jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
1457 matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
1458 if len(matches) != 2 {
1459 t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
1460 }
1461 if test.expected != matches[1] {
1462 t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
1463 }
1464 }
1465}
Rashed Abdel-Tawab8fdfe7d2019-09-25 15:51:32 -07001466*/