• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// 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 (
18	"testing"
19
20	"android/soong/android"
21)
22
23// Contains some simple tests for platform_bootclasspath.
24
25var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
26	PrepareForTestWithJavaDefaultModules,
27)
28
29func TestPlatformBootclasspath(t *testing.T) {
30	t.Parallel()
31	preparer := android.GroupFixturePreparers(
32		prepareForTestWithPlatformBootclasspath,
33		FixtureConfigureBootJars("platform:foo", "system_ext:bar"),
34		android.FixtureMergeMockFs(android.MockFS{
35			"api/current.txt": nil,
36			"api/removed.txt": nil,
37		}),
38		android.FixtureWithRootAndroidBp(`
39			platform_bootclasspath {
40				name: "platform-bootclasspath",
41			}
42
43			java_sdk_library {
44				name: "bar",
45				srcs: ["a.java"],
46				system_modules: "none",
47				sdk_version: "none",
48				compile_dex: true,
49				system_ext_specific: true,
50				unsafe_ignore_missing_latest_api: true,
51			}
52		`),
53	)
54
55	var addSourceBootclassPathModule = android.FixtureAddTextFile("source/Android.bp", `
56		java_library {
57			name: "foo",
58			host_supported: true, // verify that b/232106778 is fixed
59			srcs: ["a.java"],
60			system_modules: "none",
61			sdk_version: "none",
62			compile_dex: true,
63		}
64	`)
65
66	var addPrebuiltBootclassPathModule = android.FixtureAddTextFile("prebuilt/Android.bp", `
67		java_import {
68			name: "foo",
69			jars: ["a.jar"],
70			compile_dex: true,
71			prefer: false,
72		}
73	`)
74
75	var addPrebuiltPreferredBootclassPathModule = android.FixtureAddTextFile("prebuilt/Android.bp", `
76		java_import {
77			name: "foo",
78			jars: ["a.jar"],
79			compile_dex: true,
80			prefer: true,
81		}
82	`)
83
84	t.Run("missing", func(t *testing.T) {
85		t.Parallel()
86		preparer.
87			ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"platform-bootclasspath" depends on undefined module "foo"`)).
88			RunTest(t)
89	})
90
91	fooSourceSrc := "source/a.java"
92	barSrc := "a.java"
93
94	checkSrcJarInputs := func(t *testing.T, result *android.TestResult, name string, expected []string) {
95		t.Helper()
96		srcjar := result.ModuleForTests(t, name, "android_common").Output(name + "-transitive.srcjar")
97		android.AssertStringDoesContain(t, "srcjar arg", srcjar.Args["jarArgs"], "-srcjar")
98		android.AssertArrayString(t, "srcjar inputs", expected, srcjar.Implicits.Strings())
99	}
100	t.Run("source", func(t *testing.T) {
101		t.Parallel()
102		result := android.GroupFixturePreparers(
103			preparer,
104			addSourceBootclassPathModule,
105		).RunTest(t)
106
107		CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
108			"platform:foo",
109			"platform:bar",
110		})
111		checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
112			fooSourceSrc,
113			barSrc,
114		})
115	})
116
117	t.Run("prebuilt", func(t *testing.T) {
118		t.Parallel()
119		result := android.GroupFixturePreparers(
120			preparer,
121			addPrebuiltBootclassPathModule,
122		).RunTest(t)
123
124		CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
125			"platform:prebuilt_foo",
126			"platform:bar",
127		})
128		checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
129			// TODO(b/151360309): This should also have the srcs for prebuilt_foo
130			barSrc,
131		})
132	})
133
134	t.Run("source+prebuilt - source preferred", func(t *testing.T) {
135		t.Parallel()
136		result := android.GroupFixturePreparers(
137			preparer,
138			addSourceBootclassPathModule,
139			addPrebuiltBootclassPathModule,
140		).RunTest(t)
141
142		CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
143			"platform:foo",
144			"platform:bar",
145		})
146		checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
147			fooSourceSrc,
148			barSrc,
149		})
150	})
151
152	t.Run("source+prebuilt - prebuilt preferred", func(t *testing.T) {
153		t.Parallel()
154		result := android.GroupFixturePreparers(
155			preparer,
156			addSourceBootclassPathModule,
157			addPrebuiltPreferredBootclassPathModule,
158		).RunTest(t)
159
160		CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
161			"platform:prebuilt_foo",
162			"platform:bar",
163		})
164		checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
165			// TODO(b/151360309): This should also have the srcs for prebuilt_foo
166			barSrc,
167		})
168	})
169
170	t.Run("dex import", func(t *testing.T) {
171		t.Parallel()
172		result := android.GroupFixturePreparers(
173			preparer,
174			android.FixtureAddTextFile("deximport/Android.bp", `
175				dex_import {
176					name: "foo",
177					jars: ["a.jar"],
178				}
179			`),
180		).RunTest(t)
181
182		CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
183			"platform:prebuilt_foo",
184			"platform:bar",
185		})
186		checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
187			// TODO(b/151360309): This should also have the srcs for prebuilt_foo
188			barSrc,
189		})
190	})
191}
192
193func TestPlatformBootclasspathVariant(t *testing.T) {
194	t.Parallel()
195	result := android.GroupFixturePreparers(
196		prepareForTestWithPlatformBootclasspath,
197		android.FixtureWithRootAndroidBp(`
198			platform_bootclasspath {
199				name: "platform-bootclasspath",
200			}
201		`),
202	).RunTest(t)
203
204	variants := result.ModuleVariantsForTests("platform-bootclasspath")
205	android.AssertIntEquals(t, "expect 1 variant", 1, len(variants))
206}
207
208func TestPlatformBootclasspath_ClasspathFragmentPaths(t *testing.T) {
209	t.Parallel()
210	result := android.GroupFixturePreparers(
211		prepareForTestWithPlatformBootclasspath,
212		android.FixtureWithRootAndroidBp(`
213			platform_bootclasspath {
214				name: "platform-bootclasspath",
215			}
216		`),
217	).RunTest(t)
218
219	p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
220	android.AssertStringEquals(t, "output filepath", "bootclasspath.pb", p.ClasspathFragmentBase.outputFilepath.Base())
221	android.AssertPathRelativeToTopEquals(t, "install filepath", "out/target/product/test_device/system/etc/classpaths", p.ClasspathFragmentBase.installDirPath)
222}
223
224func TestPlatformBootclasspathModule_AndroidMkEntries(t *testing.T) {
225	t.Parallel()
226	preparer := android.GroupFixturePreparers(
227		prepareForTestWithPlatformBootclasspath,
228		android.FixtureWithRootAndroidBp(`
229			platform_bootclasspath {
230				name: "platform-bootclasspath",
231			}
232		`),
233	)
234
235	t.Run("AndroidMkEntries", func(t *testing.T) {
236		t.Parallel()
237		result := preparer.RunTest(t)
238
239		p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
240
241		entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)
242		android.AssertIntEquals(t, "AndroidMkEntries count", 2, len(entries))
243	})
244
245	t.Run("hiddenapi-flags-entry", func(t *testing.T) {
246		t.Parallel()
247		result := preparer.RunTest(t)
248
249		p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
250
251		entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)
252		got := entries[0].OutputFile
253		android.AssertBoolEquals(t, "valid output path", true, got.Valid())
254		android.AssertSame(t, "output filepath", p.hiddenAPIFlagsCSV, got.Path())
255	})
256
257	t.Run("classpath-fragment-entry", func(t *testing.T) {
258		t.Parallel()
259		result := preparer.RunTest(t)
260
261		want := map[string][]string{
262			"LOCAL_MODULE":                {"platform-bootclasspath"},
263			"LOCAL_MODULE_CLASS":          {"ETC"},
264			"LOCAL_INSTALLED_MODULE_STEM": {"bootclasspath.pb"},
265			// Output and Install paths are tested separately in TestPlatformBootclasspath_ClasspathFragmentPaths
266		}
267
268		p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
269
270		entries := android.AndroidMkEntriesForTest(t, result.TestContext, p)
271		got := entries[1]
272		for k, expectedValue := range want {
273			if value, ok := got.EntryMap[k]; ok {
274				android.AssertDeepEquals(t, k, expectedValue, value)
275			} else {
276				t.Errorf("No %s defined, saw %q", k, got.EntryMap)
277			}
278		}
279	})
280}
281
282func TestPlatformBootclasspath_Dist(t *testing.T) {
283	t.Parallel()
284	result := android.GroupFixturePreparers(
285		prepareForTestWithPlatformBootclasspath,
286		FixtureConfigureBootJars("platform:foo", "platform:bar"),
287		android.PrepareForTestWithAndroidMk,
288		android.FixtureWithRootAndroidBp(`
289			platform_bootclasspath {
290				name: "platform-bootclasspath",
291				dists: [
292					{
293						targets: ["droidcore"],
294						tag: "hiddenapi-flags.csv",
295					},
296				],
297			}
298
299			java_library {
300				name: "bar",
301				srcs: ["a.java"],
302				system_modules: "none",
303				sdk_version: "none",
304				compile_dex: true,
305			}
306
307			java_library {
308				name: "foo",
309				srcs: ["a.java"],
310				system_modules: "none",
311				sdk_version: "none",
312				compile_dex: true,
313			}
314		`),
315	).RunTest(t)
316
317	platformBootclasspath := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
318	entries := android.AndroidMkEntriesForTest(t, result.TestContext, platformBootclasspath)
319	goals := entries[0].GetDistForGoals(platformBootclasspath)
320	android.AssertStringEquals(t, "platform dist goals phony", ".PHONY: droidcore", goals[0])
321	android.AssertStringDoesContain(t, "platform dist goals meta check", goals[1], "$(if $(strip $(ALL_TARGETS.")
322	android.AssertStringDoesContain(t, "platform dist goals meta assign", goals[1], "),,$(eval ALL_TARGETS.")
323	android.AssertStringEquals(t, "platform dist goals call", "$(call dist-for-goals,droidcore,out/soong/hiddenapi/hiddenapi-flags.csv:hiddenapi-flags.csv)", android.StringRelativeToTop(result.Config, goals[2]))
324}
325
326func TestPlatformBootclasspath_HiddenAPIMonolithicFiles(t *testing.T) {
327	t.Parallel()
328	result := android.GroupFixturePreparers(
329		hiddenApiFixtureFactory,
330		PrepareForTestWithJavaSdkLibraryFiles,
331		FixtureWithLastReleaseApis("bar"),
332		FixtureConfigureBootJars("platform:foo", "platform:bar"),
333	).RunTestWithBp(t, `
334		java_library {
335			name: "foo",
336			srcs: ["a.java"],
337			compile_dex: true,
338
339			hiddenapi_additional_annotations: [
340				"foo-hiddenapi-annotations",
341			],
342		}
343
344		java_library {
345			name: "foo-hiddenapi-annotations",
346			srcs: ["a.java"],
347			compile_dex: true,
348		}
349
350		java_import {
351			name: "foo",
352			jars: ["a.jar"],
353			compile_dex: true,
354			prefer: false,
355		}
356
357		java_sdk_library {
358			name: "bar",
359			srcs: ["a.java"],
360			compile_dex: true,
361		}
362
363		platform_bootclasspath {
364			name: "myplatform-bootclasspath",
365		}
366	`)
367
368	// Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that
369	// creates the index.csv file.
370	platformBootclasspath := result.ModuleForTests(t, "myplatform-bootclasspath", "android_common")
371
372	var rule android.TestingBuildParams
373
374	// All the intermediate rules use the same inputs.
375	expectedIntermediateInputs := `
376		out/soong/.intermediates/bar.impl/android_common/javac/bar.jar
377		out/soong/.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar
378		out/soong/.intermediates/foo/android_common/javac/foo.jar
379	`
380
381	// Check flags output.
382	rule = platformBootclasspath.Output("hiddenapi-monolithic/annotation-flags-from-classes.csv")
383	CheckHiddenAPIRuleInputs(t, "intermediate flags", expectedIntermediateInputs, rule)
384
385	rule = platformBootclasspath.Output("out/soong/hiddenapi/hiddenapi-flags.csv")
386	CheckHiddenAPIRuleInputs(t, "monolithic flags", `
387		out/soong/.intermediates/myplatform-bootclasspath/android_common/hiddenapi-monolithic/annotation-flags-from-classes.csv
388		out/soong/hiddenapi/hiddenapi-stub-flags.txt
389	`, rule)
390
391	// Check metadata output.
392	rule = platformBootclasspath.Output("hiddenapi-monolithic/metadata-from-classes.csv")
393	CheckHiddenAPIRuleInputs(t, "intermediate metadata", expectedIntermediateInputs, rule)
394
395	rule = platformBootclasspath.Output("out/soong/hiddenapi/hiddenapi-unsupported.csv")
396	CheckHiddenAPIRuleInputs(t, "monolithic metadata", `
397		out/soong/.intermediates/myplatform-bootclasspath/android_common/hiddenapi-monolithic/metadata-from-classes.csv
398	`, rule)
399
400	// Check index output.
401	rule = platformBootclasspath.Output("hiddenapi-monolithic/index-from-classes.csv")
402	CheckHiddenAPIRuleInputs(t, "intermediate index", expectedIntermediateInputs, rule)
403
404	rule = platformBootclasspath.Output("out/soong/hiddenapi/hiddenapi-index.csv")
405	CheckHiddenAPIRuleInputs(t, "monolithic index", `
406		out/soong/.intermediates/myplatform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
407	`, rule)
408}
409