diff options
Diffstat (limited to 'java/robolectric.go')
| -rw-r--r-- | java/robolectric.go | 126 |
1 files changed, 90 insertions, 36 deletions
diff --git a/java/robolectric.go b/java/robolectric.go index 008b8b1c9..4cad5b153 100644 --- a/java/robolectric.go +++ b/java/robolectric.go @@ -22,19 +22,24 @@ import ( "android/soong/android" "android/soong/java/config" + "android/soong/testing" "android/soong/tradefed" "github.com/google/blueprint/proptools" ) func init() { - android.RegisterModuleType("android_robolectric_test", RobolectricTestFactory) - android.RegisterModuleType("android_robolectric_runtimes", robolectricRuntimesFactory) + RegisterRobolectricBuildComponents(android.InitRegistrationContext) +} + +func RegisterRobolectricBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("android_robolectric_test", RobolectricTestFactory) + ctx.RegisterModuleType("android_robolectric_runtimes", robolectricRuntimesFactory) } var robolectricDefaultLibs = []string{ "mockito-robolectric-prebuilt", - "truth-prebuilt", + "truth", // TODO(ccross): this is not needed at link time "junitxml", } @@ -45,6 +50,7 @@ const robolectricPrebuiltLibPattern = "platform-robolectric-%s-prebuilt" var ( roboCoverageLibsTag = dependencyTag{name: "roboCoverageLibs"} roboRuntimesTag = dependencyTag{name: "roboRuntimes"} + roboRuntimeOnlyTag = dependencyTag{name: "roboRuntimeOnlyTag"} ) type robolectricProperties struct { @@ -66,9 +72,14 @@ type robolectricProperties struct { // instead of the one built from source in external/robolectric-shadows. Robolectric_prebuilt_version *string - // Use /external/robolectric rather than /external/robolectric-shadows as the version of robolectri + // Use /external/robolectric rather than /external/robolectric-shadows as the version of robolectric // to use. /external/robolectric closely tracks github's master, and will fully replace /external/robolectric-shadows Upstream *bool + + // Use strict mode to limit access of Robolectric API directly. See go/roboStrictMode + Strict_mode *bool + + Jni_libs []string } type robolectricTest struct { @@ -111,7 +122,7 @@ func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) { if v := String(r.robolectricProperties.Robolectric_prebuilt_version); v != "" { ctx.AddVariationDependencies(nil, libTag, fmt.Sprintf(robolectricPrebuiltLibPattern, v)) - } else { + } else if !proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) { if proptools.Bool(r.robolectricProperties.Upstream) { ctx.AddVariationDependencies(nil, libTag, robolectricCurrentLib+"_upstream") } else { @@ -119,12 +130,23 @@ func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) { } } + if proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) { + ctx.AddVariationDependencies(nil, roboRuntimeOnlyTag, robolectricCurrentLib+"_upstream") + } else { + // opting out from strict mode, robolectric_non_strict_mode_permission lib should be added + ctx.AddVariationDependencies(nil, libTag, "robolectric_non_strict_mode_permission") + } + ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...) ctx.AddVariationDependencies(nil, roboCoverageLibsTag, r.robolectricProperties.Coverage_libs...) ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), roboRuntimesTag, "robolectric-android-all-prebuilts") + + for _, lib := range r.robolectricProperties.Jni_libs { + ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib) + } } func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -144,29 +166,37 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) roboTestConfig := android.PathForModuleGen(ctx, "robolectric"). Join(ctx, "com/android/tools/test_config.properties") + var ok bool + var instrumentedApp *AndroidApp + // TODO: this inserts paths to built files into the test, it should really be inserting the contents. instrumented := ctx.GetDirectDepsWithTag(instrumentationForTag) - if len(instrumented) != 1 { + if len(instrumented) == 1 { + instrumentedApp, ok = instrumented[0].(*AndroidApp) + if !ok { + ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app") + } + } else if !ctx.Config().AllowMissingDependencies() { panic(fmt.Errorf("expected exactly 1 instrumented dependency, got %d", len(instrumented))) } - instrumentedApp, ok := instrumented[0].(*AndroidApp) - if !ok { - ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app") - } - - r.manifest = instrumentedApp.mergedManifestFile - r.resourceApk = instrumentedApp.outputFile + if instrumentedApp != nil { + r.manifest = instrumentedApp.mergedManifestFile + r.resourceApk = instrumentedApp.outputFile - generateRoboTestConfig(ctx, roboTestConfig, instrumentedApp) - r.extraResources = android.Paths{roboTestConfig} + generateRoboTestConfig(ctx, roboTestConfig, instrumentedApp) + r.extraResources = android.Paths{roboTestConfig} + } r.Library.GenerateAndroidBuildActions(ctx) roboSrcJar := android.PathForModuleGen(ctx, "robolectric", ctx.ModuleName()+".srcjar") - r.generateRoboSrcJar(ctx, roboSrcJar, instrumentedApp) - r.roboSrcJar = roboSrcJar + + if instrumentedApp != nil { + r.generateRoboSrcJar(ctx, roboSrcJar, instrumentedApp) + r.roboSrcJar = roboSrcJar + } roboTestConfigJar := android.PathForModuleOut(ctx, "robolectric_samedir", "samedir_config.jar") generateSameDirRoboTestConfigJar(ctx, roboTestConfigJar) @@ -177,22 +207,31 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) // once the Make test runner is removed. roboTestConfigJar, r.outputFile, - instrumentedApp.implementationAndResourcesJar, } - handleLibDeps := func(dep android.Module) { - m := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) - r.libs = append(r.libs, ctx.OtherModuleName(dep)) + if instrumentedApp != nil { + combinedJarJars = append(combinedJarJars, instrumentedApp.implementationAndResourcesJar) + } + + handleLibDeps := func(dep android.Module, runtimeOnly bool) { + m, _ := android.OtherModuleProvider(ctx, dep, JavaInfoProvider) + if !runtimeOnly { + r.libs = append(r.libs, ctx.OtherModuleName(dep)) + } if !android.InList(ctx.OtherModuleName(dep), config.FrameworkLibraries) { combinedJarJars = append(combinedJarJars, m.ImplementationAndResourcesJars...) } } for _, dep := range ctx.GetDirectDepsWithTag(libTag) { - handleLibDeps(dep) + handleLibDeps(dep, false) } for _, dep := range ctx.GetDirectDepsWithTag(sdkLibTag) { - handleLibDeps(dep) + handleLibDeps(dep, false) + } + // handle the runtimeOnly tag for strict_mode + for _, dep := range ctx.GetDirectDepsWithTag(roboRuntimeOnlyTag) { + handleLibDeps(dep, true) } r.combinedJar = android.PathForModuleOut(ctx, "robolectric_combined", r.outputFile.Base()) @@ -213,28 +252,42 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) r.tests = append(r.tests, s) } - r.data = append(r.data, r.manifest, r.resourceApk) - - runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag) - installPath := android.PathForModuleInstall(ctx, r.BaseModuleName()) + var installDeps android.InstallPaths - installedResourceApk := ctx.InstallFile(installPath, ctx.ModuleName()+".apk", r.resourceApk) - installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", r.manifest) - installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig) + if r.manifest != nil { + r.data = append(r.data, r.manifest) + installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", r.manifest) + installDeps = append(installDeps, installedManifest) + } - var installDeps android.Paths + if r.resourceApk != nil { + r.data = append(r.data, r.resourceApk) + installedResourceApk := ctx.InstallFile(installPath, ctx.ModuleName()+".apk", r.resourceApk) + installDeps = append(installDeps, installedResourceApk) + } + + runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag) for _, runtime := range runtimes.(*robolectricRuntimes).runtimes { installDeps = append(installDeps, runtime) } - installDeps = append(installDeps, installedResourceApk, installedManifest, installedConfig) + + installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig) + installDeps = append(installDeps, installedConfig) for _, data := range android.PathsForModuleSrc(ctx, r.testProperties.Data) { installedData := ctx.InstallFile(installPath, data.Rel(), data) installDeps = append(installDeps, installedData) } + soInstallPath := installPath.Join(ctx, getLibPath(r.forceArchType)) + for _, jniLib := range collectTransitiveJniDeps(ctx) { + installJni := ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path) + installDeps = append(installDeps, installJni) + } + r.installFile = ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...) + android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{}) } func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath, @@ -281,12 +334,11 @@ func generateSameDirRoboTestConfigJar(ctx android.ModuleContext, outputFile andr func (r *robolectricTest) generateRoboSrcJar(ctx android.ModuleContext, outputFile android.WritablePath, instrumentedApp *AndroidApp) { - srcJarArgs := copyOf(instrumentedApp.srcJarArgs) + srcJarArgs := android.CopyOf(instrumentedApp.srcJarArgs) srcJarDeps := append(android.Paths(nil), instrumentedApp.srcJarDeps...) for _, m := range ctx.GetDirectDepsWithTag(roboCoverageLibsTag) { - if ctx.OtherModuleHasProvider(m, JavaInfoProvider) { - dep := ctx.OtherModuleProvider(m, JavaInfoProvider).(JavaInfo) + if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok { srcJarArgs = append(srcJarArgs, dep.SrcJarArgs...) srcJarDeps = append(srcJarDeps, dep.SrcJarDeps...) } @@ -340,7 +392,9 @@ func (r *robolectricTest) writeTestRunner(w io.Writer, module, name string, test fmt.Fprintln(w, "LOCAL_MODULE :=", name) android.AndroidMkEmitAssignList(w, "LOCAL_JAVA_LIBRARIES", []string{module}, r.libs) fmt.Fprintln(w, "LOCAL_TEST_PACKAGE :=", String(r.robolectricProperties.Instrumentation_for)) - fmt.Fprintln(w, "LOCAL_INSTRUMENT_SRCJARS :=", r.roboSrcJar.String()) + if r.roboSrcJar != nil { + fmt.Fprintln(w, "LOCAL_INSTRUMENT_SRCJARS :=", r.roboSrcJar.String()) + } android.AndroidMkEmitAssignList(w, "LOCAL_ROBOTEST_FILES", tests) if t := r.robolectricProperties.Test_options.Timeout; t != nil { fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t) |