Revert "Add more test_utils functions."

This reverts commit 5fcfcea4a9379633a83a67fc1d94938cb31f2a9c.

Reason for revert:
1 Test Suite(s) failed. angle_unittests failed because of:
TestUtils.RunApp on Linux CFI
https://ci.chromium.org/p/chromium/builders/ci/Linux%20CFI


Original change's description:
> Add more test_utils functions.
> 
> Includes methods for creating temporary files, deleting files, and
> reading files into a string. Also renames GetPathSeparator to mention
> it's only used for environment variables. Includes a new virtual type
> angle::Process that will be used to implement cross-platform async
> Process launching for tests. Also includes a way to specify a custom
> crash handler callback.
> 
> Also adds a few unit tests for the new functionality. They are disabled
> on Android because the functions are not needed by the new test runner.
> 
> Bug: angleproject:3162
> Change-Id: I3e2c2e9837608884c98379fa0f78c9ffbe158d73
> Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1821940
> Commit-Queue: Jamie Madill <jmadill@chromium.org>
> Reviewed-by: Jonah Ryan-Davis <jonahr@google.com>

TBR=ynovikov@chromium.org,jonahr@google.com,jmadill@chromium.org

Change-Id: I1441bfbae31712f72b4aebeeea9cd711c3975a5d
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: angleproject:3162
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1869254
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/common/system_utils.cpp b/src/common/system_utils.cpp
index 54693b3..257fc42 100644
--- a/src/common/system_utils.cpp
+++ b/src/common/system_utils.cpp
@@ -22,7 +22,7 @@
     else
     {
         buf = path;
-        buf += GetPathSeparatorForEnvironmentVar();
+        buf += GetPathSeparator();
         buf += oldValue;
         newValue = buf.c_str();
     }
diff --git a/src/common/system_utils.h b/src/common/system_utils.h
index ccb4e9d..1191fac 100644
--- a/src/common/system_utils.h
+++ b/src/common/system_utils.h
@@ -22,7 +22,7 @@
 bool SetEnvironmentVar(const char *variableName, const char *value);
 bool UnsetEnvironmentVar(const char *variableName);
 std::string GetEnvironmentVar(const char *variableName);
-const char *GetPathSeparatorForEnvironmentVar();
+const char *GetPathSeparator();
 bool PrependPathToEnvironmentVar(const char *variableName, const char *path);
 bool IsDirectory(const char *filename);
 
diff --git a/src/common/system_utils_posix.cpp b/src/common/system_utils_posix.cpp
index d71a073..c8cb68a 100644
--- a/src/common/system_utils_posix.cpp
+++ b/src/common/system_utils_posix.cpp
@@ -18,6 +18,56 @@
 
 namespace angle
 {
+
+namespace
+{
+struct ScopedPipe
+{
+    ~ScopedPipe()
+    {
+        closeEndPoint(0);
+        closeEndPoint(1);
+    }
+    void closeEndPoint(int index)
+    {
+        if (fds[index] >= 0)
+        {
+            close(fds[index]);
+            fds[index] = -1;
+        }
+    }
+    int fds[2] = {
+        -1,
+        -1,
+    };
+};
+
+void ReadEntireFile(int fd, std::string *out)
+{
+    out->clear();
+
+    while (true)
+    {
+        char buffer[256];
+        ssize_t bytesRead = read(fd, buffer, sizeof(buffer));
+
+        // If interrupted, retry.
+        if (bytesRead < 0 && errno == EINTR)
+        {
+            continue;
+        }
+
+        // If failed, or nothing to read, we are done.
+        if (bytesRead <= 0)
+        {
+            break;
+        }
+
+        out->append(buffer, bytesRead);
+    }
+}
+}  // anonymous namespace
+
 Optional<std::string> GetCWD()
 {
     std::array<char, 4096> pathBuf;
@@ -50,11 +100,117 @@
     return (value == nullptr ? std::string() : std::string(value));
 }
 
-const char *GetPathSeparatorForEnvironmentVar()
+const char *GetPathSeparator()
 {
     return ":";
 }
 
+bool RunApp(const std::vector<const char *> &args,
+            std::string *stdoutOut,
+            std::string *stderrOut,
+            int *exitCodeOut)
+{
+    if (args.size() == 0 || args.back() != nullptr)
+    {
+        return false;
+    }
+
+    ScopedPipe stdoutPipe;
+    ScopedPipe stderrPipe;
+
+    // Create pipes for stdout and stderr.
+    if (stdoutOut && pipe(stdoutPipe.fds) != 0)
+    {
+        return false;
+    }
+    if (stderrOut && pipe(stderrPipe.fds) != 0)
+    {
+        return false;
+    }
+
+    pid_t pid = fork();
+    if (pid < 0)
+    {
+        return false;
+    }
+
+    if (pid == 0)
+    {
+        // Child.  Execute the application.
+
+        // Redirect stdout and stderr to the pipe fds.
+        if (stdoutOut)
+        {
+            if (dup2(stdoutPipe.fds[1], STDOUT_FILENO) < 0)
+            {
+                _exit(errno);
+            }
+        }
+        if (stderrOut)
+        {
+            if (dup2(stderrPipe.fds[1], STDERR_FILENO) < 0)
+            {
+                _exit(errno);
+            }
+        }
+
+        // Execute the application, which doesn't return unless failed.  Note: execv takes argv as
+        // `char * const *` for historical reasons.  It is safe to const_cast it:
+        //
+        // http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
+        //
+        // > The statement about argv[] and envp[] being constants is included to make explicit to
+        // future writers of language bindings that these objects are completely constant. Due to a
+        // limitation of the ISO C standard, it is not possible to state that idea in standard C.
+        // Specifying two levels of const- qualification for the argv[] and envp[] parameters for
+        // the exec functions may seem to be the natural choice, given that these functions do not
+        // modify either the array of pointers or the characters to which the function points, but
+        // this would disallow existing correct code. Instead, only the array of pointers is noted
+        // as constant.
+        execv(args[0], const_cast<char *const *>(args.data()));
+        _exit(errno);
+    }
+
+    // Parent.  Read child output from the pipes and clean it up.
+
+    // Close the write end of the pipes, so EOF can be generated when child exits.
+    stdoutPipe.closeEndPoint(1);
+    stderrPipe.closeEndPoint(1);
+
+    // Read back the output of the child.
+    if (stdoutOut)
+    {
+        ReadEntireFile(stdoutPipe.fds[0], stdoutOut);
+    }
+    if (stderrOut)
+    {
+        ReadEntireFile(stderrPipe.fds[0], stderrOut);
+    }
+
+    // Cleanup the child.
+    int status = 0;
+    do
+    {
+        pid_t changedPid = waitpid(pid, &status, 0);
+        if (changedPid < 0 && errno == EINTR)
+        {
+            continue;
+        }
+        if (changedPid < 0)
+        {
+            return false;
+        }
+    } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+
+    // Retrieve the error code.
+    if (exitCodeOut)
+    {
+        *exitCodeOut = WEXITSTATUS(status);
+    }
+
+    return true;
+}
+
 class PosixLibrary : public Library
 {
   public:
diff --git a/src/common/system_utils_unittest.cpp b/src/common/system_utils_unittest.cpp
index 7b189b9..7a5948a 100644
--- a/src/common/system_utils_unittest.cpp
+++ b/src/common/system_utils_unittest.cpp
@@ -9,11 +9,46 @@
 #include "gtest/gtest.h"
 
 #include "common/system_utils.h"
+#include "common/system_utils_unittest_helper.h"
 
 using namespace angle;
 
 namespace
 {
+#if defined(ANGLE_PLATFORM_WINDOWS)
+constexpr char kRunAppHelperExecutable[] = "angle_unittests_helper.exe";
+#else
+constexpr char kRunAppHelperExecutable[] = "angle_unittests_helper";
+#endif
+
+// Transforms various line endings into C/Unix line endings:
+//
+// - A\nB -> A\nB
+// - A\rB -> A\nB
+// - A\r\nB -> A\nB
+std::string NormalizeNewLines(const std::string &str)
+{
+    std::string result;
+
+    for (size_t i = 0; i < str.size(); ++i)
+    {
+        if (str[i] == '\r')
+        {
+            if (i + 1 < str.size() && str[i + 1] == '\n')
+            {
+                ++i;
+            }
+            result += '\n';
+        }
+        else
+        {
+            result += str[i];
+        }
+    }
+
+    return result;
+}
+
 // Test getting the executable path
 TEST(SystemUtils, ExecutablePath)
 {
@@ -60,4 +95,48 @@
     readback = GetEnvironmentVar(kEnvVarName);
     EXPECT_EQ("", readback);
 }
+
+// Test running an external application and receiving its output
+TEST(SystemUtils, RunApp)
+{
+#if defined(ANGLE_PLATFORM_ANDROID)
+    // TODO: android support. http://anglebug.com/3125
+    return;
+#endif
+
+#if defined(ANGLE_PLATFORM_FUCHSIA)
+    // TODO: fuchsia support. http://anglebug.com/3161
+    return;
+#endif
+
+    std::string executablePath = GetExecutableDirectory();
+    EXPECT_NE(executablePath, "");
+    executablePath += "/";
+    executablePath += kRunAppHelperExecutable;
+
+    std::vector<const char *> args = {executablePath.c_str(), kRunAppTestArg1, kRunAppTestArg2,
+                                      nullptr};
+
+    std::string stdoutOutput;
+    std::string stderrOutput;
+    int exitCode = EXIT_FAILURE;
+
+    // Test that the application can be executed.
+    bool ranApp = RunApp(args, &stdoutOutput, &stderrOutput, &exitCode);
+    EXPECT_TRUE(ranApp);
+    EXPECT_EQ(kRunAppTestStdout, NormalizeNewLines(stdoutOutput));
+    EXPECT_EQ(kRunAppTestStderr, NormalizeNewLines(stderrOutput));
+    EXPECT_EQ(EXIT_SUCCESS, exitCode);
+
+    // Test that environment variables reach the cild.
+    bool setEnvDone = SetEnvironmentVar(kRunAppTestEnvVarName, kRunAppTestEnvVarValue);
+    EXPECT_TRUE(setEnvDone);
+
+    ranApp = RunApp(args, &stdoutOutput, &stderrOutput, &exitCode);
+    EXPECT_TRUE(ranApp);
+    EXPECT_EQ("", stdoutOutput);
+    EXPECT_EQ(kRunAppTestEnvVarValue, NormalizeNewLines(stderrOutput));
+    EXPECT_EQ(EXIT_SUCCESS, exitCode);
+}
+
 }  // anonymous namespace
diff --git a/util/test_utils_unittest_helper.cpp b/src/common/system_utils_unittest_helper.cpp
similarity index 94%
rename from util/test_utils_unittest_helper.cpp
rename to src/common/system_utils_unittest_helper.cpp
index 2604f11..f1bfa69 100644
--- a/util/test_utils_unittest_helper.cpp
+++ b/src/common/system_utils_unittest_helper.cpp
@@ -5,11 +5,9 @@
 
 // system_utils_unittest_helper.cpp: Helper to the SystemUtils.RunApp unittest
 
-#include "test_utils_unittest_helper.h"
-
-#include "common/system_utils.h"
-
+#include "common/system_utils_unittest_helper.h"
 #include <string.h>
+#include "common/system_utils.h"
 
 int main(int argc, char **argv)
 {
diff --git a/util/test_utils_unittest_helper.h b/src/common/system_utils_unittest_helper.h
similarity index 100%
rename from util/test_utils_unittest_helper.h
rename to src/common/system_utils_unittest_helper.h
diff --git a/src/common/system_utils_win.cpp b/src/common/system_utils_win.cpp
index 48e26c9..6aa196c 100644
--- a/src/common/system_utils_win.cpp
+++ b/src/common/system_utils_win.cpp
@@ -15,6 +15,56 @@
 
 namespace angle
 {
+namespace
+{
+struct ScopedPipe
+{
+    ~ScopedPipe()
+    {
+        closeReadHandle();
+        closeWriteHandle();
+    }
+    void closeReadHandle()
+    {
+        if (readHandle)
+        {
+            CloseHandle(readHandle);
+            readHandle = nullptr;
+        }
+    }
+    void closeWriteHandle()
+    {
+        if (writeHandle)
+        {
+            CloseHandle(writeHandle);
+            writeHandle = nullptr;
+        }
+    }
+    HANDLE readHandle  = nullptr;
+    HANDLE writeHandle = nullptr;
+};
+
+void ReadEntireFile(HANDLE handle, std::string *out)
+{
+    out->clear();
+
+    while (true)
+    {
+        char buffer[256];
+        DWORD bytesRead;
+
+        BOOL success = ReadFile(handle, buffer, sizeof(buffer), &bytesRead, nullptr);
+
+        if (!success || bytesRead == 0)
+        {
+            break;
+        }
+
+        out->append(buffer, bytesRead);
+    }
+}
+}  // anonymous namespace
+
 std::string GetExecutablePath()
 {
     std::array<char, MAX_PATH> executableFileBuf;
@@ -76,7 +126,7 @@
     }
 }
 
-const char *GetPathSeparatorForEnvironmentVar()
+const char *GetPathSeparator()
 {
     return ";";
 }
@@ -92,6 +142,117 @@
     return static_cast<double>(curTime.QuadPart) / frequency.QuadPart;
 }
 
+bool RunApp(const std::vector<const char *> &args,
+            std::string *stdoutOut,
+            std::string *stderrOut,
+            int *exitCodeOut)
+{
+    ScopedPipe stdoutPipe;
+    ScopedPipe stderrPipe;
+
+    SECURITY_ATTRIBUTES sa_attr;
+    // Set the bInheritHandle flag so pipe handles are inherited.
+    sa_attr.nLength              = sizeof(SECURITY_ATTRIBUTES);
+    sa_attr.bInheritHandle       = TRUE;
+    sa_attr.lpSecurityDescriptor = nullptr;
+
+    // Create pipes for stdout and stderr.  Ensure the read handles to the pipes are not inherited.
+    if (stdoutOut && !CreatePipe(&stdoutPipe.readHandle, &stdoutPipe.writeHandle, &sa_attr, 0) &&
+        !SetHandleInformation(stdoutPipe.readHandle, HANDLE_FLAG_INHERIT, 0))
+    {
+        return false;
+    }
+    if (stderrOut && !CreatePipe(&stderrPipe.readHandle, &stderrPipe.writeHandle, &sa_attr, 0) &&
+        !SetHandleInformation(stderrPipe.readHandle, HANDLE_FLAG_INHERIT, 0))
+    {
+        return false;
+    }
+
+    // Concat the nicely separated arguments into one string so the application has to reparse it.
+    // We don't support quotation and spaces in arguments currently.
+    std::vector<char> commandLineString;
+    for (const char *arg : args)
+    {
+        if (arg)
+        {
+            if (!commandLineString.empty())
+            {
+                commandLineString.push_back(' ');
+            }
+            commandLineString.insert(commandLineString.end(), arg, arg + strlen(arg));
+        }
+    }
+    commandLineString.push_back('\0');
+
+    STARTUPINFOA startInfo = {};
+
+    startInfo.cb        = sizeof(STARTUPINFOA);
+    startInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+    if (stdoutOut)
+    {
+        startInfo.hStdOutput = stdoutPipe.writeHandle;
+    }
+    else
+    {
+        startInfo.hStdError = GetStdHandle(STD_OUTPUT_HANDLE);
+    }
+    if (stderrOut)
+    {
+        startInfo.hStdError = stderrPipe.writeHandle;
+    }
+    else
+    {
+        startInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+    }
+
+    if (stderrOut || stdoutOut)
+    {
+        startInfo.dwFlags |= STARTF_USESTDHANDLES;
+    }
+
+    // Create the child process.
+    PROCESS_INFORMATION processInfo = {};
+    if (!CreateProcessA(nullptr, commandLineString.data(), nullptr, nullptr,
+                        TRUE,  // Handles are inherited.
+                        0, nullptr, nullptr, &startInfo, &processInfo))
+    {
+        return false;
+    }
+
+    // Close the write end of the pipes, so EOF can be generated when child exits.
+    stdoutPipe.closeWriteHandle();
+    stderrPipe.closeWriteHandle();
+
+    // Read back the output of the child.
+    if (stdoutOut)
+    {
+        ReadEntireFile(stdoutPipe.readHandle, stdoutOut);
+    }
+    if (stderrOut)
+    {
+        ReadEntireFile(stderrPipe.readHandle, stderrOut);
+    }
+
+    // Cleanup the child.
+    bool success = WaitForSingleObject(processInfo.hProcess, INFINITE) == WAIT_OBJECT_0;
+
+    if (success)
+    {
+        DWORD exitCode = 0;
+        success        = GetExitCodeProcess(processInfo.hProcess, &exitCode);
+
+        if (success)
+        {
+            *exitCodeOut = static_cast<int>(exitCode);
+        }
+    }
+
+    CloseHandle(processInfo.hProcess);
+    CloseHandle(processInfo.hThread);
+
+    return success;
+}
+
 class Win32Library : public Library
 {
   public:
@@ -165,5 +326,4 @@
 {
     __debugbreak();
 }
-
 }  // namespace angle
diff --git a/src/tests/BUILD.gn b/src/tests/BUILD.gn
index d0d5dec..1ac3b58 100644
--- a/src/tests/BUILD.gn
+++ b/src/tests/BUILD.gn
@@ -45,8 +45,8 @@
   }
 }
 
-angle_executable("test_utils_unittest_helper") {
-  sources = test_utils_unittest_helper_sources
+angle_executable("angle_unittests_helper") {
+  sources = angle_unittests_helper_sources
 
   deps = [
     "${angle_root}:angle_common",
@@ -104,7 +104,7 @@
     # SystemUtils.RunApp, the only unittest using a helper binary, is not supported on these
     # platforms yet.
     data_deps = [
-      ":test_utils_unittest_helper",
+      ":angle_unittests_helper",
     ]
   }
 }
diff --git a/src/tests/angle_unittests.gni b/src/tests/angle_unittests.gni
index d6a86a3..b1686cc 100644
--- a/src/tests/angle_unittests.gni
+++ b/src/tests/angle_unittests.gni
@@ -15,6 +15,7 @@
   "../common/matrix_utils_unittest.cpp",
   "../common/string_utils_unittest.cpp",
   "../common/system_utils_unittest.cpp",
+  "../common/system_utils_unittest_helper.h",
   "../common/utilities_unittest.cpp",
   "../common/vector_utils_unittest.cpp",
   "../feature_support_util/feature_support_util_unittest.cpp",
@@ -129,8 +130,6 @@
   "../tests/test_utils/ShaderCompileTreeTest.h",
   "../tests/test_utils/ShaderCompileTreeTest.cpp",
   "../tests/test_utils/ShaderExtensionTest.h",
-  "../../util/test_utils_unittest.cpp",
-  "../../util/test_utils_unittest_helper.h",
 ]
 
 # TODO(jmadill): should probably call this windows sources
@@ -139,9 +138,9 @@
   "../tests/compiler_tests/UnrollFlatten_test.cpp",
 ]
 
-test_utils_unittest_helper_sources = [
-  "../../util/test_utils_unittest_helper.cpp",
-  "../../util/test_utils_unittest_helper.h",
+angle_unittests_helper_sources = [
+  "../common/system_utils_unittest_helper.cpp",
+  "../common/system_utils_unittest_helper.h",
 ]
 
 if (is_android) {
diff --git a/src/tests/perf_tests/glmark2Benchmark.cpp b/src/tests/perf_tests/glmark2Benchmark.cpp
index 174fcc6..2d5e463 100644
--- a/src/tests/perf_tests/glmark2Benchmark.cpp
+++ b/src/tests/perf_tests/glmark2Benchmark.cpp
@@ -151,9 +151,10 @@
         }
         args.push_back(nullptr);
 
-        ProcessHandle process(args, true, false);
-        ASSERT_TRUE(process && process->started());
-        ASSERT_TRUE(process->finish());
+        std::string output;
+        int exitCode;
+
+        bool success = RunApp(args, &output, nullptr, &exitCode);
 
         // Restore the current working directory for the next tests.
         if (cwd.valid())
@@ -161,11 +162,11 @@
             SetCWD(cwd.value().c_str());
         }
 
-        ASSERT_EQ(EXIT_SUCCESS, process->getExitCode());
+        ASSERT_TRUE(success);
+        ASSERT_EQ(EXIT_SUCCESS, exitCode);
 
         if (!OneFrame())
         {
-            std::string output = process->getStdout();
             parseOutput(output, benchmarkName, completeRun);
         }
     }
diff --git a/src/tests/test_utils/ANGLETest.cpp b/src/tests/test_utils/ANGLETest.cpp
index c0a268e..993185b 100644
--- a/src/tests/test_utils/ANGLETest.cpp
+++ b/src/tests/test_utils/ANGLETest.cpp
@@ -320,15 +320,15 @@
         std::vector<const char *> childArgs = commonArgs;
         childArgs.push_back(configStr.c_str());
 
-        ProcessHandle process(childArgs, false, false);
-        if (!process->started() || !process->finish())
+        int exitCode = 0;
+        if (!RunApp(childArgs, nullptr, nullptr, &exitCode))
         {
             std::cerr << "Launching child config " << config << " failed.\n";
         }
-        else if (process->getExitCode() != 0)
+        else if (exitCode != 0)
         {
-            std::cerr << "Child config " << config << " failed with exit code "
-                      << process->getExitCode() << ".\n";
+            std::cerr << "Child config " << config << " failed with exit code " << exitCode
+                      << ".\n";
             success = false;
         }
     }
@@ -481,7 +481,7 @@
 {
     mSetUpCalled = true;
 
-    InitCrashHandler(nullptr);
+    InitCrashHandler();
 
     gDefaultPlatformMethods.overrideWorkaroundsD3D = TestPlatform_overrideWorkaroundsD3D;
     gDefaultPlatformMethods.overrideFeaturesVk     = TestPlatform_overrideFeaturesVk;
diff --git a/util/posix/crash_handler_posix.cpp b/util/posix/crash_handler_posix.cpp
index 64c31a7..e40c4b5 100644
--- a/util/posix/crash_handler_posix.cpp
+++ b/util/posix/crash_handler_posix.cpp
@@ -43,7 +43,7 @@
     // No implementations yet.
 }
 
-void InitCrashHandler(CrashCallback *callback)
+void InitCrashHandler()
 {
     // No implementations yet.
 }
@@ -140,7 +140,7 @@
     SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP,
 };
 
-void InitCrashHandler(CrashCallback *callback)
+void InitCrashHandler()
 {
     for (int sig : kSignals)
     {
diff --git a/util/posix/test_utils_posix.cpp b/util/posix/test_utils_posix.cpp
index 82c5a70..9d6c82f 100644
--- a/util/posix/test_utils_posix.cpp
+++ b/util/posix/test_utils_posix.cpp
@@ -10,13 +10,10 @@
 
 #include <errno.h>
 #include <sched.h>
-#include <signal.h>
 #include <time.h>
 #include <unistd.h>
 #include <cstdarg>
-#include <cstring>
 
-#include "common/debug.h"
 #include "common/platform.h"
 
 #if !defined(ANGLE_PLATFORM_FUCHSIA)
@@ -29,222 +26,6 @@
 
 namespace angle
 {
-namespace
-{
-struct ScopedPipe
-{
-    ~ScopedPipe()
-    {
-        closeEndPoint(0);
-        closeEndPoint(1);
-    }
-
-    void closeEndPoint(int index)
-    {
-        if (fds[index] >= 0)
-        {
-            close(fds[index]);
-            fds[index] = -1;
-        }
-    }
-
-    bool valid() const { return fds[0] != -1 || fds[1] != -1; }
-
-    int fds[2] = {
-        -1,
-        -1,
-    };
-};
-
-void ReadEntireFile(int fd, std::string *out)
-{
-    out->clear();
-
-    while (true)
-    {
-        char buffer[256];
-        ssize_t bytesRead = read(fd, buffer, sizeof(buffer));
-
-        // If interrupted, retry.
-        if (bytesRead < 0 && errno == EINTR)
-        {
-            continue;
-        }
-
-        // If failed, or nothing to read, we are done.
-        if (bytesRead <= 0)
-        {
-            break;
-        }
-
-        out->append(buffer, bytesRead);
-    }
-}
-
-class PosixProcess : public Process
-{
-  public:
-    PosixProcess(const std::vector<const char *> &commandLineArgs,
-                 bool captureStdOut,
-                 bool captureStdErr)
-    {
-#if defined(ANGLE_PLATFORM_FUCHSIA)
-        ANGLE_UNUSED_VARIABLE(ReadEntireFile);
-        ANGLE_UNUSED_VARIABLE(mExitCode);
-        ANGLE_UNUSED_VARIABLE(mPID);
-#else
-        if (commandLineArgs.empty() || commandLineArgs.back() != nullptr)
-        {
-            return;
-        }
-
-        // Create pipes for stdout and stderr.
-        if (captureStdOut && pipe(mStdoutPipe.fds) != 0)
-        {
-            return;
-        }
-        if (captureStdErr && pipe(mStderrPipe.fds) != 0)
-        {
-            return;
-        }
-
-        mPID = fork();
-        if (mPID < 0)
-        {
-            return;
-        }
-
-        mStarted = true;
-
-        if (mPID == 0)
-        {
-            // Child.  Execute the application.
-
-            // Redirect stdout and stderr to the pipe fds.
-            if (captureStdOut)
-            {
-                if (dup2(mStdoutPipe.fds[1], STDOUT_FILENO) < 0)
-                {
-                    _exit(errno);
-                }
-            }
-            if (captureStdErr)
-            {
-                if (dup2(mStderrPipe.fds[1], STDERR_FILENO) < 0)
-                {
-                    _exit(errno);
-                }
-            }
-
-            // Execute the application, which doesn't return unless failed.  Note: execv takes argv
-            // as `char * const *` for historical reasons.  It is safe to const_cast it:
-            //
-            // http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
-            //
-            // > The statement about argv[] and envp[] being constants is included to make explicit
-            // to future writers of language bindings that these objects are completely constant.
-            // Due to a limitation of the ISO C standard, it is not possible to state that idea in
-            // standard C. Specifying two levels of const- qualification for the argv[] and envp[]
-            // parameters for the exec functions may seem to be the natural choice, given that these
-            // functions do not modify either the array of pointers or the characters to which the
-            // function points, but this would disallow existing correct code. Instead, only the
-            // array of pointers is noted as constant.
-            execv(commandLineArgs[0], const_cast<char *const *>(commandLineArgs.data()));
-            _exit(errno);
-        }
-        // Parent continues execution.
-#endif  // defined(ANGLE_PLATFORM_FUCHSIA)
-    }
-
-    ~PosixProcess() override {}
-
-    bool started() override { return mStarted; }
-
-    bool finish() override
-    {
-        if (!mStarted)
-        {
-            return false;
-        }
-
-#if defined(ANGLE_PLATFORM_FUCHSIA)
-        return false;
-#else
-        // Close the write end of the pipes, so EOF can be generated when child exits.
-        // Then read back the output of the child.
-        if (mStdoutPipe.valid())
-        {
-            mStdoutPipe.closeEndPoint(1);
-            ReadEntireFile(mStdoutPipe.fds[0], &mStdout);
-        }
-        if (mStderrPipe.valid())
-        {
-            mStderrPipe.closeEndPoint(1);
-            ReadEntireFile(mStderrPipe.fds[0], &mStderr);
-        }
-
-        // Cleanup the child.
-        int status = 0;
-        do
-        {
-            pid_t changedPid = waitpid(mPID, &status, 0);
-            if (changedPid < 0 && errno == EINTR)
-            {
-                continue;
-            }
-            if (changedPid < 0)
-            {
-                return false;
-            }
-        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
-
-        // Retrieve the error code.
-        mExitCode = WEXITSTATUS(status);
-        return true;
-#endif  // defined(ANGLE_PLATFORM_FUCHSIA)
-    }
-
-    bool finished() override
-    {
-        if (!mStarted)
-        {
-            return false;
-        }
-
-        return (::kill(mPID, 0) != 0);
-    }
-
-    int getExitCode() override { return 0; }
-
-    bool kill() override
-    {
-        if (!mStarted)
-        {
-            return false;
-        }
-
-        if (finished())
-        {
-            return true;
-        }
-
-        return (::kill(mPID, SIGTERM) == 0);
-    }
-
-  private:
-    bool mStarted = false;
-    ScopedPipe mStdoutPipe;
-    ScopedPipe mStderrPipe;
-    int mExitCode = 0;
-    pid_t mPID    = -1;
-};
-
-std::string TempFileName()
-{
-    return std::string(".angle.XXXXXX");
-}
-}  // anonymous namespace
-
 void Sleep(unsigned int milliseconds)
 {
     // On Windows Sleep(0) yields while it isn't guaranteed by Posix's sleep
@@ -313,68 +94,4 @@
     return false;
 #endif
 }
-
-bool GetTempDir(char *tempDirOut, uint32_t maxDirNameLen)
-{
-    const char *tmp = getenv("TMPDIR");
-    if (tmp)
-    {
-        strncpy(tempDirOut, tmp, maxDirNameLen);
-        return true;
-    }
-
-#if defined(ANGLE_PLATFORM_ANDROID)
-    // TODO(jmadill): Android support. http://anglebug.com/3162
-    // return PathService::Get(DIR_CACHE, path);
-    return false;
-#else
-    strncpy(tempDirOut, "/tmp", maxDirNameLen);
-    return true;
-#endif
-}
-
-bool CreateTemporaryFileInDir(const char *dir, char *tempFileNameOut, uint32_t maxFileNameLen)
-{
-    std::string tempFile = TempFileName();
-    sprintf(tempFileNameOut, "%s/%s", dir, tempFile.c_str());
-    int fd = mkstemp(tempFileNameOut);
-    close(fd);
-    return fd != -1;
-}
-
-bool DeleteFile(const char *path)
-{
-    return unlink(path) == 0;
-}
-
-Process *LaunchProcess(const std::vector<const char *> &args,
-                       bool captureStdout,
-                       bool captureStderr)
-{
-    return new PosixProcess(args, captureStdout, captureStderr);
-}
-
-int NumberOfProcessors()
-{
-    // sysconf returns the number of "logical" (not "physical") processors on both
-    // Mac and Linux.  So we get the number of max available "logical" processors.
-    //
-    // Note that the number of "currently online" processors may be fewer than the
-    // returned value of NumberOfProcessors(). On some platforms, the kernel may
-    // make some processors offline intermittently, to save power when system
-    // loading is low.
-    //
-    // One common use case that needs to know the processor count is to create
-    // optimal number of threads for optimization. It should make plan according
-    // to the number of "max available" processors instead of "currently online"
-    // ones. The kernel should be smart enough to make all processors online when
-    // it has sufficient number of threads waiting to run.
-    long res = sysconf(_SC_NPROCESSORS_CONF);
-    if (res == -1)
-    {
-        return 1;
-    }
-
-    return static_cast<int>(res);
-}
 }  // namespace angle
diff --git a/util/shader_utils.cpp b/util/shader_utils.cpp
index 17b8c85..518608e 100644
--- a/util/shader_utils.cpp
+++ b/util/shader_utils.cpp
@@ -4,26 +4,33 @@
 // found in the LICENSE file.
 //
 
-#include "util/shader_utils.h"
+#include "shader_utils.h"
 
 #include <cstring>
 #include <fstream>
 #include <iostream>
 #include <vector>
 
-#include "util/test_utils.h"
-
 namespace
 {
-bool ReadEntireFile(const std::string &filePath, std::string *contentsOut)
+std::string ReadFileToString(const std::string &source)
 {
-    constexpr uint32_t kMaxBufferSize = 2000;
-    char buffer[kMaxBufferSize]       = {};
-    if (!angle::ReadEntireFileToString(filePath.c_str(), buffer, kMaxBufferSize) ||
-        strlen(buffer) == 0)
-        return false;
-    *contentsOut = buffer;
-    return true;
+    std::ifstream stream(source.c_str());
+    if (!stream)
+    {
+        std::cerr << "Failed to load shader file: " << source;
+        return "";
+    }
+
+    std::string result;
+
+    stream.seekg(0, std::ios::end);
+    result.reserve(static_cast<unsigned int>(stream.tellg()));
+    stream.seekg(0, std::ios::beg);
+
+    result.assign((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
+
+    return result;
 }
 
 GLuint CompileProgramInternal(const char *vsSource,
@@ -117,10 +124,9 @@
 
 GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath)
 {
-    std::string source;
-    if (!ReadEntireFile(sourcePath, &source))
+    std::string source = ReadFileToString(sourcePath);
+    if (source.empty())
     {
-        std::cerr << "Error reading shader file: " << sourcePath << "\n";
         return 0;
     }
 
@@ -208,17 +214,10 @@
 
 GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath)
 {
-    std::string vsSource;
-    if (!ReadEntireFile(vsPath, &vsSource))
+    std::string vsSource = ReadFileToString(vsPath);
+    std::string fsSource = ReadFileToString(fsPath);
+    if (vsSource.empty() || fsSource.empty())
     {
-        std::cerr << "Error reading shader: " << vsPath << "\n";
-        return 0;
-    }
-
-    std::string fsSource;
-    if (!ReadEntireFile(fsPath, &fsSource))
-    {
-        std::cerr << "Error reading shader: " << fsPath << "\n";
         return 0;
     }
 
diff --git a/util/test_utils.cpp b/util/test_utils.cpp
deleted file mode 100644
index ac4dc8f..0000000
--- a/util/test_utils.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-//
-// Copyright 2019 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// system_utils: Defines common utility functions
-
-#include "util/test_utils.h"
-
-#include <cstring>
-#include <fstream>
-
-namespace angle
-{
-bool CreateTemporaryFile(char *tempFileNameOut, uint32_t maxFileNameLen)
-{
-    constexpr uint32_t kMaxPath = 1000u;
-    char tempPath[kMaxPath];
-
-    if (!GetTempDir(tempPath, kMaxPath))
-        return false;
-
-    return CreateTemporaryFileInDir(tempPath, tempFileNameOut, maxFileNameLen);
-}
-
-bool GetFileSize(const char *filePath, uint32_t *sizeOut)
-{
-    std::ifstream stream(filePath);
-    if (!stream)
-    {
-        return false;
-    }
-
-    stream.seekg(0, std::ios::end);
-    *sizeOut = static_cast<uint32_t>(stream.tellg());
-    return true;
-}
-
-bool ReadEntireFileToString(const char *filePath, char *contentsOut, uint32_t maxLen)
-{
-    std::ifstream stream(filePath);
-    if (!stream)
-    {
-        return false;
-    }
-
-    std::string contents;
-
-    stream.seekg(0, std::ios::end);
-    contents.reserve(static_cast<unsigned int>(stream.tellg()));
-    stream.seekg(0, std::ios::beg);
-
-    contents.assign((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
-
-    strncpy(contentsOut, contents.c_str(), maxLen);
-    return true;
-}
-
-// static
-Process::~Process() = default;
-
-ProcessHandle::ProcessHandle() : mProcess(nullptr) {}
-
-ProcessHandle::ProcessHandle(Process *process) : mProcess(process) {}
-
-ProcessHandle::ProcessHandle(const std::vector<const char *> &args,
-                             bool captureStdout,
-                             bool captureStderr)
-    : mProcess(LaunchProcess(args, captureStdout, captureStderr))
-{}
-
-ProcessHandle::~ProcessHandle()
-{
-    reset();
-}
-
-ProcessHandle::ProcessHandle(ProcessHandle &&other) : mProcess(other.mProcess)
-{
-    other.mProcess = nullptr;
-}
-
-ProcessHandle &ProcessHandle::operator=(ProcessHandle &&rhs)
-{
-    std::swap(mProcess, rhs.mProcess);
-    return *this;
-}
-
-void ProcessHandle::reset()
-{
-    if (mProcess)
-    {
-        delete mProcess;
-        mProcess = nullptr;
-    }
-}
-}  // namespace angle
diff --git a/util/test_utils.h b/util/test_utils.h
index fe8a969..6a4951d 100644
--- a/util/test_utils.h
+++ b/util/test_utils.h
@@ -9,12 +9,9 @@
 #ifndef UTIL_TEST_UTILS_H_
 #define UTIL_TEST_UTILS_H_
 
-#include <functional>
 #include <string>
 #include <vector>
 
-#include "common/angleutils.h"
-#include "util/Timer.h"
 #include "util/util_export.h"
 
 namespace angle
@@ -31,96 +28,12 @@
 ANGLE_UTIL_EXPORT bool StabilizeCPUForBenchmarking();
 
 // Set a crash handler to print stack traces.
-using CrashCallback = std::function<void()>;
-ANGLE_UTIL_EXPORT void InitCrashHandler(CrashCallback *callback);
+ANGLE_UTIL_EXPORT void InitCrashHandler();
 ANGLE_UTIL_EXPORT void TerminateCrashHandler();
 
 // Print a stack back trace.
 ANGLE_UTIL_EXPORT void PrintStackBacktrace();
 
-// Get temporary directory.
-ANGLE_UTIL_EXPORT bool GetTempDir(char *tempDirOut, uint32_t maxDirNameLen);
-
-// Creates a temporary file. The full path is placed in |path|, and the
-// function returns true if was successful in creating the file. The file will
-// be empty and all handles closed after this function returns.
-ANGLE_UTIL_EXPORT bool CreateTemporaryFile(char *tempFileNameOut, uint32_t maxFileNameLen);
-
-// Same as CreateTemporaryFile but the file is created in |dir|.
-ANGLE_UTIL_EXPORT bool CreateTemporaryFileInDir(const char *dir,
-                                                char *tempFileNameOut,
-                                                uint32_t maxFileNameLen);
-
-// Deletes a file or directory.
-ANGLE_UTIL_EXPORT bool DeleteFile(const char *path);
-
-// Reads a file contents into a string.
-ANGLE_UTIL_EXPORT bool ReadEntireFileToString(const char *filePath,
-                                              char *contentsOut,
-                                              uint32_t maxLen);
-
-// Compute a file's size.
-ANGLE_UTIL_EXPORT bool GetFileSize(const char *filePath, uint32_t *sizeOut);
-
-class ProcessHandle;
-
-class ANGLE_UTIL_EXPORT Process : angle::NonCopyable
-{
-  public:
-    virtual bool started()    = 0;
-    virtual bool finished()   = 0;
-    virtual bool finish()     = 0;
-    virtual bool kill()       = 0;
-    virtual int getExitCode() = 0;
-
-    double getElapsedTimeSeconds() const { return mTimer.getElapsedTime(); }
-    const std::string &getStdout() const { return mStdout; }
-    const std::string &getStderr() const { return mStderr; }
-
-  protected:
-    friend class ProcessHandle;
-    virtual ~Process();
-
-    Timer mTimer;
-    std::string mStdout;
-    std::string mStderr;
-};
-
-class ANGLE_UTIL_EXPORT ProcessHandle final : angle::NonCopyable
-{
-  public:
-    ProcessHandle();
-    ProcessHandle(Process *process);
-    ProcessHandle(const std::vector<const char *> &args, bool captureStdout, bool captureStderr);
-    ~ProcessHandle();
-    ProcessHandle(ProcessHandle &&other);
-    ProcessHandle &operator=(ProcessHandle &&rhs);
-
-    Process *operator->() { return mProcess; }
-    const Process *operator->() const { return mProcess; }
-
-    operator bool() const { return mProcess != nullptr; }
-
-    void reset();
-
-  private:
-    Process *mProcess;
-};
-
-// Launch a process and optionally get the output. Uses a vector of c strings as command line
-// arguments to the child process. Returns a Process handle which can be used to retrieve
-// the stdout and stderr outputs as well as the exit code.
-//
-// Pass false for stdoutOut/stderrOut if you don't need to capture them.
-//
-// On success, returns a Process pointer with started() == true.
-// On failure, returns a Process pointer with started() == false.
-ANGLE_UTIL_EXPORT Process *LaunchProcess(const std::vector<const char *> &args,
-                                         bool captureStdout,
-                                         bool captureStderr);
-
-ANGLE_UTIL_EXPORT int NumberOfProcessors();
-
 }  // namespace angle
 
 #endif  // UTIL_TEST_UTILS_H_
diff --git a/util/test_utils_unittest.cpp b/util/test_utils_unittest.cpp
deleted file mode 100644
index 380d43f..0000000
--- a/util/test_utils_unittest.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-//
-// Copyright 2019 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// test_utils_unittest.cpp: Unit tests for ANGLE's test utility functions
-
-#include "gtest/gtest.h"
-
-#include "common/system_utils.h"
-#include "util/Timer.h"
-#include "util/test_utils.h"
-#include "util/test_utils_unittest_helper.h"
-
-using namespace angle;
-
-namespace
-{
-#if defined(ANGLE_PLATFORM_WINDOWS)
-constexpr char kRunAppHelperExecutable[] = "test_utils_unittest_helper.exe";
-#else
-constexpr char kRunAppHelperExecutable[] = "test_utils_unittest_helper";
-#endif
-
-// Transforms various line endings into C/Unix line endings:
-//
-// - A\nB -> A\nB
-// - A\rB -> A\nB
-// - A\r\nB -> A\nB
-std::string NormalizeNewLines(const std::string &str)
-{
-    std::string result;
-
-    for (size_t i = 0; i < str.size(); ++i)
-    {
-        if (str[i] == '\r')
-        {
-            if (i + 1 < str.size() && str[i + 1] == '\n')
-            {
-                ++i;
-            }
-            result += '\n';
-        }
-        else
-        {
-            result += str[i];
-        }
-    }
-
-    return result;
-}
-
-// Tests that Sleep() actually waits some time.
-TEST(TestUtils, Sleep)
-{
-    Timer timer;
-    timer.start();
-    angle::Sleep(500);
-    timer.stop();
-
-    // Use a slightly fuzzy range
-    EXPECT_GT(timer.getElapsedTime(), 0.48);
-}
-
-constexpr uint32_t kMaxPath = 1000;
-
-// Temporary file creation is not supported on Android right now.
-#if defined(ANGLE_PLATFORM_ANDROID)
-#    define MAYBE_CreateAndDeleteTemporaryFile DISABLED_CreateAndDeleteTemporaryFile
-#    define MAYBE_CreateAndDeleteFileInTempDir DISABLED_CreateAndDeleteFileInTempDir
-#else
-#    define MAYBE_CreateAndDeleteTemporaryFile CreateAndDeleteTemporaryFile
-#    define MAYBE_CreateAndDeleteFileInTempDir CreateAndDeleteFileInTempDir
-#endif  // defined(ANGLE_PLATFORM_ANDROID)
-
-// Test creating and deleting temporary file.
-TEST(TestUtils, MAYBE_CreateAndDeleteTemporaryFile)
-{
-    char path[kMaxPath] = {};
-    ASSERT_TRUE(CreateTemporaryFile(path, kMaxPath));
-    ASSERT_TRUE(strlen(path) > 0);
-
-    const char kOutputString[] = "test output";
-
-    FILE *fp = fopen(path, "wt");
-    ASSERT_NE(fp, nullptr);
-    int retval = fputs(kOutputString, fp);
-    fclose(fp);
-
-    EXPECT_GE(retval, 0);
-
-    // Test ReadEntireFileToString
-    char actualString[kMaxPath];
-    EXPECT_TRUE(ReadEntireFileToString(path, actualString, kMaxPath));
-    EXPECT_EQ(strcmp(actualString, kOutputString), 0);
-
-    // Delete the temporary file.
-    EXPECT_TRUE(angle::DeleteFile(path));
-}
-
-// Tests creating and deleting a file in the system temp dir.
-TEST(TestUtils, MAYBE_CreateAndDeleteFileInTempDir)
-{
-    char tempDir[kMaxPath];
-    ASSERT_TRUE(GetTempDir(tempDir, kMaxPath));
-
-    char path[kMaxPath] = {};
-    ASSERT_TRUE(CreateTemporaryFileInDir(tempDir, path, kMaxPath));
-    ASSERT_TRUE(strlen(path) > 0);
-
-    const char kOutputString[] = "test output";
-
-    FILE *fp = fopen(path, "wt");
-    ASSERT_NE(fp, nullptr);
-    int retval = fputs(kOutputString, fp);
-    fclose(fp);
-
-    EXPECT_GE(retval, 0);
-
-    // Test ReadEntireFileToString
-    char actualString[kMaxPath];
-    EXPECT_TRUE(ReadEntireFileToString(path, actualString, kMaxPath));
-    EXPECT_EQ(strcmp(actualString, kOutputString), 0);
-
-    // Delete the temporary file.
-    EXPECT_TRUE(angle::DeleteFile(path));
-}
-
-// Test running an external application and receiving its output
-TEST(TestUtils, RunApp)
-{
-#if defined(ANGLE_PLATFORM_ANDROID)
-    // TODO: android support. http://anglebug.com/3125
-    return;
-#endif
-
-#if defined(ANGLE_PLATFORM_FUCHSIA)
-    // TODO: fuchsia support. http://anglebug.com/3161
-    return;
-#endif
-
-    std::string executablePath = GetExecutableDirectory();
-    EXPECT_NE(executablePath, "");
-    executablePath += "/";
-    executablePath += kRunAppHelperExecutable;
-
-    std::vector<const char *> args = {executablePath.c_str(), kRunAppTestArg1, kRunAppTestArg2,
-                                      nullptr};
-
-    // Test that the application can be executed.
-    {
-        ProcessHandle process(args, true, true);
-        EXPECT_TRUE(process->started());
-        EXPECT_TRUE(process->finish());
-        EXPECT_TRUE(process->finished());
-
-        EXPECT_EQ(kRunAppTestStdout, NormalizeNewLines(process->getStdout()));
-        EXPECT_EQ(kRunAppTestStderr, NormalizeNewLines(process->getStderr()));
-        EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
-    }
-
-    // Test that environment variables reach the cild.
-    {
-        bool setEnvDone = SetEnvironmentVar(kRunAppTestEnvVarName, kRunAppTestEnvVarValue);
-        EXPECT_TRUE(setEnvDone);
-
-        ProcessHandle process(LaunchProcess(args, true, true));
-        EXPECT_TRUE(process->started());
-        EXPECT_TRUE(process->finish());
-
-        EXPECT_EQ("", process->getStdout());
-        EXPECT_EQ(kRunAppTestEnvVarValue, NormalizeNewLines(process->getStderr()));
-        EXPECT_EQ(EXIT_SUCCESS, process->getExitCode());
-    }
-}
-
-// Verify that NumberOfProcessors returns something sane.
-TEST(TestUtils, NumberOfProcessors)
-{
-    int numProcs = angle::NumberOfProcessors();
-    EXPECT_GT(numProcs, 0);
-    EXPECT_LT(numProcs, 1000);
-}
-}  // namespace
diff --git a/util/util.gni b/util/util.gni
index fa1b336..4304cae 100644
--- a/util/util.gni
+++ b/util/util.gni
@@ -12,7 +12,6 @@
   "util/random_utils.h",
   "util/shader_utils.cpp",
   "util/shader_utils.h",
-  "util/test_utils.cpp",
   "util/test_utils.h",
   "util/util_export.h",
   "util/util_gl.h",
diff --git a/util/windows/test_utils_win.cpp b/util/windows/test_utils_win.cpp
index 3349d1a..05a44c8 100644
--- a/util/windows/test_utils_win.cpp
+++ b/util/windows/test_utils_win.cpp
@@ -11,14 +11,8 @@
 #include <stdarg.h>
 #include <windows.h>
 #include <array>
-#include <iostream>
-#include <vector>
-
-#include <aclapi.h>
 
 #include "common/angleutils.h"
-
-#include "anglebase/no_destructor.h"
 #include "util/windows/third_party/StackWalker/src/StackWalker.h"
 
 namespace angle
@@ -111,312 +105,6 @@
     // The compiler wants us to return something.  This is what we'd do if we didn't _exit().
     return EXCEPTION_EXECUTE_HANDLER;
 }
-
-CrashCallback *gCrashHandlerCallback;
-
-LONG WINAPI CrashHandler(EXCEPTION_POINTERS *e)
-{
-    if (gCrashHandlerCallback)
-    {
-        (*gCrashHandlerCallback)();
-    }
-    return StackTraceCrashHandler(e);
-}
-
-struct ScopedPipe
-{
-    ~ScopedPipe()
-    {
-        closeReadHandle();
-        closeWriteHandle();
-    }
-    bool closeReadHandle()
-    {
-        if (readHandle)
-        {
-            if (::CloseHandle(readHandle) == FALSE)
-            {
-                std::cerr << "Error closing write handle: " << GetLastError();
-                return false;
-            }
-            readHandle = nullptr;
-        }
-
-        return true;
-    }
-    bool closeWriteHandle()
-    {
-        if (writeHandle)
-        {
-            if (::CloseHandle(writeHandle) == FALSE)
-            {
-                std::cerr << "Error closing write handle: " << GetLastError();
-                return false;
-            }
-            writeHandle = nullptr;
-        }
-
-        return true;
-    }
-
-    bool valid() const { return readHandle != nullptr || writeHandle != nullptr; }
-
-    bool initPipe(SECURITY_ATTRIBUTES *securityAttribs)
-    {
-        if (::CreatePipe(&readHandle, &writeHandle, securityAttribs, 0) == FALSE)
-        {
-            std::cerr << "Error creating pipe: " << GetLastError() << "\n";
-            return false;
-        }
-
-        // Ensure the read handles to the pipes are not inherited.
-        if (::SetHandleInformation(readHandle, HANDLE_FLAG_INHERIT, 0) == FALSE)
-        {
-            std::cerr << "Error setting handle info on pipe: " << GetLastError() << "\n";
-            return false;
-        }
-
-        return true;
-    }
-
-    HANDLE readHandle  = nullptr;
-    HANDLE writeHandle = nullptr;
-};
-
-// Returns false on EOF or error.
-void ReadFromFile(bool blocking, HANDLE handle, std::string *out)
-{
-    char buffer[8192];
-    DWORD bytesRead = 0;
-
-    while (true)
-    {
-        if (!blocking)
-        {
-            BOOL success = ::PeekNamedPipe(handle, nullptr, 0, nullptr, &bytesRead, nullptr);
-            if (success == FALSE || bytesRead == 0)
-                return;
-        }
-
-        BOOL success = ::ReadFile(handle, buffer, sizeof(buffer), &bytesRead, nullptr);
-        if (success == FALSE || bytesRead == 0)
-            return;
-
-        out->append(buffer, bytesRead);
-    }
-
-    // unreachable.
-}
-
-// Returns the Win32 last error code or ERROR_SUCCESS if the last error code is
-// ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND. This is useful in cases where
-// the absence of a file or path is a success condition (e.g., when attempting
-// to delete an item in the filesystem).
-bool ReturnSuccessOnNotFound()
-{
-    const DWORD error_code = ::GetLastError();
-    return (error_code == ERROR_FILE_NOT_FOUND || error_code == ERROR_PATH_NOT_FOUND);
-}
-
-class WindowsProcess : public Process
-{
-  public:
-    WindowsProcess(const std::vector<const char *> &commandLineArgs,
-                   bool captureStdOut,
-                   bool captureStdErr)
-    {
-        mProcessInfo.hProcess = INVALID_HANDLE_VALUE;
-        mProcessInfo.hThread  = INVALID_HANDLE_VALUE;
-
-        std::vector<char> commandLineString;
-        for (const char *arg : commandLineArgs)
-        {
-            if (arg)
-            {
-                if (!commandLineString.empty())
-                {
-                    commandLineString.push_back(' ');
-                }
-                commandLineString.insert(commandLineString.end(), arg, arg + strlen(arg));
-            }
-        }
-        commandLineString.push_back('\0');
-
-        // Set the bInheritHandle flag so pipe handles are inherited.
-        SECURITY_ATTRIBUTES securityAttribs;
-        securityAttribs.nLength              = sizeof(SECURITY_ATTRIBUTES);
-        securityAttribs.bInheritHandle       = TRUE;
-        securityAttribs.lpSecurityDescriptor = nullptr;
-
-        STARTUPINFOA startInfo = {};
-
-        // Create pipes for stdout and stderr.
-        startInfo.cb        = sizeof(STARTUPINFOA);
-        startInfo.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
-        if (captureStdOut)
-        {
-            if (!mStdoutPipe.initPipe(&securityAttribs))
-            {
-                return;
-            }
-            startInfo.hStdOutput = mStdoutPipe.writeHandle;
-        }
-        else
-        {
-            startInfo.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
-        }
-
-        if (captureStdErr)
-        {
-            if (!mStderrPipe.initPipe(&securityAttribs))
-            {
-                return;
-            }
-            startInfo.hStdError = mStderrPipe.writeHandle;
-        }
-        else
-        {
-            startInfo.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
-        }
-
-        if (captureStdOut || captureStdErr)
-        {
-            startInfo.dwFlags |= STARTF_USESTDHANDLES;
-        }
-
-        // Create the child process.
-        if (::CreateProcessA(nullptr, commandLineString.data(), nullptr, nullptr,
-                             TRUE,  // Handles are inherited.
-                             0, nullptr, nullptr, &startInfo, &mProcessInfo) == FALSE)
-        {
-            std::cerr << "CreateProcessA Error code: " << GetLastError() << "\n";
-            return;
-        }
-
-        // Close the write end of the pipes, so EOF can be generated when child exits.
-        if (!mStdoutPipe.closeWriteHandle() || !mStderrPipe.closeWriteHandle())
-            return;
-
-        mStarted = true;
-        mTimer.start();
-    }
-
-    ~WindowsProcess() override
-    {
-        if (mProcessInfo.hProcess != INVALID_HANDLE_VALUE)
-        {
-            ::CloseHandle(mProcessInfo.hProcess);
-        }
-        if (mProcessInfo.hThread != INVALID_HANDLE_VALUE)
-        {
-            ::CloseHandle(mProcessInfo.hThread);
-        }
-    }
-
-    bool started() override { return mStarted; }
-
-    bool finish() override
-    {
-        if (mStdoutPipe.valid())
-        {
-            ReadFromFile(true, mStdoutPipe.readHandle, &mStdout);
-        }
-
-        if (mStderrPipe.valid())
-        {
-            ReadFromFile(true, mStderrPipe.readHandle, &mStderr);
-        }
-
-        DWORD result = ::WaitForSingleObject(mProcessInfo.hProcess, INFINITE);
-        mTimer.stop();
-        return result == WAIT_OBJECT_0;
-    }
-
-    bool finished() override
-    {
-        if (!mStarted)
-            return false;
-
-        // Pipe stdin and stdout.
-        if (mStdoutPipe.valid())
-        {
-            ReadFromFile(false, mStdoutPipe.readHandle, &mStdout);
-        }
-
-        if (mStderrPipe.valid())
-        {
-            ReadFromFile(false, mStderrPipe.readHandle, &mStderr);
-        }
-
-        DWORD result = ::WaitForSingleObject(mProcessInfo.hProcess, 0);
-        if (result == WAIT_OBJECT_0)
-        {
-            mTimer.stop();
-            return true;
-        }
-        if (result == WAIT_TIMEOUT)
-            return false;
-
-        mTimer.stop();
-        std::cerr << "Unexpected result from WaitForSingleObject: " << result
-                  << ". Last error: " << ::GetLastError() << "\n";
-        return false;
-    }
-
-    int getExitCode() override
-    {
-        if (!mStarted)
-            return -1;
-
-        if (mProcessInfo.hProcess == INVALID_HANDLE_VALUE)
-            return -1;
-
-        DWORD exitCode = 0;
-        if (::GetExitCodeProcess(mProcessInfo.hProcess, &exitCode) == FALSE)
-            return -1;
-
-        return static_cast<int>(exitCode);
-    }
-
-    bool kill() override
-    {
-        if (!mStarted)
-            return true;
-
-        HANDLE newHandle;
-        if (::DuplicateHandle(::GetCurrentProcess(), mProcessInfo.hProcess, ::GetCurrentProcess(),
-                              &newHandle, PROCESS_ALL_ACCESS, false,
-                              DUPLICATE_CLOSE_SOURCE) == FALSE)
-        {
-            std::cerr << "Error getting permission to terminate process: " << ::GetLastError()
-                      << "\n";
-            return false;
-        }
-        mProcessInfo.hProcess = newHandle;
-
-        if (::TerminateThread(mProcessInfo.hThread, 1) == FALSE)
-        {
-            std::cerr << "TerminateThread failed: " << GetLastError() << "\n";
-            return false;
-        }
-
-        if (::TerminateProcess(mProcessInfo.hProcess, 1) == FALSE)
-        {
-            std::cerr << "TerminateProcess failed: " << GetLastError() << "\n";
-            return false;
-        }
-
-        mStarted = false;
-        mTimer.stop();
-        return true;
-    }
-
-  private:
-    bool mStarted = false;
-    ScopedPipe mStdoutPipe;
-    ScopedPipe mStderrPipe;
-    PROCESS_INFORMATION mProcessInfo = {};
-};
 }  // anonymous namespace
 
 void Sleep(unsigned int milliseconds)
@@ -439,18 +127,13 @@
     OutputDebugStringA(buffer.data());
 }
 
-void InitCrashHandler(CrashCallback *callback)
+void InitCrashHandler()
 {
-    if (callback)
-    {
-        gCrashHandlerCallback = callback;
-    }
-    SetUnhandledExceptionFilter(CrashHandler);
+    SetUnhandledExceptionFilter(StackTraceCrashHandler);
 }
 
 void TerminateCrashHandler()
 {
-    gCrashHandlerCallback = nullptr;
     SetUnhandledExceptionFilter(nullptr);
 }
 
@@ -461,61 +144,4 @@
     RtlCaptureContext(&context);
     PrintBacktrace(&context);
 }
-
-Process *LaunchProcess(const std::vector<const char *> &args,
-                       bool captureStdout,
-                       bool captureStderr)
-{
-    return new WindowsProcess(args, captureStdout, captureStderr);
-}
-
-bool GetTempDir(char *tempDirOut, uint32_t maxDirNameLen)
-{
-    DWORD pathLen = ::GetTempPathA(maxDirNameLen, tempDirOut);
-    return (pathLen < MAX_PATH && pathLen > 0);
-}
-
-bool CreateTemporaryFileInDir(const char *dir, char *tempFileNameOut, uint32_t maxFileNameLen)
-{
-    char fileName[MAX_PATH + 1];
-    if (::GetTempFileNameA(dir, "ANGLE", 0, fileName) == 0)
-        return false;
-
-    strncpy(tempFileNameOut, fileName, maxFileNameLen);
-    return true;
-}
-
-bool DeleteFile(const char *path)
-{
-    if (strlen(path) >= MAX_PATH)
-        return false;
-
-    const DWORD attr = ::GetFileAttributesA(path);
-    // Report success if the file or path does not exist.
-    if (attr == INVALID_FILE_ATTRIBUTES)
-    {
-        return ReturnSuccessOnNotFound();
-    }
-
-    // Clear the read-only bit if it is set.
-    if ((attr & FILE_ATTRIBUTE_READONLY) &&
-        !::SetFileAttributesA(path, attr & ~FILE_ATTRIBUTE_READONLY))
-    {
-        // It's possible for |path| to be gone now under a race with other deleters.
-        return ReturnSuccessOnNotFound();
-    }
-
-    // We don't handle directories right now.
-    if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
-    {
-        return false;
-    }
-
-    return !!::DeleteFileA(path) ? true : ReturnSuccessOnNotFound();
-}
-
-int NumberOfProcessors()
-{
-    return ::GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
-}
 }  // namespace angle
diff --git a/util/windows/win32/test_utils_win32.cpp b/util/windows/win32/test_utils_win32.cpp
index 9e08b23..4f4aa8d 100644
--- a/util/windows/win32/test_utils_win32.cpp
+++ b/util/windows/win32/test_utils_win32.cpp
@@ -11,10 +11,9 @@
 #include <windows.h>
 #include <array>
 
-#include "util/random_utils.h"
-
 namespace angle
 {
+
 void SetLowPriorityProcess()
 {
     SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
@@ -22,15 +21,15 @@
 
 bool StabilizeCPUForBenchmarking()
 {
-    if (::SetThreadAffinityMask(::GetCurrentThread(), 1) == 0)
+    if (SetThreadAffinityMask(GetCurrentThread(), 1) == 0)
     {
         return false;
     }
-    if (::SetPriorityClass(::GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE)
+    if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE)
     {
         return false;
     }
-    if (::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == FALSE)
+    if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == FALSE)
     {
         return false;
     }