Skip to content

Commit a144eef

Browse files
committed
Make test.xml a regular test action output
This ensures that BwoB correctly invalidates the action if `test.xml` is newly requested to be downloaded.
1 parent a63ccfe commit a144eef

File tree

4 files changed

+77
-14
lines changed

4 files changed

+77
-14
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,8 @@ private TestParams createTestAction()
388388

389389
Artifact.DerivedArtifact testLog =
390390
ruleContext.getPackageRelativeArtifact(dir.getRelative("test.log"), root);
391+
Artifact.DerivedArtifact testXml =
392+
ruleContext.getPackageRelativeArtifact(dir.getRelative("test.xml"), root);
391393
Artifact.DerivedArtifact cacheStatus =
392394
ruleContext.getPackageRelativeArtifact(dir.getRelative("test.cache_status"), root);
393395

@@ -421,6 +423,7 @@ private TestParams createTestAction()
421423
testXmlGeneratorExecutable,
422424
collectCoverageScript,
423425
testLog,
426+
testXml,
424427
cacheStatus,
425428
coverageArtifact,
426429
coverageDirectory,

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

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public class TestRunnerAction extends AbstractAction
118118
private final BuildConfigurationValue configuration;
119119
private final TestConfiguration testConfiguration;
120120
private final Artifact testLog;
121+
private final Artifact testXml;
121122
private final Artifact cacheStatus;
122123
private final PathFragment testWarningsPath;
123124
private final PathFragment unusedRunfilesLogPath;
@@ -128,7 +129,6 @@ public class TestRunnerAction extends AbstractAction
128129
private final PathFragment undeclaredOutputsManifestPath;
129130
private final PathFragment undeclaredOutputsAnnotationsPath;
130131
private final PathFragment undeclaredOutputsAnnotationsPbPath;
131-
private final PathFragment xmlOutputPath;
132132
@Nullable private final PathFragment testShard;
133133
private final PathFragment testExitSafe;
134134
private final PathFragment testStderr;
@@ -198,6 +198,7 @@ private static ImmutableSet<Artifact> nonNullAsSet(Artifact... artifacts) {
198198
Artifact testXmlGeneratorScript, // Must be in inputs
199199
@Nullable Artifact collectCoverageScript, // Must be in inputs, if not null
200200
Artifact testLog,
201+
Artifact testXml,
201202
Artifact cacheStatus,
202203
Artifact coverageArtifact,
203204
@Nullable Artifact coverageDirectory,
@@ -219,7 +220,12 @@ private static ImmutableSet<Artifact> nonNullAsSet(Artifact... artifacts) {
219220
owner,
220221
inputs,
221222
nonNullAsSet(
222-
testLog, cacheStatus, coverageArtifact, coverageDirectory, undeclaredOutputsDir));
223+
testLog,
224+
testXml,
225+
cacheStatus,
226+
coverageArtifact,
227+
coverageDirectory,
228+
undeclaredOutputsDir));
223229
Preconditions.checkState((collectCoverageScript == null) == (coverageArtifact == null));
224230
this.runfilesTree = runfilesTree;
225231
this.testSetupScript = testSetupScript;
@@ -228,6 +234,7 @@ private static ImmutableSet<Artifact> nonNullAsSet(Artifact... artifacts) {
228234
this.configuration = checkNotNull(configuration);
229235
this.testConfiguration = checkNotNull(configuration.getFragment(TestConfiguration.class));
230236
this.testLog = testLog;
237+
this.testXml = testXml;
231238
this.cacheStatus = cacheStatus;
232239
this.coverageData = coverageArtifact;
233240
this.coverageDirectory = coverageDirectory;
@@ -246,7 +253,6 @@ private static ImmutableSet<Artifact> nonNullAsSet(Artifact... artifacts) {
246253
this.testExitSafe = baseDir.getChild("test.exited_prematurely");
247254
// testShard Path should be set only if sharding is enabled.
248255
this.testShard = totalShards > 1 ? baseDir.getChild("test.shard") : null;
249-
this.xmlOutputPath = baseDir.getChild("test.xml");
250256
this.testWarningsPath = baseDir.getChild("test.warnings");
251257
this.unusedRunfilesLogPath = baseDir.getChild("test.unused_runfiles_log");
252258
this.testStderr = baseDir.getChild("test.err");
@@ -283,7 +289,6 @@ private static ImmutableSet<Artifact> nonNullAsSet(Artifact... artifacts) {
283289
ImmutableSet.Builder<PathFragment> filesToDeleteBuilder =
284290
ImmutableSet.<PathFragment>builder()
285291
.add(
286-
xmlOutputPath,
287292
testWarningsPath,
288293
unusedRunfilesLogPath,
289294
testStderr,
@@ -366,7 +371,6 @@ public boolean checkShardingSupport() {
366371

367372
public List<ActionInput> getSpawnOutputs() {
368373
final List<ActionInput> outputs = new ArrayList<>();
369-
outputs.add(ActionInputHelper.fromPath(getXmlOutputPath()));
370374
outputs.add(ActionInputHelper.fromPath(getExitSafeFile()));
371375
if (isSharded()) {
372376
outputs.add(ActionInputHelper.fromPath(getTestShard()));
@@ -773,7 +777,7 @@ public void setupEnvVariables(Map<String, String> env) {
773777
env.put("TEST_TOTAL_SHARDS", Integer.toString(getExecutionSettings().getTotalShards()));
774778
env.put("TEST_SHARD_STATUS_FILE", getTestShard().getPathString());
775779
}
776-
env.put("XML_OUTPUT_FILE", getXmlOutputPath().getPathString());
780+
env.put("XML_OUTPUT_FILE", testXml.getExecPathString());
777781

778782
if (!configuration.runfilesEnabled()) {
779783
// If runfiles are disabled, tell remote-runtest.sh/local-runtest.sh about that.
@@ -832,6 +836,10 @@ public Artifact getTestLog() {
832836
return testLog;
833837
}
834838

839+
public Artifact getTestXml() {
840+
return testXml;
841+
}
842+
835843
/** Returns all environment variables which must be set in order to run this test. */
836844
public ActionEnvironment getExtraTestEnv() {
837845
return extraTestEnv;
@@ -906,11 +914,6 @@ public PathFragment getInfrastructureFailureFile() {
906914
return testInfrastructureFailure;
907915
}
908916

909-
/** Returns path to the optionally created XML output file created by the test. */
910-
public PathFragment getXmlOutputPath() {
911-
return xmlOutputPath;
912-
}
913-
914917
/** Returns coverage data artifact or null if code coverage was not requested. */
915918
@Nullable
916919
public Artifact getCoverageData() {
@@ -1183,7 +1186,7 @@ public Path getInfrastructureFailureFile() {
11831186

11841187
/** Returns path to the optionally created XML output file created by the test. */
11851188
public Path getXmlOutputPath() {
1186-
return getPath(xmlOutputPath);
1189+
return getPath(testXml.getExecPath());
11871190
}
11881191

11891192
public Path getCoverageDirectory() {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ private static Spawn createXmlGeneratingSpawn(
450450
.getExecPath()
451451
.getCallablePathStringForOs(action.getExecutionSettings().getExecutionOs()),
452452
action.getTestLog().getExecPathString(),
453-
action.getXmlOutputPath().getPathString(),
453+
action.getTestXml().getExecPathString(),
454454
Integer.toString(result.getWallTimeInMs() / 1000),
455455
Integer.toString(result.exitCode()));
456456
ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.builder();
@@ -474,7 +474,7 @@ private static Spawn createXmlGeneratingSpawn(
474474
/* inputs= */ NestedSetBuilder.create(
475475
Order.STABLE_ORDER, action.getTestXmlGeneratorScript(), action.getTestLog()),
476476
/* tools= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
477-
/* outputs= */ ImmutableSet.of(ActionInputHelper.fromPath(action.getXmlOutputPath())),
477+
/* outputs= */ ImmutableSet.of(action.getTestXml()),
478478
/* mandatoryOutputs= */ null,
479479
SpawnAction.DEFAULT_RESOURCE_SET);
480480
}

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,63 @@ EOF
648648
assert_exists bazel-bin/a/test
649649
}
650650

651+
function test_download_regex_changed_with_action_cache_hit_for_test() {
652+
# Regression test for #25762
653+
# Test that changes to --remote_download_regex are effective when matching
654+
# test.xml even when the test is cached.
655+
656+
add_rules_shell "MODULE.bazel"
657+
mkdir -p a
658+
659+
cat > a/test.sh <<'EOF'
660+
#!/bin/sh
661+
662+
cat > "$XML_OUTPUT_FILE" <<EOF2
663+
<?xml version="1.0" encoding="UTF-8"?>
664+
<testsuites>
665+
<testsuite name="test" tests="1" failures="0" errors="0">
666+
<testcase name="test_case" status="run">
667+
<system-out>test_case succeeded.</system-out>
668+
</testcase>
669+
</testsuite>
670+
</testsuites>
671+
EOF2
672+
echo "hi" > "$TEST_UNDECLARED_OUTPUTS_DIR/out.txt"
673+
EOF
674+
675+
chmod +x a/test.sh
676+
677+
cat > a/BUILD <<EOF
678+
load("@rules_shell//shell:sh_test.bzl", "sh_test")
679+
sh_test(
680+
name = 'test',
681+
srcs = [ 'test.sh' ],
682+
)
683+
EOF
684+
685+
bazel test \
686+
--remote_executor=grpc://localhost:${worker_port} \
687+
--remote_download_minimal \
688+
//a:test >& $TEST_log || fail "Expected success"
689+
690+
rm -rf bazel-out bazel-testlogs
691+
692+
bazel test \
693+
--remote_executor=grpc://localhost:${worker_port} \
694+
--remote_download_minimal \
695+
//a:test >& $TEST_log || fail "Expected success"
696+
697+
assert_not_exists bazel-testlogs/a/test/test.xml
698+
699+
bazel test \
700+
--remote_executor=grpc://localhost:${worker_port} \
701+
--remote_download_minimal \
702+
--remote_download_regex='.*/test.xml' \
703+
//a:test >& $TEST_log || fail "Expected success"
704+
705+
assert_exists bazel-testlogs/a/test/test.xml
706+
}
707+
651708
function do_test_non_test_toplevel_targets() {
652709
# Regression test for https://github.com/bazelbuild/bazel/issues/17190.
653710
#

0 commit comments

Comments
 (0)