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