blob: 58f1b1d54622a88f81871ac1d68b3ec4ddcc7aec [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 checkRuleInputs(t *testing.T, expected string, hiddenAPIRule android.TestingBuildParams) {
80 actual := strings.TrimSpace(strings.Join(android.NormalizePathsForTesting(hiddenAPIRule.Implicits), "\n"))
81 expected = strings.TrimSpace(expected)
82 if actual != expected {
83 t.Errorf("Expected hiddenapi rule inputs:\n%s\nactual inputs:\n%s", expected, actual)
84 }
85}
86
87func TestHiddenAPIIndexSingleton(t *testing.T) {
88 ctx, _ := testHiddenAPIBootJars(t, `
89 java_library {
90 name: "foo",
91 srcs: ["a.java"],
92 compile_dex: true,
93 }
94
95 java_import {
96 name: "foo",
97 jars: ["a.jar"],
98 compile_dex: true,
99 prefer: false,
100 }
101
102 java_sdk_library {
103 name: "bar",
104 srcs: ["a.java"],
105 compile_dex: true,
106 }
107 `, []string{"platform:foo", "platform:bar"}, nil)
108
109 hiddenAPIIndex := ctx.SingletonForTests("hiddenapi_index")
110 indexRule := hiddenAPIIndex.Rule("singleton-merged-hiddenapi-index")
111 checkRuleInputs(t, `
112.intermediates/bar.impl/android_common/hiddenapi/index.csv
113.intermediates/bar/android_common/hiddenapi/index.csv
114.intermediates/foo/android_common/hiddenapi/index.csv
115.intermediates/prebuilt_foo/android_common/hiddenapi/index.csv
116`,
117 indexRule)
118}
119
Liz Kammer5ca3a622020-08-05 15:40:41 -0700120func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
Anton Hanssona2adc372020-07-03 15:31:32 +0100121 ctx, _ := testHiddenAPIBootJars(t, `
Liz Kammer5ca3a622020-08-05 15:40:41 -0700122 java_import {
123 name: "foo",
124 jars: ["a.jar"],
125 compile_dex: true,
126 }
Paul Duffin9c3ac962021-02-03 14:11:27 +0000127 `, []string{"platform:foo"}, nil)
Liz Kammer5ca3a622020-08-05 15:40:41 -0700128
129 hiddenAPI := ctx.SingletonForTests("hiddenapi")
130 hiddenapiRule := hiddenAPI.Rule("hiddenapi")
Bill Peckhamff89ffa2020-12-23 16:13:04 -0800131 want := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar"
Liz Kammer5ca3a622020-08-05 15:40:41 -0700132 if !strings.Contains(hiddenapiRule.RuleParams.Command, want) {
133 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", want, hiddenapiRule.RuleParams.Command)
134 }
135}
136
137func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) {
Anton Hanssona2adc372020-07-03 15:31:32 +0100138 ctx, _ := testHiddenAPIBootJars(t, `
Liz Kammer5ca3a622020-08-05 15:40:41 -0700139 java_library {
140 name: "foo",
141 srcs: ["a.java"],
142 compile_dex: true,
Paul Duffin01289a22021-02-04 17:49:33 +0000143 }
Liz Kammer5ca3a622020-08-05 15:40:41 -0700144
145 java_import {
146 name: "foo",
147 jars: ["a.jar"],
148 compile_dex: true,
149 prefer: false,
Paul Duffin01289a22021-02-04 17:49:33 +0000150 }
Paul Duffin9c3ac962021-02-03 14:11:27 +0000151 `, []string{"platform:foo"}, nil)
Liz Kammer5ca3a622020-08-05 15:40:41 -0700152
153 hiddenAPI := ctx.SingletonForTests("hiddenapi")
154 hiddenapiRule := hiddenAPI.Rule("hiddenapi")
155 fromSourceJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar"
156 if !strings.Contains(hiddenapiRule.RuleParams.Command, fromSourceJarArg) {
157 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", fromSourceJarArg, hiddenapiRule.RuleParams.Command)
158 }
159
160 prebuiltJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/dex/foo.jar"
161 if strings.Contains(hiddenapiRule.RuleParams.Command, prebuiltJarArg) {
162 t.Errorf("Did not expect %s in hiddenapi command, but it was present: %s", prebuiltJarArg, hiddenapiRule.RuleParams.Command)
163 }
164}
165
166func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) {
Anton Hanssona2adc372020-07-03 15:31:32 +0100167 ctx, _ := testHiddenAPIBootJars(t, `
Liz Kammer5ca3a622020-08-05 15:40:41 -0700168 java_library {
169 name: "foo",
170 srcs: ["a.java"],
171 compile_dex: true,
Paul Duffin01289a22021-02-04 17:49:33 +0000172 }
Liz Kammer5ca3a622020-08-05 15:40:41 -0700173
174 java_import {
175 name: "foo",
176 jars: ["a.jar"],
177 compile_dex: true,
178 prefer: true,
Paul Duffin01289a22021-02-04 17:49:33 +0000179 }
Paul Duffin9c3ac962021-02-03 14:11:27 +0000180 `, []string{"platform:foo"}, nil)
Liz Kammer5ca3a622020-08-05 15:40:41 -0700181
182 hiddenAPI := ctx.SingletonForTests("hiddenapi")
183 hiddenapiRule := hiddenAPI.Rule("hiddenapi")
184 prebuiltJarArg := "--boot-dex=" + buildDir + "/.intermediates/prebuilt_foo/android_common/dex/foo.jar"
185 if !strings.Contains(hiddenapiRule.RuleParams.Command, prebuiltJarArg) {
186 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", prebuiltJarArg, hiddenapiRule.RuleParams.Command)
187 }
188
189 fromSourceJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar"
190 if strings.Contains(hiddenapiRule.RuleParams.Command, fromSourceJarArg) {
191 t.Errorf("Did not expect %s in hiddenapi command, but it was present: %s", fromSourceJarArg, hiddenapiRule.RuleParams.Command)
192 }
193}
Anton Hanssona2adc372020-07-03 15:31:32 +0100194
195func TestHiddenAPISingletonSdks(t *testing.T) {
196 testCases := []struct {
197 name string
198 unbundledBuild bool
199 publicStub string
200 systemStub string
201 testStub string
202 corePlatformStub string
203 }{
204 {
205 name: "testBundled",
206 unbundledBuild: false,
207 publicStub: "android_stubs_current",
208 systemStub: "android_system_stubs_current",
209 testStub: "android_test_stubs_current",
210 corePlatformStub: "legacy.core.platform.api.stubs",
211 }, {
212 name: "testUnbundled",
213 unbundledBuild: true,
214 publicStub: "sdk_public_current_android",
215 systemStub: "sdk_system_current_android",
216 testStub: "sdk_test_current_android",
217 corePlatformStub: "legacy.core.platform.api.stubs",
218 },
219 }
220 for _, tc := range testCases {
221 t.Run(tc.name, func(t *testing.T) {
222 ctx, _ := testHiddenAPIUnbundled(t, tc.unbundledBuild)
223
224 hiddenAPI := ctx.SingletonForTests("hiddenapi")
225 hiddenapiRule := hiddenAPI.Rule("hiddenapi")
226 wantPublicStubs := "--public-stub-classpath=" + generateSdkDexPath(tc.publicStub, tc.unbundledBuild)
227 if !strings.Contains(hiddenapiRule.RuleParams.Command, wantPublicStubs) {
228 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantPublicStubs, hiddenapiRule.RuleParams.Command)
229 }
230
231 wantSystemStubs := "--system-stub-classpath=" + generateSdkDexPath(tc.systemStub, tc.unbundledBuild)
232 if !strings.Contains(hiddenapiRule.RuleParams.Command, wantSystemStubs) {
233 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantSystemStubs, hiddenapiRule.RuleParams.Command)
234 }
235
236 wantTestStubs := "--test-stub-classpath=" + generateSdkDexPath(tc.testStub, tc.unbundledBuild)
237 if !strings.Contains(hiddenapiRule.RuleParams.Command, wantTestStubs) {
238 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantTestStubs, hiddenapiRule.RuleParams.Command)
239 }
240
241 wantCorePlatformStubs := "--core-platform-stub-classpath=" + generateDexPath(tc.corePlatformStub)
242 if !strings.Contains(hiddenapiRule.RuleParams.Command, wantCorePlatformStubs) {
243 t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", wantCorePlatformStubs, hiddenapiRule.RuleParams.Command)
244 }
245 })
246 }
247}
248
249func generateDexedPath(subDir, dex, module string) string {
250 return fmt.Sprintf("%s/.intermediates/%s/android_common/%s/%s.jar", buildDir, subDir, dex, module)
251}
252
253func generateDexPath(module string) string {
254 return generateDexedPath(module, "dex", module)
255}
256
257func generateSdkDexPath(module string, unbundled bool) string {
258 if unbundled {
259 return generateDexedPath("prebuilts/sdk/"+module, "dex", module)
260 }
261 return generateDexPath(module)
262}
Bill Peckhambae47492021-01-08 09:34:44 -0800263
264func TestHiddenAPISingletonWithPrebuiltCsvFile(t *testing.T) {
265
266 // The idea behind this test is to ensure that when the build is
267 // confugured with a PrebuiltHiddenApiDir that the rules for the
268 // hiddenapi singleton copy the prebuilts to the typical output
269 // location, and then use that output location for the hiddenapi encode
270 // dex step.
271
272 // Where to find the prebuilt hiddenapi files:
273 prebuiltHiddenApiDir := "path/to/prebuilt/hiddenapi"
274
275 ctx, _ := testHiddenAPIBootJars(t, `
276 java_import {
277 name: "foo",
278 jars: ["a.jar"],
279 compile_dex: true,
280 }
Paul Duffin9c3ac962021-02-03 14:11:27 +0000281 `, []string{"platform:foo"}, &prebuiltHiddenApiDir)
Bill Peckhambae47492021-01-08 09:34:44 -0800282
283 expectedCpInput := prebuiltHiddenApiDir + "/hiddenapi-flags.csv"
284 expectedCpOutput := buildDir + "/hiddenapi/hiddenapi-flags.csv"
285 expectedFlagsCsv := buildDir + "/hiddenapi/hiddenapi-flags.csv"
286
287 foo := ctx.ModuleForTests("foo", "android_common")
288
289 hiddenAPI := ctx.SingletonForTests("hiddenapi")
290 cpRule := hiddenAPI.Rule("Cp")
291 actualCpInput := cpRule.BuildParams.Input
292 actualCpOutput := cpRule.BuildParams.Output
293 encodeDexRule := foo.Rule("hiddenAPIEncodeDex")
294 actualFlagsCsv := encodeDexRule.BuildParams.Args["flagsCsv"]
295
296 if actualCpInput.String() != expectedCpInput {
297 t.Errorf("Prebuilt hiddenapi cp rule input mismatch, actual: %s, expected: %s", actualCpInput, expectedCpInput)
298 }
299
300 if actualCpOutput.String() != expectedCpOutput {
301 t.Errorf("Prebuilt hiddenapi cp rule output mismatch, actual: %s, expected: %s", actualCpOutput, expectedCpOutput)
302 }
303
304 if actualFlagsCsv != expectedFlagsCsv {
305 t.Errorf("Prebuilt hiddenapi encode dex rule flags csv mismatch, actual: %s, expected: %s", actualFlagsCsv, expectedFlagsCsv)
306 }
307}