New test.
[mono.git] / mono / tests / appdomain-unload.cs
1 using System;
2 using System.Threading;
3 using System.Reflection;
4
5 [Serializable]
6 public class Foo {
7
8         ~Foo () {
9                 Console.WriteLine ("FINALIZING IN DOMAIN " + AppDomain.CurrentDomain.FriendlyName + ": " + AppDomain.CurrentDomain.IsFinalizingForUnload ());
10         }
11 }
12
13 [Serializable]
14 public class SlowFinalize {
15
16         ~SlowFinalize () {
17                 Console.WriteLine ("FINALIZE1.");
18                 try {
19                         Thread.Sleep (500);
20                 }
21                 catch (Exception ex) {
22                         Console.WriteLine ("A: " + ex);
23                 }
24                 Console.WriteLine ("FINALIZE2.");
25         }
26 }
27
28 [Serializable]
29 public class AThread {
30
31         public AThread () {
32                 new Thread (new ThreadStart (Run)).Start ();
33         }
34
35         public void Run () {
36                 try {
37                         while (true)
38                                 Thread.Sleep (100);
39                 }
40                 catch (ThreadAbortException ex) {
41                         Console.WriteLine ("Thread aborted correctly.");
42                 }
43         }
44 }
45
46 // A Thread which refuses to die
47 public class BThread : MarshalByRefObject {
48
49         bool stop;
50
51         public BThread () {
52                 new Thread (new ThreadStart (Run)).Start ();
53         }
54
55         public void Stop () {
56                 stop = true;
57         }
58
59         public void Run () {
60                 try {
61                         while (true)
62                                 Thread.Sleep (100);
63                 }
64                 catch (ThreadAbortException ex) {
65                         while (!stop)
66                                 Thread.Sleep (100);
67                 }
68         }
69 }
70
71 public class UnloadThread {
72
73         AppDomain domain;
74
75         public UnloadThread (AppDomain domain) {
76                 this.domain = domain;
77         }
78
79         public void Run () {
80                 Console.WriteLine ("UNLOAD1");
81                 AppDomain.Unload (domain);
82                 Console.WriteLine ("UNLOAD2");
83         }
84 }
85
86 class CrossDomainTester : MarshalByRefObject
87 {
88 }
89
90 public class Tests
91 {
92         public static int Main() {
93                 return TestDriver.RunTests (typeof (Tests));
94         }
95
96         public static int test_0_unload () {
97                 for (int i = 0; i < 10; ++i) {
98                         AppDomain appDomain = AppDomain.CreateDomain("Test-unload" + i);
99
100                         appDomain.CreateInstanceAndUnwrap (
101                                 typeof (CrossDomainTester).Assembly.FullName, "CrossDomainTester");
102
103                         AppDomain.Unload(appDomain);
104                 }
105
106                 return 0;
107         }
108
109         public static int test_0_unload_default () {
110                 try {
111                         AppDomain.Unload (Thread.GetDomain ());
112                 }
113                 catch (CannotUnloadAppDomainException) {
114                         return 0;
115                 }
116                 return 1;
117         }
118
119         public static int test_0_unload_after_unload () {
120                 AppDomain domain = AppDomain.CreateDomain ("Test2");
121                 AppDomain.Unload (domain);
122
123                 try {
124                         AppDomain.Unload (domain);
125                 }
126                 catch (Exception) {
127                         return 0;
128                 }
129
130                 return 1;
131         }
132
133         public static int test_0_is_finalizing () {
134                 AppDomain domain = AppDomain.CreateDomain ("Test-is-finalizing");
135                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "Foo");
136
137                 if (domain.IsFinalizingForUnload ())
138                         return 1;
139
140                 AppDomain.Unload (domain);
141
142                 return 0;
143         }
144
145         public static int test_0_unload_with_active_threads () {
146                 AppDomain domain = AppDomain.CreateDomain ("Test3");
147                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "AThread");
148                 Thread.Sleep (100);
149
150                 AppDomain.Unload (domain);
151
152                 return 0;
153         }
154
155         public static int test_0_unload_with_active_threads_timeout () {
156                 AppDomain domain = AppDomain.CreateDomain ("Test4");
157                 BThread o = (BThread)domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "BThread");
158                 Thread.Sleep (100);
159
160                 try {
161                         AppDomain.Unload (domain);
162                 }
163                 catch (Exception) {
164                         // Try again
165                         o.Stop ();
166                         AppDomain.Unload (domain);
167                         return 0;
168                 }
169
170                 return 1;
171         }
172
173         static void Worker (object x) {
174                 Thread.Sleep (100000);
175         }
176
177         public static void invoke_workers () {
178                 for (int i = 0; i < 1; i ++)
179                         ThreadPool.QueueUserWorkItem (Worker);
180         }
181
182         public static int test_0_unload_with_threadpool () {
183                 AppDomain domain = AppDomain.CreateDomain ("test_0_unload_with_threadpool");
184
185                 domain.DoCallBack (new CrossAppDomainDelegate (invoke_workers));
186                 AppDomain.Unload (domain);
187
188                 return 0;
189         }
190
191         /*
192          * This test is not very deterministic since the thread which enqueues
193          * the work item might or might not be inside the domain when the unload
194          * happens. So disable this for now.
195          */
196         /*
197         public static void DoUnload (object state) {
198                 AppDomain.Unload (AppDomain.CurrentDomain);
199         }
200
201         public static void Callback () {
202                 Console.WriteLine (AppDomain.CurrentDomain);
203                 WaitCallback unloadDomainCallback = new WaitCallback (DoUnload);
204                 ThreadPool.QueueUserWorkItem (unloadDomainCallback);
205         }               
206
207         public static int test_0_unload_inside_appdomain_async () {
208                 AppDomain domain = AppDomain.CreateDomain ("Test3");
209
210                 domain.DoCallBack (new CrossAppDomainDelegate (Callback));
211
212                 return 0;
213         }
214         */
215
216         public static void SyncCallback () {
217                 AppDomain.Unload (AppDomain.CurrentDomain);
218         }               
219
220         public static int test_0_unload_inside_appdomain_sync () {
221                 AppDomain domain = AppDomain.CreateDomain ("Test3");
222
223                 try {
224                         domain.DoCallBack (new CrossAppDomainDelegate (SyncCallback));
225                 }
226                 catch (Exception ex) {
227                         /* Should throw a ThreadAbortException */
228                         Thread.ResetAbort ();
229                 }
230
231                 return 0;
232         }
233
234         // FIXME: This does not work yet, because the thread is finalized too
235         // early
236         /*
237         public static int test_0_unload_during_unload () {
238                 AppDomain domain = AppDomain.CreateDomain ("Test3");
239                 object o = domain.CreateInstanceFromAndUnwrap (typeof (Tests).Assembly.Location, "SlowFinalize");
240
241                 UnloadThread t = new UnloadThread (domain);
242
243                 // Start unloading in a separate thread
244                 new Thread (new ThreadStart (t.Run)).Start ();
245
246                 Thread.Sleep (100);
247
248                 try {
249                         AppDomain.Unload (domain);
250                 }
251                 catch (Exception) {
252                         Console.WriteLine ("OK");
253                 }
254
255                 return 0;
256         }       
257 */
258 }
259