Windows, test wrapper: refactor main method

Refactor the main method by splitting its first
part between a ParseArgs method and the existing
PrintTestLogStartMarker method.

Consolidate most of the main function into a
disjunctive form (if !A or !B or !C then fail).

Also rename the "test_wrapper_bin" target to "tw"
to yield a shorter binary name, which saves path
space on Windows and allows for a longer output
base.

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

PiperOrigin-RevId: 213974457
diff --git a/src/test/shell/bazel/testdata/embedded_tools_srcs_deps b/src/test/shell/bazel/testdata/embedded_tools_srcs_deps
index 07704af..b5d6b3c 100644
--- a/src/test/shell/bazel/testdata/embedded_tools_srcs_deps
+++ b/src/test/shell/bazel/testdata/embedded_tools_srcs_deps
@@ -2,7 +2,7 @@
 @com_google_protobuf//:protoc_lib
 @com_google_protobuf//:protobuf
 @com_google_protobuf//:protobuf_lite
-//tools/test:test_wrapper_bin
+//tools/test:tw
 //third_party/ijar:zipper
 //third_party/ijar:ijar
 //third_party/ijar:zip
diff --git a/tools/test/BUILD b/tools/test/BUILD
index f7e0580..6f6cc02 100644
--- a/tools/test/BUILD
+++ b/tools/test/BUILD
@@ -38,8 +38,10 @@
     srcs = ["@bazel_tools//tools/test/CoverageOutputGenerator/java/com/google/devtools/coverageoutputgenerator:Main"],
 )
 
+# Test wrapper binary to run tests on Windows.
+# See https://github.com/bazelbuild/bazel/issues/5508
 cc_binary(
-    name = "test_wrapper_bin",
+    name = "tw",
     srcs = select({
         "@bazel_tools//src/conditions:windows": ["windows/test_wrapper.cc"],
         "//conditions:default": ["empty_test_wrapper.cc"],
@@ -76,7 +78,7 @@
         "collect_coverage.sh",
         "collect_cc_coverage.sh",
     ] + glob(["LcovMerger/**"]) + select({
-        "@bazel_tools//src/conditions:windows": ["test_wrapper_bin"],
+        "@bazel_tools//src/conditions:windows": ["tw"],
         "//conditions:default": [],
     }),
     visibility = ["//tools:__pkg__"],
diff --git a/tools/test/BUILD.tools b/tools/test/BUILD.tools
index 248a1db..63e0ae3 100644
--- a/tools/test/BUILD.tools
+++ b/tools/test/BUILD.tools
@@ -40,8 +40,12 @@
 
 filegroup(
     name = "test_wrapper",
+    # "tw" is the Windows-native test wrapper. It has a short name because paths
+    # have short limits on Windows.
+    # On other platforms this binary is a no-op.
+    # See https://github.com/bazelbuild/bazel/issues/5508
     srcs = select({
-        "@bazel_tools//src/conditions:windows": ["test_wrapper_bin.exe"],
-        "//conditions:default": ["test_wrapper_bin"],
+        "@bazel_tools//src/conditions:windows": ["tw.exe"],
+        "//conditions:default": ["tw"],
     }),
 )
diff --git a/tools/test/windows/test_wrapper.cc b/tools/test/windows/test_wrapper.cc
index e524262..c4c2471 100644
--- a/tools/test/windows/test_wrapper.cc
+++ b/tools/test/windows/test_wrapper.cc
@@ -327,11 +327,28 @@
   return true;
 }
 
-inline void PrintTestLogStartMarker() {
+inline bool PrintTestLogStartMarker(bool suppress_output) {
+  if (suppress_output) {
+    return true;
+  }
+
+  std::wstring test_target;
+  if (!GetEnv(L"TEST_TARGET", &test_target)) {
+    return false;
+  }
+  if (test_target.empty()) {
+    // According to the Bazel Test Encyclopedia, setting TEST_TARGET is
+    // optional.
+    wprintf(L"Executing tests from unknown target\n");
+  } else {
+    wprintf(L"Executing tests from %s\n", test_target.c_str());
+  }
+
   // This header marks where --test_output=streamed will start being printed.
   printf(
       "------------------------------------------------------------------------"
       "-----\n");
+  return true;
 }
 
 inline bool GetWorkspaceName(std::wstring* result) {
@@ -433,6 +450,31 @@
   }
 }
 
+bool ParseArgs(int argc, wchar_t** argv, Path* out_argv0,
+               std::wstring* out_test_path_arg, bool* out_suppress_output) {
+  if (!out_argv0->Set(argv[0])) {
+    return false;
+  }
+  argc--;
+  argv++;
+  *out_suppress_output = false;
+  if (argc > 0 && wcscmp(argv[0], L"--no_echo") == 0) {
+    // Don't print anything to stdout in this special case.
+    // Currently needed for persistent test runner.
+    *out_suppress_output = true;
+    argc--;
+    argv++;
+  }
+
+  if (argc < 1) {
+    LogError(__LINE__, "Usage: $0 [--no_echo] <test_path> [test_args...]");
+    return false;
+  }
+
+  *out_test_path_arg = argv[0];
+  return true;
+}
+
 bool Path::Set(const std::wstring& path) {
   std::wstring result;
   std::string error;
@@ -462,54 +504,16 @@
 }  // namespace
 
 int wmain(int argc, wchar_t** 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
-
   Path argv0;
-  if (!argv0.Set(argv[0])) {
-    return 1;
-  }
-  argc--;
-  argv++;
+  std::wstring test_path_arg;
   bool suppress_output = false;
-  if (argc > 0 && wcscmp(argv[0], L"--no_echo") == 0) {
-    // Don't print anything to stdout in this special case.
-    // Currently needed for persistent test runner.
-    suppress_output = true;
-    argc--;
-    argv++;
-  } else {
-    std::wstring test_target;
-    if (!GetEnv(L"TEST_TARGET", &test_target)) {
-      return 1;
-    }
-    if (test_target.empty()) {
-      // According to the Bazel Test Encyclopedia, setting TEST_TARGET is
-      // optional.
-      wprintf(L"Executing tests from unknown target\n");
-    } else {
-      wprintf(L"Executing tests from %s\n", test_target.c_str());
-    }
-  }
-
-  if (argc < 1) {
-    LogError(__LINE__, "Usage: $0 [--no_echo] <test_path> [test_args...]");
-    return 1;
-  }
-
-  const wchar_t* test_path_arg = argv[0];
-  Path test_path;
-  if (!FindTestBinary(argv0, test_path_arg, &test_path)) {
-    return 1;
-  }
-
-  Path exec_root;
-  if (!GetCwd(&exec_root)) {
-    return 1;
-  }
-
-  Path srcdir, tmpdir, xml_output, undecl_zip, undecl_mf, undecl_annot;
-  if (!ExportUserName() || !ExportSrcPath(exec_root, &srcdir) ||
+  Path exec_root, test_path, srcdir, tmpdir, xml_output, undecl_zip, undecl_mf,
+      undecl_annot;
+  if (!ParseArgs(argc, argv, &argv0, &test_path_arg, &suppress_output) ||
+      !PrintTestLogStartMarker(suppress_output) ||
+      !FindTestBinary(argv0, test_path_arg, &test_path) ||
+      !GetCwd(&exec_root) || !ExportUserName() ||
+      !ExportSrcPath(exec_root, &srcdir) ||
       !ExportTmpPath(exec_root, &tmpdir) || !ExportHome(tmpdir) ||
       !ExportRunfiles(exec_root, srcdir) || !ExportShardStatusFile(exec_root) ||
       !ExportGtestVariables(tmpdir) || !ExportMiscEnvvars(exec_root) ||
@@ -518,10 +522,6 @@
     return 1;
   }
 
-  if (!suppress_output) {
-    PrintTestLogStartMarker();
-  }
-
   HANDLE process;
   if (!StartSubprocess(test_path, &process)) {
     return 1;