Merge pull request #273 from joncham/bug-getpid
[mono.git] / mono / tests / appdomain-unload.cs
index c330ba1e5237024529aaf7863f68076dda041ec3..c811eec33676834d4ce737fd0434385a9ce6987e 100644 (file)
@@ -1,5 +1,7 @@
 using System;
 using System.Threading;
+using System.Reflection;
+using System.Runtime.Remoting;
 
 [Serializable]
 public class Foo {
@@ -9,6 +11,13 @@ public class Foo {
        }
 }
 
+public class Bar : MarshalByRefObject {
+       public int test (int x) {
+               Console.WriteLine ("in " + Thread.GetDomain ().FriendlyName);
+               return x + 1;
+       }
+}
+
 [Serializable]
 public class SlowFinalize {
 
@@ -42,21 +51,27 @@ public class AThread {
        }
 }
 
-[Serializable]
 // A Thread which refuses to die
-public class BThread {
+public class BThread : MarshalByRefObject {
+
+       bool stop;
 
        public BThread () {
                new Thread (new ThreadStart (Run)).Start ();
        }
 
+       public void Stop () {
+               stop = true;
+       }
+
        public void Run () {
                try {
                        while (true)
                                Thread.Sleep (100);
                }
                catch (ThreadAbortException ex) {
-                       Thread.Sleep (1000000000);
+                       while (!stop)
+                               Thread.Sleep (100);
                }
        }
 }
@@ -76,15 +91,23 @@ public class UnloadThread {
        }
 }
 
+class CrossDomainTester : MarshalByRefObject
+{
+}
+
 public class Tests
 {
-       public static int Main() {
-               return TestDriver.RunTests (typeof (Tests));
+       public static int Main(string[] args) {
+               return TestDriver.RunTests (typeof (Tests), args);
        }
 
        public static int test_0_unload () {
                for (int i = 0; i < 10; ++i) {
                        AppDomain appDomain = AppDomain.CreateDomain("Test-unload" + i);
+
+                       appDomain.CreateInstanceAndUnwrap (
+                               typeof (CrossDomainTester).Assembly.FullName, "CrossDomainTester");
+
                        AppDomain.Unload(appDomain);
                }
 
@@ -117,7 +140,7 @@ public class Tests
 
        public static int test_0_is_finalizing () {
                AppDomain domain = AppDomain.CreateDomain ("Test-is-finalizing");
-               object o = domain.CreateInstanceFromAndUnwrap ("unload.exe", "Foo");
+               object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "Foo");
 
                if (domain.IsFinalizingForUnload ())
                        return 1;
@@ -129,7 +152,7 @@ public class Tests
 
        public static int test_0_unload_with_active_threads () {
                AppDomain domain = AppDomain.CreateDomain ("Test3");
-               object o = domain.CreateInstanceFromAndUnwrap ("unload.exe", "AThread");
+               object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "AThread");
                Thread.Sleep (100);
 
                AppDomain.Unload (domain);
@@ -137,27 +160,114 @@ public class Tests
                return 0;
        }
 
+       /* In recent mono versions, there is no unload timeout */
+       /*
        public static int test_0_unload_with_active_threads_timeout () {
                AppDomain domain = AppDomain.CreateDomain ("Test4");
-               object o = domain.CreateInstanceFromAndUnwrap ("unload.exe", "BThread");
+               BThread o = (BThread)domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "BThread");
                Thread.Sleep (100);
 
                try {
                        AppDomain.Unload (domain);
                }
                catch (Exception) {
+                       // Try again
+                       o.Stop ();
+                       AppDomain.Unload (domain);
                        return 0;
                }
 
                return 1;
        }
+       */
+
+       static void Worker (object x) {
+               Thread.Sleep (100000);
+       }
+
+       public static void invoke_workers () {
+               for (int i = 0; i < 1; i ++)
+                       ThreadPool.QueueUserWorkItem (Worker);
+       }
+
+       public static int test_0_unload_with_threadpool () {
+               AppDomain domain = AppDomain.CreateDomain ("test_0_unload_with_threadpool");
+
+               domain.DoCallBack (new CrossAppDomainDelegate (invoke_workers));
+               AppDomain.Unload (domain);
+
+               return 0;
+       }
+
+       /*
+        * This test is not very deterministic since the thread which enqueues
+        * the work item might or might not be inside the domain when the unload
+        * happens. So disable this for now.
+        */
+       /*
+       public static void DoUnload (object state) {
+               AppDomain.Unload (AppDomain.CurrentDomain);
+       }
+
+       public static void Callback () {
+               Console.WriteLine (AppDomain.CurrentDomain);
+               WaitCallback unloadDomainCallback = new WaitCallback (DoUnload);
+               ThreadPool.QueueUserWorkItem (unloadDomainCallback);
+       }               
+
+       public static int test_0_unload_inside_appdomain_async () {
+               AppDomain domain = AppDomain.CreateDomain ("Test3");
+
+               domain.DoCallBack (new CrossAppDomainDelegate (Callback));
+
+               return 0;
+       }
+       */
+
+       public static void SyncCallback () {
+               AppDomain.Unload (AppDomain.CurrentDomain);
+       }               
+
+       public static int test_0_unload_inside_appdomain_sync () {
+               AppDomain domain = AppDomain.CreateDomain ("Test3");
+
+               try {
+                       domain.DoCallBack (new CrossAppDomainDelegate (SyncCallback));
+               }
+               catch (Exception ex) {
+                       /* Should throw a ThreadAbortException */
+                       Thread.ResetAbort ();
+               }
+
+               return 0;
+       }
+
+       public static int test_0_invoke_after_unload () {
+               AppDomain domain = AppDomain.CreateDomain ("DeadInvokeTest");
+               Bar bar = (Bar)domain.CreateInstanceAndUnwrap (typeof (Tests).Assembly.FullName, "Bar");
+               int x;
+
+               if (!RemotingServices.IsTransparentProxy(bar))
+                       return 3;
+
+               AppDomain.Unload (domain);
+
+               try {
+                       x = bar.test (123);
+                       if (x == 124)
+                               return 1;
+                       return 2;
+               } catch (Exception e) {
+                       return 0;
+               }
+       }
 
        // FIXME: This does not work yet, because the thread is finalized too
        // early
        /*
        public static int test_0_unload_during_unload () {
                AppDomain domain = AppDomain.CreateDomain ("Test3");
-               object o = domain.CreateInstanceFromAndUnwrap ("unload.exe", "SlowFinalize");
+               object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "SlowFinalize");
 
                UnloadThread t = new UnloadThread (domain);