From 1464b756a4ef091ef97d1bf7340188ab5fe5492a Mon Sep 17 00:00:00 2001 From: David Sherret Date: Mon, 19 Sep 2022 09:32:21 -0500 Subject: refactor: move out test files from root testdata directory into sub directories (#15949) --- cli/tests/testdata/assets/DenoWinRunner.cs | 127 +++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 cli/tests/testdata/assets/DenoWinRunner.cs (limited to 'cli/tests/testdata/assets/DenoWinRunner.cs') diff --git a/cli/tests/testdata/assets/DenoWinRunner.cs b/cli/tests/testdata/assets/DenoWinRunner.cs new file mode 100644 index 000000000..2f9e9f89f --- /dev/null +++ b/cli/tests/testdata/assets/DenoWinRunner.cs @@ -0,0 +1,127 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +[Flags] +public enum DenoConstraints : int +{ + None = 0, + NoStdin = 1, + NoStdout = 2, + NoStderr = 4 +} + +public class DenoWinRunner +{ + private const int STD_INPUT_HANDLE = -10; + private const int STD_OUTPUT_HANDLE = -11; + private const int STD_ERROR_HANDLE = -12; + + private const int FILE_NOT_FOUND = 2; + private const int WAIT_TIMEOUT = 258; + + [DllImport("kernel32.dll")] + private static extern void SetStdHandle(int nStdHandle, IntPtr handle); + + /// + /// Runs Deno.exe under the specified constraints + /// + /// Path to the Deno.exe file. Can be absolute or relative + /// Path to the script file Deno should run. + /// The constraints to apply to the Deno process + /// How long to wait for the Deno process to exit + /// The deno.exe exit code, or an exit code provided by the test runner + public static int RunDenoScript(string pathToDenoExe, string pathToTestScript, DenoConstraints constraints, uint timeoutMilliseconds = 1000) + { + try + { + if (!File.Exists(pathToDenoExe)) + { + Console.Error.WriteLine("Cannot find Deno.exe at " + pathToDenoExe); + return FILE_NOT_FOUND; + } + + if (!File.Exists(pathToTestScript)) + { + Console.Error.WriteLine("Cannot find test script at " + pathToTestScript); + return FILE_NOT_FOUND; + } + + ProcessStartInfo startInfo = new ProcessStartInfo(pathToDenoExe) + { + ErrorDialog = false, + UseShellExecute = false, + Arguments = @"run -A " + pathToTestScript, + RedirectStandardInput = !constraints.HasFlag(DenoConstraints.NoStdin), + RedirectStandardOutput = !constraints.HasFlag(DenoConstraints.NoStdout), + RedirectStandardError = !constraints.HasFlag(DenoConstraints.NoStderr) + }; + + startInfo.Environment.Add("RUST_BACKTRACE", "1"); + + if (constraints.HasFlag(DenoConstraints.NoStdin)) + { + SetStdHandle(STD_INPUT_HANDLE, (IntPtr)null); + } + + if (constraints.HasFlag(DenoConstraints.NoStdout)) + { + SetStdHandle(STD_OUTPUT_HANDLE, (IntPtr)null); + } + + if (constraints.HasFlag(DenoConstraints.NoStderr)) + { + SetStdHandle(STD_ERROR_HANDLE, (IntPtr)null); + } + + Process process = new Process { StartInfo = startInfo }; + process.Start(); + + Task stdErrTask = startInfo.RedirectStandardError ? + process.StandardError.ReadToEndAsync() : Task.FromResult(null); + Task stdOutTask = startInfo.RedirectStandardOutput ? + process.StandardOutput.ReadToEndAsync() : Task.FromResult(null); + + if (!process.WaitForExit((int)timeoutMilliseconds)) + { + Console.Error.WriteLine("Timed out waiting for Deno process to exit"); + try + { + process.Kill(); + } + catch + { + // Kill might fail, either because the process already exited or due to some other error + Console.Error.WriteLine("Failure killing the Deno process - possible Zombie Deno.exe process"); + } + return WAIT_TIMEOUT; + } + + // If the Deno process wrote to STDERR - append it to our STDERR + if (!constraints.HasFlag(DenoConstraints.NoStderr)) + { + string error = stdErrTask.Result; + if (!string.IsNullOrWhiteSpace(error)) + { + Console.Error.WriteLine(error); + } + } + + return process.ExitCode; + + } + catch (Win32Exception ex) + { + Console.Error.WriteLine("Win32Exception: code = " + ex.ErrorCode + ", message: " + ex.Message); + return ex.NativeErrorCode; + } + catch (Exception ex) + { + Console.Error.WriteLine("Exception: message: " + ex.Message); + return -1; + } + } +} -- cgit v1.2.3