Merge pull request #475 from pruiz/xamarin-bug-7408
[mono.git] / mcs / class / corlib / Test / System.Runtime.Remoting / SynchronizationAttributeTest.cs
1 //
2 // MonoTests.System.Runtime.Remoting.SynchronizationAttributeTest.cs
3 //
4 // Author: Lluis Sanchez Gual (lluis@ximian.com)
5 //
6 // 2003 (C) Copyright, Novell, Inc.
7 //
8
9 using System;
10 using System.Threading;
11 using System.Runtime.Remoting.Contexts;
12 using NUnit.Framework;
13
14 namespace MonoTests.System.Runtime.Remoting
15 {
16         enum SynchRes { SameSync, NewSync, NoSync }
17
18         class SincroBase: ContextBoundObject
19         {
20                 public int idx = 0;
21
22                 public bool CheckConcurrency ()
23                 {
24                         int t = idx;
25                         for (int n=0; n<40; n++)
26                         {
27                                 idx++;
28                                 Thread.Sleep (25);
29                         }
30                         return (t+40 != idx);
31                 }
32                 
33                 public bool CheckUnlockedConcurrency ()
34                 {
35                         Lock (false);
36                         return CheckConcurrency ();
37                 }
38                 
39                 public SynchRes CheckContext (Context ctx)
40                 {
41                         object otherp = ctx.GetProperty ("Synchronization");
42                         object thisp = Thread.CurrentContext.GetProperty ("Synchronization");
43
44                         if (thisp == null) return SynchRes.NoSync;
45                         if (thisp == otherp) return SynchRes.SameSync;
46                         return SynchRes.NewSync;
47                 }
48
49                 public SynchRes CheckContextTransition (Type type)
50                 {
51                         SincroBase bob = (SincroBase)Activator.CreateInstance (type);
52                         return bob.CheckContext (Thread.CurrentContext);
53                 }
54
55                 public bool CheckCalloutConcurrency (SincroBase bob)
56                 {
57                         bool res = bob.CheckConcurrency ();
58                         return res;
59                 }
60
61                 public void CheckLock1 ()
62                 {
63                         Thread.Sleep (2000);
64                         Lock (false);
65                         Thread.Sleep (6000);
66                 }
67
68                 public void CheckLock2 ()
69                 {
70                         Thread.Sleep (1000);
71                         Lock (true);
72                         Thread.Sleep (2000);
73                 }
74
75                 public void Lock (bool b)
76                 {
77                         SynchronizationAttribute thisp = (SynchronizationAttribute) Thread.CurrentContext.GetProperty ("Synchronization");
78                         thisp.Locked = b;
79                 }
80
81                 public bool GetLocked ()
82                 {
83                         SynchronizationAttribute thisp = (SynchronizationAttribute) Thread.CurrentContext.GetProperty ("Synchronization");
84                         return thisp.Locked;
85                 }
86                 
87                 public bool CheckMonitorWait (bool exitContext)
88                 {
89                         lock (this)
90                         {
91                                 return Monitor.Wait (this, 1000, exitContext);
92                         }
93                 }
94                 
95                 public void CheckMonitorPulse ()
96                 {
97                         lock (this)
98                         {
99                                 Monitor.Pulse (this);
100                         }
101                 }
102         }
103
104         [Synchronization (SynchronizationAttribute.SUPPORTED)]
105         class SincroSupported: SincroBase
106         {
107         }
108
109         [Synchronization (SynchronizationAttribute.REQUIRED)]
110         class SincroRequired: SincroBase
111         {
112         }
113
114         [Synchronization (SynchronizationAttribute.REQUIRES_NEW)]
115         class SincroRequiresNew: SincroBase
116         {
117                 public bool TestCallback ()
118                 {
119                         SincroNotSupported bob = new SincroNotSupported ();
120                         return bob.CallBack (this);
121                 }
122         }
123
124         [Synchronization (SynchronizationAttribute.NOT_SUPPORTED)]
125         class SincroNotSupported: SincroBase
126         {
127                 public bool CallBack (SincroRequiresNew bob)
128                 {
129                         return bob.CheckConcurrency ();
130                 }
131         }
132
133         [Synchronization (SynchronizationAttribute.REQUIRES_NEW, true)]
134         class SincroRequiresNewReentrant: SincroBase
135         {
136         }
137
138         [TestFixture]
139         public class SynchronizationAttributeTest
140         {
141                 SincroRequiresNew sincob = new SincroRequiresNew ();
142                 SincroNotSupported notsup = new SincroNotSupported ();
143                 SincroRequiresNewReentrant reentrant = new SincroRequiresNewReentrant ();
144                 SincroRequiresNew notreentrant = new SincroRequiresNew ();
145                 bool otResult;
146
147                 [Test]
148                 public void TestSynchronization ()
149                 {
150                         Thread tr = new Thread (new ThreadStart (FirstSyncThread));
151                         tr.Start ();
152                         Thread.Sleep (200);
153                         SecondSyncThread ();
154                         
155                         tr.Join ();
156                         Assert.IsTrue (!otResult, "Concurrency detected in FirstSyncThread");
157                 }
158
159                 void FirstSyncThread ()
160                 {
161                         otResult = sincob.CheckConcurrency ();
162                 }
163
164                 void SecondSyncThread ()
165                 {
166                         bool concurrent = sincob.CheckConcurrency ();
167                         Assert.IsTrue (!concurrent, "Concurrency detected");
168                 }
169
170                 [Test]
171                 public void TestSupported ()
172                 {
173                         SincroRequiresNew ob = new SincroRequiresNew ();
174                         SynchRes res = ob.CheckContextTransition (typeof(SincroSupported));
175                         Assert.IsTrue (res == SynchRes.SameSync, "Synchronizaton context expected");
176
177                         SincroSupported ob2 = new SincroSupported ();
178                         res = ob2.CheckContext (Thread.CurrentContext);
179                         Assert.IsTrue (res == SynchRes.NoSync, "Synchronizaton context not expected");
180                 }
181
182                 [Test]
183                 public void TestRequired ()
184                 {
185                         SincroRequiresNew ob = new SincroRequiresNew ();
186                         SynchRes res = ob.CheckContextTransition (typeof(SincroRequired));
187                         Assert.IsTrue (res == SynchRes.SameSync, "Synchronizaton context expected 1");
188
189                         SincroRequired ob2 = new SincroRequired ();
190                         res = ob2.CheckContext (Thread.CurrentContext);
191                         Assert.IsTrue (res == SynchRes.NewSync, "Synchronizaton context expected 2");
192                 }
193
194                 [Test]
195                 public void TestRequiresNew ()
196                 {
197                         SincroRequiresNew ob = new SincroRequiresNew ();
198                         SynchRes res = ob.CheckContextTransition (typeof(SincroRequiresNew));
199                         Assert.IsTrue (res == SynchRes.NewSync, "New synchronizaton context expected");
200
201                         SincroRequiresNew ob2 = new SincroRequiresNew ();
202                         res = ob2.CheckContext (Thread.CurrentContext);
203                         Assert.IsTrue (res == SynchRes.NewSync, "Synchronizaton context not expected");
204                 }
205
206                 [Test]
207                 public void TestNotSupported ()
208                 {
209                         SincroRequiresNew ob = new SincroRequiresNew ();
210                         SynchRes res = ob.CheckContextTransition (typeof(SincroNotSupported));
211                         Assert.IsTrue (res == SynchRes.NoSync, "Synchronizaton context not expected 1");
212
213                         SincroNotSupported ob2 = new SincroNotSupported ();
214                         res = ob2.CheckContext (Thread.CurrentContext);
215                         Assert.IsTrue (res == SynchRes.NoSync, "Synchronizaton context not expected 2");
216                 }
217
218                 [Test]
219                 public void TestLocked1 ()
220                 {
221                         sincob.Lock (false);
222                         Thread tr = new Thread (new ThreadStart (FirstSyncThread));
223                         tr.Start ();
224                         Thread.Sleep (200);
225                         SecondSyncThread ();
226                         
227                         tr.Join ();
228                         Assert.IsTrue (!otResult, "Concurrency detected in FirstSyncThread");
229                 }
230
231                 [Test]
232                 public void TestLocked2 ()
233                 {
234                         Thread tr = new Thread (new ThreadStart (FirstNotSyncThread));
235                         tr.Start ();
236                         Thread.Sleep (200);
237                         SecondNotSyncThread ();
238                         
239                         tr.Join ();
240                         Assert.IsTrue (otResult, "Concurrency not detected in FirstReentryThread");
241                 }
242
243                 void FirstNotSyncThread ()
244                 {
245                         otResult = sincob.CheckUnlockedConcurrency ();
246                 }
247
248                 void SecondNotSyncThread ()
249                 {
250                         bool concurrent = sincob.CheckConcurrency ();
251                         Assert.IsTrue (concurrent, "Concurrency not detected");
252                 }
253
254                 [Test]
255                 public void TestLocked3 ()
256                 {
257                         Thread tr = new Thread (new ThreadStart (Lock1Thread));
258                         tr.Start ();
259                         Thread.Sleep (200);
260                         Lock2Thread ();
261                 }
262
263                 void Lock1Thread ()
264                 {
265                         sincob.CheckLock1 ();
266                 }
267
268                 void Lock2Thread ()
269                 {
270                         sincob.CheckLock2 ();
271                 }
272
273                 [Test]
274                 public void TestReentry ()
275                 {
276                         Thread tr = new Thread (new ThreadStart (FirstReentryThread));
277                         tr.Start ();
278                         Thread.Sleep (200);
279                         SecondReentryThread ();
280                         
281                         tr.Join ();
282                         Assert.IsTrue (otResult, "Concurrency not detected in FirstReentryThread");
283                 }
284
285                 void FirstReentryThread ()
286                 {
287                         otResult = reentrant.CheckCalloutConcurrency (notsup);
288                 }
289
290                 void SecondReentryThread ()
291                 {
292                         bool concurrent = reentrant.CheckCalloutConcurrency (notsup);
293                         Assert.IsTrue (concurrent, "Concurrency not detected");
294                 }
295
296                 [Test]
297                 public void TestNoReentry ()
298                 {
299                         Thread tr = new Thread (new ThreadStart (FirstNoReentryThread));
300                         tr.Start ();
301                         Thread.Sleep (200);
302                         SecondNoReentryThread ();
303                         
304                         tr.Join ();
305                         Assert.IsTrue (!otResult, "Concurrency detected in FirstNoReentryThread");
306                 }
307
308                 void FirstNoReentryThread ()
309                 {
310                         otResult = notreentrant.CheckCalloutConcurrency (notsup);
311                 }
312
313                 void SecondNoReentryThread ()
314                 {
315                         bool concurrent = notreentrant.CheckCalloutConcurrency (notsup);
316                         Assert.IsTrue (!concurrent, "Concurrency detected");
317                 }
318
319                 [Test]
320                 public void TestCallback ()
321                 {
322                         Thread tr = new Thread (new ThreadStart (CallbackThread));
323                         tr.Start ();
324                         Thread.Sleep (200);
325                         bool concurrent = notreentrant.CheckConcurrency ();
326                         Assert.IsTrue (!concurrent, "Concurrency detected");
327                         notreentrant.CheckContext (Thread.CurrentContext);
328                         
329                         tr.Join ();
330                         Assert.IsTrue (!otResult, "Concurrency detected in CallbackThread");
331                 }
332
333                 void CallbackThread ()
334                 {
335                         otResult = notreentrant.TestCallback ();
336                 }
337                 
338                 [Test]
339                 [Category("NotDotNet")]
340                 [Category ("MobileNotWorking")]
341                 public void TestMonitorWait ()
342                 {
343                         Thread tr = new Thread (new ThreadStart (DoMonitorPulse));
344                         tr.Start ();
345                         
346                         bool r = sincob.CheckMonitorWait (true);
347                         Assert.IsTrue (r, "Wait timeout");
348                         
349                         r = tr.Join (1000);
350                         Assert.IsTrue (r, "Join timeout");
351                         
352                         tr = new Thread (new ThreadStart (DoMonitorPulse));
353                         tr.Start ();
354                         
355                         r = sincob.CheckMonitorWait (false);
356                         Assert.IsTrue (!r, "Expected wait timeout");
357                         
358                         r = tr.Join (1000);
359                         Assert.IsTrue (r, "Join timeout 2");
360                 }
361
362                 void DoMonitorPulse ()
363                 {
364                         Thread.Sleep (100);
365                         sincob.CheckMonitorPulse ();
366                 }
367         }
368 }