A list of log paths will be provided in build output. These log paths are aggregated from the metadataLog field on the SpawnResult. RELNOTES: A list of log paths will be provided in build output. PiperOrigin-RevId: 268278303
diff --git a/src/test/java/com/google/devtools/build/lib/actions/SpawnResultTest.java b/src/test/java/com/google/devtools/build/lib/actions/SpawnResultTest.java index 6bedfc9..7d55123 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/SpawnResultTest.java +++ b/src/test/java/com/google/devtools/build/lib/actions/SpawnResultTest.java
@@ -14,8 +14,12 @@ package com.google.devtools.build.lib.actions; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; +import com.google.devtools.build.lib.actions.SpawnResult.MetadataLog; import com.google.devtools.build.lib.actions.SpawnResult.Status; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.util.FileSystems; import com.google.protobuf.ByteString; import java.time.Duration; import org.junit.Test; @@ -70,4 +74,20 @@ assertThat(r.getInMemoryOutput(null)).isEqualTo(null); assertThat(r.getInMemoryOutput(ActionInputHelper.fromPath("/does/not/exist"))).isEqualTo(null); } + + @Test + public void getSpawnResultLogs() throws Exception { + SpawnResult.Builder builder = + new SpawnResult.Builder().setStatus(Status.SUCCESS).setExitCode(0).setRunnerName("test"); + + assertThat(builder.build().getActionMetadataLog()).isEmpty(); + + String logName = "/path/to/logs.txt"; + Path logPath = FileSystems.getJavaIoFileSystem().getPath(logName); + MetadataLog metadataLog = new MetadataLog("test_metadata_log", logPath); + SpawnResult withLogs = builder.setActionMetadataLog(metadataLog).build(); + + assertThat(withLogs.getActionMetadataLog()).hasValue(metadataLog); + assertThat(withLogs.getActionMetadataLog().get().getFilePath()).isEqualTo(logPath); + } }
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java index 0bfb233..021f247 100644 --- a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java +++ b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
@@ -33,6 +33,7 @@ import com.google.devtools.build.lib.actions.ArtifactRoot; import com.google.devtools.build.lib.actions.CompletionContext; import com.google.devtools.build.lib.actions.EventReportingArtifacts; +import com.google.devtools.build.lib.actions.SpawnResult.MetadataLog; import com.google.devtools.build.lib.actions.util.ActionsTestUtil; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ServerDirectories; @@ -50,6 +51,7 @@ import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos; import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.Aborted.AbortReason; import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.NamedSetOfFilesId; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.File; import com.google.devtools.build.lib.buildeventstream.BuildEventTransport; import com.google.devtools.build.lib.buildeventstream.BuildEventTransportClosedEvent; import com.google.devtools.build.lib.buildeventstream.BuildEventWithConfiguration; @@ -70,6 +72,7 @@ import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.Root; +import com.google.devtools.build.lib.vfs.util.FileSystems; import com.google.devtools.common.options.Options; import java.util.ArrayList; import java.util.Collection; @@ -115,6 +118,30 @@ streamer = null; } + private static BuildEventContext getTestBuildEventContext(ArtifactGroupNamer artifactGroupNamer) { + return new BuildEventContext() { + @Override + public ArtifactGroupNamer artifactGroupNamer() { + return artifactGroupNamer; + } + + @Override + public PathConverter pathConverter() { + return new PathConverter() { + @Override + public String apply(Path path) { + return path.toString(); + } + }; + } + + @Override + public BuildEventProtocolOptions getOptions() { + return Options.getDefaults(BuildEventProtocolOptions.class); + } + }; + } + private static final ActionExecutedEvent SUCCESSFUL_ACTION_EXECUTED_EVENT = new ActionExecutedEvent( ActionsTestUtil.DUMMY_ARTIFACT.getExecPath(), @@ -123,6 +150,7 @@ ActionsTestUtil.DUMMY_ARTIFACT.getPath(), /* stdout= */ null, /* stderr= */ null, + /* actionMetadataLogs= */ ImmutableList.of(), ErrorTiming.NO_ERROR); private static class RecordingBuildEventTransport implements BuildEventTransport { @@ -147,29 +175,7 @@ @Override public synchronized void sendBuildEvent(BuildEvent event) { events.add(event); - eventsAsProtos.add( - event.asStreamProto( - new BuildEventContext() { - @Override - public ArtifactGroupNamer artifactGroupNamer() { - return artifactGroupNamer; - } - - @Override - public PathConverter pathConverter() { - return new PathConverter() { - @Override - public String apply(Path path) { - return path.toString(); - } - }; - } - - @Override - public BuildEventProtocolOptions getOptions() { - return Options.getDefaults(BuildEventProtocolOptions.class); - } - })); + eventsAsProtos.add(event.asStreamProto(getTestBuildEventContext(this.artifactGroupNamer))); } @Override @@ -1144,6 +1150,7 @@ ActionsTestUtil.DUMMY_ARTIFACT.getPath(), /* stdout= */ null, /* stderr= */ null, + /* actionMetadataLogs= */ ImmutableList.of(), ErrorTiming.BEFORE_EXECUTION); streamer.buildEvent(SUCCESSFUL_ACTION_EXECUTED_EVENT); @@ -1178,6 +1185,7 @@ ActionsTestUtil.DUMMY_ARTIFACT.getPath(), /* stdout= */ null, /* stderr= */ null, + /* actionMetadataLogs= */ ImmutableList.of(), ErrorTiming.BEFORE_EXECUTION); streamer.buildEvent(SUCCESSFUL_ACTION_EXECUTED_EVENT); @@ -1325,4 +1333,69 @@ } return new BuildCompleteEvent(result); } + + private static ActionExecutedEvent createActionExecutedEventWithLogs( + ImmutableList<MetadataLog> metadataLogs) { + return new ActionExecutedEvent( + ActionsTestUtil.DUMMY_ARTIFACT.getExecPath(), + new ActionsTestUtil.NullAction(), + /* exception= */ null, + ActionsTestUtil.DUMMY_ARTIFACT.getPath(), + /* stdout= */ null, + /* stderr= */ null, + metadataLogs, + ErrorTiming.NO_ERROR); + } + + @Test + public void testActionExecutedEventLogsConstructor() { + String metadataLogName = "action_metadata"; + Path testPath1 = FileSystems.getJavaIoFileSystem().getPath("/path/to/logs-1"); + Path testPath2 = FileSystems.getJavaIoFileSystem().getPath("/path/to/logs-2"); + MetadataLog testMetadataLog1 = new MetadataLog(metadataLogName, testPath1); + MetadataLog testMetadataLog2 = new MetadataLog(metadataLogName, testPath2); + + ActionExecutedEvent withLogsEvent = + createActionExecutedEventWithLogs(ImmutableList.of(testMetadataLog1, testMetadataLog2)); + ActionExecutedEvent withNoLogsEvent = SUCCESSFUL_ACTION_EXECUTED_EVENT; + + assertWithMessage("List parameter should return list of log path values") + .that(withLogsEvent.getActionMetadataLogs()) + .containsExactly(testMetadataLog1, testMetadataLog2); + assertWithMessage("Null logs parameter should return empty list.") + .that(withNoLogsEvent.getActionMetadataLogs()) + .isEmpty(); + } + + @Test + public void testActionExcutedEventProtoLogs() { + String metadataLogName = "action_metadata"; + Path testPath1 = FileSystems.getJavaIoFileSystem().getPath("/path/to/logs-1"); + Path testPath2 = FileSystems.getJavaIoFileSystem().getPath("/path/to/logs-2"); + + ActionExecutedEvent withLogsEvent = + createActionExecutedEventWithLogs( + ImmutableList.of( + new MetadataLog(metadataLogName, testPath1), + new MetadataLog(metadataLogName, testPath2))); + ActionExecutedEvent withNoLogsEvents = SUCCESSFUL_ACTION_EXECUTED_EVENT; + + BuildEventStreamProtos.BuildEvent buildEventLogs = + withLogsEvent.asStreamProto(getTestBuildEventContext(artifactGroupNamer)); + BuildEventStreamProtos.BuildEvent buildEventNoLogs = + withNoLogsEvents.asStreamProto(getTestBuildEventContext(artifactGroupNamer)); + + assertWithMessage("With logs build event action should contain 2 log files") + .that(buildEventLogs.getAction().getActionMetadataLogsCount()) + .isEqualTo(2); + assertWithMessage("No logs build event action should contain 0 log files") + .that(buildEventNoLogs.getAction().getActionMetadataLogsCount()) + .isEqualTo(0); + assertWithMessage("Event action should contains the two paths") + .that( + buildEventLogs.getAction().getActionMetadataLogsList().stream() + .map(File::getUri) + .collect(ImmutableList.toImmutableList())) + .containsExactly(testPath1.toString(), testPath2.toString()); + } }