aboutsummaryrefslogtreecommitdiff
path: root/java/java_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/java_test.go')
-rw-r--r--java/java_test.go250
1 files changed, 230 insertions, 20 deletions
diff --git a/java/java_test.go b/java/java_test.go
index 6c0a90856..f7cf03f4d 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -15,6 +15,7 @@
package java
import (
+ "fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -29,7 +30,6 @@ import (
"android/soong/android"
"android/soong/cc"
"android/soong/dexpreopt"
- "android/soong/genrule"
"android/soong/python"
)
@@ -70,9 +70,9 @@ func testConfig(env map[string]string, bp string, fs map[string][]byte) android.
return config
}
-func testContext() *android.TestContext {
+func testContext(config android.Config) *android.TestContext {
- ctx := android.NewTestArchContext()
+ ctx := android.NewTestArchContext(config)
RegisterJavaBuildComponents(ctx)
RegisterAppBuildComponents(ctx)
RegisterAARBuildComponents(ctx)
@@ -80,7 +80,6 @@ func testContext() *android.TestContext {
RegisterSystemModulesBuildComponents(ctx)
ctx.RegisterModuleType("java_plugin", PluginFactory)
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
- ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
ctx.RegisterModuleType("python_binary_host", python.PythonBinaryHostFactory)
RegisterDocsBuildComponents(ctx)
RegisterStubsBuildComponents(ctx)
@@ -92,8 +91,8 @@ func testContext() *android.TestContext {
ctx.PreDepsMutators(python.RegisterPythonPreDepsMutators)
ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
- ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
- ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory))
+ ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(ctx.Context, OverlaySingletonFactory))
+ ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(ctx.Context, sdkPreSingletonFactory))
android.RegisterPrebuiltMutators(ctx)
@@ -115,7 +114,7 @@ func run(t *testing.T, ctx *android.TestContext, config android.Config) {
pathCtx := android.PathContextForTesting(config)
dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
- ctx.Register(config)
+ ctx.Register()
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
@@ -129,12 +128,12 @@ func testJavaError(t *testing.T, pattern string, bp string) (*android.TestContex
func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config) (*android.TestContext, android.Config) {
t.Helper()
- ctx := testContext()
+ ctx := testContext(config)
pathCtx := android.PathContextForTesting(config)
dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
- ctx.Register(config)
+ ctx.Register()
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
if len(errs) > 0 {
android.FailIfNoMatchingErrors(t, pattern, errs)
@@ -163,7 +162,7 @@ func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) {
func testJavaWithConfig(t *testing.T, config android.Config) (*android.TestContext, android.Config) {
t.Helper()
- ctx := testContext()
+ ctx := testContext(config)
run(t, ctx, config)
return ctx, config
@@ -202,7 +201,7 @@ func TestJavaLinkType(t *testing.T) {
}
`)
- testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
+ testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
java_library {
name: "foo",
srcs: ["a.java"],
@@ -246,7 +245,7 @@ func TestJavaLinkType(t *testing.T) {
}
`)
- testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
+ testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
java_library {
name: "foo",
srcs: ["a.java"],
@@ -314,8 +313,9 @@ func TestSimple(t *testing.T) {
func TestExportedPlugins(t *testing.T) {
type Result struct {
- library string
- processors string
+ library string
+ processors string
+ disableTurbine bool
}
var tests = []struct {
name string
@@ -374,6 +374,18 @@ func TestExportedPlugins(t *testing.T) {
{library: "foo", processors: "-processor com.android.TestPlugin,com.android.TestPlugin2"},
},
},
+ {
+ name: "Exports plugin to with generates_api to dependee",
+ extra: `
+ java_library{name: "exports", exported_plugins: ["plugin_generates_api"]}
+ java_library{name: "foo", srcs: ["a.java"], libs: ["exports"]}
+ java_library{name: "bar", srcs: ["a.java"], static_libs: ["exports"]}
+ `,
+ results: []Result{
+ {library: "foo", processors: "-processor com.android.TestPlugin", disableTurbine: true},
+ {library: "bar", processors: "-processor com.android.TestPlugin", disableTurbine: true},
+ },
+ },
}
for _, test := range tests {
@@ -383,6 +395,11 @@ func TestExportedPlugins(t *testing.T) {
name: "plugin",
processor_class: "com.android.TestPlugin",
}
+ java_plugin {
+ name: "plugin_generates_api",
+ generates_api: true,
+ processor_class: "com.android.TestPlugin",
+ }
`+test.extra)
for _, want := range test.results {
@@ -390,6 +407,11 @@ func TestExportedPlugins(t *testing.T) {
if javac.Args["processor"] != want.processors {
t.Errorf("For library %v, expected %v, found %v", want.library, want.processors, javac.Args["processor"])
}
+ turbine := ctx.ModuleForTests(want.library, "android_common").MaybeRule("turbine")
+ disableTurbine := turbine.BuildParams.Rule == nil
+ if disableTurbine != want.disableTurbine {
+ t.Errorf("For library %v, expected disableTurbine %v, found %v", want.library, want.disableTurbine, disableTurbine)
+ }
}
})
}
@@ -622,6 +644,35 @@ func assertDeepEquals(t *testing.T, message string, expected interface{}, actual
}
}
+func TestPrebuiltStubsSources(t *testing.T) {
+ test := func(t *testing.T, sourcesPath string, expectedInputs []string) {
+ ctx, _ := testJavaWithFS(t, fmt.Sprintf(`
+prebuilt_stubs_sources {
+ name: "stubs-source",
+ srcs: ["%s"],
+}`, sourcesPath), map[string][]byte{
+ "stubs/sources/pkg/A.java": nil,
+ "stubs/sources/pkg/B.java": nil,
+ })
+
+ zipSrc := ctx.ModuleForTests("stubs-source", "android_common").Rule("zip_src")
+ if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) {
+ t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual)
+ }
+ }
+
+ t.Run("empty/missing directory", func(t *testing.T) {
+ test(t, "empty-directory", []string{})
+ })
+
+ t.Run("non-empty set of sources", func(t *testing.T) {
+ test(t, "stubs/sources", []string{
+ "stubs/sources/pkg/A.java",
+ "stubs/sources/pkg/B.java",
+ })
+ })
+}
+
func TestJavaSdkLibraryImport(t *testing.T) {
ctx, _ := testJava(t, `
java_library {
@@ -754,6 +805,165 @@ func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
})
}
+func TestJavaSdkLibraryEnforce(t *testing.T) {
+ partitionToBpOption := func(partition string) string {
+ switch partition {
+ case "system":
+ return ""
+ case "vendor":
+ return "soc_specific: true,"
+ case "product":
+ return "product_specific: true,"
+ default:
+ panic("Invalid partition group name: " + partition)
+ }
+ }
+
+ type testConfigInfo struct {
+ libraryType string
+ fromPartition string
+ toPartition string
+ enforceVendorInterface bool
+ enforceProductInterface bool
+ enforceJavaSdkLibraryCheck bool
+ allowList []string
+ }
+
+ createTestConfig := func(info testConfigInfo) android.Config {
+ bpFileTemplate := `
+ java_library {
+ name: "foo",
+ srcs: ["foo.java"],
+ libs: ["bar"],
+ sdk_version: "current",
+ %s
+ }
+
+ %s {
+ name: "bar",
+ srcs: ["bar.java"],
+ sdk_version: "current",
+ %s
+ }
+ `
+
+ bpFile := fmt.Sprintf(bpFileTemplate,
+ partitionToBpOption(info.fromPartition),
+ info.libraryType,
+ partitionToBpOption(info.toPartition))
+
+ config := testConfig(nil, bpFile, nil)
+ configVariables := config.TestProductVariables
+
+ configVariables.EnforceProductPartitionInterface = proptools.BoolPtr(info.enforceProductInterface)
+ if info.enforceVendorInterface {
+ configVariables.DeviceVndkVersion = proptools.StringPtr("current")
+ }
+ configVariables.EnforceInterPartitionJavaSdkLibrary = proptools.BoolPtr(info.enforceJavaSdkLibraryCheck)
+ configVariables.InterPartitionJavaLibraryAllowList = info.allowList
+
+ return config
+ }
+
+ isValidDependency := func(configInfo testConfigInfo) bool {
+ if configInfo.enforceVendorInterface == false {
+ return true
+ }
+
+ if configInfo.enforceJavaSdkLibraryCheck == false {
+ return true
+ }
+
+ if inList("bar", configInfo.allowList) {
+ return true
+ }
+
+ if configInfo.libraryType == "java_library" {
+ if configInfo.fromPartition != configInfo.toPartition {
+ if !configInfo.enforceProductInterface &&
+ ((configInfo.fromPartition == "system" && configInfo.toPartition == "product") ||
+ (configInfo.fromPartition == "product" && configInfo.toPartition == "system")) {
+ return true
+ }
+ return false
+ }
+ }
+
+ return true
+ }
+
+ errorMessage := "is not allowed across the partitions"
+
+ allPartitionCombinations := func() [][2]string {
+ var result [][2]string
+ partitions := []string{"system", "vendor", "product"}
+
+ for _, fromPartition := range partitions {
+ for _, toPartition := range partitions {
+ result = append(result, [2]string{fromPartition, toPartition})
+ }
+ }
+
+ return result
+ }
+
+ allFlagCombinations := func() [][3]bool {
+ var result [][3]bool
+ flagValues := [2]bool{false, true}
+
+ for _, vendorInterface := range flagValues {
+ for _, productInterface := range flagValues {
+ for _, enableEnforce := range flagValues {
+ result = append(result, [3]bool{vendorInterface, productInterface, enableEnforce})
+ }
+ }
+ }
+
+ return result
+ }
+
+ for _, libraryType := range []string{"java_library", "java_sdk_library"} {
+ for _, partitionValues := range allPartitionCombinations() {
+ for _, flagValues := range allFlagCombinations() {
+ testInfo := testConfigInfo{
+ libraryType: libraryType,
+ fromPartition: partitionValues[0],
+ toPartition: partitionValues[1],
+ enforceVendorInterface: flagValues[0],
+ enforceProductInterface: flagValues[1],
+ enforceJavaSdkLibraryCheck: flagValues[2],
+ }
+
+ if isValidDependency(testInfo) {
+ testJavaWithConfig(t, createTestConfig(testInfo))
+ } else {
+ testJavaErrorWithConfig(t, errorMessage, createTestConfig(testInfo))
+ }
+ }
+ }
+ }
+
+ testJavaWithConfig(t, createTestConfig(testConfigInfo{
+ libraryType: "java_library",
+ fromPartition: "vendor",
+ toPartition: "system",
+ enforceVendorInterface: true,
+ enforceProductInterface: true,
+ enforceJavaSdkLibraryCheck: true,
+ allowList: []string{"bar"},
+ }))
+
+ testJavaErrorWithConfig(t, errorMessage, createTestConfig(testConfigInfo{
+ libraryType: "java_library",
+ fromPartition: "vendor",
+ toPartition: "system",
+ enforceVendorInterface: true,
+ enforceProductInterface: true,
+ enforceJavaSdkLibraryCheck: true,
+ allowList: []string{"foo"},
+ }))
+}
+
func TestDefaults(t *testing.T) {
ctx, _ := testJava(t, `
java_defaults {
@@ -1379,8 +1589,8 @@ func TestJarGenrules(t *testing.T) {
baz := ctx.ModuleForTests("baz", "android_common").Output("javac/baz.jar")
barCombined := ctx.ModuleForTests("bar", "android_common").Output("combined/bar.jar")
- if len(jargen.Inputs) != 1 || jargen.Inputs[0].String() != foo.Output.String() {
- t.Errorf("expected jargen inputs [%q], got %q", foo.Output.String(), jargen.Inputs.Strings())
+ if g, w := jargen.Implicits.Strings(), foo.Output.String(); !android.InList(w, g) {
+ t.Errorf("expected jargen inputs [%q], got %q", w, g)
}
if !strings.Contains(bar.Args["classpath"], jargen.Output.String()) {
@@ -1440,7 +1650,7 @@ func TestJavaLibrary(t *testing.T) {
}
`),
})
- ctx := testContext()
+ ctx := testContext(config)
run(t, ctx, config)
}
@@ -1458,7 +1668,7 @@ func TestJavaImport(t *testing.T) {
}
`),
})
- ctx := testContext()
+ ctx := testContext(config)
run(t, ctx, config)
}
@@ -1593,8 +1803,8 @@ func TestJavaSdkLibrary(t *testing.T) {
// test if baz has exported SDK lib names foo and bar to qux
qux := ctx.ModuleForTests("qux", "android_common")
if quxLib, ok := qux.Module().(*Library); ok {
- sdkLibs := android.SortedStringKeys(quxLib.ExportedSdkLibs())
- if w := []string{"bar", "foo", "fred", "quuz"}; !reflect.DeepEqual(w, sdkLibs) {
+ sdkLibs := quxLib.ClassLoaderContexts().UsesLibs()
+ if w := []string{"foo", "bar", "fred", "quuz"}; !reflect.DeepEqual(w, sdkLibs) {
t.Errorf("qux should export %q but exports %q", w, sdkLibs)
}
}