Skip to content

Commit 4d6e6db

Browse files
meteorcloudycoeuvre
authored andcommitted
Propagate test envs to xml generation action
Previously, we hardcode the envs of the xml generation action, which caused problem for process-wrapper because it's dynamically linked to some system libraries and the required PATH or LD_LIBRARY_PATH are not set. This change propagate the envs we set for the actual test action to the xml file generation action to make sure the env vars are correctly set and can also be controlled by --action_env and --test_env. Fixes bazelbuild#4137 Fixes bazelbuild#12579 Closes bazelbuild#12659. PiperOrigin-RevId: 347596753
1 parent ae56b54 commit 4d6e6db

File tree

3 files changed

+36
-18
lines changed

3 files changed

+36
-18
lines changed

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

+16-11
Original file line numberDiff line numberDiff line change
@@ -391,26 +391,30 @@ private static BuildEventStreamProtos.TestResult.ExecutionInfo extractExecutionI
391391
* A spawn to generate a test.xml file from the test log. This is only used if the test does not
392392
* generate a test.xml file itself.
393393
*/
394-
private static Spawn createXmlGeneratingSpawn(TestRunnerAction action, SpawnResult result) {
394+
private static Spawn createXmlGeneratingSpawn(
395+
TestRunnerAction action, ImmutableMap<String, String> testEnv, SpawnResult result) {
395396
ImmutableList<String> args =
396397
ImmutableList.of(
397398
action.getTestXmlGeneratorScript().getExecPath().getCallablePathString(),
398399
action.getTestLog().getExecPathString(),
399400
action.getXmlOutputPath().getPathString(),
400401
Long.toString(result.getWallTime().orElse(Duration.ZERO).getSeconds()),
401402
Integer.toString(result.exitCode()));
402-
403-
String testBinaryName =
404-
action.getExecutionSettings().getExecutable().getRootRelativePath().getCallablePathString();
403+
ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.builder();
404+
// "PATH" and "TEST_BINARY" are also required, they should always be set in testEnv.
405+
Preconditions.checkArgument(testEnv.containsKey("PATH"));
406+
Preconditions.checkArgument(testEnv.containsKey("TEST_BINARY"));
407+
envBuilder.putAll(testEnv).put("TEST_NAME", action.getTestName());
408+
// testEnv only contains TEST_SHARD_INDEX and TEST_TOTAL_SHARDS if the test action is sharded,
409+
// we need to set the default value when the action isn't sharded.
410+
if (!action.isSharded()) {
411+
envBuilder.put("TEST_SHARD_INDEX", "0");
412+
envBuilder.put("TEST_TOTAL_SHARDS", "0");
413+
}
405414
return new SimpleSpawn(
406415
action,
407416
args,
408-
ImmutableMap.of(
409-
"PATH", "/usr/bin:/bin",
410-
"TEST_SHARD_INDEX", Integer.toString(action.getShardNum()),
411-
"TEST_TOTAL_SHARDS", Integer.toString(action.getExecutionSettings().getTotalShards()),
412-
"TEST_NAME", action.getTestName(),
413-
"TEST_BINARY", testBinaryName),
417+
envBuilder.build(),
414418
// Pass the execution info of the action which is identical to the supported tags set on the
415419
// test target. In particular, this does not set the test timeout on the spawn.
416420
ImmutableMap.copyOf(action.getExecutionInfo()),
@@ -767,7 +771,8 @@ public TestAttemptContinuation execute()
767771
if (executionOptions.splitXmlGeneration
768772
&& fileOutErr.getOutputPath().exists()
769773
&& !xmlOutputPath.exists()) {
770-
Spawn xmlGeneratingSpawn = createXmlGeneratingSpawn(testAction, spawnResults.get(0));
774+
Spawn xmlGeneratingSpawn =
775+
createXmlGeneratingSpawn(testAction, spawn.getEnvironment(), spawnResults.get(0));
771776
SpawnStrategyResolver spawnStrategyResolver =
772777
actionExecutionContext.getContext(SpawnStrategyResolver.class);
773778
// We treat all failures to generate the test.xml here as catastrophic, and won't rerun

src/test/java/com/google/devtools/build/lib/exec/StandaloneTestStrategyTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public FakeActionExecutionContext(
143143
LostInputsCheck.NONE,
144144
fileOutErr,
145145
/*eventHandler=*/ null,
146-
/*clientEnv=*/ ImmutableMap.of(),
146+
/*clientEnv=*/ ImmutableMap.of("PATH", "/usr/bin:/bin"),
147147
/*topLevelFilesets=*/ ImmutableMap.of(),
148148
/*artifactExpander=*/ null,
149149
/*actionFileSystem=*/ null,

tools/test/windows/tw.cc

+19-6
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ struct Duration {
189189
bool FromString(const wchar_t* str);
190190
};
191191

192+
enum class MainType { kTestWrapperMain, kXmlWriterMain };
193+
enum class DeleteAfterwards { kEnabled, kDisabled };
194+
192195
void WriteStdout(const std::string& s) {
193196
DWORD written;
194197
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), s.c_str(), s.size(), &written,
@@ -1603,9 +1606,16 @@ std::string CreateErrorTag(int exit_code) {
16031606
}
16041607
}
16051608

1606-
bool ShouldCreateXml(const Path& xml_log, bool* result) {
1609+
bool ShouldCreateXml(const Path& xml_log, const MainType main_type,
1610+
bool* result) {
16071611
*result = true;
16081612

1613+
// If running from the xml generator binary, we should always create the xml
1614+
// file.
1615+
if (main_type == MainType::kXmlWriterMain) {
1616+
return true;
1617+
}
1618+
16091619
DWORD attr = GetFileAttributesW(AddUncPrefixMaybe(xml_log).c_str());
16101620
if (attr != INVALID_FILE_ATTRIBUTES) {
16111621
// The XML file already exists, maybe the test framework wrote it.
@@ -1630,9 +1640,10 @@ bool ShouldCreateXml(const Path& xml_log, bool* result) {
16301640

16311641
bool CreateXmlLog(const Path& output, const Path& test_outerr,
16321642
const Duration duration, const int exit_code,
1633-
const bool delete_afterwards) {
1643+
const DeleteAfterwards delete_afterwards,
1644+
const MainType main_type) {
16341645
bool should_create_xml;
1635-
if (!ShouldCreateXml(output, &should_create_xml)) {
1646+
if (!ShouldCreateXml(output, main_type, &should_create_xml)) {
16361647
LogErrorWithArg(__LINE__, "Failed to decide if XML log is needed",
16371648
output.Get());
16381649
return false;
@@ -1645,7 +1656,7 @@ bool CreateXmlLog(const Path& output, const Path& test_outerr,
16451656
// Delete the test's outerr file after we have the XML file.
16461657
// We don't care if this succeeds or not, because the outerr file is not a
16471658
// declared output.
1648-
if (delete_afterwards) {
1659+
if (delete_afterwards == DeleteAfterwards::kEnabled) {
16491660
DeleteFileW(test_outerr.Get().c_str());
16501661
}
16511662
});
@@ -1904,7 +1915,8 @@ int TestWrapperMain(int argc, wchar_t** argv) {
19041915

19051916
Duration test_duration;
19061917
int result = RunSubprocess(test_path, args, test_outerr, &test_duration);
1907-
if (!CreateXmlLog(xml_log, test_outerr, test_duration, result, true) ||
1918+
if (!CreateXmlLog(xml_log, test_outerr, test_duration, result,
1919+
DeleteAfterwards::kEnabled, MainType::kTestWrapperMain) ||
19081920
!ArchiveUndeclaredOutputs(undecl) ||
19091921
!CreateUndeclaredOutputsAnnotations(undecl.annotations_dir,
19101922
undecl.annotations)) {
@@ -1921,7 +1933,8 @@ int XmlWriterMain(int argc, wchar_t** argv) {
19211933
if (!GetCwd(&cwd) ||
19221934
!ParseXmlWriterArgs(argc, argv, cwd, &test_outerr, &test_xml_log,
19231935
&duration, &exit_code) ||
1924-
!CreateXmlLog(test_xml_log, test_outerr, duration, exit_code, false)) {
1936+
!CreateXmlLog(test_xml_log, test_outerr, duration, exit_code,
1937+
DeleteAfterwards::kDisabled, MainType::kXmlWriterMain)) {
19251938
return 1;
19261939
}
19271940

0 commit comments

Comments
 (0)