blob: 7297926631ed19be63d8e2f43a281d68c2a8d94b [file] [log] [blame]
Paul Duffinb432df92021-03-22 22:09:42 +00001// 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 apex
16
17import (
Paul Duffinffa83752021-06-09 14:32:53 +010018 "fmt"
19 "strings"
Paul Duffinb432df92021-03-22 22:09:42 +000020 "testing"
21
22 "android/soong/android"
Paul Duffinb432df92021-03-22 22:09:42 +000023 "android/soong/java"
24 "github.com/google/blueprint"
Paul Duffin7487a7a2021-05-19 09:36:09 +010025 "github.com/google/blueprint/proptools"
Paul Duffinb432df92021-03-22 22:09:42 +000026)
27
28// Contains tests for platform_bootclasspath logic from java/platform_bootclasspath.go that requires
29// apexes.
30
31var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
32 java.PrepareForTestWithDexpreopt,
33 PrepareForTestWithApexBuildComponents,
34)
35
Paul Duffinffa83752021-06-09 14:32:53 +010036func TestPlatformBootclasspath_Fragments(t *testing.T) {
37 result := android.GroupFixturePreparers(
38 prepareForTestWithPlatformBootclasspath,
Paul Duffindc3f9562021-06-09 15:31:05 +010039 prepareForTestWithMyapex,
Paul Duffinffa83752021-06-09 14:32:53 +010040 java.PrepareForTestWithJavaSdkLibraryFiles,
41 java.FixtureWithLastReleaseApis("foo"),
Paul Duffindc3f9562021-06-09 15:31:05 +010042 java.FixtureConfigureBootJars("myapex:bar"),
Paul Duffinffa83752021-06-09 14:32:53 +010043 android.FixtureWithRootAndroidBp(`
44 platform_bootclasspath {
45 name: "platform-bootclasspath",
46 fragments: [
Paul Duffindc3f9562021-06-09 15:31:05 +010047 {
48 apex: "myapex",
49 module:"bar-fragment",
50 },
Paul Duffinffa83752021-06-09 14:32:53 +010051 ],
52 hidden_api: {
53 unsupported: [
54 "unsupported.txt",
55 ],
56 removed: [
57 "removed.txt",
58 ],
59 max_target_r_low_priority: [
60 "max-target-r-low-priority.txt",
61 ],
62 max_target_q: [
63 "max-target-q.txt",
64 ],
65 max_target_p: [
66 "max-target-p.txt",
67 ],
68 max_target_o_low_priority: [
69 "max-target-o-low-priority.txt",
70 ],
71 blocked: [
72 "blocked.txt",
73 ],
74 unsupported_packages: [
75 "unsupported-packages.txt",
76 ],
77 },
78 }
79
Paul Duffindc3f9562021-06-09 15:31:05 +010080 apex {
81 name: "myapex",
82 key: "myapex.key",
83 bootclasspath_fragments: [
84 "bar-fragment",
85 ],
86 updatable: false,
87 }
88
89 apex_key {
90 name: "myapex.key",
91 public_key: "testkey.avbpubkey",
92 private_key: "testkey.pem",
93 }
94
Paul Duffinffa83752021-06-09 14:32:53 +010095 bootclasspath_fragment {
96 name: "bar-fragment",
97 contents: ["bar"],
Paul Duffindc3f9562021-06-09 15:31:05 +010098 apex_available: ["myapex"],
Paul Duffinffa83752021-06-09 14:32:53 +010099 api: {
100 stub_libs: ["foo"],
101 },
102 hidden_api: {
103 unsupported: [
104 "bar-unsupported.txt",
105 ],
106 removed: [
107 "bar-removed.txt",
108 ],
109 max_target_r_low_priority: [
110 "bar-max-target-r-low-priority.txt",
111 ],
112 max_target_q: [
113 "bar-max-target-q.txt",
114 ],
115 max_target_p: [
116 "bar-max-target-p.txt",
117 ],
118 max_target_o_low_priority: [
119 "bar-max-target-o-low-priority.txt",
120 ],
121 blocked: [
122 "bar-blocked.txt",
123 ],
124 unsupported_packages: [
125 "bar-unsupported-packages.txt",
126 ],
127 },
128 }
129
130 java_library {
131 name: "bar",
Paul Duffindc3f9562021-06-09 15:31:05 +0100132 apex_available: ["myapex"],
Paul Duffinffa83752021-06-09 14:32:53 +0100133 srcs: ["a.java"],
134 system_modules: "none",
135 sdk_version: "none",
136 compile_dex: true,
Paul Duffindc3f9562021-06-09 15:31:05 +0100137 permitted_packages: ["bar"],
Paul Duffinffa83752021-06-09 14:32:53 +0100138 }
139
140 java_sdk_library {
141 name: "foo",
142 srcs: ["a.java"],
143 public: {
144 enabled: true,
145 },
146 compile_dex: true,
147 }
148 `),
149 ).RunTest(t)
150
151 pbcp := result.Module("platform-bootclasspath", "android_common")
152 info := result.ModuleProvider(pbcp, java.MonolithicHiddenAPIInfoProvider).(java.MonolithicHiddenAPIInfo)
153
154 for _, category := range java.HiddenAPIFlagFileCategories {
155 name := category.PropertyName
156 message := fmt.Sprintf("category %s", name)
157 filename := strings.ReplaceAll(name, "_", "-")
158 expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)}
159 android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category])
160 }
161
Paul Duffindc3f9562021-06-09 15:31:05 +0100162 android.AssertPathsRelativeToTopEquals(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/stub-flags.csv"}, info.StubFlagsPaths)
163 android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths)
164 android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/metadata.csv"}, info.MetadataPaths)
165 android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/index.csv"}, info.IndexPaths)
166 android.AssertPathsRelativeToTopEquals(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/all-flags.csv"}, info.AllFlagsPaths)
Paul Duffinffa83752021-06-09 14:32:53 +0100167}
168
Paul Duffinb432df92021-03-22 22:09:42 +0000169func TestPlatformBootclasspathDependencies(t *testing.T) {
170 result := android.GroupFixturePreparers(
171 prepareForTestWithPlatformBootclasspath,
172 prepareForTestWithArtApex,
173 prepareForTestWithMyapex,
174 // Configure some libraries in the art and framework boot images.
Paul Duffin60264a02021-04-12 20:02:36 +0100175 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo"),
176 java.FixtureConfigureUpdatableBootJars("myapex:bar"),
Paul Duffinb432df92021-03-22 22:09:42 +0000177 java.PrepareForTestWithJavaSdkLibraryFiles,
178 java.FixtureWithLastReleaseApis("foo"),
179 ).RunTestWithBp(t, `
180 apex {
181 name: "com.android.art",
182 key: "com.android.art.key",
183 bootclasspath_fragments: [
184 "art-bootclasspath-fragment",
185 ],
186 updatable: false,
187 }
188
189 apex_key {
190 name: "com.android.art.key",
191 public_key: "com.android.art.avbpubkey",
192 private_key: "com.android.art.pem",
193 }
194
195 bootclasspath_fragment {
196 name: "art-bootclasspath-fragment",
197 apex_available: [
198 "com.android.art",
199 ],
200 contents: [
201 "baz",
202 "quuz",
203 ],
204 }
205
206 java_library {
207 name: "baz",
208 apex_available: [
209 "com.android.art",
210 ],
211 srcs: ["b.java"],
212 installable: true,
213 }
214
215 // Add a java_import that is not preferred and so won't have an appropriate apex variant created
216 // for it to make sure that the platform_bootclasspath doesn't try and add a dependency onto it.
217 java_import {
218 name: "baz",
219 apex_available: [
220 "com.android.art",
221 ],
222 jars: ["b.jar"],
223 }
224
225 java_library {
226 name: "quuz",
227 apex_available: [
228 "com.android.art",
229 ],
230 srcs: ["b.java"],
231 installable: true,
232 }
233
234 apex {
235 name: "myapex",
236 key: "myapex.key",
237 java_libs: [
238 "bar",
239 ],
240 updatable: false,
241 }
242
243 apex_key {
244 name: "myapex.key",
245 public_key: "testkey.avbpubkey",
246 private_key: "testkey.pem",
247 }
248
249 java_sdk_library {
250 name: "foo",
251 srcs: ["b.java"],
252 }
253
254 java_library {
255 name: "bar",
256 srcs: ["b.java"],
257 installable: true,
258 apex_available: ["myapex"],
259 permitted_packages: ["bar"],
260 }
261
262 platform_bootclasspath {
263 name: "myplatform-bootclasspath",
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100264
265 fragments: [
266 {
267 apex: "com.android.art",
268 module: "art-bootclasspath-fragment",
269 },
270 ],
Paul Duffinb432df92021-03-22 22:09:42 +0000271 }
272`,
273 )
274
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100275 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
Paul Duffin74431d52021-04-21 14:10:42 +0100276 // The configured contents of BootJars.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100277 "com.android.art:baz",
278 "com.android.art:quuz",
279 "platform:foo",
Paul Duffin74431d52021-04-21 14:10:42 +0100280
281 // The configured contents of UpdatableBootJars.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100282 "myapex:bar",
283 })
284
285 java.CheckPlatformBootclasspathFragments(t, result, "myplatform-bootclasspath", []string{
286 `com.android.art:art-bootclasspath-fragment`,
287 })
288
Paul Duffinb432df92021-03-22 22:09:42 +0000289 // Make sure that the myplatform-bootclasspath has the correct dependencies.
290 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
Paul Duffin74431d52021-04-21 14:10:42 +0100291 // The following are stubs.
292 `platform:android_stubs_current`,
293 `platform:android_system_stubs_current`,
294 `platform:android_test_stubs_current`,
295 `platform:legacy.core.platform.api.stubs`,
296
297 // Needed for generating the boot image.
Paul Duffinb432df92021-03-22 22:09:42 +0000298 `platform:dex2oatd`,
Paul Duffin74431d52021-04-21 14:10:42 +0100299
300 // The configured contents of BootJars.
Paul Duffinb432df92021-03-22 22:09:42 +0000301 `com.android.art:baz`,
302 `com.android.art:quuz`,
303 `platform:foo`,
Paul Duffin74431d52021-04-21 14:10:42 +0100304
305 // The configured contents of UpdatableBootJars.
Paul Duffinb432df92021-03-22 22:09:42 +0000306 `myapex:bar`,
Paul Duffin74431d52021-04-21 14:10:42 +0100307
308 // The fragments.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100309 `com.android.art:art-bootclasspath-fragment`,
Paul Duffinb432df92021-03-22 22:09:42 +0000310 })
311}
312
Paul Duffin7487a7a2021-05-19 09:36:09 +0100313// TestPlatformBootclasspath_AlwaysUsePrebuiltSdks verifies that the build does not fail when
314// AlwaysUsePrebuiltSdk() returns true. The structure of the modules in this test matches what
315// currently exists in some places in the Android build but it is not the intended structure. It is
316// in fact an invalid structure that should cause build failures. However, fixing that structure
317// will take too long so in the meantime this tests the workarounds to avoid build breakages.
318//
319// The main issues with this structure are:
320// 1. There is no prebuilt_bootclasspath_fragment referencing the "foo" java_sdk_library_import.
321// 2. There is no prebuilt_apex/apex_set which makes the dex implementation jar available to the
322// prebuilt_bootclasspath_fragment and the "foo" java_sdk_library_import.
323//
324// Together these cause the following symptoms:
325// 1. The "foo" java_sdk_library_import does not have a dex implementation jar.
326// 2. The "foo" java_sdk_library_import does not have a myapex variant.
327//
328// TODO(b/179354495): Fix the structure in this test once the main Android build has been fixed.
329func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
330 result := android.GroupFixturePreparers(
331 prepareForTestWithPlatformBootclasspath,
332 prepareForTestWithMyapex,
333 // Configure two libraries, the first is a java_sdk_library whose prebuilt will be used because
334 // of AlwaysUsePrebuiltsSdk() but does not have an appropriate apex variant and does not provide
335 // a boot dex jar. The second is a normal library that is unaffected. The order matters because
336 // if the dependency on myapex:foo is filtered out because of either of those conditions then
337 // the dependencies resolved by the platform_bootclasspath will not match the configured list
338 // and so will fail the test.
339 java.FixtureConfigureUpdatableBootJars("myapex:foo", "myapex:bar"),
340 java.PrepareForTestWithJavaSdkLibraryFiles,
341 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
342 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
343 }),
344 java.FixtureWithPrebuiltApis(map[string][]string{
345 "current": {},
346 "30": {"foo"},
347 }),
348 ).RunTestWithBp(t, `
349 apex {
350 name: "myapex",
351 key: "myapex.key",
352 bootclasspath_fragments: [
353 "mybootclasspath-fragment",
354 ],
355 updatable: false,
356 }
357
358 apex_key {
359 name: "myapex.key",
360 public_key: "testkey.avbpubkey",
361 private_key: "testkey.pem",
362 }
363
364 java_library {
365 name: "bar",
366 srcs: ["b.java"],
367 installable: true,
368 apex_available: ["myapex"],
369 permitted_packages: ["bar"],
370 }
371
372 java_sdk_library {
373 name: "foo",
374 srcs: ["b.java"],
375 shared_library: false,
376 public: {
377 enabled: true,
378 },
379 apex_available: ["myapex"],
380 permitted_packages: ["foo"],
381 }
382
383 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred
384 // because AlwaysUsePrebuiltSdks() is true.
385 java_sdk_library_import {
386 name: "foo",
387 prefer: false,
388 shared_library: false,
389 public: {
390 jars: ["sdk_library/public/foo-stubs.jar"],
391 stub_srcs: ["sdk_library/public/foo_stub_sources"],
392 current_api: "sdk_library/public/foo.txt",
393 removed_api: "sdk_library/public/foo-removed.txt",
394 sdk_version: "current",
395 },
396 apex_available: ["myapex"],
397 }
398
399 // This always depends on the source foo module, its dependencies are not affected by the
400 // AlwaysUsePrebuiltSdks().
401 bootclasspath_fragment {
402 name: "mybootclasspath-fragment",
403 apex_available: [
404 "myapex",
405 ],
406 contents: [
407 "foo", "bar",
408 ],
409 }
410
411 platform_bootclasspath {
412 name: "myplatform-bootclasspath",
413 }
414`,
415 )
416
417 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
418 // The configured contents of BootJars.
419 "platform:prebuilt_foo", // Note: This is the platform not myapex variant.
420 "myapex:bar",
421 })
422
423 // Make sure that the myplatform-bootclasspath has the correct dependencies.
424 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
425 // The following are stubs.
426 "platform:prebuilt_sdk_public_current_android",
427 "platform:prebuilt_sdk_system_current_android",
428 "platform:prebuilt_sdk_test_current_android",
429
430 // Not a prebuilt as no prebuilt existed when it was added.
431 "platform:legacy.core.platform.api.stubs",
432
433 // Needed for generating the boot image.
434 `platform:dex2oatd`,
435
436 // The platform_bootclasspath intentionally adds dependencies on both source and prebuilt
437 // modules when available as it does not know which one will be preferred.
438 //
439 // The source module has an APEX variant but the prebuilt does not.
440 "myapex:foo",
441 "platform:prebuilt_foo",
442
443 // Only a source module exists.
444 "myapex:bar",
445 })
446}
447
Paul Duffinb432df92021-03-22 22:09:42 +0000448// CheckModuleDependencies checks the dependencies of the selected module against the expected list.
449//
450// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the
451// name of the apex, or platform is it is not part of an apex and <module> is the module name.
452func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
453 t.Helper()
454 module := ctx.ModuleForTests(name, variant).Module()
455 modules := []android.Module{}
456 ctx.VisitDirectDeps(module, func(m blueprint.Module) {
457 modules = append(modules, m.(android.Module))
458 })
459
460 pairs := java.ApexNamePairsFromModules(ctx, modules)
461 android.AssertDeepEquals(t, "module dependencies", expected, pairs)
462}