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