test-wrapper: add empty impl + Bazel flag

This commit adds:

- the skeleton implementation of the Windows
  native test wrapper

- a depenency on the native test wrapper from test
  rules, through the new $test_wrapper rule
  attribute

- the --windows_native_test_wrapper Bazel flag,
  which is currently a no-op

See https://github.com/bazelbuild/bazel/issues/5508

Change-Id: I8df95c8ce8bab53c51c257698ec95416065a836e

Closes #5854.

Change-Id: I2ffc78bceec5dd867af775b5878f105fa87c3dba
PiperOrigin-RevId: 208650699
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
index 2bd7daf..d75f64a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BaseRuleClasses.java
@@ -166,6 +166,11 @@
           .add(attr("args", STRING_LIST))
           // Input files for every test action
           .add(
+              attr("$test_wrapper", LABEL)
+                  .cfg(HostTransition.INSTANCE)
+                  .singleArtifact()
+                  .value(env.getToolsLabel("//tools/test:test_wrapper")))
+          .add(
               attr("$test_runtime", LABEL_LIST)
                   .cfg(HostTransition.INSTANCE)
                   .value(ImmutableList.of(env.getToolsLabel("//tools/test:runtime"))))
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
index fffbe7a..4a99825 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
@@ -166,6 +166,11 @@
         .add(attr("args", STRING_LIST))
         // Input files for every test action
         .add(
+            attr("$test_wrapper", LABEL)
+                .cfg(HostTransition.INSTANCE)
+                .singleArtifact()
+                .value(labelCache.getUnchecked(toolsRepository + "//tools/test:test_wrapper")))
+        .add(
             attr("$test_runtime", LABEL_LIST)
                 .cfg(HostTransition.INSTANCE)
                 .value(
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/TestConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/test/TestConfiguration.java
index 0d2f85b..fe60cc1 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/test/TestConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/test/TestConfiguration.java
@@ -216,6 +216,23 @@
     )
     public Label coverageReportGenerator;
 
+    @Option(
+        name = "windows_native_test_wrapper",
+        // Undocumented: this features is under development and not yet ready for production use.
+        // We define the flag to be able to test the feature.
+        // Design:
+        // https://github.com/laszlocsomor/proposals/blob/win-test-runner/designs/2018-07-18-windows-native-test-runner.md
+        documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+        // Affects loading and analysis: this flag affects which target Bazel loads and creates test
+        // actions with on Windows.
+        effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS},
+        defaultValue = "false",
+        help =
+            "Do not use yet, this flag's functionality is not yet implemented. "
+                + "(On Windows: if true, uses the C++ test wrapper to run tests, otherwise uses "
+                + "tools/test/test-setup.sh as on other platforms. On other platforms: no-op.)")
+    public boolean windowsNativeTestWrapper;
+
     @Override
     public Map<String, Set<Label>> getDefaultsLabels() {
       return ImmutableMap.<String, Set<Label>>of(
@@ -298,6 +315,10 @@
     return options.coverageReportGenerator;
   }
 
+  public boolean isUsingWindowsNativeTestWrapper() {
+    return options.windowsNativeTestWrapper;
+  }
+
   /**
    * @return number of times the given test should run. If the test doesn't match any of the
    *     filters, runs it once.
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
index 801ac17..614a355 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
@@ -124,8 +124,10 @@
     config.create(
         "/bazel_tools_workspace/tools/genrule/BUILD", "exports_files(['genrule-setup.sh'])");
 
-    config.create("/bazel_tools_workspace/tools/test/BUILD",
+    config.create(
+        "/bazel_tools_workspace/tools/test/BUILD",
         "filegroup(name = 'runtime', srcs = ['test-setup.sh', 'test-xml-generator.sh'])",
+        "filegroup(name = 'test_wrapper', srcs = ['test_wrapper_bin'])",
         "filegroup(name = 'test_setup', srcs = ['test-setup.sh'])",
         "filegroup(name = 'test_xml_generator', srcs = ['test-xml-generator.sh'])",
         "filegroup(name = 'collect_coverage', srcs = ['collect_coverage.sh'])",
diff --git a/src/test/shell/bazel/testdata/embedded_tools_srcs_deps b/src/test/shell/bazel/testdata/embedded_tools_srcs_deps
index c508152..5f37378 100644
--- a/src/test/shell/bazel/testdata/embedded_tools_srcs_deps
+++ b/src/test/shell/bazel/testdata/embedded_tools_srcs_deps
@@ -3,6 +3,7 @@
 @com_google_protobuf//:protobuf
 @com_google_protobuf//:protobuf_lite
 @com_google_protobuf//:js_embed
+//tools/test:test_wrapper_bin
 //third_party/ijar:zipper
 //third_party/ijar:ijar
 //third_party/ijar:zip
diff --git a/tools/test/BUILD b/tools/test/BUILD
index 18dc71b..4d5a3ab 100644
--- a/tools/test/BUILD
+++ b/tools/test/BUILD
@@ -33,6 +33,15 @@
     srcs = ["@bazel_tools//tools/test/LcovMerger/java/com/google/devtools/lcovmerger:Main"],
 )
 
+cc_binary(
+    name = "test_wrapper_bin",
+    srcs = select({
+        "@bazel_tools//src/conditions:windows": ["windows/test_wrapper.cc"],
+        "//conditions:default": ["empty_test_wrapper.cc"],
+    }),
+    visibility = ["//visibility:private"],
+)
+
 filegroup(
     name = "srcs",
     srcs = glob(["**"]),
@@ -45,7 +54,10 @@
         "test-setup.sh",
         "generate-xml.sh",
         "collect_coverage.sh",
-    ] + glob(["LcovMerger/**"]),
+    ] + glob(["LcovMerger/**"]) + select({
+        "@bazel_tools//src/conditions:windows": ["test_wrapper_bin"],
+        "//conditions:default": [],
+    }),
     visibility = ["//tools:__pkg__"],
 )
 
diff --git a/tools/test/BUILD.tools b/tools/test/BUILD.tools
index 5e4e5f55d..c41e293 100644
--- a/tools/test/BUILD.tools
+++ b/tools/test/BUILD.tools
@@ -32,3 +32,11 @@
     name = "coverage_report_generator",
     srcs = ["@bazel_tools//tools/test/LcovMerger/java/com/google/devtools/lcovmerger:Main"],
 )
+
+filegroup(
+    name = "test_wrapper",
+    srcs = select({
+        "@bazel_tools//src/conditions:windows": ["test_wrapper_bin.exe"],
+        "//conditions:default": ["test_wrapper_bin"],
+    }),
+)
diff --git a/tools/test/empty_test_wrapper.cc b/tools/test/empty_test_wrapper.cc
new file mode 100644
index 0000000..006f29d
--- /dev/null
+++ b/tools/test/empty_test_wrapper.cc
@@ -0,0 +1,28 @@
+// Copyright 2018 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.
+
+// Empty implementation of the test wrapper.
+//
+// As of 2018-08-10, every platform uses //tools/test:test-setup.sh as the test
+// wrapper, and we are working on introducing a C++ test wrapper for Windows.
+// See
+// https://github.com/laszlocsomor/proposals/blob/win-test-runner/designs/2018-07-18-windows-native-test-runner.md
+
+#include <stdio.h>
+
+int main(int, char**) {
+  fprintf(stderr,
+          __FILE__ ": The C++ test wrapper is not used on this platform.\n");
+  return 1;
+}
diff --git a/tools/test/windows/test_wrapper.cc b/tools/test/windows/test_wrapper.cc
new file mode 100644
index 0000000..dc911fd
--- /dev/null
+++ b/tools/test/windows/test_wrapper.cc
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+// Test wrapper implementation for Windows.
+// Design:
+// https://github.com/laszlocsomor/proposals/blob/win-test-runner/designs/2018-07-18-windows-native-test-runner.md
+
+int main(int argc, char** argv) {
+  // TODO(laszlocsomor): Implement the functionality described in
+  // https://github.com/laszlocsomor/proposals/blob/win-test-runner/designs/2018-07-18-windows-native-test-runner.md
+  return 0;
+}