blob: 2216b111ca88c6d91673bda3cc41b51b464caa14 [file] [log] [blame]
Paul Duffinbb7f1ac2021-03-29 22:18:45 +01001// Copyright (C) 2021 The Android Open Source Project
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 (
Paul Duffin9b381ef2021-04-08 23:01:37 +010018 "fmt"
19 "strings"
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010020 "testing"
21
22 "android/soong/android"
23 "android/soong/dexpreopt"
24)
25
26// Contains some simple tests for platform_bootclasspath.
27
28var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
29 PrepareForTestWithJavaDefaultModules,
30 dexpreopt.PrepareForTestByEnablingDexpreopt,
31)
32
33func TestPlatformBootclasspath(t *testing.T) {
Paul Duffinb432df92021-03-22 22:09:42 +000034 preparer := android.GroupFixturePreparers(
35 prepareForTestWithPlatformBootclasspath,
Paul Duffin110b0ad2021-04-27 14:36:08 +010036 FixtureConfigureBootJars("platform:foo", "system_ext:bar"),
Paul Duffinb432df92021-03-22 22:09:42 +000037 android.FixtureWithRootAndroidBp(`
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010038 platform_bootclasspath {
39 name: "platform-bootclasspath",
40 }
Paul Duffinb432df92021-03-22 22:09:42 +000041
42 java_library {
43 name: "bar",
44 srcs: ["a.java"],
45 system_modules: "none",
46 sdk_version: "none",
47 compile_dex: true,
Paul Duffin110b0ad2021-04-27 14:36:08 +010048 system_ext_specific: true,
Paul Duffinb432df92021-03-22 22:09:42 +000049 }
50 `),
51 )
52
53 var addSourceBootclassPathModule = android.FixtureAddTextFile("source/Android.bp", `
54 java_library {
55 name: "foo",
56 srcs: ["a.java"],
57 system_modules: "none",
58 sdk_version: "none",
59 compile_dex: true,
60 }
61 `)
62
63 var addPrebuiltBootclassPathModule = android.FixtureAddTextFile("prebuilt/Android.bp", `
64 java_import {
65 name: "foo",
66 jars: ["a.jar"],
67 compile_dex: true,
68 prefer: false,
69 }
70 `)
71
72 var addPrebuiltPreferredBootclassPathModule = android.FixtureAddTextFile("prebuilt/Android.bp", `
73 java_import {
74 name: "foo",
75 jars: ["a.jar"],
76 compile_dex: true,
77 prefer: true,
78 }
79 `)
80
81 t.Run("missing", func(t *testing.T) {
82 preparer.
83 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"platform-bootclasspath" depends on undefined module "foo"`)).
84 RunTest(t)
85 })
86
87 t.Run("source", func(t *testing.T) {
88 result := android.GroupFixturePreparers(
89 preparer,
90 addSourceBootclassPathModule,
91 ).RunTest(t)
92
93 CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
94 "platform:foo",
95 "platform:bar",
96 })
97 })
98
99 t.Run("prebuilt", func(t *testing.T) {
100 result := android.GroupFixturePreparers(
101 preparer,
102 addPrebuiltBootclassPathModule,
103 ).RunTest(t)
104
105 CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
106 "platform:prebuilt_foo",
107 "platform:bar",
108 })
109 })
110
111 t.Run("source+prebuilt - source preferred", func(t *testing.T) {
112 result := android.GroupFixturePreparers(
113 preparer,
114 addSourceBootclassPathModule,
115 addPrebuiltBootclassPathModule,
116 ).RunTest(t)
117
118 CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
119 "platform:foo",
120 "platform:bar",
121 })
122 })
123
124 t.Run("source+prebuilt - prebuilt preferred", func(t *testing.T) {
125 result := android.GroupFixturePreparers(
126 preparer,
127 addSourceBootclassPathModule,
128 addPrebuiltPreferredBootclassPathModule,
129 ).RunTest(t)
130
131 CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
132 "platform:prebuilt_foo",
133 "platform:bar",
134 })
135 })
Paul Duffinbb7f1ac2021-03-29 22:18:45 +0100136}
Paul Duffin6a766452021-04-12 14:15:22 +0100137
Paul Duffin9b381ef2021-04-08 23:01:37 +0100138func TestPlatformBootclasspath_Fragments(t *testing.T) {
139 result := android.GroupFixturePreparers(
140 prepareForTestWithPlatformBootclasspath,
141 android.FixtureWithRootAndroidBp(`
142 platform_bootclasspath {
143 name: "platform-bootclasspath",
144 fragments: [
145 {module:"bar-fragment"},
146 ],
147 hidden_api: {
148 unsupported: [
149 "unsupported.txt",
150 ],
151 removed: [
152 "removed.txt",
153 ],
154 max_target_r_low_priority: [
155 "max-target-r-low-priority.txt",
156 ],
157 max_target_q: [
158 "max-target-q.txt",
159 ],
160 max_target_p: [
161 "max-target-p.txt",
162 ],
163 max_target_o_low_priority: [
164 "max-target-o-low-priority.txt",
165 ],
166 blocked: [
167 "blocked.txt",
168 ],
169 unsupported_packages: [
170 "unsupported-packages.txt",
171 ],
172 },
173 }
174
175 bootclasspath_fragment {
176 name: "bar-fragment",
177 contents: ["bar"],
178 hidden_api: {
179 unsupported: [
180 "bar-unsupported.txt",
181 ],
182 removed: [
183 "bar-removed.txt",
184 ],
185 max_target_r_low_priority: [
186 "bar-max-target-r-low-priority.txt",
187 ],
188 max_target_q: [
189 "bar-max-target-q.txt",
190 ],
191 max_target_p: [
192 "bar-max-target-p.txt",
193 ],
194 max_target_o_low_priority: [
195 "bar-max-target-o-low-priority.txt",
196 ],
197 blocked: [
198 "bar-blocked.txt",
199 ],
200 unsupported_packages: [
201 "bar-unsupported-packages.txt",
202 ],
203 },
204 }
205
206 java_library {
207 name: "bar",
208 srcs: ["a.java"],
209 system_modules: "none",
210 sdk_version: "none",
211 compile_dex: true,
212 }
213 `),
214 ).RunTest(t)
215
216 pbcp := result.Module("platform-bootclasspath", "android_common")
217 info := result.ModuleProvider(pbcp, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
218
219 for _, category := range hiddenAPIFlagFileCategories {
220 name := category.propertyName
221 message := fmt.Sprintf("category %s", name)
222 filename := strings.ReplaceAll(name, "_", "-")
223 expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)}
224 android.AssertPathsRelativeToTopEquals(t, message, expected, info.categoryToPaths[category])
225 }
226}
227
Artur Satayev97259dc2021-04-07 15:17:14 +0100228func TestPlatformBootclasspathVariant(t *testing.T) {
229 result := android.GroupFixturePreparers(
230 prepareForTestWithPlatformBootclasspath,
231 android.FixtureWithRootAndroidBp(`
232 platform_bootclasspath {
233 name: "platform-bootclasspath",
234 }
235 `),
236 ).RunTest(t)
237
238 variants := result.ModuleVariantsForTests("platform-bootclasspath")
239 android.AssertIntEquals(t, "expect 1 variant", 1, len(variants))
240}
241
242func TestPlatformBootclasspath_ClasspathFragmentPaths(t *testing.T) {
243 result := android.GroupFixturePreparers(
244 prepareForTestWithPlatformBootclasspath,
245 android.FixtureWithRootAndroidBp(`
246 platform_bootclasspath {
247 name: "platform-bootclasspath",
248 }
249 `),
250 ).RunTest(t)
251
252 p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
253 android.AssertStringEquals(t, "output filepath", p.Name()+".pb", p.ClasspathFragmentBase.outputFilepath.Base())
254 android.AssertPathRelativeToTopEquals(t, "install filepath", "out/soong/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath)
255}
256
257func TestPlatformBootclasspathModule_AndroidMkEntries(t *testing.T) {
258 preparer := android.GroupFixturePreparers(
259 prepareForTestWithPlatformBootclasspath,
260 android.FixtureWithRootAndroidBp(`
261 platform_bootclasspath {
262 name: "platform-bootclasspath",
263 }
264 `),
265 )
266
267 t.Run("AndroidMkEntries", func(t *testing.T) {
268 result := preparer.RunTest(t)
269
270 p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
271
272 entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)
273 android.AssertIntEquals(t, "AndroidMkEntries count", 2, len(entries))
274 })
275
276 t.Run("hiddenapi-flags-entry", func(t *testing.T) {
277 result := preparer.RunTest(t)
278
279 p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
280
281 entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)
282 got := entries[0].OutputFile
283 android.AssertBoolEquals(t, "valid output path", true, got.Valid())
284 android.AssertSame(t, "output filepath", p.hiddenAPIFlagsCSV, got.Path())
285 })
286
287 t.Run("classpath-fragment-entry", func(t *testing.T) {
288 result := preparer.RunTest(t)
289
290 want := map[string][]string{
291 "LOCAL_MODULE": {"platform-bootclasspath"},
292 "LOCAL_MODULE_CLASS": {"ETC"},
293 "LOCAL_INSTALLED_MODULE_STEM": {"platform-bootclasspath.pb"},
294 // Output and Install paths are tested separately in TestPlatformBootclasspath_ClasspathFragmentPaths
295 }
296
297 p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
298
299 entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)
300 got := entries[1]
301 for k, expectedValue := range want {
302 if value, ok := got.EntryMap[k]; ok {
303 android.AssertDeepEquals(t, k, expectedValue, value)
304 } else {
305 t.Errorf("No %s defined, saw %q", k, got.EntryMap)
306 }
307 }
308 })
309}
310
Paul Duffin6a766452021-04-12 14:15:22 +0100311func TestPlatformBootclasspath_Dist(t *testing.T) {
312 result := android.GroupFixturePreparers(
313 prepareForTestWithPlatformBootclasspath,
Paul Duffin60264a02021-04-12 20:02:36 +0100314 FixtureConfigureBootJars("platform:foo", "platform:bar"),
Paul Duffin6a766452021-04-12 14:15:22 +0100315 android.PrepareForTestWithAndroidMk,
316 android.FixtureWithRootAndroidBp(`
317 platform_bootclasspath {
318 name: "platform-bootclasspath",
319 dists: [
320 {
321 targets: ["droidcore"],
322 tag: "hiddenapi-flags.csv",
323 },
324 ],
325 }
326
327 java_library {
328 name: "bar",
329 srcs: ["a.java"],
330 system_modules: "none",
331 sdk_version: "none",
332 compile_dex: true,
333 }
334
335 java_library {
336 name: "foo",
337 srcs: ["a.java"],
338 system_modules: "none",
339 sdk_version: "none",
340 compile_dex: true,
341 }
342 `),
343 ).RunTest(t)
344
345 platformBootclasspath := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
346 entries := android.AndroidMkEntriesForTest(t, result.TestContext, platformBootclasspath)
347 goals := entries[0].GetDistForGoals(platformBootclasspath)
348 android.AssertStringEquals(t, "platform dist goals phony", ".PHONY: droidcore\n", goals[0])
349 android.AssertStringEquals(t, "platform dist goals call", "$(call dist-for-goals,droidcore,out/soong/hiddenapi/hiddenapi-flags.csv:hiddenapi-flags.csv)\n", android.StringRelativeToTop(result.Config, goals[1]))
350}
Paul Duffin00b2bfd2021-04-12 17:24:36 +0100351
Paul Duffin85dee5d2021-04-13 00:14:38 +0100352func TestPlatformBootclasspath_HiddenAPIMonolithicFiles(t *testing.T) {
Paul Duffin00b2bfd2021-04-12 17:24:36 +0100353 result := android.GroupFixturePreparers(
354 hiddenApiFixtureFactory,
355 PrepareForTestWithJavaSdkLibraryFiles,
356 FixtureWithLastReleaseApis("bar"),
357 FixtureConfigureBootJars("platform:foo", "platform:bar"),
358 ).RunTestWithBp(t, `
359 java_library {
360 name: "foo",
361 srcs: ["a.java"],
362 compile_dex: true,
363
364 hiddenapi_additional_annotations: [
365 "foo-hiddenapi-annotations",
366 ],
367 }
368
369 java_library {
370 name: "foo-hiddenapi-annotations",
371 srcs: ["a.java"],
372 compile_dex: true,
373 }
374
375 java_import {
376 name: "foo",
377 jars: ["a.jar"],
378 compile_dex: true,
379 prefer: false,
380 }
381
382 java_sdk_library {
383 name: "bar",
384 srcs: ["a.java"],
385 compile_dex: true,
386 }
387
388 platform_bootclasspath {
389 name: "myplatform-bootclasspath",
390 }
391 `)
392
393 platformBootclasspath := result.ModuleForTests("myplatform-bootclasspath", "android_common")
394 indexRule := platformBootclasspath.Rule("platform-bootclasspath-monolithic-hiddenapi-index")
395 CheckHiddenAPIRuleInputs(t, `
396.intermediates/bar/android_common/hiddenapi/index.csv
397.intermediates/foo/android_common/hiddenapi/index.csv
398`,
399 indexRule)
400
401 // Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that
402 // creates the index.csv file.
403 foo := result.ModuleForTests("foo", "android_common")
404 indexParams := foo.Output("hiddenapi/index.csv")
405 CheckHiddenAPIRuleInputs(t, `
406.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar
407.intermediates/foo/android_common/javac/foo.jar
408`, indexParams)
409}