That's to ensure we do not have regression in the Process implementation.
SUBDIRS = assemblyresolve gc-descriptors
-check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-cattr-type-load test-reflection-load-with-context test_platform test-process-exit test-console-output test-messages test-env-options test-unhandled-exception-2 test-appdomain-unload rm-empty-logs
+check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-cattr-type-load test-reflection-load-with-context test_platform \
+ test-console-output test-messages test-env-options test-unhandled-exception-2 test-appdomain-unload test-process-stress rm-empty-logs
check-full: test-sgen check-local
check-parallel: compile-tests check-full
@diff -w console-output.exe.stdout $(srcdir)/console-output.exe.stdout.expected \
&& diff -w console-output.exe.stderr $(srcdir)/console-output.exe.stderr.expected
+PROCESS_STRESS_TESTS= \
+ process-stress-1.exe \
+ process-stress-2.exe \
+ process-stress-3.exe
+
+test-process-stress: $(PROCESS_STRESS_TESTS) test-runner.exe
+ $(RUNTIME) ./test-runner.exe --testsuite-name $@ $(PROCESS_STRESS_TESTS)
+
coreclr-gcstress:
$(MAKE) -C $(mono_build_root)/acceptance-tests coreclr-gcstress
--- /dev/null
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+
+class Driver
+{
+ static void Main ()
+ {
+ for (int i = 0; i < 1000; ++i) {
+ ProcessStartInfo psi = new ProcessStartInfo () {
+ FileName = "echo",
+ Arguments = "hello 1>/dev/null",
+ };
+
+ Process p = Process.Start (psi);
+
+ ManualResetEvent mre = new ManualResetEvent (false);
+
+ Task t = Task.Run (() => {
+ mre.Set ();
+ if (!p.WaitForExit (1000))
+ Environment.Exit (1);
+ });
+
+ if (!mre.WaitOne (1000))
+ Environment.Exit (2);
+ if (!p.WaitForExit (1000))
+ Environment.Exit (3);
+
+ if (!t.Wait (1000))
+ Environment.Exit (4);
+ }
+ }
+}
--- /dev/null
+
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+class Driver
+{
+ static void Main ()
+ {
+ Action<Process>[] tests = new Action<Process> [] {
+ new Action<Process> (Test1),
+ new Action<Process> (Test2),
+ };
+
+ ProcessStartInfo psi = new ProcessStartInfo () {
+ FileName = "echo",
+ Arguments = "hello",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ };
+
+ foreach (Action<Process> test in tests) {
+ for (int i = 0; i < 500; ++i) {
+ test (new Process () { StartInfo = psi });
+ }
+ }
+ }
+
+ static void Test1 (Process p)
+ {
+ StringBuilder sb = new StringBuilder ();
+ ManualResetEvent mre_exit = new ManualResetEvent (false);
+ ManualResetEvent mre_output = new ManualResetEvent (false);
+
+ p.EnableRaisingEvents = true;
+ p.Exited += (s, a) => mre_exit.Set ();
+
+ p.Start ();
+
+ p.OutputDataReceived += (s, a) => {
+ if (a.Data == null) {
+ mre_output.Set ();
+ return;
+ }
+ sb.Append (a.Data);
+ };
+
+ p.BeginOutputReadLine ();
+
+ if (!mre_exit.WaitOne (1000))
+ Environment.Exit (1);
+ if (!mre_output.WaitOne (1000))
+ Environment.Exit (2);
+
+ if (sb.ToString () != "hello") {
+ Console.WriteLine ("process output = '{0}'", sb.ToString ());
+ Environment.Exit (3);
+ }
+ }
+
+ static void Test2 (Process p)
+ {
+ StringBuilder sb = new StringBuilder ();
+ ManualResetEvent mre_output = new ManualResetEvent (false);
+
+ p.Start ();
+
+ p.OutputDataReceived += (s, a) => {
+ if (a.Data == null) {
+ mre_output.Set ();
+ return;
+ }
+
+ sb.Append (a.Data);
+ };
+
+ p.BeginOutputReadLine ();
+
+ if (!p.WaitForExit (1000))
+ Environment.Exit (4);
+ if (!mre_output.WaitOne (1000))
+ Environment.Exit (5);
+
+ if (sb.ToString () != "hello") {
+ Console.WriteLine ("process output = '{0}'", sb.ToString ());
+ Environment.Exit (6);
+ }
+ }
+}
--- /dev/null
+
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+class Driver
+{
+ static void Main ()
+ {
+ Action<Process>[] tests = new Action<Process> [] {
+ new Action<Process> (Test1),
+ new Action<Process> (Test2),
+ };
+
+ ProcessStartInfo psi = new ProcessStartInfo () {
+ FileName = "find",
+ Arguments = "/ -maxdepth 4",
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ };
+
+ foreach (Action<Process> test in tests) {
+ for (int i = 0; i < 200; ++i) {
+ test (new Process () { StartInfo = psi });
+ }
+ }
+ }
+
+ static void Test1 (Process p)
+ {
+ ManualResetEvent mre_exit = new ManualResetEvent (false);
+ ManualResetEvent mre_output = new ManualResetEvent (false);
+ ManualResetEvent mre_error = new ManualResetEvent (false);
+
+ p.EnableRaisingEvents = true;
+ p.Exited += (s, a) => mre_exit.Set ();
+
+ p.Start ();
+
+ p.OutputDataReceived += (s, a) => {
+ if (a.Data == null) {
+ mre_output.Set ();
+ return;
+ }
+ };
+
+ p.ErrorDataReceived += (s, a) => {
+ if (a.Data == null) {
+ mre_error.Set ();
+ return;
+ }
+ };
+
+ p.BeginOutputReadLine ();
+ p.BeginErrorReadLine ();
+
+ if (!mre_exit.WaitOne (10000))
+ Environment.Exit (1);
+ if (!mre_output.WaitOne (1000))
+ Environment.Exit (2);
+ if (!mre_error.WaitOne (1000))
+ Environment.Exit (3);
+ }
+
+ static void Test2 (Process p)
+ {
+ ManualResetEvent mre_output = new ManualResetEvent (false);
+ ManualResetEvent mre_error = new ManualResetEvent (false);
+
+ p.Start ();
+
+ p.OutputDataReceived += (s, a) => {
+ if (a.Data == null) {
+ mre_output.Set ();
+ return;
+ }
+ };
+
+ p.ErrorDataReceived += (s, a) => {
+ if (a.Data == null) {
+ mre_error.Set ();
+ return;
+ }
+ };
+
+ p.BeginOutputReadLine ();
+ p.BeginErrorReadLine ();
+
+ if (!p.WaitForExit (10000))
+ Environment.Exit (4);
+ if (!mre_output.WaitOne (1000))
+ Environment.Exit (5);
+ if (!mre_error.WaitOne (1000))
+ Environment.Exit (6);
+ }
+}