diff options
Diffstat (limited to 'java/hiddenapi_singleton_test.go')
-rw-r--r-- | java/hiddenapi_singleton_test.go | 297 |
1 files changed, 222 insertions, 75 deletions
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go index e4dc03794..dcd363c2c 100644 --- a/java/hiddenapi_singleton_test.go +++ b/java/hiddenapi_singleton_test.go @@ -15,125 +15,221 @@ package java import ( - "android/soong/android" - "strings" + "fmt" + "path/filepath" "testing" + + "android/soong/android" + "github.com/google/blueprint/proptools" ) -func testConfigWithBootJars(bp string, bootJars []string, prebuiltHiddenApiDir *string) android.Config { - config := testConfig(nil, bp, nil) - config.TestProductVariables.BootJars = bootJars - config.TestProductVariables.PrebuiltHiddenApiDir = prebuiltHiddenApiDir - return config -} +// TODO(b/177892522): Move these tests into a more appropriate place. -func testContextWithHiddenAPI() *android.TestContext { - ctx := testContext() - ctx.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory) - return ctx +func fixtureSetPrebuiltHiddenApiDirProductVariable(prebuiltHiddenApiDir *string) android.FixturePreparer { + return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.PrebuiltHiddenApiDir = prebuiltHiddenApiDir + }) } -func testHiddenAPI(t *testing.T, bp string, bootJars []string, prebuiltHiddenApiDir *string) (*android.TestContext, android.Config) { - t.Helper() +var prepareForTestWithDefaultPlatformBootclasspath = android.FixtureAddTextFile("frameworks/base/boot/Android.bp", ` + platform_bootclasspath { + name: "platform-bootclasspath", + } +`) - config := testConfigWithBootJars(bp, bootJars, prebuiltHiddenApiDir) - ctx := testContextWithHiddenAPI() +var hiddenApiFixtureFactory = android.GroupFixturePreparers( + prepareForJavaTest, PrepareForTestWithHiddenApiBuildComponents) - run(t, ctx, config) +func TestHiddenAPISingleton(t *testing.T) { + result := android.GroupFixturePreparers( + hiddenApiFixtureFactory, + FixtureConfigureBootJars("platform:foo"), + prepareForTestWithDefaultPlatformBootclasspath, + ).RunTestWithBp(t, ` + java_library { + name: "foo", + srcs: ["a.java"], + compile_dex: true, + } + `) - return ctx, config + hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common") + hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags") + want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar" + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want) } -func TestHiddenAPISingleton(t *testing.T) { - ctx, _ := testHiddenAPI(t, ` +func TestHiddenAPISingletonWithSourceAndPrebuiltPreferredButNoDex(t *testing.T) { + expectedErrorMessage := "module prebuilt_foo{os:android,arch:common} does not provide a dex jar" + + android.GroupFixturePreparers( + hiddenApiFixtureFactory, + FixtureConfigureBootJars("platform:foo"), + prepareForTestWithDefaultPlatformBootclasspath, + ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorMessage)). + RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], compile_dex: true, - } - `, []string{"foo"}, nil) + } - hiddenAPI := ctx.SingletonForTests("hiddenapi") - hiddenapiRule := hiddenAPI.Rule("hiddenapi") - want := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar" - if !strings.Contains(hiddenapiRule.RuleParams.Command, want) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", want, hiddenapiRule.RuleParams.Command) - } + java_import { + name: "foo", + jars: ["a.jar"], + prefer: true, + } + `) } func TestHiddenAPISingletonWithPrebuilt(t *testing.T) { - ctx, _ := testHiddenAPI(t, ` + result := android.GroupFixturePreparers( + hiddenApiFixtureFactory, + FixtureConfigureBootJars("platform:foo"), + prepareForTestWithDefaultPlatformBootclasspath, + ).RunTestWithBp(t, ` java_import { name: "foo", jars: ["a.jar"], compile_dex: true, } - `, []string{"foo"}, nil) + `) - hiddenAPI := ctx.SingletonForTests("hiddenapi") - hiddenapiRule := hiddenAPI.Rule("hiddenapi") - want := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar" - if !strings.Contains(hiddenapiRule.RuleParams.Command, want) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", want, hiddenapiRule.RuleParams.Command) - } + hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common") + hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags") + want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar" + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want) } func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) { - ctx, _ := testHiddenAPI(t, ` + result := android.GroupFixturePreparers( + hiddenApiFixtureFactory, + FixtureConfigureBootJars("platform:foo"), + prepareForTestWithDefaultPlatformBootclasspath, + ).RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], compile_dex: true, - } + } java_import { name: "foo", jars: ["a.jar"], compile_dex: true, prefer: false, - } - `, []string{"foo"}, nil) + } + `) - hiddenAPI := ctx.SingletonForTests("hiddenapi") - hiddenapiRule := hiddenAPI.Rule("hiddenapi") - fromSourceJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar" - if !strings.Contains(hiddenapiRule.RuleParams.Command, fromSourceJarArg) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", fromSourceJarArg, hiddenapiRule.RuleParams.Command) - } + hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common") + hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags") + fromSourceJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar" + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg) - prebuiltJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/dex/foo.jar" - if strings.Contains(hiddenapiRule.RuleParams.Command, prebuiltJarArg) { - t.Errorf("Did not expect %s in hiddenapi command, but it was present: %s", prebuiltJarArg, hiddenapiRule.RuleParams.Command) - } + prebuiltJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/dex/foo.jar" + android.AssertStringDoesNotContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg) } func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) { - ctx, _ := testHiddenAPI(t, ` + result := android.GroupFixturePreparers( + hiddenApiFixtureFactory, + FixtureConfigureBootJars("platform:foo"), + prepareForTestWithDefaultPlatformBootclasspath, + ).RunTestWithBp(t, ` java_library { name: "foo", srcs: ["a.java"], compile_dex: true, - } + } java_import { name: "foo", jars: ["a.jar"], compile_dex: true, prefer: true, + } + `) + + hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common") + hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags") + prebuiltJarArg := "--boot-dex=out/soong/.intermediates/prebuilt_foo/android_common/dex/foo.jar" + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg) + + fromSourceJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar" + android.AssertStringDoesNotContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg) +} + +func TestHiddenAPISingletonSdks(t *testing.T) { + testCases := []struct { + name string + unbundledBuild bool + publicStub string + systemStub string + testStub string + corePlatformStub string + + // Additional test preparer + preparer android.FixturePreparer + }{ + { + name: "testBundled", + unbundledBuild: false, + publicStub: "android_stubs_current", + systemStub: "android_system_stubs_current", + testStub: "android_test_stubs_current", + corePlatformStub: "legacy.core.platform.api.stubs", + preparer: android.GroupFixturePreparers(), + }, { + name: "testUnbundled", + unbundledBuild: true, + publicStub: "sdk_public_current_android", + systemStub: "sdk_system_current_android", + testStub: "sdk_test_current_android", + corePlatformStub: "legacy.core.platform.api.stubs", + preparer: PrepareForTestWithPrebuiltsOfCurrentApi, + }, } - `, []string{"foo"}, nil) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := android.GroupFixturePreparers( + hiddenApiFixtureFactory, + tc.preparer, + prepareForTestWithDefaultPlatformBootclasspath, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.Always_use_prebuilt_sdks = proptools.BoolPtr(tc.unbundledBuild) + }), + ).RunTest(t) + + hiddenAPI := result.ModuleForTests("platform-bootclasspath", "android_common") + hiddenapiRule := hiddenAPI.Rule("platform-bootclasspath-monolithic-hiddenapi-stub-flags") + wantPublicStubs := "--public-stub-classpath=" + generateSdkDexPath(tc.publicStub, tc.unbundledBuild) + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantPublicStubs) - hiddenAPI := ctx.SingletonForTests("hiddenapi") - hiddenapiRule := hiddenAPI.Rule("hiddenapi") - prebuiltJarArg := "--boot-dex=" + buildDir + "/.intermediates/prebuilt_foo/android_common/dex/foo.jar" - if !strings.Contains(hiddenapiRule.RuleParams.Command, prebuiltJarArg) { - t.Errorf("Expected %s in hiddenapi command, but it was not present: %s", prebuiltJarArg, hiddenapiRule.RuleParams.Command) + wantSystemStubs := "--system-stub-classpath=" + generateSdkDexPath(tc.systemStub, tc.unbundledBuild) + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantSystemStubs) + + wantTestStubs := "--test-stub-classpath=" + generateSdkDexPath(tc.testStub, tc.unbundledBuild) + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantTestStubs) + + wantCorePlatformStubs := "--core-platform-stub-classpath=" + generateDexPath(defaultJavaDir, tc.corePlatformStub) + android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantCorePlatformStubs) + }) } +} - fromSourceJarArg := "--boot-dex=" + buildDir + "/.intermediates/foo/android_common/aligned/foo.jar" - if strings.Contains(hiddenapiRule.RuleParams.Command, fromSourceJarArg) { - t.Errorf("Did not expect %s in hiddenapi command, but it was present: %s", fromSourceJarArg, hiddenapiRule.RuleParams.Command) +func generateDexedPath(subDir, dex, module string) string { + return fmt.Sprintf("out/soong/.intermediates/%s/android_common/%s/%s.jar", subDir, dex, module) +} + +func generateDexPath(moduleDir string, module string) string { + return generateDexedPath(filepath.Join(moduleDir, module), "dex", module) +} + +func generateSdkDexPath(module string, unbundled bool) string { + if unbundled { + return generateDexedPath("prebuilts/sdk/"+module, "dex", module) } + return generateDexPath(defaultJavaDir, module) } func TestHiddenAPISingletonWithPrebuiltCsvFile(t *testing.T) { @@ -147,36 +243,87 @@ func TestHiddenAPISingletonWithPrebuiltCsvFile(t *testing.T) { // Where to find the prebuilt hiddenapi files: prebuiltHiddenApiDir := "path/to/prebuilt/hiddenapi" - ctx, _ := testHiddenAPI(t, ` + result := android.GroupFixturePreparers( + hiddenApiFixtureFactory, + FixtureConfigureBootJars("platform:foo"), + fixtureSetPrebuiltHiddenApiDirProductVariable(&prebuiltHiddenApiDir), + ).RunTestWithBp(t, ` java_import { name: "foo", jars: ["a.jar"], compile_dex: true, } - `, []string{"foo"}, &prebuiltHiddenApiDir) + `) expectedCpInput := prebuiltHiddenApiDir + "/hiddenapi-flags.csv" - expectedCpOutput := buildDir + "/hiddenapi/hiddenapi-flags.csv" - expectedFlagsCsv := buildDir + "/hiddenapi/hiddenapi-flags.csv" + expectedCpOutput := "out/soong/hiddenapi/hiddenapi-flags.csv" + expectedFlagsCsv := "out/soong/hiddenapi/hiddenapi-flags.csv" - foo := ctx.ModuleForTests("foo", "android_common") + foo := result.ModuleForTests("foo", "android_common") - hiddenAPI := ctx.SingletonForTests("hiddenapi") + hiddenAPI := result.SingletonForTests("hiddenapi") cpRule := hiddenAPI.Rule("Cp") actualCpInput := cpRule.BuildParams.Input actualCpOutput := cpRule.BuildParams.Output encodeDexRule := foo.Rule("hiddenAPIEncodeDex") actualFlagsCsv := encodeDexRule.BuildParams.Args["flagsCsv"] - if actualCpInput.String() != expectedCpInput { - t.Errorf("Prebuilt hiddenapi cp rule input mismatch, actual: %s, expected: %s", actualCpInput, expectedCpInput) - } + android.AssertPathRelativeToTopEquals(t, "hiddenapi cp rule input", expectedCpInput, actualCpInput) - if actualCpOutput.String() != expectedCpOutput { - t.Errorf("Prebuilt hiddenapi cp rule output mismatch, actual: %s, expected: %s", actualCpOutput, expectedCpOutput) - } + android.AssertPathRelativeToTopEquals(t, "hiddenapi cp rule output", expectedCpOutput, actualCpOutput) - if actualFlagsCsv != expectedFlagsCsv { - t.Errorf("Prebuilt hiddenapi encode dex rule flags csv mismatch, actual: %s, expected: %s", actualFlagsCsv, expectedFlagsCsv) + android.AssertStringEquals(t, "hiddenapi encode dex rule flags csv", expectedFlagsCsv, actualFlagsCsv) +} + +func TestHiddenAPIEncoding_JavaSdkLibrary(t *testing.T) { + + result := android.GroupFixturePreparers( + hiddenApiFixtureFactory, + FixtureConfigureBootJars("platform:foo"), + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("foo"), + + // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding + // is disabled. + android.FixtureAddTextFile("frameworks/base/Android.bp", ""), + ).RunTestWithBp(t, ` + java_sdk_library { + name: "foo", + srcs: ["a.java"], + shared_library: false, + compile_dex: true, + public: {enabled: true}, + } + `) + + checkDexEncoded := func(t *testing.T, name, unencodedDexJar, encodedDexJar string) { + moduleForTests := result.ModuleForTests(name, "android_common") + + encodeDexRule := moduleForTests.Rule("hiddenAPIEncodeDex") + actualUnencodedDexJar := encodeDexRule.Input + + // Make sure that the module has its dex jar encoded. + android.AssertStringEquals(t, "encode embedded java_library", unencodedDexJar, actualUnencodedDexJar.String()) + + // Make sure that the encoded dex jar is the exported one. + exportedDexJar := moduleForTests.Module().(UsesLibraryDependency).DexJarBuildPath() + android.AssertPathRelativeToTopEquals(t, "encode embedded java_library", encodedDexJar, exportedDexJar) } + + // The java_library embedded with the java_sdk_library must be dex encoded. + t.Run("foo", func(t *testing.T) { + expectedUnencodedDexJar := "out/soong/.intermediates/foo/android_common/aligned/foo.jar" + expectedEncodedDexJar := "out/soong/.intermediates/foo/android_common/hiddenapi/foo.jar" + checkDexEncoded(t, "foo", expectedUnencodedDexJar, expectedEncodedDexJar) + }) + + // The dex jar of the child implementation java_library of the java_sdk_library is not currently + // dex encoded. + t.Run("foo.impl", func(t *testing.T) { + fooImpl := result.ModuleForTests("foo.impl", "android_common") + encodeDexRule := fooImpl.MaybeRule("hiddenAPIEncodeDex") + if encodeDexRule.Rule != nil { + t.Errorf("foo.impl is not expected to be encoded") + } + }) } |