aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar jingwen <jingwen@google.com>2017-12-19 09:30:45 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2017-12-19 09:32:20 -0800
commit741dbc081e2479fd8b0b9c289802b8a0e4af7c06 (patch)
tree45430c4303439099540e77619f3c1b949e2416be /src/main/java/com/google/devtools/build
parent691bd158149602aeb6bbcc46fd4b22367d0157b4 (diff)
Ensure that the target package in the <instrumentation> tag of the instrumentation android_binary's AndroidManifest.xml references the correct package name of the instrumented android_binary.
During an instrumentation test, ART will use the targetPackage specified in the instrumentation APK's AndroidManifest to determine the application to be instrumented. We can perform this check in Bazel at execution time, before the apps are loaded onto the device. See android_instrumentation_test_integration_test.sh for the e2e example. GITHUB: https://github.com/bazelbuild/bazel/issues/903 RELNOTES: None. PiperOrigin-RevId: 179564246
Diffstat (limited to 'src/main/java/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java40
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTest.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java15
3 files changed, 52 insertions, 7 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index 3b1933cf3d..694c5d7dab 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -43,6 +43,7 @@ import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorAr
import com.google.devtools.build.lib.analysis.actions.ParamFileInfo;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
+import com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder;
import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -562,17 +563,46 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
// If this is an instrumentation APK, create the provider for android_instrumentation_test.
if (isInstrumentation(ruleContext)) {
- Artifact targetApk =
- ruleContext
- .getPrerequisite("instruments", Mode.TARGET)
- .getProvider(ApkProvider.class)
- .getApk();
+ ApkProvider targetApkProvider =
+ ruleContext.getPrerequisite("instruments", Mode.TARGET, ApkProvider.class);
+
+ Artifact targetApk = targetApkProvider.getApk();
Artifact instrumentationApk = zipAlignedApk;
AndroidInstrumentationInfo instrumentationProvider =
new AndroidInstrumentationInfo(targetApk, instrumentationApk);
builder.addNativeDeclaredProvider(instrumentationProvider);
+
+ // At this point, the Android manifests of both target and instrumentation APKs are finalized.
+ FilesToRunProvider checker =
+ ruleContext.getExecutablePrerequisite("$instrumentation_test_check", Mode.HOST);
+ Artifact targetManifest = targetApkProvider.getMergedManifest();
+ Artifact instrumentationManifest = applicationManifest.getManifest();
+ Artifact checkOutput =
+ ruleContext.getImplicitOutputArtifact(
+ AndroidRuleClasses.INSTRUMENTATION_TEST_CHECK_RESULTS);
+
+ SpawnAction.Builder checkAction =
+ new Builder()
+ .setExecutable(checker)
+ .addInput(targetManifest)
+ .addInput(instrumentationManifest)
+ .addOutput(checkOutput)
+ .setProgressMessage(
+ "Validating the merged manifests of the target and instrumentation APKs")
+ .setMnemonic("AndroidManifestInstrumentationCheck");
+
+ CustomCommandLine commandLine =
+ CustomCommandLine.builder()
+ .addExecPath("--instrumentation_manifest", instrumentationManifest)
+ .addExecPath("--target_manifest", targetManifest)
+ .addExecPath("--output", checkOutput)
+ .build();
+
+ builder.addOutputGroup(OutputGroupInfo.HIDDEN_TOP_LEVEL, checkOutput);
+ checkAction.addCommandLine(commandLine);
+ ruleContext.registerAction(checkAction.build(ruleContext));
}
androidCommon.addTransitiveInfoProviders(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTest.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTest.java
index 30e26d1803..cc3d44e9fc 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTest.java
@@ -56,8 +56,8 @@ public class AndroidInstrumentationTest implements RuleConfiguredTargetFactory {
ruleContext.throwWithAttributeError(
"instrumentation",
String.format(
- "The android_binary target at %s is missing an 'instruments' attribute. Please set "
- + "it as the label of the android_binary under test.",
+ "The android_binary target %s is missing an 'instruments' attribute. Please set "
+ + "it to the label of the android_binary under test.",
ruleContext.attributes().get("instrumentation", BuildType.LABEL)));
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
index e13978ce6c..faa903ecb6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
@@ -164,6 +164,8 @@ public final class AndroidRuleClasses {
fromTemplates("%{name}_files/deploy_info_split.deployinfo.pb");
public static final SafeImplicitOutputsFunction REX_OUTPUT_PACKAGE_MAP =
fromTemplates("%{name}_rex/rex_output_package.map");
+ public static final SafeImplicitOutputsFunction INSTRUMENTATION_TEST_CHECK_RESULTS =
+ fromTemplates("%{name}_files/instrumentation_test_check_results.txt");
// This needs to be in its own directory because ApkBuilder only has a function (-rf) for source
// folders but not source files, and it's easiest to guarantee that nothing gets put beside this
@@ -992,6 +994,19 @@ public final class AndroidRuleClasses {
.allowedRuleClasses("android_binary")
.allowedFileTypes(NO_FILE))
.add(
+ attr("$instrumentation_test_check", LABEL)
+ .cfg(HOST)
+ .value(
+ new Attribute.ComputedDefault() {
+ @Override
+ public Object getDefault(AttributeMap rule) {
+ return rule.isAttributeValueExplicitlySpecified("instruments")
+ ? env.getToolsLabel("//tools/android:instrumentation_test_check")
+ : null;
+ }
+ })
+ .exec())
+ .add(
attr("$zip_filter", LABEL)
.cfg(HOST)
.exec()