Skip to content

Commit 4a47ad5

Browse files
committed
Actually check TEST_SHARD_STATUS_FILE has been touched
Adds the missing check that a test runner running a sharded test actually declares support for sharding by generating the `TEST_SHARD_STATUS_FILE`. Previously, if it didn't, each shard would silently run all tests. This new behavior is guarded by the new `--incompatible_check_sharding_support` flag. Closes #18236. PiperOrigin-RevId: 530259354 Change-Id: If3b01b2c796e66ad7a77e542145efe3ab412eae9
1 parent 84b45ae commit 4a47ad5

File tree

7 files changed

+126
-2
lines changed

7 files changed

+126
-2
lines changed

site/en/reference/test-encyclopedia.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,9 @@ index, beginning at 0. Runners use this information to select which tests to
223223
run - for example, using a round-robin strategy. Not all test runners support
224224
sharding. If a runner supports sharding, it must create or update the last
225225
modified date of the file specified by
226-
[`TEST_SHARD_STATUS_FILE`](#initial-conditions). Otherwise, Bazel assumes it
227-
does not support sharding and will not launch additional runners.
226+
[`TEST_SHARD_STATUS_FILE`](#initial-conditions). Otherwise, if
227+
[`--incompatible_check_sharding_support`](/reference/command-line-reference#flag--incompatible_check_sharding_support)
228+
is enabled, Bazel will fail the test if it is sharded.
228229

229230
## Initial conditions {:#initial-conditions}
230231

src/main/java/com/google/devtools/build/lib/analysis/test/TestConfiguration.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,19 @@ public static class TestOptions extends FragmentOptions {
280280
help = "If true, undeclared test outputs will be archived in a zip file.")
281281
public boolean zipUndeclaredTestOutputs;
282282

283+
@Option(
284+
name = "incompatible_check_sharding_support",
285+
defaultValue = "false",
286+
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
287+
metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE},
288+
effectTags = {OptionEffectTag.UNKNOWN},
289+
help =
290+
"If true, Bazel will fail a sharded test if the test runner does not indicate that it "
291+
+ "supports sharding by touching the file at the path in TEST_SHARD_STATUS_FILE. "
292+
+ "If false, a test runner that does not support sharding will lead to all tests "
293+
+ "running in each shard.")
294+
public boolean checkShardingSupport;
295+
283296
@Override
284297
public FragmentOptions getHost() {
285298
// Options here are either:
@@ -380,6 +393,10 @@ public boolean getZipUndeclaredTestOutputs() {
380393
return options.zipUndeclaredTestOutputs;
381394
}
382395

396+
public boolean checkShardingSupport() {
397+
return options.checkShardingSupport;
398+
}
399+
383400
/**
384401
* Option converter that han handle two styles of value for "--runs_per_test":
385402
*

src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ public boolean showsOutputUnconditionally() {
336336
return true;
337337
}
338338

339+
public boolean checkShardingSupport() {
340+
return testConfiguration.checkShardingSupport();
341+
}
342+
339343
public List<ActionInput> getSpawnOutputs() {
340344
final List<ActionInput> outputs = new ArrayList<>();
341345
outputs.add(ActionInputHelper.fromPath(getXmlOutputPath()));

src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,25 @@ public TestAttemptContinuation execute()
747747
}
748748
long endTimeMillis = actionExecutionContext.getClock().currentTimeMillis();
749749

750+
if (testAction.isSharded()) {
751+
if (testAction.checkShardingSupport()
752+
&& !actionExecutionContext
753+
.getPathResolver()
754+
.convertPath(resolvedPaths.getTestShard())
755+
.exists()) {
756+
TestExecException e =
757+
createTestExecException(
758+
TestAction.Code.LOCAL_TEST_PREREQ_UNMET,
759+
"Sharding requested, but the test runner did not advertise support for it by "
760+
+ "touching TEST_SHARD_STATUS_FILE. Either remove the 'shard_count' attribute, "
761+
+ "use a test runner that supports sharding or temporarily disable this check "
762+
+ "via --noincompatible_check_sharding_support.");
763+
closeSuppressed(e, streamed);
764+
closeSuppressed(e, fileOutErr);
765+
throw e;
766+
}
767+
}
768+
750769
// SpawnActionContext guarantees the first entry to correspond to the spawn passed in (there
751770
// may be additional entries due to tree artifact handling).
752771
SpawnResult primaryResult = spawnResults.get(0);

src/test/py/bazel/bazel_windows_test.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,41 @@ def testZipUndeclaredTestOutputs(self):
451451
self.assertTrue(os.path.exists(output_file))
452452
self.assertFalse(os.path.exists(output_zip))
453453

454+
def testTestShardStatusFile(self):
455+
self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
456+
self.ScratchFile(
457+
'BUILD',
458+
[
459+
'sh_test(',
460+
' name = "foo_test",',
461+
' srcs = ["foo.sh"],',
462+
' shard_count = 2,',
463+
')',
464+
],
465+
)
466+
self.ScratchFile('foo.sh')
467+
468+
exit_code, stdout, stderr = self.RunBazel(
469+
['test', '--incompatible_check_sharding_support', '//:foo_test'],
470+
allow_failure=True,
471+
)
472+
# Check for "tests failed" exit code
473+
self.AssertExitCode(exit_code, 3, stderr, stdout)
474+
self.assertTrue(
475+
any(
476+
'Sharding requested, but the test runner did not advertise support'
477+
' for it by touching TEST_SHARD_STATUS_FILE.'
478+
in line
479+
for line in stderr
480+
)
481+
)
482+
483+
self.ScratchFile('foo.sh', ['touch "$TEST_SHARD_STATUS_FILE"'])
484+
485+
self.RunBazel(
486+
['test', '--incompatible_check_sharding_support', '//:foo_test']
487+
)
488+
454489

455490
if __name__ == '__main__':
456491
unittest.main()

src/test/shell/bazel/bazel_test_test.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,4 +997,26 @@ EOF
997997
expect_log "<testcase name=\"x\""
998998
}
999999

1000+
function test_shard_status_file_checked() {
1001+
cat <<'EOF' > BUILD
1002+
sh_test(
1003+
name = 'x',
1004+
srcs = ['x.sh'],
1005+
shard_count = 2,
1006+
)
1007+
EOF
1008+
touch x.sh
1009+
chmod +x x.sh
1010+
1011+
bazel test \
1012+
--incompatible_check_sharding_support \
1013+
//:x &> $TEST_log && fail "expected failure"
1014+
expect_log "Sharding requested, but the test runner did not advertise support for it by touching TEST_SHARD_STATUS_FILE."
1015+
1016+
echo 'touch "$TEST_SHARD_STATUS_FILE"' > x.sh
1017+
bazel test \
1018+
--incompatible_check_sharding_support \
1019+
//:x &> $TEST_log || fail "expected success"
1020+
}
1021+
10001022
run_suite "bazel test tests"

src/test/shell/bazel/remote/remote_execution_test.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3271,4 +3271,30 @@ function test_external_cc_binary_tool_with_dynamic_deps_sibling_repository_layou
32713271
@other_repo//pkg:rule >& $TEST_log || fail "Build should succeed"
32723272
}
32733273

3274+
function test_shard_status_file_checked_remote_download_minimal() {
3275+
cat <<'EOF' > BUILD
3276+
sh_test(
3277+
name = 'x',
3278+
srcs = ['x.sh'],
3279+
shard_count = 2,
3280+
)
3281+
EOF
3282+
touch x.sh
3283+
chmod +x x.sh
3284+
3285+
bazel test \
3286+
--remote_executor=grpc://localhost:${worker_port} \
3287+
--incompatible_check_sharding_support \
3288+
--remote_download_minimal \
3289+
//:x &> $TEST_log && fail "expected failure"
3290+
expect_log "Sharding requested, but the test runner did not advertise support for it by touching TEST_SHARD_STATUS_FILE."
3291+
3292+
echo 'touch "$TEST_SHARD_STATUS_FILE"' > x.sh
3293+
bazel test \
3294+
--remote_executor=grpc://localhost:${worker_port} \
3295+
--incompatible_check_sharding_support \
3296+
--remote_download_minimal \
3297+
//:x &> $TEST_log || fail "expected success"
3298+
}
3299+
32743300
run_suite "Remote execution and remote cache tests"

0 commit comments

Comments
 (0)