[runtime] Add testing for unhandled exception
authorLudovic Henry <ludovic@xamarin.com>
Tue, 4 Aug 2015 20:40:36 +0000 (16:40 -0400)
committerLudovic Henry <ludovic@xamarin.com>
Wed, 5 Aug 2015 13:18:51 +0000 (09:18 -0400)
mono/tests/Makefile.am
mono/tests/unhandled-exception.cs [new file with mode: 0644]

index aa6c3529afe59ef0814e1e0b259ac46157742325..97ad6e34dfd6156a69bc9056e9f3788047fbdecf 100644 (file)
@@ -1,6 +1,6 @@
 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-messages 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-process-exit test-messages test-unhandled-exception-2 rm-empty-logs
 check-full: test-sgen check-local
 check-parallel: compile-tests check-full
 
@@ -1349,6 +1349,19 @@ test-oom: $(OOM_TESTS)
                MONO_GC_PARAMS=max-heap-size=16m                                                  $(RUNTIME) $$fn > $$fn.stdout || exit 1;      \
        done
 
+if HOST_WIN32
+test-unhandled-exception-2:
+else
+test-unhandled-exception-2: unhandled-exception.exe
+       @echo "Testing unhandled-exception_1 ..."; $(RUNTIME) $+ 1 1> unhandled-exception_1.exe.stdout 2> unhandled-exception_1.exe.stderr; if test "x$$?" != "x1";   then exit 1; fi;  \
+        echo "Testing unhandled-exception_2 ..."; $(RUNTIME) $+ 2 1> unhandled-exception_2.exe.stdout 2> unhandled-exception_2.exe.stderr; if test "x$$?" != "x0";   then exit 2; fi;  \
+        echo "Testing unhandled-exception_3 ..."; $(RUNTIME) $+ 3 1> unhandled-exception_3.exe.stdout 2> unhandled-exception_3.exe.stderr; if test "x$$?" != "x0";   then exit 3; fi;  \
+        echo "Testing unhandled-exception_4 ..."; $(RUNTIME) $+ 4 1> unhandled-exception_4.exe.stdout 2> unhandled-exception_4.exe.stderr; if test "x$$?" != "x0";   then exit 4; fi;  \
+        echo "Testing unhandled-exception_5 ..."; $(RUNTIME) $+ 5 1> unhandled-exception_5.exe.stdout 2> unhandled-exception_5.exe.stderr; if test "x$$?" != "x255"; then exit 5; fi;  \
+        echo "Testing unhandled-exception_6 ..."; $(RUNTIME) $+ 6 1> unhandled-exception_6.exe.stdout 2> unhandled-exception_6.exe.stderr; if test "x$$?" != "x0";   then exit 6; fi;  \
+        echo "Testing unhandled-exception_7 ..."; $(RUNTIME) $+ 7 1> unhandled-exception_7.exe.stdout 2> unhandled-exception_7.exe.stderr; if test "x$$?" != "x0";   then exit 7; fi;  \
+        echo "Testing unhandled-exception_8 ..."; $(RUNTIME) $+ 8 1> unhandled-exception_8.exe.stdout 2> unhandled-exception_8.exe.stderr; if test "x$$?" != "x3";   then exit 8; fi
+endif
 
 noinst_LTLIBRARIES = libtest.la
 
diff --git a/mono/tests/unhandled-exception.cs b/mono/tests/unhandled-exception.cs
new file mode 100644 (file)
index 0000000..7658e07
--- /dev/null
@@ -0,0 +1,193 @@
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+
+class CustomException : Exception
+{
+}
+
+class CustomException2 : Exception
+{
+}
+
+
+class CrossDomain : MarshalByRefObject
+{
+       public Action NewDelegateWithTarget ()
+       {
+               return new Action (Bar);
+       }
+
+       public Action NewDelegateWithoutTarget ()
+       {
+               return () => { throw new CustomException (); };
+       }
+
+       public void Bar ()
+       {
+               throw new CustomException ();
+       }
+}
+
+class Driver {
+       static ManualResetEvent mre = new ManualResetEvent (false);
+
+       static void DoTest1 ()
+       {
+               mre.Reset ();
+
+               var t = new Thread (new ThreadStart (() => { try { throw new CustomException (); } finally { mre.Set (); } }));
+               t.Start ();
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+
+               t.Join ();
+       }
+
+       static void DoTest2 ()
+       {
+               mre.Reset ();
+
+               var a = new Action (() => { try { throw new CustomException (); } finally { mre.Set (); } });
+               var ares = a.BeginInvoke (null, null);
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+
+               try {
+                       a.EndInvoke (ares);
+                       throw new Exception ();
+               } catch (CustomException) {                     
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+
+       static void DoTest3 ()
+       {
+               mre.Reset ();
+
+               ThreadPool.QueueUserWorkItem (_ => { try { throw new CustomException (); } finally { mre.Set (); } });
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+       }
+
+       static void DoTest4 ()
+       {
+               mre.Reset ();
+
+               var t = Task.Factory.StartNew (new Action (() => { try { throw new CustomException (); } finally { mre.Set (); } }));
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+
+               try {
+                       t.Wait ();
+                       throw new Exception ();
+               } catch (AggregateException ae) {
+                       if (!(ae.InnerExceptions [0] is CustomException))
+                               Environment.Exit (4);
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+       
+       class FinalizedClass
+       {
+               ~FinalizedClass ()
+               {
+                       try {
+                               throw new CustomException ();
+                       } finally {
+                               mre.Set ();
+                       }
+               }
+       }
+
+       static void DoTest5 ()
+       {
+               mre.Reset ();
+
+               new FinalizedClass();
+
+               GC.Collect ();
+               GC.WaitForPendingFinalizers ();
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+       }
+
+       static void DoTest6 ()
+       {
+               ManualResetEvent mre2 = new ManualResetEvent (false);
+
+               mre.Reset ();
+
+               var a = new Action (() => { try { throw new CustomException (); } finally { mre.Set (); } });
+               var ares = a.BeginInvoke (_ => { mre2.Set (); throw new CustomException2 (); }, null);
+
+               if (!mre.WaitOne (5000))
+                       Environment.Exit (2);
+               if (!mre2.WaitOne (5000))
+                       Environment.Exit (22);
+
+               try {
+                       a.EndInvoke (ares);
+                       throw new Exception ();
+               } catch (CustomException) {
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+
+       static void DoTest7 ()
+       {
+               var cd = (CrossDomain) AppDomain.CreateDomain ("ad").CreateInstanceAndUnwrap (typeof(CrossDomain).Assembly.FullName, "CrossDomain");
+
+               var a = cd.NewDelegateWithoutTarget ();
+               var ares = a.BeginInvoke (delegate { throw new CustomException2 (); }, null);
+
+               try {
+                       a.EndInvoke (ares);
+                       throw new Exception ();
+               } catch (CustomException) {
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+
+       static void DoTest8 ()
+       {
+               var cd = (CrossDomain) AppDomain.CreateDomain ("ad").CreateInstanceAndUnwrap (typeof(CrossDomain).Assembly.FullName, "CrossDomain");
+
+               var a = cd.NewDelegateWithTarget ();
+               var ares = a.BeginInvoke (delegate { throw new CustomException2 (); }, null);
+
+               try {
+                       a.EndInvoke (ares);
+                       throw new Exception ();
+               } catch (CustomException) {
+               } catch (Exception) {
+                       Environment.Exit (3);
+               }
+       }
+
+       static void Main (string[] args)
+       {
+               switch (int.Parse (args [0])) {
+               case 1: DoTest1 (); break;
+               case 2: DoTest2 (); break;
+               case 3: DoTest3 (); break;
+               case 4: DoTest4 (); break;
+               case 5: DoTest5 (); break;
+               case 6: DoTest6 (); break;
+               case 7: DoTest7 (); break;
+               case 8: DoTest8 (); break;
+               default: throw new ArgumentOutOfRangeException ();
+               }
+               Environment.Exit (0);
+       }
+}