Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / tests / appdomain-unload.cs
1 using System;
2 using System.Threading;
3 using System.Reflection;
4 using System.Runtime.Remoting;
5
6 [Serializable]
7 public class Foo {
8
9         ~Foo () {
10                 Console.WriteLine ("FINALIZING IN DOMAIN " + AppDomain.CurrentDomain.FriendlyName + ": " + AppDomain.CurrentDomain.IsFinalizingForUnload ());
11         }
12 }
13
14 public class Bar : MarshalByRefObject {
15         public int test (int x) {
16                 Console.WriteLine ("in " + Thread.GetDomain ().FriendlyName);
17                 return x + 1;
18         }
19
20         public void start_wait () {
21                 Action a = delegate () {
22                         Thread.Sleep (10000);
23                 };
24                 a.BeginInvoke (null, null);
25         }
26 }
27
28 [Serializable]
29 public class SlowFinalize {
30
31         ~SlowFinalize () {
32                 Console.WriteLine ("FINALIZE1.");
33                 try {
34                         Thread.Sleep (500);
35                 }
36                 catch (Exception ex) {
37                         Console.WriteLine ("A: " + ex);
38                 }
39                 Console.WriteLine ("FINALIZE2.");
40         }
41 }
42
43 [Serializable]
44 public class AThread {
45
46         public AThread () {
47                 new Thread (new ThreadStart (Run)).Start ();
48         }
49
50         public void Run () {
51                 try {
52                         while (true)
53                                 Thread.Sleep (100);
54                 }
55                 catch (ThreadAbortException ex) {
56                         Console.WriteLine ("Thread aborted correctly.");
57                 }
58         }
59 }
60
61 // A Thread which refuses to die
62 public class BThread : MarshalByRefObject {
63
64         bool stop;
65
66         public BThread () {
67                 new Thread (new ThreadStart (Run)).Start ();
68         }
69
70         public void Stop () {
71                 stop = true;
72         }
73
74         public void Run () {
75                 try {
76                         while (true)
77                                 Thread.Sleep (100);
78                 }
79                 catch (ThreadAbortException ex) {
80                         while (!stop)
81                                 Thread.Sleep (100);
82                 }
83         }
84 }
85
86 public interface IRunnable {
87         void Run ();
88 }
89
90 public class MBRObject : MarshalByRefObject, IRunnable {
91         /* XDomain wrappers for invocation */
92         public void Run () {
93                 while (true) {
94                         try {
95                                 while (true)
96                                         Thread.Sleep (100);
97                         }
98                         catch (ThreadAbortException ex) {
99                                 Thread.ResetAbort ();
100                         }
101                 }
102         }
103 }
104
105 public class CBObject : ContextBoundObject, IRunnable {
106         /* Slow corlib path for invocation */
107         public void Run () {
108                 while (true) {
109                         try {
110                                 while (true)
111                                         Thread.Sleep (100);
112                         }
113                         catch (ThreadAbortException ex) {
114                                 Thread.ResetAbort ();
115                         }
116                 }
117         }
118 }
119
120 public class UnloadThread {
121
122         AppDomain domain;
123
124         public UnloadThread (AppDomain domain) {
125                 this.domain = domain;
126         }
127
128         public void Run () {
129                 Console.WriteLine ("UNLOAD1");
130                 AppDomain.Unload (domain);
131                 Console.WriteLine ("UNLOAD2");
132         }
133 }
134
135 class CrossDomainTester : MarshalByRefObject
136 {
137 }
138
139 public class Tests
140 {
141         public static int Main(string[] args) {
142                 if (args.Length == 0)
143                         return TestDriver.RunTests (typeof (Tests), new String[] { "-v" });
144                 else
145                         return TestDriver.RunTests (typeof (Tests), args);
146         }
147
148         public static int test_0_unload () {
149                 for (int i = 0; i < 10; ++i) {
150                         AppDomain appDomain = AppDomain.CreateDomain("Test-unload" + i);
151
152                         appDomain.CreateInstanceAndUnwrap (
153                                 typeof (CrossDomainTester).Assembly.FullName, "CrossDomainTester");
154
155                         AppDomain.Unload(appDomain);
156                 }
157
158                 return 0;
159         }
160
161         public static int test_0_unload_default () {
162                 try {
163                         AppDomain.Unload (Thread.GetDomain ());
164                 }
165                 catch (CannotUnloadAppDomainException) {
166                         return 0;
167                 }
168                 return 1;
169         }
170
171         public static int test_0_unload_after_unload () {
172                 AppDomain domain = AppDomain.CreateDomain ("Test2");
173                 AppDomain.Unload (domain);
174
175                 try {
176                         AppDomain.Unload (domain);
177                 }
178                 catch (Exception) {
179                         return 0;
180                 }
181
182                 return 1;
183         }
184
185         public static int test_0_is_finalizing () {
186                 AppDomain domain = AppDomain.CreateDomain ("Test-is-finalizing");
187                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "Foo");
188
189                 if (domain.IsFinalizingForUnload ())
190                         return 1;
191
192                 AppDomain.Unload (domain);
193
194                 return 0;
195         }
196
197         public static int test_0_unload_with_active_threads () {
198                 AppDomain domain = AppDomain.CreateDomain ("Test3");
199                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "AThread");
200                 Thread.Sleep (100);
201
202                 AppDomain.Unload (domain);
203
204                 return 0;
205         }
206
207         /* In recent mono versions, there is no unload timeout */
208         /*
209         public static int test_0_unload_with_active_threads_timeout () {
210                 AppDomain domain = AppDomain.CreateDomain ("Test4");
211                 BThread o = (BThread)domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "BThread");
212                 Thread.Sleep (100);
213
214                 try {
215                         AppDomain.Unload (domain);
216                 }
217                 catch (Exception) {
218                         // Try again
219                         o.Stop ();
220                         AppDomain.Unload (domain);
221                         return 0;
222                 }
223
224                 return 1;
225         }
226         */
227
228         public static void ThreadStart (object obj)
229         {
230                 IRunnable runnable = (IRunnable)obj;
231
232                 try {
233                         runnable.Run ();
234                 } catch (AppDomainUnloadedException) {
235                         Console.WriteLine ("OK");
236                 } catch (ThreadAbortException) {
237                         throw new Exception ();
238                 }
239         }
240
241         public static int test_0_unload_reset_abort () {
242                 AppDomain domain = AppDomain.CreateDomain ("test_0_unload_reset_abort");
243                 MBRObject mbro = (MBRObject) domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "MBRObject");
244                 CBObject cbo = (CBObject) domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "CBObject");
245
246                 new Thread (ThreadStart).Start (mbro);
247                 new Thread (ThreadStart).Start (cbo);
248                 Thread.Sleep (100);
249
250                 AppDomain.Unload (domain);
251                 return 0;
252         }
253
254         static void Worker (object x) {
255                 Thread.Sleep (100000);
256         }
257
258         public static void invoke_workers () {
259                 for (int i = 0; i < 1; i ++)
260                         ThreadPool.QueueUserWorkItem (Worker);
261         }
262
263         public static int test_0_unload_with_threadpool () {
264                 AppDomain domain = AppDomain.CreateDomain ("test_0_unload_with_threadpool");
265
266                 domain.DoCallBack (new CrossAppDomainDelegate (invoke_workers));
267                 AppDomain.Unload (domain);
268
269                 return 0;
270         }
271
272         /*
273          * This test is not very deterministic since the thread which enqueues
274          * the work item might or might not be inside the domain when the unload
275          * happens. So disable this for now.
276          */
277         /*
278         public static void DoUnload (object state) {
279                 AppDomain.Unload (AppDomain.CurrentDomain);
280         }
281
282         public static void Callback () {
283                 Console.WriteLine (AppDomain.CurrentDomain);
284                 WaitCallback unloadDomainCallback = new WaitCallback (DoUnload);
285                 ThreadPool.QueueUserWorkItem (unloadDomainCallback);
286         }               
287
288         public static int test_0_unload_inside_appdomain_async () {
289                 AppDomain domain = AppDomain.CreateDomain ("Test3");
290
291                 domain.DoCallBack (new CrossAppDomainDelegate (Callback));
292
293                 return 0;
294         }
295         */
296
297         public static void SyncCallback () {
298                 AppDomain.Unload (AppDomain.CurrentDomain);
299         }               
300
301         public static int test_0_unload_inside_appdomain_sync () {
302                 AppDomain domain = AppDomain.CreateDomain ("Test3");
303                 bool caught = false;
304
305                 try {
306                         domain.DoCallBack (new CrossAppDomainDelegate (SyncCallback));
307                 }
308                 catch (AppDomainUnloadedException ex) {
309                         caught = true;
310                 }
311
312                 if (!caught)
313                         return 1;
314
315                 return 0;
316         }
317
318         public static int test_0_invoke_after_unload () {
319                 AppDomain domain = AppDomain.CreateDomain ("DeadInvokeTest");
320                 Bar bar = (Bar)domain.CreateInstanceAndUnwrap (typeof (Tests).Assembly.FullName, "Bar");
321                 int x;
322
323                 if (!RemotingServices.IsTransparentProxy(bar))
324                         return 3;
325
326                 AppDomain.Unload (domain);
327
328                 try {
329                         x = bar.test (123);
330                         if (x == 124)
331                                 return 1;
332                         return 2;
333                 } catch (Exception e) {
334                         return 0;
335                 }
336         }
337
338         public static int test_0_abort_wait () {
339                 AppDomain domain = AppDomain.CreateDomain ("AbortWait");
340                 Bar bar = (Bar)domain.CreateInstanceAndUnwrap (typeof (Tests).Assembly.FullName, "Bar");
341                 int x;
342
343                 bar.start_wait ();
344                 AppDomain.Unload (domain);
345                 return 0;
346         }
347
348         // FIXME: This does not work yet, because the thread is finalized too
349         // early
350         /*
351         public static int test_0_unload_during_unload () {
352                 AppDomain domain = AppDomain.CreateDomain ("Test3");
353                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "SlowFinalize");
354
355                 UnloadThread t = new UnloadThread (domain);
356
357                 // Start unloading in a separate thread
358                 new Thread (new ThreadStart (t.Run)).Start ();
359
360                 Thread.Sleep (100);
361
362                 try {
363                         AppDomain.Unload (domain);
364                 }
365                 catch (Exception) {
366                         Console.WriteLine ("OK");
367                 }
368
369                 return 0;
370         }       
371 */
372 }
373