Windows, testing: only look up shell if needed

TestActionBuilder now only looks up the shell (via
ShToolchain.getPathOrError) when the shell is
required.

Now, when using the Windows-native test wrapper
with --shell_toolchain="" (and without a
shell-command-looking --run_under argument) the
TestActionBuilder won't depend on Bash.

Related: https://github.com/bazelbuild/bazel/issues/4319

Closes #8161.

PiperOrigin-RevId: 246275913
diff --git a/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java b/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java
index 5eddd8a..e887d2f 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.exec;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
@@ -366,7 +367,10 @@
     // configuration, not the machine Bazel happens to run on. Change this to something like:
     // testAction.getConfiguration().getExecOS() == OS.WINDOWS
     if (OS.getCurrent() == OS.WINDOWS && !action.isUsingTestWrapperInsteadOfTestSetupScript()) {
-      args.add(action.getShExecutable().getPathString());
+      // TestActionBuilder constructs TestRunnerAction with a 'null' shell path only when we use the
+      // native test wrapper. Something clearly went wrong.
+      Preconditions.checkNotNull(action.getShExecutableMaybe(), "%s", action);
+      args.add(action.getShExecutableMaybe().getPathString());
       args.add("-c");
       args.add("$0 $*");
     }