Also generate a build stream for fetch

Bazel's fetch command is also related to building. So generate
a build-event stream for this as well. As a first step, generate
a minimal stream with only the console output by white listing
the command, setting the separateFinishedEvent flag on the
NoBuildEvent, and generating a NoBuildRequestFinishedEvent.

Change-Id: Iee0c4e84ee5a060565ac86692a2b1917691a84ab
PiperOrigin-RevId: 161782448
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 15fbf12..dadb76a 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -784,6 +784,7 @@
         ":packages-internal",
         ":runtime",
         ":util",
+        "//src/main/java/com/google/devtools/build/lib:build-base",
         "//src/main/java/com/google/devtools/build/lib/query2",
         "//src/main/java/com/google/devtools/build/lib/query2:query-engine",
         "//src/main/java/com/google/devtools/common/options",
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/commands/FetchCommand.java b/src/main/java/com/google/devtools/build/lib/bazel/commands/FetchCommand.java
index 04e3ccf..b47fa35 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/commands/FetchCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/commands/FetchCommand.java
@@ -17,6 +17,8 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.analysis.NoBuildEvent;
+import com.google.devtools.build.lib.analysis.NoBuildRequestFinishedEvent;
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.pkgcache.PackageCacheOptions;
@@ -109,6 +111,7 @@
       return ExitCode.COMMAND_LINE_ERROR;
     }
 
+    env.getReporter().post(new NoBuildEvent(env.getCommandName(), env.getCommandStartTime(), true));
     // 2. Evaluate expression:
     try {
       queryEnv.evaluateQuery(expr, new ThreadSafeOutputFormatterCallback<Target>() {
@@ -118,10 +121,18 @@
         }
       });
     } catch (InterruptedException e) {
+      env.getReporter()
+          .post(
+              new NoBuildRequestFinishedEvent(
+                  ExitCode.COMMAND_LINE_ERROR, env.getRuntime().getClock().currentTimeMillis()));
       return ExitCode.COMMAND_LINE_ERROR;
     } catch (QueryException e) {
       // Keep consistent with reportBuildFileError()
       env.getReporter().handle(Event.error(e.getMessage()));
+      env.getReporter()
+          .post(
+              new NoBuildRequestFinishedEvent(
+                  ExitCode.COMMAND_LINE_ERROR, env.getRuntime().getClock().currentTimeMillis()));
       return ExitCode.COMMAND_LINE_ERROR;
     } catch (IOException e) {
       // Should be impossible since our OutputFormatterCallback doesn't throw IOException.
@@ -130,6 +141,10 @@
 
     env.getReporter().handle(
         Event.progress("All external dependencies fetched successfully."));
+    env.getReporter()
+        .post(
+            new NoBuildRequestFinishedEvent(
+                ExitCode.SUCCESS, env.getRuntime().getClock().currentTimeMillis()));
     return ExitCode.SUCCESS;
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModule.java b/src/main/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModule.java
index 0ba8d60..cdbc58a 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModule.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventservice/BazelBuildEventServiceModule.java
@@ -42,6 +42,6 @@
 
   @Override
   protected Set<String> whitelistedCommands() {
-    return ImmutableSet.of("build", "test", "run", "query", "coverage", "mobile-install");
+    return ImmutableSet.of("fetch", "build", "test", "run", "query", "coverage", "mobile-install");
   }
 }
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index a388293..fe94b75 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -110,6 +110,13 @@
 )
 
 sh_test(
+    name = "bazel_build_event_stream_test",
+    size = "medium",
+    srcs = ["bazel_build_event_stream_test.sh"],
+    data = [":test-deps"],
+)
+
+sh_test(
     name = "bazel_rules_test",
     size = "large",
     srcs = ["bazel_rules_test.sh"],
diff --git a/src/test/shell/bazel/bazel_build_event_stream_test.sh b/src/test/shell/bazel/bazel_build_event_stream_test.sh
new file mode 100644
index 0000000..4e772b5
--- /dev/null
+++ b/src/test/shell/bazel/bazel_build_event_stream_test.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+#
+# 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.
+#
+# An end-to-end test for bazel-specific parts of the build-event stream.
+
+# Load the test setup defined in the parent directory
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "${CURRENT_DIR}/../integration_test_setup.sh" \
+  || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
+
+#### SETUP #############################################################
+
+set -e
+
+function set_up() {
+  mkdir -p pkg
+  touch pkg/BUILD
+}
+
+#### TESTS #############################################################
+
+
+function test_fetch_test() {
+  # We expect the "fetch" command to generate at least a minimally useful
+  # build-event stream.
+  bazel shutdown
+  rm -f "${TEST_log}"
+  bazel fetch --build_event_text_file="${TEST_log}" //pkg/... \
+      || fail "bazel fetch failed"
+  [ -f "${TEST_log}" ] \
+      || fail "fetch did not generate requested build-event file"
+  expect_log '^started'
+  expect_log '^finished'
+  expect_log 'name: "SUCCESS"'
+}
+
+run_suite "Bazel-specific integration tests for the build-event stream"