blob: fb63820a8c72fd4059ffd25f26f3ed529e39a755 [file] [log] [blame]
Liz Kammer5ca3a622020-08-05 15:40:41 -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 java
16
17import (
Anton Hanssona2adc372020-07-03 15:31:32 +010018 "fmt"
Liz Kammer5ca3a622020-08-05 15:40:41 -070019 "strings"
20 "testing"
Anton Hanssona2adc372020-07-03 15:31:32 +010021
Paul Duffin01289a22021-02-04 17:49:33 +000022 "android/soong/android"
23
Anton Hanssona2adc372020-07-03 15:31:32 +010024 "github.com/google/blueprint/proptools"
Liz Kammer5ca3a622020-08-05 15:40:41 -070025)
26
Bill Peckhambae47492021-01-08 09:34:44 -080027func testConfigWithBootJars(bp string, bootJars []string, prebuiltHiddenApiDir *string) android.Config {
Liz Kammer5ca3a622020-08-05 15:40:41 -070028 config := testConfig(nil, bp, nil)
Paul Duffine10dfa42020-10-23 21:23:44 +010029 config.TestProductVariables.BootJars = android.CreateTestConfiguredJarList(bootJars)
Bill Peckhambae47492021-01-08 09:34:44 -080030 config.TestProductVariables.PrebuiltHiddenApiDir = prebuiltHiddenApiDir
Liz Kammer5ca3a622020-08-05 15:40:41 -070031 return config
32}
33
Colin Crossae8600b2020-10-29 17:09:13 -070034func testContextWithHiddenAPI(config android.Config) *android.TestContext {
35 ctx := testContext(config)
Paul Duffin01289a22021-02-04 17:49:33 +000036 RegisterHiddenApiSingletonComponents(ctx)
Liz Kammer5ca3a622020-08-05 15:40:41 -070037 return ctx
38}
39
Anton Hanssona2adc372020-07-03 15:31:32 +010040func testHiddenAPIWithConfig(t *testing.T, config android.Config) *android.TestContext {
Liz Kammer5ca3a622020-08-05 15:40:41 -070041 t.Helper()
42
Colin Crossae8600b2020-10-29 17:09:13 -070043 ctx := testContextWithHiddenAPI(config)
Liz Kammer5ca3a622020-08-05 15:40:41 -070044
45 run(t, ctx, config)
Anton Hanssona2adc372020-07-03 15:31:32 +010046 return ctx
47}
Liz Kammer5ca3a622020-08-05 15:40:41 -070048
Bill Peckhambae47492021-01-08 09:34:44 -080049func testHiddenAPIBootJars(t *testing.T, bp string, bootJars []string, prebuiltHiddenApiDir *string) (*android.TestContext, android.Config) {
50 config := testConfigWithBootJars(bp, bootJars, prebuiltHiddenApiDir)
Anton Hanssona2adc372020-07-03 15:31:32 +010051
52 return testHiddenAPIWithConfig(t, config), config
53}
54
55func testHiddenAPIUnbundled(t *testing.T, unbundled bool) (*android.TestContext, android.Config) {
56 config := testConfig(nil, ``, nil)
57 config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(unbundled)
58
59 return testHiddenAPIWithConfig(t, config), config
Liz Kammer5ca3a622020-08-05 15:40:41 -070060}
61
62func TestHiddenAPISingleton(t *testing.T) {
Anton Hanssona2adc372020-07-03 15:31:32 +010063 ctx, _ := testHiddenAPIBootJars(t, `
Liz Kammer5ca3a622020-08-05 15:40:41 -070064 java_library {
65 name: "foo",
66 srcs: ["a.java"],
67 compile_dex: true,
Paul Duffin01289a22021-02-04 17:49:33 +000068 }
Paul Duffin9c3ac962021-02-03 14:11:27 +000069 `, []string{"platform:foo"}, nil)
Liz Kammer5ca3a622020-08-05 15:40:41 -070070
71 hiddenAPI := ctx.SingletonForTests("hiddenapi")
72 hiddenapiRule := hiddenAPI.Rule("hiddenapi")
73 want := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar"
74 if !strings.Contains(hiddenapiRule.RuleParams.Command, want) {
75 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", want, hiddenapiRule.RuleParams.Command)
76 }
77}
78
Paul Duffin01289a22021-02-04 17:49:33 +000079func TestHiddenAPIIndexSingleton(t *testing.T) {
80 ctx, _ := testHiddenAPIBootJars(t, `
81 java_library {
82 name: "foo",
83 srcs: ["a.java"],
84 compile_dex: true,
Paul Duffin031d8692021-02-12 11:46:42 +000085
86 hiddenapi_additional_annotations: [
87 "foo-hiddenapi-annotations",
88 ],
Paul Duffin01289a22021-02-04 17:49:33 +000089 }
90
Paul Duffine7975ff2021-02-11 15:33:37 +000091 java_library {
Paul Duffin031d8692021-02-12 11:46:42 +000092 name: "foo-hiddenapi-annotations",
93 srcs: ["a.java"],
94 compile_dex: true,
95 }
96
Paul Duffin01289a22021-02-04 17:49:33 +000097 java_import {
98 name: "foo",
99 jars: ["a.jar"],
100 compile_dex: true,
101 prefer: false,
102 }
103
104 java_sdk_library {
105 name: "bar",
106 srcs: ["a.java"],
107 compile_dex: true,
108 }
109 `, []string{"platform:foo", "platform:bar"}, nil)
110
111 hiddenAPIIndex := ctx.SingletonForTests("hiddenapi_index")
112 indexRule := hiddenAPIIndex.Rule("singleton-merged-hiddenapi-index")
Paul Duffin4fd997b2021-02-03 20:06:33 +0000113 CheckHiddenAPIRuleInputs(t, `
Paul Duffin01289a22021-02-04 17:49:33 +0000114.intermediates/bar/android_common/hiddenapi/index.csv
115.intermediates/foo/android_common/hiddenapi/index.csv
Paul Duffin01289a22021-02-04 17:49:33 +0000116`,
117 indexRule)
Paul Duffin031d8692021-02-12 11:46:42 +0000118
119 // Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that
120 // creates the index.csv file.
121 foo := ctx.ModuleForTests("foo", "android_common")
122 indexParams := foo.Output("hiddenapi/index.csv")
123 CheckHiddenAPIRuleInputs(t, `
124.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar
125.intermediates/foo/android_common/javac/foo.jar
126`, indexParams)
Paul Duffin01289a22021-02-04 17:49:33 +0000127}
128
Paul Duffinec0fe172021-02-25 15:34:13 +0000129func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) {
130 config := testConfigWithBootJars(`
131 java_library {
132 name: "foo",
133 srcs: ["a.java"],
134 compile_dex: true,
135 }
136
137 java_import {
138 name: "foo",
139 jars: ["a.jar"],
140 prefer: true,
141 }
142 `, []string{"platform:foo"}, nil)
143
144 ctx := testContextWithHiddenAPI(config)
145
146 runWithErrors(t, ctx, config,
147 "hiddenapi has determined that the source module \"foo\" should be ignored as it has been"+
148 " replaced by the prebuilt module \"prebuilt_foo\" but unfortunately it does not provide a"+
149 " suitable boot dex jar")
150}
151
Liz Kammer5ca3a622020-08-05 15:40:41 -0700152func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
Anton Hanssona2adc372020-07-03 15:31:32 +0100153 ctx, _ := testHiddenAPIBootJars(t, `
Liz Kammer5ca3a622020-08-05 15:40:41 -0700154 java_import {
155 name: "foo",
156 jars: ["a.jar"],
157 compile_dex: true,
158 }
Paul Duffin9c3ac962021-02-03 14:11:27 +0000159 `, []string{"platform:foo"}, nil)
Liz Kammer5ca3a622020-08-05 15:40:41 -0700160
161 hiddenAPI := ctx.SingletonForTests("hiddenapi")
162 hiddenapiRule := hiddenAPI.Rule("hiddenapi")
Bill Peckhamff89ffa2020-12-23 16:13:04 -0800163 want := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar"
Liz Kammer5ca3a622020-08-05 15:40:41 -0700164 if !strings.Contains(hiddenapiRule.RuleParams.Command, want) {
165 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", want, hiddenapiRule.RuleParams.Command)
166 }
167}
168
169func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) {
Anton Hanssona2adc372020-07-03 15:31:32 +0100170 ctx, _ := testHiddenAPIBootJars(t, `
Liz Kammer5ca3a622020-08-05 15:40:41 -0700171 java_library {
172 name: "foo",
173 srcs: ["a.java"],
174 compile_dex: true,
Paul Duffin01289a22021-02-04 17:49:33 +0000175 }
Liz Kammer5ca3a622020-08-05 15:40:41 -0700176
177 java_import {
178 name: "foo",
179 jars: ["a.jar"],
180 compile_dex: true,
181 prefer: false,
Paul Duffin01289a22021-02-04 17:49:33 +0000182 }
Paul Duffin9c3ac962021-02-03 14:11:27 +0000183 `, []string{"platform:foo"}, nil)
Liz Kammer5ca3a622020-08-05 15:40:41 -0700184
185 hiddenAPI := ctx.SingletonForTests("hiddenapi")
186 hiddenapiRule := hiddenAPI.Rule("hiddenapi")
187 fromSourceJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar"
188 if !strings.Contains(hiddenapiRule.RuleParams.Command, fromSourceJarArg) {
189 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", fromSourceJarArg, hiddenapiRule.RuleParams.Command)
190 }
191
192 prebuiltJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/dex/foo.jar"
193 if strings.Contains(hiddenapiRule.RuleParams.Command, prebuiltJarArg) {
194 t.Errorf("Did not expect %s in hiddenapi command, but it was present: %s", prebuiltJarArg, hiddenapiRule.RuleParams.Command)
195 }
196}
197
198func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) {
Anton Hanssona2adc372020-07-03 15:31:32 +0100199 ctx, _ := testHiddenAPIBootJars(t, `
Liz Kammer5ca3a622020-08-05 15:40:41 -0700200 java_library {
201 name: "foo",
202 srcs: ["a.java"],
203 compile_dex: true,
Paul Duffin01289a22021-02-04 17:49:33 +0000204 }
Liz Kammer5ca3a622020-08-05 15:40:41 -0700205
206 java_import {
207 name: "foo",
208 jars: ["a.jar"],
209 compile_dex: true,
210 prefer: true,
Paul Duffin01289a22021-02-04 17:49:33 +0000211 }
Paul Duffin9c3ac962021-02-03 14:11:27 +0000212 `, []string{"platform:foo"}, nil)
Liz Kammer5ca3a622020-08-05 15:40:41 -0700213
214 hiddenAPI := ctx.SingletonForTests("hiddenapi")
215 hiddenapiRule := hiddenAPI.Rule("hiddenapi")
216 prebuiltJarArg := "--boot-dex=" + buildDir + "/.intermediates/prebuilt_foo/android_common/dex/foo.jar"
217 if !strings.Contains(hiddenapiRule.RuleParams.Command, prebuiltJarArg) {
218 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", prebuiltJarArg, hiddenapiRule.RuleParams.Command)
219 }
220
221 fromSourceJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar"
222 if strings.Contains(hiddenapiRule.RuleParams.Command, fromSourceJarArg) {
223 t.Errorf("Did not expect %s in hiddenapi command, but it was present: %s", fromSourceJarArg, hiddenapiRule.RuleParams.Command)
224 }
225}
Anton Hanssona2adc372020-07-03 15:31:32 +0100226
227func TestHiddenAPISingletonSdks(t *testing.T) {
228 testCases := []struct {
229 name string
230 unbundledBuild bool
231 publicStub string
232 systemStub string
233 testStub string
234 corePlatformStub string
235 }{
236 {
237 name: "testBundled",
238 unbundledBuild: false,
239 publicStub: "android_stubs_current",
240 systemStub: "android_system_stubs_current",
241 testStub: "android_test_stubs_current",
242 corePlatformStub: "legacy.core.platform.api.stubs",
243 }, {
244 name: "testUnbundled",
245 unbundledBuild: true,
246 publicStub: "sdk_public_current_android",
247 systemStub: "sdk_system_current_android",
248 testStub: "sdk_test_current_android",
249 corePlatformStub: "legacy.core.platform.api.stubs",
250 },
251 }
252 for _, tc := range testCases {
253 t.Run(tc.name, func(t *testing.T) {
254 ctx, _ := testHiddenAPIUnbundled(t, tc.unbundledBuild)
255
256 hiddenAPI := ctx.SingletonForTests("hiddenapi")
257 hiddenapiRule := hiddenAPI.Rule("hiddenapi")
258 wantPublicStubs := "--public-stub-classpath=" + generateSdkDexPath(tc.publicStub, tc.unbundledBuild)
259 if !strings.Contains(hiddenapiRule.RuleParams.Command, wantPublicStubs) {
260 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantPublicStubs, hiddenapiRule.RuleParams.Command)
261 }
262
263 wantSystemStubs := "--system-stub-classpath=" + generateSdkDexPath(tc.systemStub, tc.unbundledBuild)
264 if !strings.Contains(hiddenapiRule.RuleParams.Command, wantSystemStubs) {
265 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantSystemStubs, hiddenapiRule.RuleParams.Command)
266 }
267
268 wantTestStubs := "--test-stub-classpath=" + generateSdkDexPath(tc.testStub, tc.unbundledBuild)
269 if !strings.Contains(hiddenapiRule.RuleParams.Command, wantTestStubs) {
270 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantTestStubs, hiddenapiRule.RuleParams.Command)
271 }
272
273 wantCorePlatformStubs := "--core-platform-stub-classpath=" + generateDexPath(tc.corePlatformStub)
274 if !strings.Contains(hiddenapiRule.RuleParams.Command, wantCorePlatformStubs) {
275 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantCorePlatformStubs, hiddenapiRule.RuleParams.Command)
276 }
277 })
278 }
279}
280
281func generateDexedPath(subDir, dex, module string) string {
282 return fmt.Sprintf("%s/.intermediates/%s/android_common/%s/%s.jar", buildDir, subDir, dex, module)
283}
284
285func generateDexPath(module string) string {
286 return generateDexedPath(module, "dex", module)
287}
288
289func generateSdkDexPath(module string, unbundled bool) string {
290 if unbundled {
291 return generateDexedPath("prebuilts/sdk/"+module, "dex", module)
292 }
293 return generateDexPath(module)
294}
Bill Peckhambae47492021-01-08 09:34:44 -0800295
296func TestHiddenAPISingletonWithPrebuiltCsvFile(t *testing.T) {
297
298 // The idea behind this test is to ensure that when the build is
299 // confugured with a PrebuiltHiddenApiDir that the rules for the
300 // hiddenapi singleton copy the prebuilts to the typical output
301 // location, and then use that output location for the hiddenapi encode
302 // dex step.
303
304 // Where to find the prebuilt hiddenapi files:
305 prebuiltHiddenApiDir := "path/to/prebuilt/hiddenapi"
306
307 ctx, _ := testHiddenAPIBootJars(t, `
308 java_import {
309 name: "foo",
310 jars: ["a.jar"],
311 compile_dex: true,
312 }
Paul Duffin9c3ac962021-02-03 14:11:27 +0000313 `, []string{"platform:foo"}, &prebuiltHiddenApiDir)
Bill Peckhambae47492021-01-08 09:34:44 -0800314
315 expectedCpInput := prebuiltHiddenApiDir + "/hiddenapi-flags.csv"
316 expectedCpOutput := buildDir + "/hiddenapi/hiddenapi-flags.csv"
317 expectedFlagsCsv := buildDir + "/hiddenapi/hiddenapi-flags.csv"
318
319 foo := ctx.ModuleForTests("foo", "android_common")
320
321 hiddenAPI := ctx.SingletonForTests("hiddenapi")
322 cpRule := hiddenAPI.Rule("Cp")
323 actualCpInput := cpRule.BuildParams.Input
324 actualCpOutput := cpRule.BuildParams.Output
325 encodeDexRule := foo.Rule("hiddenAPIEncodeDex")
326 actualFlagsCsv := encodeDexRule.BuildParams.Args["flagsCsv"]
327
328 if actualCpInput.String() != expectedCpInput {
329 t.Errorf("Prebuilt hiddenapi cp rule input mismatch, actual: %s, expected: %s", actualCpInput, expectedCpInput)
330 }
331
332 if actualCpOutput.String() != expectedCpOutput {
333 t.Errorf("Prebuilt hiddenapi cp rule output mismatch, actual: %s, expected: %s", actualCpOutput, expectedCpOutput)
334 }
335
336 if actualFlagsCsv != expectedFlagsCsv {
337 t.Errorf("Prebuilt hiddenapi encode dex rule flags csv mismatch, actual: %s, expected: %s", actualFlagsCsv, expectedFlagsCsv)
338 }
339}