// Input: EchoBack process public static async Task WaitForExitAsyncTimesOut(IChildProcess sut) { Assert.False(await sut.WaitForExitAsync(0)); Assert.False(await sut.WaitForExitAsync(1)); sut.StandardInput.Close(); Assert.True(await sut.WaitForExitAsync(1000)); }
// Input: EchoBack process public static void WaitForExitTimesOut(IChildProcess sut) { Assert.False(sut.WaitForExit(0)); Assert.False(sut.WaitForExit(1)); sut.StandardInput.Close(); sut.WaitForExit(); Assert.True(sut.WaitForExit(0)); }
// Input: EchoBack process public static void ExitCodeThrowsBeforeChildExits(IChildProcess sut) { Assert.Throws <InvalidOperationException>(() => sut.IsSuccessful); Assert.Throws <InvalidOperationException>(() => sut.ExitCode); sut.StandardInput.Close(); sut.WaitForExit(); Assert.True(sut.IsSuccessful); Assert.Equal(0, sut.ExitCode); }
// Input: TestChild with no arg public static void CanCreateChildProcess(IChildProcess sut) { sut.WaitForExit(); Assert.Equal(0, sut.ExitCode); // This closes StandardOutput, which should be acceptable. using (var sr = new StreamReader(sut.StandardOutput)) { Assert.Equal("TestChild", sr.ReadToEnd()); } }
static async Task Impl(IChildProcess sut, string expectedStdout, string expectedStderr) { using var srOut = new StreamReader(sut.StandardOutput); using var srErr = new StreamReader(sut.StandardError); var stdoutTask = srOut.ReadToEndAsync(); var stderrTask = srErr.ReadToEndAsync(); sut.WaitForExit(); Assert.Equal(0, sut.ExitCode); Assert.Equal(expectedStdout, await stdoutTask); Assert.Equal(expectedStderr, await stderrTask); }
// Input: EchoOutAndError process public static async Task CorrectlyConnectsPipesAsync(IChildProcess sut, string expectedStdout, string expectedStderr) { using (var srOut = new StreamReader(sut.StandardOutput)) using (var srErr = new StreamReader(sut.StandardError)) { var stdoutTask = srOut.ReadToEndAsync(); var stderrTask = srErr.ReadToEndAsync(); sut.WaitForExit(); Assert.Equal(expectedStdout, await stdoutTask); Assert.Equal(expectedStderr, await stderrTask); } }
// Input: EchoBack process public static async Task PipesAreAsynchronousAsync(IChildProcess sut) { Assert.True(((FileStream)sut.StandardInput).IsAsync); Assert.True(((FileStream)sut.StandardOutput).IsAsync); Assert.True(((FileStream)sut.StandardError).IsAsync); using (var sr = new StreamReader(sut.StandardOutput)) { const string text = "foobar"; var stdoutTask = sr.ReadToEndAsync(); using (var sw = new StreamWriter(sut.StandardInput)) { await sw.WriteAsync(text); } Assert.Equal(text, await stdoutTask); } sut.WaitForExit(); Assert.Equal(0, sut.ExitCode); }
// Input: EchoBack process public static async Task CanCancelWaitForExitAsync(IChildProcess sut) { Assert.False(await sut.WaitForExitAsync(0)); using (var cts = new CancellationTokenSource()) { var t = sut.WaitForExitAsync(1000, cts.Token); cts.Cancel(); Assert.Throws <TaskCanceledException>(() => t.GetAwaiter().GetResult()); } sut.StandardInput.Close(); Thread.Sleep(100); // If the process has already exited, returns true instead of returning CanceledTask. using (var cts = new CancellationTokenSource()) { cts.Cancel(); Assert.True(await sut.WaitForExitAsync(0, cts.Token)); } }
private static void WaitForAsyncIsTrulyAsynchronous(IChildProcess sut) { var sw = Stopwatch.StartNew(); // Because WaitForExitAsync is truly asynchronous and does not block a thread-pool thread, // we can create WaitForExitAsync tasks without consuming thread-pool threads. // In other words, if WaitForExitAsync would consume a thread-pool thread, the works queued by Task.Run would be blocked. var waitTasks = Enumerable.Range(0, Environment.ProcessorCount * 8) .Select(_ => sut.WaitForExitAsync(1000)) .ToArray(); Assert.True(waitTasks.All(x => !x.IsCompleted)); var emptyTasks = Enumerable.Range(0, Environment.ProcessorCount * 8) .Select(_ => Task.Run(() => { })) .ToArray(); Task.WaitAll(emptyTasks); Assert.True(sw.ElapsedMilliseconds < 100); }
private void StartProcess() { _childProcess = new ChildProcess(); _childProcess.Start(); Console.WriteLine("I am a new Process!"); _election.SetProcess(); }