1 // 2 // Copyright 2014 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // test_utils.h: declaration of OS-specific utility functions 8 9 #ifndef UTIL_TEST_UTILS_H_ 10 #define UTIL_TEST_UTILS_H_ 11 12 #include <functional> 13 #include <string> 14 #include <vector> 15 16 #include "common/angleutils.h" 17 #include "util/Timer.h" 18 19 namespace angle 20 { 21 // Cross platform equivalent of the Windows Sleep function 22 void Sleep(unsigned int milliseconds); 23 24 void SetLowPriorityProcess(); 25 26 // Write a debug message, either to a standard output or Debug window. 27 void WriteDebugMessage(const char *format, ...); 28 29 // Set thread affinity and priority. 30 bool StabilizeCPUForBenchmarking(); 31 32 // Set a crash handler to print stack traces. 33 using CrashCallback = std::function<void()>; 34 void InitCrashHandler(CrashCallback *callback); 35 void TerminateCrashHandler(); 36 37 // Print a stack back trace. 38 void PrintStackBacktrace(); 39 40 // Deletes a file or directory. 41 bool DeleteSystemFile(const char *path); 42 43 // Reads a file contents into a string. Note: this method cannot be exported across a shared module 44 // boundary because it does memory allocation. 45 bool ReadEntireFileToString(const char *filePath, std::string *contentsOut); 46 47 // Compute a file's size. 48 bool GetFileSize(const char *filePath, uint32_t *sizeOut); 49 50 class ProcessHandle; 51 52 class Process : angle::NonCopyable 53 { 54 public: 55 virtual bool started() = 0; 56 virtual bool finished() = 0; 57 virtual bool finish() = 0; 58 virtual bool kill() = 0; 59 virtual int getExitCode() = 0; 60 getElapsedTimeSeconds()61 double getElapsedTimeSeconds() const { return mTimer.getElapsedWallClockTime(); } getStdout()62 const std::string &getStdout() const { return mStdout; } getStderr()63 const std::string &getStderr() const { return mStderr; } 64 65 protected: 66 friend class ProcessHandle; 67 virtual ~Process(); 68 69 Timer mTimer; 70 std::string mStdout; 71 std::string mStderr; 72 }; 73 74 enum class ProcessOutputCapture 75 { 76 Nothing, 77 // Capture stdout only 78 StdoutOnly, 79 // Capture stdout, and pipe stderr to stdout 80 StdoutAndStderrInterleaved, 81 // Capture stdout and stderr separately 82 StdoutAndStderrSeparately, 83 }; 84 85 class ProcessHandle final : angle::NonCopyable 86 { 87 public: 88 ProcessHandle(); 89 ProcessHandle(Process *process); 90 ProcessHandle(const std::vector<const char *> &args, ProcessOutputCapture captureOutput); 91 ~ProcessHandle(); 92 ProcessHandle(ProcessHandle &&other); 93 ProcessHandle &operator=(ProcessHandle &&rhs); 94 95 Process *operator->() { return mProcess; } 96 const Process *operator->() const { return mProcess; } 97 98 operator bool() const { return mProcess != nullptr; } 99 100 void reset(); 101 102 private: 103 Process *mProcess; 104 }; 105 106 // Launch a process and optionally get the output. Uses a vector of c strings as command line 107 // arguments to the child process. Returns a Process handle which can be used to retrieve 108 // the stdout and stderr outputs as well as the exit code. 109 // 110 // Pass false for stdoutOut/stderrOut if you don't need to capture them. 111 // 112 // On success, returns a Process pointer with started() == true. 113 // On failure, returns a Process pointer with started() == false. 114 Process *LaunchProcess(const std::vector<const char *> &args, ProcessOutputCapture captureOutput); 115 116 int NumberOfProcessors(); 117 118 const char *GetNativeEGLLibraryNameWithExtension(); 119 120 // Intercept Metal shader cache access to avoid slow caching mechanism that caused the test timeout 121 // in the past. Note: 122 // - If there is NO "--skip-file-hooking" switch in the argument list: 123 // - This function will re-launch the app with additional argument "--skip-file-hooking". 124 // - The running process's image & memory will be re-created. 125 // - If there is "--skip-file-hooking" switch in the argument list, this function will do nothing. 126 #if defined(ANGLE_PLATFORM_APPLE) 127 void InitMetalFileAPIHooking(int argc, char **argv); 128 #endif 129 130 enum ArgHandling 131 { 132 Delete, 133 Preserve, 134 }; 135 136 bool ParseIntArg(const char *flag, int *argc, char **argv, int argIndex, int *valueOut); 137 bool ParseFlag(const char *flag, int *argc, char **argv, int argIndex, bool *flagOut); 138 bool ParseStringArg(const char *flag, int *argc, char **argv, int argIndex, std::string *valueOut); 139 bool ParseCStringArg(const char *flag, int *argc, char **argv, int argIndex, const char **valueOut); 140 141 // Note: return value is always false with ArgHandling::Preserve handling 142 bool ParseIntArgWithHandling(const char *flag, 143 int *argc, 144 char **argv, 145 int argIndex, 146 int *valueOut, 147 ArgHandling handling); 148 bool ParseCStringArgWithHandling(const char *flag, 149 int *argc, 150 char **argv, 151 int argIndex, 152 const char **valueOut, 153 ArgHandling handling); 154 155 void AddArg(int *argc, char **argv, const char *arg); 156 157 uint32_t GetPlatformANGLETypeFromArg(const char *useANGLEArg, uint32_t defaultPlatformType); 158 uint32_t GetANGLEDeviceTypeFromArg(const char *useANGLEArg, uint32_t defaultDeviceType); 159 } // namespace angle 160 161 #endif // UTIL_TEST_UTILS_H_ 162