• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 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 (
18	"fmt"
19	"reflect"
20	"regexp"
21	"sort"
22	"strings"
23	"testing"
24
25	"android/soong/android"
26	"android/soong/cc"
27	"android/soong/dexpreopt"
28
29	"github.com/google/blueprint"
30)
31
32const defaultJavaDir = "default/java"
33
34// Test fixture preparer that will register most java build components.
35//
36// Singletons and mutators should only be added here if they are needed for a majority of java
37// module types, otherwise they should be added under a separate preparer to allow them to be
38// selected only when needed to reduce test execution time.
39//
40// Module types do not have much of an overhead unless they are used so this should include as many
41// module types as possible. The exceptions are those module types that require mutators and/or
42// singletons in order to function in which case they should be kept together in a separate
43// preparer.
44var PrepareForTestWithJavaBuildComponents = android.GroupFixturePreparers(
45	// Make sure that mutators and module types, e.g. prebuilt mutators available.
46	android.PrepareForTestWithAndroidBuildComponents,
47	// Make java build components available to the test.
48	android.FixtureRegisterWithContext(registerRequiredBuildComponentsForTest),
49	android.FixtureRegisterWithContext(registerJavaPluginBuildComponents),
50	// Additional files needed in tests that disallow non-existent source files.
51	// This includes files that are needed by all, or at least most, instances of a java module type.
52	android.MockFS{
53		// Needed for linter used by java_library.
54		"build/soong/java/lint_defaults.txt": nil,
55		// Needed for apps that do not provide their own.
56		"build/make/target/product/security": nil,
57		// Required to generate Java used-by API coverage
58		"build/soong/scripts/gen_java_usedby_apex.sh": nil,
59	}.AddToFixture(),
60)
61
62// Test fixture preparer that will define all default java modules except the
63// fake_tool_binary for dex2oatd.
64var PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd = android.GroupFixturePreparers(
65	// Make sure that all the module types used in the defaults are registered.
66	PrepareForTestWithJavaBuildComponents,
67	// Additional files needed when test disallows non-existent source.
68	android.MockFS{
69		// Needed for framework-res
70		defaultJavaDir + "/AndroidManifest.xml": nil,
71		// Needed for framework
72		defaultJavaDir + "/framework/aidl": nil,
73		// Needed for various deps defined in GatherRequiredDepsForTest()
74		defaultJavaDir + "/a.java": nil,
75
76		// Needed for R8 rules on apps
77		"build/make/core/proguard.flags":             nil,
78		"build/make/core/proguard_basic_keeps.flags": nil,
79	}.AddToFixture(),
80	// The java default module definitions.
81	android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", gatherRequiredDepsForTest()),
82	// Add dexpreopt compat libs (android.test.base, etc.) and a fake dex2oatd module.
83	dexpreopt.PrepareForTestWithDexpreoptCompatLibs,
84)
85
86// Test fixture preparer that will define default java modules, e.g. standard prebuilt modules.
87var PrepareForTestWithJavaDefaultModules = android.GroupFixturePreparers(
88	PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd,
89	dexpreopt.PrepareForTestWithFakeDex2oatd,
90)
91
92// Provides everything needed by dexpreopt.
93var PrepareForTestWithDexpreopt = android.GroupFixturePreparers(
94	PrepareForTestWithJavaDefaultModules,
95	dexpreopt.PrepareForTestByEnablingDexpreopt,
96)
97
98var PrepareForTestWithOverlayBuildComponents = android.FixtureRegisterWithContext(registerOverlayBuildComponents)
99
100// Prepare a fixture to use all java module types, mutators and singletons fully.
101//
102// This should only be used by tests that want to run with as much of the build enabled as possible.
103var PrepareForIntegrationTestWithJava = android.GroupFixturePreparers(
104	cc.PrepareForIntegrationTestWithCc,
105	PrepareForTestWithJavaDefaultModules,
106)
107
108// Prepare a fixture with the standard files required by a java_sdk_library module.
109var PrepareForTestWithJavaSdkLibraryFiles = android.FixtureMergeMockFs(android.MockFS{
110	"api/current.txt":               nil,
111	"api/removed.txt":               nil,
112	"api/system-current.txt":        nil,
113	"api/system-removed.txt":        nil,
114	"api/test-current.txt":          nil,
115	"api/test-removed.txt":          nil,
116	"api/module-lib-current.txt":    nil,
117	"api/module-lib-removed.txt":    nil,
118	"api/system-server-current.txt": nil,
119	"api/system-server-removed.txt": nil,
120})
121
122// FixtureWithLastReleaseApis creates a preparer that creates prebuilt versions of the specified
123// modules for the `last` API release. By `last` it just means last in the list of supplied versions
124// and as this only provides one version it can be any value.
125//
126// This uses FixtureWithPrebuiltApis under the covers so the limitations of that apply to this.
127func FixtureWithLastReleaseApis(moduleNames ...string) android.FixturePreparer {
128	return FixtureWithPrebuiltApis(map[string][]string{
129		"30": moduleNames,
130	})
131}
132
133// PrepareForTestWithPrebuiltsOfCurrentApi is a preparer that creates prebuilt versions of the
134// standard modules for the current version.
135//
136// This uses FixtureWithPrebuiltApis under the covers so the limitations of that apply to this.
137var PrepareForTestWithPrebuiltsOfCurrentApi = FixtureWithPrebuiltApis(map[string][]string{
138	"current": {},
139	// Can't have current on its own as it adds a prebuilt_apis module but doesn't add any
140	// .txt files which causes the prebuilt_apis module to fail.
141	"30": {},
142})
143
144// FixtureWithPrebuiltApis creates a preparer that will define prebuilt api modules for the
145// specified releases and modules.
146//
147// The supplied map keys are the releases, e.g. current, 29, 30, etc. The values are a list of
148// modules for that release. Due to limitations in the prebuilt_apis module which this preparer
149// uses the set of releases must include at least one numbered release, i.e. it cannot just include
150// "current".
151//
152// This defines a file in the mock file system in a predefined location (prebuilts/sdk/Android.bp)
153// and so only one instance of this can be used in each fixture.
154func FixtureWithPrebuiltApis(release2Modules map[string][]string) android.FixturePreparer {
155	return FixtureWithPrebuiltApisAndExtensions(release2Modules, nil)
156}
157
158func FixtureWithPrebuiltApisAndExtensions(apiLevel2Modules map[string][]string, extensionLevel2Modules map[string][]string) android.FixturePreparer {
159	mockFS := android.MockFS{}
160	path := "prebuilts/sdk/Android.bp"
161
162	bp := fmt.Sprintf(`
163			prebuilt_apis {
164				name: "sdk",
165				api_dirs: ["%s"],
166				extensions_dir: "extensions",
167				imports_sdk_version: "none",
168				imports_compile_dex: true,
169			}
170		`, strings.Join(android.SortedStringKeys(apiLevel2Modules), `", "`))
171
172	for release, modules := range apiLevel2Modules {
173		mockFS.Merge(prebuiltApisFilesForModules([]string{release}, modules))
174	}
175	if extensionLevel2Modules != nil {
176		for release, modules := range extensionLevel2Modules {
177			mockFS.Merge(prebuiltExtensionApiFiles([]string{release}, modules))
178		}
179	}
180	return android.GroupFixturePreparers(
181		android.FixtureAddTextFile(path, bp),
182		android.FixtureMergeMockFs(mockFS),
183	)
184}
185
186func prebuiltApisFilesForModules(apiLevels []string, modules []string) map[string][]byte {
187	libs := append([]string{"android"}, modules...)
188
189	fs := make(map[string][]byte)
190	for _, level := range apiLevels {
191		apiLevel := android.ApiLevelForTest(level)
192		for _, sdkKind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkModule, android.SdkSystemServer, android.SdkTest} {
193			// A core-for-system-modules file must only be created for the sdk kind that supports it.
194			if sdkKind == systemModuleKind(sdkKind, apiLevel) {
195				fs[fmt.Sprintf("prebuilts/sdk/%s/%s/core-for-system-modules.jar", level, sdkKind)] = nil
196			}
197
198			for _, lib := range libs {
199				// Create a jar file for every library.
200				fs[fmt.Sprintf("prebuilts/sdk/%s/%s/%s.jar", level, sdkKind, lib)] = nil
201
202				// No finalized API files for "current"
203				if level != "current" {
204					fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s.txt", level, sdkKind, lib)] = nil
205					fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s-removed.txt", level, sdkKind, lib)] = nil
206				}
207			}
208		}
209		if level == "current" {
210			fs["prebuilts/sdk/current/core/android.jar"] = nil
211		}
212		fs[fmt.Sprintf("prebuilts/sdk/%s/public/framework.aidl", level)] = nil
213	}
214	return fs
215}
216
217func prebuiltExtensionApiFiles(extensionLevels []string, modules []string) map[string][]byte {
218	fs := make(map[string][]byte)
219	for _, level := range extensionLevels {
220		for _, sdkKind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkModule, android.SdkSystemServer} {
221			for _, lib := range modules {
222				fs[fmt.Sprintf("prebuilts/sdk/extensions/%s/%s/api/%s.txt", level, sdkKind, lib)] = nil
223				fs[fmt.Sprintf("prebuilts/sdk/extensions/%s/%s/api/%s-removed.txt", level, sdkKind, lib)] = nil
224			}
225		}
226	}
227	return fs
228}
229
230// FixtureConfigureBootJars configures the boot jars in both the dexpreopt.GlobalConfig and
231// Config.productVariables structs. As a side effect that enables dexpreopt.
232func FixtureConfigureBootJars(bootJars ...string) android.FixturePreparer {
233	artBootJars := []string{}
234	for _, j := range bootJars {
235		artApex := false
236		for _, artApexName := range artApexNames {
237			if strings.HasPrefix(j, artApexName+":") {
238				artApex = true
239				break
240			}
241		}
242		if artApex {
243			artBootJars = append(artBootJars, j)
244		}
245	}
246	return android.GroupFixturePreparers(
247		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
248			variables.BootJars = android.CreateTestConfiguredJarList(bootJars)
249		}),
250		dexpreopt.FixtureSetBootJars(bootJars...),
251		dexpreopt.FixtureSetArtBootJars(artBootJars...),
252
253		// Add a fake dex2oatd module.
254		dexpreopt.PrepareForTestWithFakeDex2oatd,
255	)
256}
257
258// FixtureConfigureApexBootJars configures the apex boot jars in both the
259// dexpreopt.GlobalConfig and Config.productVariables structs. As a side effect that enables
260// dexpreopt.
261func FixtureConfigureApexBootJars(bootJars ...string) android.FixturePreparer {
262	return android.GroupFixturePreparers(
263		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
264			variables.ApexBootJars = android.CreateTestConfiguredJarList(bootJars)
265		}),
266		dexpreopt.FixtureSetApexBootJars(bootJars...),
267
268		// Add a fake dex2oatd module.
269		dexpreopt.PrepareForTestWithFakeDex2oatd,
270	)
271}
272
273// FixtureUseLegacyCorePlatformApi prepares the fixture by setting the exception list of those
274// modules that are allowed to use the legacy core platform API to be the ones supplied.
275func FixtureUseLegacyCorePlatformApi(moduleNames ...string) android.FixturePreparer {
276	lookup := make(map[string]struct{})
277	for _, moduleName := range moduleNames {
278		lookup[moduleName] = struct{}{}
279	}
280	return android.FixtureModifyConfig(func(config android.Config) {
281		// Try and set the legacyCorePlatformApiLookup in the config, the returned value will be the
282		// actual value that is set.
283		cached := config.Once(legacyCorePlatformApiLookupKey, func() interface{} {
284			return lookup
285		})
286		// Make sure that the cached value is the one we need.
287		if !reflect.DeepEqual(cached, lookup) {
288			panic(fmt.Errorf("attempting to set legacyCorePlatformApiLookupKey to %q but it has already been set to %q", lookup, cached))
289		}
290	})
291}
292
293// registerRequiredBuildComponentsForTest registers the build components used by
294// PrepareForTestWithJavaDefaultModules.
295//
296// As functionality is moved out of here into separate FixturePreparer instances they should also
297// be moved into GatherRequiredDepsForTest for use by tests that have not yet switched to use test
298// fixtures.
299func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
300	RegisterAARBuildComponents(ctx)
301	RegisterAppBuildComponents(ctx)
302	RegisterAppImportBuildComponents(ctx)
303	RegisterAppSetBuildComponents(ctx)
304	registerBootclasspathBuildComponents(ctx)
305	registerBootclasspathFragmentBuildComponents(ctx)
306	RegisterDexpreoptBootJarsComponents(ctx)
307	RegisterDocsBuildComponents(ctx)
308	RegisterGenRuleBuildComponents(ctx)
309	registerJavaBuildComponents(ctx)
310	registerPlatformBootclasspathBuildComponents(ctx)
311	RegisterPrebuiltApisBuildComponents(ctx)
312	RegisterRuntimeResourceOverlayBuildComponents(ctx)
313	RegisterSdkLibraryBuildComponents(ctx)
314	RegisterStubsBuildComponents(ctx)
315	RegisterSystemModulesBuildComponents(ctx)
316	registerSystemserverClasspathBuildComponents(ctx)
317	registerLintBuildComponents(ctx)
318}
319
320// gatherRequiredDepsForTest gathers the module definitions used by
321// PrepareForTestWithJavaDefaultModules.
322//
323// As functionality is moved out of here into separate FixturePreparer instances they should also
324// be moved into GatherRequiredDepsForTest for use by tests that have not yet switched to use test
325// fixtures.
326func gatherRequiredDepsForTest() string {
327	var bp string
328
329	extraModules := []string{
330		"core-lambda-stubs",
331		"ext",
332		"android_stubs_current",
333		"android_system_stubs_current",
334		"android_test_stubs_current",
335		"android_module_lib_stubs_current",
336		"android_system_server_stubs_current",
337		"core.current.stubs",
338		"legacy.core.platform.api.stubs",
339		"stable.core.platform.api.stubs",
340		"kotlin-stdlib",
341		"kotlin-stdlib-jdk7",
342		"kotlin-stdlib-jdk8",
343		"kotlin-annotations",
344		"stub-annotations",
345	}
346
347	for _, extra := range extraModules {
348		bp += fmt.Sprintf(`
349			java_library {
350				name: "%s",
351				srcs: ["a.java"],
352				sdk_version: "none",
353				system_modules: "stable-core-platform-api-stubs-system-modules",
354				compile_dex: true,
355			}
356		`, extra)
357	}
358
359	bp += `
360		java_library {
361			name: "framework",
362			srcs: ["a.java"],
363			sdk_version: "none",
364			system_modules: "stable-core-platform-api-stubs-system-modules",
365			aidl: {
366				export_include_dirs: ["framework/aidl"],
367			},
368		}
369
370		android_app {
371			name: "framework-res",
372			sdk_version: "core_platform",
373		}`
374
375	systemModules := []string{
376		"core-public-stubs-system-modules",
377		"core-module-lib-stubs-system-modules",
378		"legacy-core-platform-api-stubs-system-modules",
379		"stable-core-platform-api-stubs-system-modules",
380	}
381
382	for _, extra := range systemModules {
383		bp += fmt.Sprintf(`
384			java_system_modules {
385				name: "%[1]s",
386				libs: ["%[1]s-lib"],
387			}
388			java_library {
389				name: "%[1]s-lib",
390				sdk_version: "none",
391				system_modules: "none",
392			}
393		`, extra)
394	}
395
396	// Make sure that the dex_bootjars singleton module is instantiated for the tests.
397	bp += `
398		dex_bootjars {
399			name: "dex_bootjars",
400		}
401`
402
403	return bp
404}
405
406func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
407	t.Helper()
408	module := ctx.ModuleForTests(name, variant).Module()
409	deps := []string{}
410	ctx.VisitDirectDeps(module, func(m blueprint.Module) {
411		deps = append(deps, m.Name())
412	})
413	sort.Strings(deps)
414
415	if actual := deps; !reflect.DeepEqual(expected, actual) {
416		t.Errorf("expected %#q, found %#q", expected, actual)
417	}
418}
419
420// CheckPlatformBootclasspathModules returns the apex:module pair for the modules depended upon by
421// the platform-bootclasspath module.
422func CheckPlatformBootclasspathModules(t *testing.T, result *android.TestResult, name string, expected []string) {
423	t.Helper()
424	platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule)
425	pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.configuredModules)
426	android.AssertDeepEquals(t, fmt.Sprintf("%s modules", "platform-bootclasspath"), expected, pairs)
427}
428
429func CheckClasspathFragmentProtoContentInfoProvider(t *testing.T, result *android.TestResult, generated bool, contents, outputFilename, installDir string) {
430	t.Helper()
431	p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
432	info := result.ModuleProvider(p, ClasspathFragmentProtoContentInfoProvider).(ClasspathFragmentProtoContentInfo)
433
434	android.AssertBoolEquals(t, "classpath proto generated", generated, info.ClasspathFragmentProtoGenerated)
435	android.AssertStringEquals(t, "classpath proto contents", contents, info.ClasspathFragmentProtoContents.String())
436	android.AssertStringEquals(t, "output filepath", outputFilename, info.ClasspathFragmentProtoOutput.Base())
437	android.AssertPathRelativeToTopEquals(t, "install filepath", installDir, info.ClasspathFragmentProtoInstallDir)
438}
439
440// ApexNamePairsFromModules returns the apex:module pair for the supplied modules.
441func ApexNamePairsFromModules(ctx *android.TestContext, modules []android.Module) []string {
442	pairs := []string{}
443	for _, module := range modules {
444		pairs = append(pairs, apexNamePairFromModule(ctx, module))
445	}
446	return pairs
447}
448
449func apexNamePairFromModule(ctx *android.TestContext, module android.Module) string {
450	name := module.Name()
451	var apex string
452	apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
453	if apexInfo.IsForPlatform() {
454		apex = "platform"
455	} else {
456		apex = apexInfo.InApexVariants[0]
457	}
458
459	return fmt.Sprintf("%s:%s", apex, name)
460}
461
462// CheckPlatformBootclasspathFragments returns the apex:module pair for the fragments depended upon
463// by the platform-bootclasspath module.
464func CheckPlatformBootclasspathFragments(t *testing.T, result *android.TestResult, name string, expected []string) {
465	t.Helper()
466	platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule)
467	pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.fragments)
468	android.AssertDeepEquals(t, fmt.Sprintf("%s fragments", "platform-bootclasspath"), expected, pairs)
469}
470
471func CheckHiddenAPIRuleInputs(t *testing.T, message string, expected string, hiddenAPIRule android.TestingBuildParams) {
472	t.Helper()
473	inputs := android.Paths{}
474	if hiddenAPIRule.Input != nil {
475		inputs = append(inputs, hiddenAPIRule.Input)
476	}
477	inputs = append(inputs, hiddenAPIRule.Inputs...)
478	inputs = append(inputs, hiddenAPIRule.Implicits...)
479	inputs = android.SortedUniquePaths(inputs)
480	actual := strings.TrimSpace(strings.Join(inputs.RelativeToTop().Strings(), "\n"))
481	re := regexp.MustCompile(`\n\s+`)
482	expected = strings.TrimSpace(re.ReplaceAllString(expected, "\n"))
483	if actual != expected {
484		t.Errorf("Expected hiddenapi rule inputs - %s:\n%s\nactual inputs:\n%s", message, expected, actual)
485	}
486}
487
488// Check that the merged file create by platform_compat_config_singleton has the correct inputs.
489func CheckMergedCompatConfigInputs(t *testing.T, result *android.TestResult, message string, expectedPaths ...string) {
490	sourceGlobalCompatConfig := result.SingletonForTests("platform_compat_config_singleton")
491	allOutputs := sourceGlobalCompatConfig.AllOutputs()
492	android.AssertIntEquals(t, message+": output len", 1, len(allOutputs))
493	output := sourceGlobalCompatConfig.Output(allOutputs[0])
494	android.AssertPathsRelativeToTopEquals(t, message+": inputs", expectedPaths, output.Implicits)
495}
496
497// Register the fake APEX mutator to `android.InitRegistrationContext` as if the real mutator exists
498// at runtime. This must be called in `init()` of a test if the test is going to use the fake APEX
499// mutator. Otherwise, we will be missing the runtime mutator because "soong-apex" is not a
500// dependency, which will cause an inconsistency between testing and runtime mutators.
501func RegisterFakeRuntimeApexMutator() {
502	registerFakeApexMutator(android.InitRegistrationContext)
503}
504
505var PrepareForTestWithFakeApexMutator = android.GroupFixturePreparers(
506	android.FixtureRegisterWithContext(registerFakeApexMutator),
507)
508
509func registerFakeApexMutator(ctx android.RegistrationContext) {
510	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
511		ctx.BottomUp("apex", fakeApexMutator).Parallel()
512	})
513}
514
515type apexModuleBase interface {
516	ApexAvailable() []string
517}
518
519var _ apexModuleBase = (*Library)(nil)
520var _ apexModuleBase = (*SdkLibrary)(nil)
521
522// A fake APEX mutator that creates a platform variant and an APEX variant for modules with
523// `apex_available`. It helps us avoid a dependency on the real mutator defined in "soong-apex",
524// which will cause a cyclic dependency, and it provides an easy way to create an APEX variant for
525// testing without dealing with all the complexities in the real mutator.
526func fakeApexMutator(mctx android.BottomUpMutatorContext) {
527	switch mctx.Module().(type) {
528	case *Library, *SdkLibrary:
529		if len(mctx.Module().(apexModuleBase).ApexAvailable()) > 0 {
530			modules := mctx.CreateVariations("", "apex1000")
531			apexInfo := android.ApexInfo{
532				ApexVariationName: "apex1000",
533			}
534			mctx.SetVariationProvider(modules[1], android.ApexInfoProvider, apexInfo)
535		}
536	}
537}
538
539// Applies the given modifier on the boot image config with the given name.
540func FixtureModifyBootImageConfig(name string, configModifier func(*bootImageConfig)) android.FixturePreparer {
541	return android.FixtureModifyConfig(func(androidConfig android.Config) {
542		pathCtx := android.PathContextForTesting(androidConfig)
543		config := genBootImageConfigRaw(pathCtx)
544		configModifier(config[name])
545	})
546}
547
548// Sets the value of `installDirOnDevice` of the boot image config with the given name.
549func FixtureSetBootImageInstallDirOnDevice(name string, installDir string) android.FixturePreparer {
550	return FixtureModifyBootImageConfig(name, func(config *bootImageConfig) {
551		config.installDirOnDevice = installDir
552	})
553}
554