diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html
index 4011a0f6969fb6..2af4ae112c8f19 100644
--- a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html
+++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/tags.html
@@ -88,8 +88,9 @@
exclusive
keyword will force the test to be run in the
"exclusive" mode, ensuring that no other tests are running at the
same time. Such tests will be executed in serial fashion after all build
- activity and non-exclusive tests have been completed. They will also always
- run locally and thus without sandboxing.
+ activity and non-exclusive tests have been completed. Remote execution is
+ disabled for such tests because Bazel doesn't have control over what's
+ running on a remote machine.
manual
keyword will force the test target to not be included in target pattern
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/TestTargetProperties.java b/src/main/java/com/google/devtools/build/lib/analysis/test/TestTargetProperties.java
index e7a83540995e89..b5f51ceb0c7d85 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/test/TestTargetProperties.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/test/TestTargetProperties.java
@@ -88,9 +88,12 @@ private static ResourceSet getResourceSetFromSize(TestSize size) {
Map executionInfo = Maps.newLinkedHashMap();
executionInfo.putAll(TargetUtils.getExecutionInfo(rule));
- if (TargetUtils.isLocalTestRule(rule) || TargetUtils.isExclusiveTestRule(rule)) {
+ if (TargetUtils.isLocalTestRule(rule)) {
executionInfo.put(ExecutionRequirements.LOCAL, "");
}
+ if (TargetUtils.isExclusiveTestRule(rule)) {
+ executionInfo.put(ExecutionRequirements.NO_REMOTE_EXEC, "");
+ }
if (executionRequirements != null) {
// This will overwrite whatever TargetUtils put there, which might be confusing.
diff --git a/src/test/java/com/google/devtools/build/lib/rules/test/TestTargetPropertiesTest.java b/src/test/java/com/google/devtools/build/lib/rules/test/TestTargetPropertiesTest.java
index 5571f5fcde4ec7..bdb86e1c90a8f1 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/test/TestTargetPropertiesTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/test/TestTargetPropertiesTest.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
+import com.google.devtools.build.lib.actions.ExecutionRequirements;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.test.TestProvider;
@@ -50,4 +51,23 @@ public void testTestWithCpusTagHasCorrectLocalResourcesEstimate() throws Excepti
.getLocalResourceUsage(testAction.getOwner().getLabel(), false);
assertThat(localResourceUsage.getCpuUsage()).isEqualTo(4.0);
}
+
+ @Test
+ public void testTestWithExclusiveDisablesRemoteExecution() throws Exception {
+ scratch.file("tests/test.sh", "#!/bin/bash", "exit 0");
+ scratch.file(
+ "tests/BUILD",
+ "sh_test(",
+ " name = 'test',",
+ " size = 'small',",
+ " srcs = ['test.sh'],",
+ " tags = ['exclusive'],",
+ ")");
+ ConfiguredTarget testTarget = getConfiguredTarget("//tests:test");
+ TestRunnerAction testAction =
+ (TestRunnerAction)
+ getGeneratingAction(TestProvider.getTestStatusArtifacts(testTarget).get(0));
+ assertThat(testAction.getExecutionInfo()).containsKey(ExecutionRequirements.NO_REMOTE_EXEC);
+ assertThat(testAction.getExecutionInfo()).hasSize(1);
+ }
}
diff --git a/src/test/shell/bazel/remote/remote_execution_test.sh b/src/test/shell/bazel/remote/remote_execution_test.sh
index 328bae19efa1c6..a70ce9f7d31e81 100755
--- a/src/test/shell/bazel/remote/remote_execution_test.sh
+++ b/src/test/shell/bazel/remote/remote_execution_test.sh
@@ -1131,6 +1131,34 @@ EOF
expect_log "uri:.*bytestream://localhost"
}
+function test_exclusive_tag() {
+ # Test that the exclusive tag works with the remote cache.
+ mkdir -p a
+ cat > a/success.sh <<'EOF'
+#!/bin/sh
+exit 0
+EOF
+ chmod 755 a/success.sh
+ cat > a/BUILD <<'EOF'
+sh_test(
+ name = "success_test",
+ srcs = ["success.sh"],
+ tags = ["exclusive"],
+)
+EOF
+
+ bazel test \
+ --remote_cache=grpc://localhost:${worker_port} \
+ //a:success_test || fail "Failed to test //a:success_test"
+
+ bazel test \
+ --remote_cache=grpc://localhost:${worker_port} \
+ --nocache_test_results \
+ //a:success_test >& $TEST_log || fail "Failed to test //a:success_test"
+
+ expect_log "remote cache hit"
+}
+
# TODO(alpha): Add a test that fails remote execution when remote worker
# supports sandbox.