From 8d8abe46bd7ab0c87beb31d97c9185760d762d79 Mon Sep 17 00:00:00 2001 From: Eduardo Colaco Date: Thu, 3 Nov 2016 15:33:47 +0000 Subject: Writes a machine readable representation of BuildEvents to a file (varint delimited). Adds --experimental_build_event_binary_file option that enables varint delimited proto loggging to the specified file path Adds varint delimited BuildEventStreamTransport and BuildEventStreamerModule Adds BuildEventStreamerModule for configuring and setting up BuildEventStreamer and its associated BuildEventTransports. Adds BuildEventTransportFactory which creates a Set of transports from command options. Moves BuildEventStreamer configuration from BlazeCommandDispatcher and BuildEventStreamerModule -- Change-Id: If71f2b58654879c2509206da47e6d1a846bf397f Reviewed-on: https://bazel-review.googlesource.com/#/c/7010/ MOS_MIGRATED_REVID=138073726 --- .../build/lib/buildeventstream/transports/BUILD | 24 ++++ .../transports/BinaryFormatFileTransportTest.java | 90 ++++++++++++++ .../transports/BuildEventTransportFactoryTest.java | 130 +++++++++++++++++++++ .../transports/TextFormatFileTransportTest.java | 91 +++++++++++++++ 4 files changed, 335 insertions(+) create mode 100644 src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD create mode 100644 src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransportTest.java create mode 100644 src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java create mode 100644 src/test/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransportTest.java (limited to 'src/test/java/com/google/devtools/build/lib/buildeventstream/transports') diff --git a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD new file mode 100644 index 0000000000..6472d8aa21 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BUILD @@ -0,0 +1,24 @@ +filegroup( + name = "srcs", + srcs = glob(["**"]), + visibility = ["//src/test/java/com/google/devtools/build/lib:__pkg__"], +) + +java_test( + name = "BuildEventTransportTest", + srcs = glob(["*.java"]), + test_class = "com.google.devtools.build.lib.AllTests", + runtime_deps = ["//src/test/java/com/google/devtools/build/lib:test_runner"], + deps = [ + "//src/main/java/com/google/devtools/build/lib:buildeventstream", + "//src/main/java/com/google/devtools/build/lib:runtime", + "//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto", + "//src/main/java/com/google/devtools/build/lib/buildeventstream/transports", + "//src/test/java/com/google/devtools/build/lib:packages_testutil", + "//third_party:guava", + "//third_party:junit4", + "//third_party:mockito", + "//third_party:truth", + "//third_party/protobuf", + ], +) diff --git a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransportTest.java b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransportTest.java new file mode 100644 index 0000000000..e241e8410c --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BinaryFormatFileTransportTest.java @@ -0,0 +1,90 @@ +// Copyright 2016 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.buildeventstream.transports; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; + +import com.google.devtools.build.lib.buildeventstream.BuildEvent; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildStarted; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.Progress; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.TargetComplete; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +/** Tests {@link BinaryFormatFileTransport}. **/ +@RunWith(JUnit4.class) +public class BinaryFormatFileTransportTest { + + @Rule public TemporaryFolder tmp = new TemporaryFolder(); + + @Mock public BuildEvent buildEvent; + + @Before + public void initMocks() { + MockitoAnnotations.initMocks(this); + } + + @After + public void validateMocks() { + Mockito.validateMockitoUsage(); + } + + @Test + public void testCreatesFileAndWritesProtoTextFormat() throws IOException { + File output = tmp.newFile(); + + BuildEventStreamProtos.BuildEvent started = + BuildEventStreamProtos.BuildEvent.newBuilder() + .setStarted(BuildStarted.newBuilder().setCommand("build")) + .build(); + when(buildEvent.asStreamProto()).thenReturn(started); + BinaryFormatFileTransport transport = new BinaryFormatFileTransport(output.getAbsolutePath()); + transport.sendBuildEvent(buildEvent); + + BuildEventStreamProtos.BuildEvent progress = + BuildEventStreamProtos.BuildEvent.newBuilder().setProgress(Progress.newBuilder()).build(); + when(buildEvent.asStreamProto()).thenReturn(progress); + transport.sendBuildEvent(buildEvent); + + BuildEventStreamProtos.BuildEvent completed = + BuildEventStreamProtos.BuildEvent.newBuilder() + .setCompleted(TargetComplete.newBuilder().setSuccess(true)) + .build(); + when(buildEvent.asStreamProto()).thenReturn(completed); + transport.sendBuildEvent(buildEvent); + + transport.close(); + try (InputStream in = new FileInputStream(output)) { + assertThat(BuildEventStreamProtos.BuildEvent.parseDelimitedFrom(in)).isEqualTo(started); + assertThat(BuildEventStreamProtos.BuildEvent.parseDelimitedFrom(in)).isEqualTo(progress); + assertThat(BuildEventStreamProtos.BuildEvent.parseDelimitedFrom(in)).isEqualTo(completed); + assertThat(in.available()).isEqualTo(0); + } + } +} diff --git a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java new file mode 100644 index 0000000000..8d4aa520db --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/BuildEventTransportFactoryTest.java @@ -0,0 +1,130 @@ +// Copyright 2016 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.buildeventstream.transports; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; + +import com.google.common.base.Function; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.buildeventstream.BuildEvent; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildStarted; +import com.google.devtools.build.lib.buildeventstream.BuildEventTransport; +import java.io.File; +import java.io.IOException; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +/** Tests {@link BuildEventTransportFactory}. **/ +@RunWith(JUnit4.class) +public class BuildEventTransportFactoryTest { + + private static final Function> GET_CLASS = + new Function>() { + @Override + public Class apply(Object o) { + return o.getClass(); + } + }; + + private static final BuildEventStreamProtos.BuildEvent BUILD_EVENT_AS_PROTO = + BuildEventStreamProtos.BuildEvent.newBuilder() + .setStarted(BuildStarted.newBuilder().setCommand("build")) + .build(); + + @Rule public TemporaryFolder tmp = new TemporaryFolder(); + + @Mock public BuildEventStreamOptions options; + + @Mock public BuildEvent buildEvent; + + @Before + public void before() { + MockitoAnnotations.initMocks(this); + when(buildEvent.asStreamProto()).thenReturn(BUILD_EVENT_AS_PROTO); + } + + @After + public void validateMocks() { + Mockito.validateMockitoUsage(); + } + + @Test + public void testCreatesTextFormatFileTransport() throws IOException { + File textFile = tmp.newFile(); + when(options.getBuildEventTextFile()).thenReturn(textFile.getAbsolutePath()); + when(options.getBuildEventBinaryFile()).thenReturn(""); + ImmutableSet transports = + BuildEventTransportFactory.createFromOptions(options); + assertThat(FluentIterable.from(transports).transform(GET_CLASS)) + .containsExactly(TextFormatFileTransport.class); + sendEventsAndClose(buildEvent, transports); + assertThat(textFile.exists()).isTrue(); + } + + @Test + public void testCreatesBinaryFormatFileTransport() throws IOException { + File binaryFile = tmp.newFile(); + when(options.getBuildEventTextFile()).thenReturn(""); + when(options.getBuildEventBinaryFile()).thenReturn(binaryFile.getAbsolutePath()); + ImmutableSet transports = + BuildEventTransportFactory.createFromOptions(options); + assertThat(FluentIterable.from(transports).transform(GET_CLASS)) + .containsExactly(BinaryFormatFileTransport.class); + sendEventsAndClose(buildEvent, transports); + assertThat(binaryFile.exists()).isTrue(); + } + + @Test + public void testCreatesAllTransports() throws IOException { + File textFile = tmp.newFile(); + File binaryFile = tmp.newFile(); + when(options.getBuildEventTextFile()).thenReturn(textFile.getAbsolutePath()); + when(options.getBuildEventBinaryFile()).thenReturn(binaryFile.getAbsolutePath()); + ImmutableSet transports = + BuildEventTransportFactory.createFromOptions(options); + assertThat(FluentIterable.from(transports).transform(GET_CLASS)) + .containsExactly(TextFormatFileTransport.class, BinaryFormatFileTransport.class); + sendEventsAndClose(buildEvent, transports); + assertThat(textFile.exists()).isTrue(); + assertThat(binaryFile.exists()).isTrue(); + } + + @Test + public void testCreatesNoTransports() throws IOException { + when(options.getBuildEventTextFile()).thenReturn(""); + ImmutableSet transports = + BuildEventTransportFactory.createFromOptions(options); + assertThat(transports).isEmpty(); + } + + private void sendEventsAndClose(BuildEvent event, Iterable transports) + throws IOException{ + for (BuildEventTransport transport : transports) { + transport.sendBuildEvent(event); + transport.close(); + } + } +} diff --git a/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransportTest.java b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransportTest.java new file mode 100644 index 0000000000..798e8557c8 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/buildeventstream/transports/TextFormatFileTransportTest.java @@ -0,0 +1,91 @@ +// Copyright 2016 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.buildeventstream.transports; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; + +import com.google.common.base.Joiner; +import com.google.common.io.Files; +import com.google.devtools.build.lib.buildeventstream.BuildEvent; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildStarted; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.Progress; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.TargetComplete; +import com.google.protobuf.TextFormat; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +/** Tests {@link TextFormatFileTransport}. **/ +@RunWith(JUnit4.class) +public class TextFormatFileTransportTest { + + @Rule public TemporaryFolder tmp = new TemporaryFolder(); + + @Mock public BuildEvent buildEvent; + + @Before + public void initMocks() { + MockitoAnnotations.initMocks(this); + } + + @After + public void validateMocks() { + Mockito.validateMockitoUsage(); + } + + @Test + public void testCreatesFileAndWritesProtoTextFormat() throws IOException { + File output = tmp.newFile(); + + BuildEventStreamProtos.BuildEvent started = + BuildEventStreamProtos.BuildEvent.newBuilder() + .setStarted(BuildStarted.newBuilder().setCommand("build")) + .build(); + when(buildEvent.asStreamProto()).thenReturn(started); + TextFormatFileTransport transport = new TextFormatFileTransport(output.getAbsolutePath()); + transport.sendBuildEvent(buildEvent); + + BuildEventStreamProtos.BuildEvent progress = + BuildEventStreamProtos.BuildEvent.newBuilder().setProgress(Progress.newBuilder()).build(); + when(buildEvent.asStreamProto()).thenReturn(progress); + transport.sendBuildEvent(buildEvent); + + BuildEventStreamProtos.BuildEvent completed = + BuildEventStreamProtos.BuildEvent.newBuilder() + .setCompleted(TargetComplete.newBuilder().setSuccess(true)) + .build(); + when(buildEvent.asStreamProto()).thenReturn(completed); + transport.sendBuildEvent(buildEvent); + + transport.close(); + String contents = + Joiner.on(System.lineSeparator()).join(Files.readLines(output, StandardCharsets.UTF_8)); + assertThat(contents).contains(TextFormat.printToString(started)); + assertThat(contents).contains(TextFormat.printToString(progress)); + assertThat(contents).contains(TextFormat.printToString(completed)); + } +} -- cgit v1.2.3