Implement MachineKey.Protect and MachineKey.Unprotect
[mono.git] / mcs / class / corlib / Test / System.Threading / ManualResetEventSlimTests.cs
1 // ManualResetEventSlimTests.cs
2 //
3 // Authors:
4 //       Marek Safar (marek.safar@gmail.com)
5 //       Jeremie Laval (jeremie.laval@gmail.com)
6 //
7 // Copyright (c) 2008 Jérémie "Garuma" Laval
8 // Copyright (c) 2012 Xamarin, Inc (http://www.xamarin.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 // THE SOFTWARE.
27 //
28 //
29
30 #if NET_4_0
31
32 using System;
33 using System.Threading;
34
35 using NUnit.Framework;
36
37 using MonoTests.System.Threading.Tasks;
38
39 namespace MonoTests.System.Threading
40 {
41         
42         [TestFixture]
43         public class ManualResetEventSlimTests
44         {
45                 ManualResetEventSlim mre;
46                 
47                 [SetUp]
48                 public void Setup()
49                 {
50                         mre = new ManualResetEventSlim();
51                 }
52
53                 [Test]
54                 public void Constructor_Defaults ()
55                 {
56                         Assert.IsFalse (mre.IsSet, "#1");
57                         Assert.AreEqual (10, mre.SpinCount, "#2");
58                 }
59
60                 [Test]
61                 public void Constructor_Invalid ()
62                 {
63                         try {
64                                 new ManualResetEventSlim (true, -1);
65                                 Assert.Fail ("#1");
66                         } catch (ArgumentException) {
67                         }
68
69                         try {
70                                 new ManualResetEventSlim (true, 2048);
71                                 Assert.Fail ("#2");
72                         } catch (ArgumentException) {
73                         }
74                 }
75                 
76                 [Test]
77                 public void IsSetTestCase()
78                 {
79                         Assert.IsFalse(mre.IsSet, "#1");
80                         mre.Set();
81                         Assert.IsTrue(mre.IsSet, "#2");
82                         mre.Reset();
83                         Assert.IsFalse(mre.IsSet, "#3");
84                 }
85                 
86                 [Test]
87                 public void WaitTest()
88                 {
89                         int count = 0;
90                         bool s = false;
91                         
92                         ParallelTestHelper.ParallelStressTest(mre, delegate (ManualResetEventSlim m) {
93                                 if (Interlocked.Increment(ref count) % 2 == 0) {
94                                         Thread.Sleep(50);
95                                         for (int i = 0; i < 10; i++) {
96                                                 if (i % 2 == 0)
97                                                         m.Reset();
98                                                 else
99                                                         m.Set();
100                                         }
101                                 } else {
102                                         m.Wait();
103                                         s = true;
104                                 }
105                         }, 2);  
106                         
107                         Assert.IsTrue(s, "#1");
108                         Assert.IsTrue(mre.IsSet, "#2");
109                 }
110
111                 [Test]
112                 public void Wait_SetConcurrent ()
113                 {
114                         for (int i = 0; i < 10000; ++i) {
115                                 var mre = new ManualResetEventSlim ();
116                                 bool b = true;
117
118                                 ThreadPool.QueueUserWorkItem (delegate {
119                                         mre.Set ();
120                                 });
121
122                                 ThreadPool.QueueUserWorkItem (delegate {
123                                         b &= mre.Wait (1000);
124                                 });
125
126                                 Assert.IsTrue (mre.Wait (1000), i.ToString ());
127                                 Assert.IsTrue (b, i.ToString ());
128                         }
129                 }
130
131                 [Test]
132                 public void Wait_DisposeWithCancel ()
133                 {
134                         var token = new CancellationTokenSource ();
135                         ThreadPool.QueueUserWorkItem (delegate {
136                                 Thread.Sleep (10);
137                                 mre.Dispose ();
138                                 token.Cancel ();
139                         });
140
141                         try {
142                                 mre.Wait (10000, token.Token);
143                                 Assert.Fail ("#0");
144                         } catch (OperationCanceledException e) {
145                         }
146                 }
147
148                 [Test]
149                 public void Wait_Expired ()
150                 {
151                         Assert.IsFalse (mre.Wait (10));
152                 }
153
154                 [Test, ExpectedException (typeof (ObjectDisposedException))]
155                 public void WaitAfterDisposeTest ()
156                 {
157                         mre.Dispose ();
158                         mre.Wait ();
159                 }
160
161                 [Test]
162                 public void SetAfterDisposeTest ()
163                 {
164                         ParallelTestHelper.Repeat (delegate {
165                                 Exception disp = null, setting = null;
166
167                                 CountdownEvent evt = new CountdownEvent (2);
168                                 CountdownEvent evtFinish = new CountdownEvent (2);
169
170                                 ThreadPool.QueueUserWorkItem (delegate {
171                                         try {
172                                                 evt.Signal ();
173                                                 evt.Wait (1000);
174                                                 mre.Dispose ();
175                                         } catch (Exception e) {
176                                                 disp = e;
177                                         }
178                                         evtFinish.Signal ();
179                                 });
180                                 ThreadPool.QueueUserWorkItem (delegate {
181                                         try {
182                                                 evt.Signal ();
183                                                 evt.Wait (1000);
184                                                 mre.Set ();
185                                         } catch (Exception e) {
186                                                 setting = e;
187                                         }
188                                         evtFinish.Signal ();
189                                 });
190
191                                 bool bb = evtFinish.Wait (1000);
192                                 if (!bb)
193                                         Assert.AreEqual (true, evtFinish.IsSet);
194
195                                 Assert.IsTrue (bb, "#0");
196                                 Assert.IsNull (disp, "#1");
197                                 Assert.IsNull (setting, "#2");
198
199                                 evt.Dispose ();
200                                 evtFinish.Dispose ();
201                         });
202                 }
203
204                 [Test]
205                 public void WaitHandle_Initialized ()
206                 {
207                         var mre = new ManualResetEventSlim (true);
208                         Assert.IsTrue (mre.WaitHandle.WaitOne (0), "#1");
209                         mre.Reset ();
210                         Assert.IsFalse (mre.WaitHandle.WaitOne (0), "#2");
211                         Assert.AreEqual (mre.WaitHandle, mre.WaitHandle, "#3");
212                 }
213
214                 [Test]
215                 public void WaitHandle_NotInitialized ()
216                 {
217                         var mre = new ManualResetEventSlim (false);
218                         Assert.IsFalse (mre.WaitHandle.WaitOne (0), "#1");
219                         mre.Set ();
220                         Assert.IsTrue (mre.WaitHandle.WaitOne (0), "#2");
221                 }
222
223                 [Test]
224                 public void WaitHandleConsistencyTest ()
225                 {
226                         var mre = new ManualResetEventSlim ();
227                         mre.WaitHandle.WaitOne (0);
228
229                         for (int i = 0; i < 10000; i++) {
230                                 int count = 2;
231                                 SpinWait wait = new SpinWait ();
232
233                                 ThreadPool.QueueUserWorkItem (_ => { mre.Set (); Interlocked.Decrement (ref count); });
234                                 ThreadPool.QueueUserWorkItem (_ => { mre.Reset (); Interlocked.Decrement (ref count); });
235
236                                 while (count > 0)
237                                         wait.SpinOnce ();
238                                 Assert.AreEqual (mre.IsSet, mre.WaitHandle.WaitOne (0));
239                         }
240                 }
241
242                 [Test]
243                 public void WaitWithCancellationTokenAndNotImmediateSetTest ()
244                 {
245                         var mres = new ManualResetEventSlim ();
246                         var cts = new CancellationTokenSource ();
247                         ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); mres.Set (); });
248                         Assert.IsTrue (mres.Wait (TimeSpan.FromSeconds (10), cts.Token), "Wait returned false despite event was set.");
249                 }
250
251                 [Test]
252                 public void WaitWithCancellationTokenAndCancel ()
253                 {
254                         var mres = new ManualResetEventSlim ();
255                         var cts = new CancellationTokenSource ();
256                         ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); cts.Cancel (); });
257                         try {
258                                 mres.Wait (TimeSpan.FromSeconds (10), cts.Token);
259                                 Assert.Fail ("Wait did not throw an exception despite cancellation token was cancelled.");
260                         } catch (OperationCanceledException) {
261                         }
262                 }
263
264                 [Test]
265                 public void WaitWithCancellationTokenAndTimeout ()
266                 {
267                         var mres = new ManualResetEventSlim ();
268                         var cts = new CancellationTokenSource ();
269                         Assert.IsFalse (mres.Wait (TimeSpan.FromSeconds (1), cts.Token), "Wait returned true despite timeout.");
270                 }
271
272                 [Test]
273                 public void Dispose ()
274                 {
275                         var mre = new ManualResetEventSlim (false);
276                         mre.Dispose ();
277                         Assert.IsFalse (mre.IsSet, "#0a");
278
279                         try {
280                             mre.Reset ();
281                             Assert.Fail ("#1");
282                         } catch (ObjectDisposedException) {
283                         }
284
285                         mre.Set ();
286
287                         try {
288                                 mre.Wait (0);
289                                 Assert.Fail ("#3");
290                         } catch (ObjectDisposedException) {
291                         }
292
293                         try {
294                                 var v = mre.WaitHandle;
295                                 Assert.Fail ("#4");
296                         } catch (ObjectDisposedException) {
297                         }
298                 }
299
300                 [Test]
301                 public void Dispose_Double ()
302                 {
303                         var mre = new ManualResetEventSlim ();
304                         mre.Dispose ();
305                         mre.Dispose ();
306                 }
307         }
308 }
309 #endif