Handle more event types in ExecutionGraphDumpModule.
This is mostly intended to catch actions which don't publish SpawnExecutedEvent, like SymlinkAction.
PiperOrigin-RevId: 475881450
Change-Id: Ie87cbe934548ae9124f20eb1a3b68ecf4aff0fab
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/ExecutionGraphDumpModuleTest.java b/src/test/java/com/google/devtools/build/lib/runtime/ExecutionGraphDumpModuleTest.java
index 07c30aa..0f9458c 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/ExecutionGraphDumpModuleTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/ExecutionGraphDumpModuleTest.java
@@ -27,6 +27,8 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.eventbus.EventBus;
+import com.google.devtools.build.lib.actions.Action;
+import com.google.devtools.build.lib.actions.ActionCompletionEvent;
import com.google.devtools.build.lib.actions.ActionInput;
import com.google.devtools.build.lib.actions.ActionInputHelper;
import com.google.devtools.build.lib.actions.ActionOwner;
@@ -46,6 +48,7 @@
import com.google.devtools.build.lib.buildtool.BuildResult;
import com.google.devtools.build.lib.buildtool.BuildResult.BuildToolLogCollection;
import com.google.devtools.build.lib.buildtool.buildevent.BuildCompleteEvent;
+import com.google.devtools.build.lib.clock.BlazeClock;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.exec.util.FakeOwner;
@@ -141,7 +144,8 @@
assertThat(nodes.get(0).getMetrics().getDurationMillis()).isEqualTo(1234L);
assertThat(nodes.get(0).getMetrics().getFetchMillis()).isEqualTo(0);
assertThat(nodes.get(0).getMetrics().getProcessOutputsMillis()).isEqualTo(3456);
- assertThat(nodes.get(0).getMetrics().getStartTimestampMillis()).isEqualTo(startTimeInstant.toEpochMilli());
+ assertThat(nodes.get(0).getMetrics().getStartTimestampMillis())
+ .isEqualTo(startTimeInstant.toEpochMilli());
assertThat(nodes.get(0).getIndex()).isEqualTo(0);
assertThat(nodes.get(0).getDependentIndexList()).isEmpty();
}
@@ -361,6 +365,81 @@
}
@Test
+ public void spawnAndAction_withSameOutputs() throws Exception {
+ // zstd is broken on Windows: https://github.com/bazelbuild/bazel/issues/16041
+ assumeTrue(OS.getCurrent() != OS.WINDOWS);
+
+ var buffer = new ByteArrayOutputStream();
+ startLogging(eventBus, UUID.randomUUID(), buffer, DependencyInfo.ALL);
+ var options = new ExecutionGraphDumpModule.ExecutionGraphDumpOptions();
+ options.logMissedActions = true;
+ module.setOptions(options);
+
+ module.spawnExecuted(
+ new SpawnExecutedEvent(
+ new SpawnBuilder().withOwnerPrimaryOutput(createOutputArtifact("foo/out")).build(),
+ createRemoteSpawnResult(Duration.ofMillis(200)),
+ Instant.ofEpochMilli(100)));
+ module.actionComplete(
+ new ActionCompletionEvent(
+ 0, new ActionsTestUtil.NullAction(createOutputArtifact("foo/out")), null));
+ module.buildComplete(new BuildCompleteEvent(new BuildResult(1000)));
+
+ assertThat(parse(buffer))
+ .containsExactly(
+ executionGraphNodeBuilderForSpawnBuilderSpawn()
+ .setIndex(0)
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
+ .setStartTimestampMillis(100)
+ .setDurationMillis(200)
+ .setOtherMillis(200))
+ .setRunner("remote")
+ .build());
+ }
+
+ @Test
+ public void spawnAndAction_withDifferentOutputs() throws Exception {
+ // zstd is broken on Windows: https://github.com/bazelbuild/bazel/issues/16041
+ assumeTrue(OS.getCurrent() != OS.WINDOWS);
+
+ var buffer = new ByteArrayOutputStream();
+ startLogging(eventBus, UUID.randomUUID(), buffer, DependencyInfo.ALL);
+ var options = new ExecutionGraphDumpModule.ExecutionGraphDumpOptions();
+ options.logMissedActions = true;
+ module.setOptions(options);
+ var nanosToMillis = BlazeClock.createNanosToMillisSinceEpochConverter();
+ module.setNanosToMillis(nanosToMillis);
+
+ module.spawnExecuted(
+ new SpawnExecutedEvent(
+ new SpawnBuilder().withOwnerPrimaryOutput(createOutputArtifact("foo/out")).build(),
+ createRemoteSpawnResult(Duration.ofMillis(200)),
+ Instant.ofEpochMilli(100)));
+ var action = new ActionsTestUtil.NullAction(createOutputArtifact("bar/out"));
+ module.actionComplete(new ActionCompletionEvent(0, action, null));
+ module.buildComplete(new BuildCompleteEvent(new BuildResult(1000)));
+
+ assertThat(parse(buffer))
+ .containsExactly(
+ executionGraphNodeBuilderForSpawnBuilderSpawn()
+ .setIndex(0)
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
+ .setStartTimestampMillis(100)
+ .setDurationMillis(200)
+ .setOtherMillis(200))
+ .setRunner("remote")
+ .build(),
+ executionGraphNodeBuilderForAction(action)
+ .setIndex(1)
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
+ .setStartTimestampMillis(nanosToMillis.toEpochMillis(0)))
+ .build());
+ }
+
+ @Test
public void multipleSpawnsWithSameOutput_recordsBothSpawnsWithRetry() throws Exception {
// zstd is broken on Windows: https://github.com/bazelbuild/bazel/issues/16041
assumeTrue(OS.getCurrent() != OS.WINDOWS);
@@ -381,7 +460,8 @@
.containsExactly(
executionGraphNodeBuilderForSpawnBuilderSpawn()
.setIndex(0)
- .setMetrics(ExecutionGraph.Metrics.newBuilder()
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
.setStartTimestampMillis(0)
.setDurationMillis(100)
.setOtherMillis(100))
@@ -389,10 +469,11 @@
.build(),
executionGraphNodeBuilderForSpawnBuilderSpawn()
.setIndex(1)
- .setMetrics(ExecutionGraph.Metrics.newBuilder()
- .setStartTimestampMillis(100)
- .setDurationMillis(200)
- .setOtherMillis(200))
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
+ .setStartTimestampMillis(100)
+ .setDurationMillis(200)
+ .setOtherMillis(200))
.setRunner("remote")
.setRetryOf(0)
.build())
@@ -455,18 +536,20 @@
.containsExactly(
executionGraphNodeBuilderForSpawnBuilderSpawn()
.setIndex(0)
- .setMetrics(ExecutionGraph.Metrics.newBuilder()
- .setStartTimestampMillis(0)
- .setDurationMillis(100)
- .setOtherMillis(100))
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
+ .setStartTimestampMillis(0)
+ .setDurationMillis(100)
+ .setOtherMillis(100))
.setRunner("local")
.build(),
executionGraphNodeBuilderForSpawnBuilderSpawn()
.setIndex(1)
- .setMetrics(ExecutionGraph.Metrics.newBuilder()
- .setStartTimestampMillis(10)
- .setDurationMillis(200)
- .setOtherMillis(200))
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
+ .setStartTimestampMillis(10)
+ .setDurationMillis(200)
+ .setOtherMillis(200))
.setRunner("remote")
.build())
.inOrder();
@@ -509,26 +592,29 @@
.containsExactly(
executionGraphNodeBuilderForSpawnBuilderSpawn()
.setIndex(0)
- .setMetrics(ExecutionGraph.Metrics.newBuilder()
- .setStartTimestampMillis(0)
- .setDurationMillis(100)
- .setOtherMillis(100))
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
+ .setStartTimestampMillis(0)
+ .setDurationMillis(100)
+ .setOtherMillis(100))
.setRunner("local")
.build(),
executionGraphNodeBuilderForSpawnBuilderSpawn()
.setIndex(1)
- .setMetrics(ExecutionGraph.Metrics.newBuilder()
- .setStartTimestampMillis(10)
- .setDurationMillis(200)
- .setOtherMillis(200))
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
+ .setStartTimestampMillis(10)
+ .setDurationMillis(200)
+ .setOtherMillis(200))
.setRunner("remote")
.build(),
executionGraphNodeBuilderForSpawnBuilderSpawn()
.setIndex(2)
- .setMetrics(ExecutionGraph.Metrics.newBuilder()
- .setStartTimestampMillis(300)
- .setDurationMillis(300)
- .setOtherMillis(300))
+ .setMetrics(
+ ExecutionGraph.Metrics.newBuilder()
+ .setStartTimestampMillis(300)
+ .setDurationMillis(300)
+ .setOtherMillis(300))
.setRunner("remote")
.addDependentIndex(0)
.build())
@@ -587,4 +673,14 @@
// This comes from SpawnResult.Builder, which defaults to an empty string.
.setRunnerSubtype("");
}
+
+ /**
+ * Creates a {@link ExecutionGraph.Node.Builder} with pre-populated defaults for action events.
+ */
+ private ExecutionGraph.Node.Builder executionGraphNodeBuilderForAction(Action action) {
+ return ExecutionGraph.Node.newBuilder()
+ .setDescription(action.prettyPrint())
+ .setTargetLabel(action.getOwner().getLabel().toString())
+ .setMnemonic(action.getMnemonic());
+ }
}