Support android_robolectric_test with merged binary resources
android_robolectric_test with merged binary resources
requires a gnerated test_config.properties file pointing
to the APK containing binary resources.
Test: m RunSettingsLibRoboTests
Change-Id: Ic84714c09ea1bae70537556c8385405fe392f79f
diff --git a/java/robolectric.go b/java/robolectric.go
index 26f1e9d..6d7052e 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -33,10 +33,17 @@
"truth-prebuilt",
}
+var (
+ roboCoverageLibsTag = dependencyTag{name: "roboSrcs"}
+)
+
type robolectricProperties struct {
// The name of the android_app module that the tests will run against.
Instrumentation_for *string
+ // Additional libraries for which coverage data should be generated
+ Coverage_libs []string
+
Test_options struct {
// Timeout in seconds when running the tests.
Timeout *string
@@ -49,6 +56,8 @@
robolectricProperties robolectricProperties
libs []string
+
+ roboSrcJar android.Path
}
func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -61,16 +70,75 @@
}
ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...)
+
+ ctx.AddVariationDependencies(nil, roboCoverageLibsTag, r.robolectricProperties.Coverage_libs...)
}
func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ roboTestConfig := android.PathForModuleGen(ctx, "robolectric").
+ Join(ctx, "com/android/tools/test_config.properties")
+
+ // 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 {
+ 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")
+ }
+
+ 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
+
for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
r.libs = append(r.libs, ctx.OtherModuleName(dep))
}
}
+func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath, instrumentedApp *AndroidApp) {
+ manifest := instrumentedApp.mergedManifestFile
+ resourceApk := instrumentedApp.outputFile
+
+ rule := android.NewRuleBuilder()
+
+ rule.Command().Text("rm -f").Output(outputFile)
+ rule.Command().
+ Textf(`echo "android_merged_manifest=%s" >>`, manifest.String()).Output(outputFile).Text("&&").
+ Textf(`echo "android_resource_apk=%s" >>`, resourceApk.String()).Output(outputFile).
+ // Make it depend on the files to which it points so the test file's timestamp is updated whenever the
+ // contents change
+ Implicit(manifest).
+ Implicit(resourceApk)
+
+ rule.Build(pctx, ctx, "generate_test_config", "generate test_config.properties")
+}
+
+func (r *robolectricTest) generateRoboSrcJar(ctx android.ModuleContext, outputFile android.WritablePath,
+ instrumentedApp *AndroidApp) {
+
+ srcJarArgs := copyOf(instrumentedApp.srcJarArgs)
+ srcJarDeps := append(android.Paths(nil), instrumentedApp.srcJarDeps...)
+
+ for _, m := range ctx.GetDirectDepsWithTag(roboCoverageLibsTag) {
+ if dep, ok := m.(Dependency); ok {
+ depSrcJarArgs, depSrcJarDeps := dep.SrcJarArgs()
+ srcJarArgs = append(srcJarArgs, depSrcJarArgs...)
+ srcJarDeps = append(srcJarDeps, depSrcJarDeps...)
+ }
+ }
+
+ TransformResourcesToJar(ctx, outputFile, srcJarArgs, srcJarDeps)
+}
+
func (r *robolectricTest) AndroidMk() android.AndroidMkData {
data := r.Library.AndroidMk()
@@ -83,6 +151,7 @@
fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES :=", name)
fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES += ", strings.Join(r.libs, " "))
fmt.Fprintln(w, "LOCAL_TEST_PACKAGE :=", String(r.robolectricProperties.Instrumentation_for))
+ fmt.Fprintln(w, "LOCAL_INSTRUMENT_SRCJARS :=", r.roboSrcJar.String())
if t := r.robolectricProperties.Test_options.Timeout; t != nil {
fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
}