[corlib] Use ManualResetEvent.WaitOne instead of Thread.Sleep to test Thread.Interrupt
[mono.git] / mcs / class / corlib / Test / System.Threading / CountdownEventTests.cs
1 // CountdownEventTests.cs
2 //
3 // Authors:
4 //    Marek Safar  <marek.safar@gmail.com>
5 //
6 // Copyright (c) 2008 Jérémie "Garuma" Laval
7 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26 //
27 //
28
29 #if NET_4_0
30
31 using System;
32 using System.Threading;
33
34 using NUnit.Framework;
35
36 using MonoTests.System.Threading.Tasks;
37
38 namespace MonoTests.System.Threading
39 {
40         [TestFixtureAttribute]
41         public class CountdownEventTests
42         {
43                 [Test]
44                 public void Constructor_Invalid ()
45                 {
46                         try {
47                                 new CountdownEvent (-2);
48                                 Assert.Fail ("#1");
49                         } catch (ArgumentOutOfRangeException) {
50                         }
51                 }
52
53                 [Test]
54                 public void Constructor_Zero ()
55                 {
56                         var ce = new CountdownEvent (0);
57                         Assert.IsTrue (ce.IsSet, "#1");
58                         Assert.AreEqual (0, ce.InitialCount, "#2");
59                         Assert.IsTrue (ce.Wait (0), "#3");
60                 }
61
62                 [Test]
63                 public void Constructor_Max ()
64                 {
65                         new CountdownEvent (int.MaxValue);
66                 }
67
68                 [Test]
69                 public void AddCount_Invalid ()
70                 {
71                         var ev = new CountdownEvent (1);
72                         try {
73                                 ev.AddCount (0);
74                                 Assert.Fail ("#1");
75                         } catch (ArgumentOutOfRangeException) {
76                         }
77
78                         try {
79                                 ev.AddCount (-1);
80                                 Assert.Fail ("#2");
81                         } catch (ArgumentOutOfRangeException) {
82                         }
83                 }
84
85                 [Test]
86                 public void AddCount_HasBeenSet ()
87                 {
88                         var ev = new CountdownEvent (0);
89                         try {
90                                 ev.AddCount (1);
91                                 Assert.Fail ("#1");
92                         } catch (InvalidOperationException) {
93                         }
94
95                         ev = new CountdownEvent (1);
96                         Assert.IsTrue (ev.Signal (), "#2");
97                         try {
98                                 ev.AddCount (1);
99                                 Assert.Fail ("#3");
100                         } catch (InvalidOperationException) {
101                         }
102                 }
103
104                 [Test]
105                 public void AddCountSignalStressTestCase ()
106                 {
107                         var evt = new CountdownEvent (5);
108
109                         int count = 0;
110                         ParallelTestHelper.ParallelStressTest (evt, delegate (CountdownEvent e) {
111                                 int num = Interlocked.Increment (ref count);
112                                 if (num % 2 == 0)
113                                         e.AddCount ();
114                                 else
115                                         e.Signal ();
116                         }, 7);
117
118                         Assert.AreEqual (4, evt.CurrentCount, "#1");
119                         Assert.IsFalse (evt.IsSet, "#2");
120                 }
121                 
122                 [Test]
123                 public void InitialTestCase()
124                 {
125                         var evt = new CountdownEvent (5);
126
127                         Assert.AreEqual(5, evt.InitialCount, "#1");
128                         evt.AddCount();
129                         evt.Signal(3);
130                         Assert.AreEqual(5, evt.InitialCount, "#2");
131                 }
132                 
133                 [Test]
134                 public void CurrentCountTestCase()
135                 {
136                         var evt = new CountdownEvent (5);
137
138                         Assert.AreEqual(5, evt.CurrentCount, "#1");
139                         
140                         evt.AddCount();
141                         Assert.AreEqual(6, evt.CurrentCount, "#2");
142                         
143                         evt.TryAddCount(2);
144                         Assert.AreEqual(8, evt.CurrentCount, "#3");
145                         
146                         evt.Signal(4);
147                         Assert.AreEqual(4, evt.CurrentCount, "#4");
148                         
149                         evt.Reset();
150                         Assert.AreEqual(5, evt.CurrentCount, "#5");
151                 }
152
153                 [Test]
154                 public void Dispose ()
155                 {
156                         var ce = new CountdownEvent (1);
157                         ce.Dispose ();
158                         Assert.AreEqual (1, ce.CurrentCount, "#0a");
159                         Assert.AreEqual (1, ce.InitialCount, "#0b");
160                         Assert.IsFalse (ce.IsSet, "#0c");
161
162                         try {
163                                 ce.AddCount ();
164                                 Assert.Fail ("#1");
165                         } catch (ObjectDisposedException) {
166                         }
167
168                         try {
169                                 ce.Reset ();
170                                 Assert.Fail ("#2");
171                         } catch (ObjectDisposedException) {
172                         }
173
174                         try {
175                                 ce.Signal ();
176                                 Assert.Fail ("#3");
177                         } catch (ObjectDisposedException) {
178                         }
179
180                         try {
181                                 ce.TryAddCount ();
182                                 Assert.Fail ("#4");
183                         } catch (ObjectDisposedException) {
184                         }
185
186                         try {
187                                 ce.Wait (5);
188                                 Assert.Fail ("#4");
189                         } catch (ObjectDisposedException) {
190                         }
191
192                         try {
193                                 var v = ce.WaitHandle;
194                                 Assert.Fail ("#5");
195                         } catch (ObjectDisposedException) {
196                         }
197                 }
198
199                 [Test]
200                 public void Dispose_Double ()
201                 {
202                         var ce = new CountdownEvent (1);
203                         ce.Dispose ();
204                         ce.Dispose ();
205                 }
206                 
207                 [Test]
208                 public void IsSetTestCase()
209                 {
210                         var evt = new CountdownEvent (5);
211
212                         Assert.IsFalse(evt.IsSet, "#1");
213                         
214                         evt.Signal(5);
215                         Assert.IsTrue(evt.IsSet, "#2");
216                         
217                         evt.Reset();
218                         Assert.IsFalse(evt.IsSet, "#3");
219                 }
220
221                 [Test]
222                 public void Reset_Invalid ()
223                 {
224                         var ev = new CountdownEvent (1);
225                         try {
226                                 ev.Reset (-1);
227                                 Assert.Fail ("#1");
228                         } catch (ArgumentOutOfRangeException) {
229                                 Assert.AreEqual (1, ev.CurrentCount, "#1a");
230                         }
231                 }
232
233                 [Test]
234                 public void Reset_FullInitialized ()
235                 {
236                         var ev = new CountdownEvent (0);
237                         Assert.IsTrue (ev.IsSet, "#1");
238                         Assert.AreEqual (0, ev.CurrentCount, "#2");
239
240                         ev.Reset (4);
241                         Assert.IsFalse (ev.IsSet, "#3");
242                         Assert.AreEqual (4, ev.CurrentCount, "#4");
243                         Assert.IsFalse (ev.Wait (0), "#5");
244                 }
245
246                 [Test]
247                 public void Reset_Zero ()
248                 {
249                         var ev = new CountdownEvent (1);
250                         Assert.IsFalse (ev.IsSet, "#1");
251
252                         ev.Reset (0);
253                         Assert.IsTrue (ev.IsSet, "#2");
254                         Assert.IsTrue (ev.Wait (0), "#3");
255                         Assert.AreEqual (0, ev.CurrentCount, "#4");
256                 }
257
258                 [Test]
259                 public void Signal_Invalid ()
260                 {
261                         var ev = new CountdownEvent (1);
262                         try {
263                                 ev.Signal (0);
264                                 Assert.Fail ("#1");
265                         } catch (ArgumentOutOfRangeException) {
266                                 Assert.AreEqual (1, ev.CurrentCount, "#1a");
267                         }
268
269                         try {
270                                 ev.Signal (-1);
271                                 Assert.Fail ("#2");
272                         } catch (ArgumentOutOfRangeException) {
273                                 Assert.AreEqual (1, ev.CurrentCount, "#2a");
274                         }
275                 }
276
277                 [Test]
278                 public void Signal_Negative ()
279                 {
280                         var ev = new CountdownEvent (1);
281                         try {
282                                 ev.Signal (2);
283                                 Assert.Fail ("#1");
284                         } catch (InvalidOperationException) {
285                                 Assert.AreEqual (1, ev.CurrentCount, "#1a");
286                         }
287
288                         ev.Signal ();
289                         try {
290                                 ev.Signal ();
291                                 Assert.Fail ("#2");
292                         } catch (InvalidOperationException) {
293                                 Assert.AreEqual (0, ev.CurrentCount, "#2a");
294                         }
295                 }
296
297                 [Test]
298                 public void Signal_Concurrent ()
299                 {
300                         for (int r = 0; r < 100; ++r) {
301                                 using (var ce = new CountdownEvent (500)) {
302                                         for (int i = 0; i < ce.InitialCount; ++i) {
303                                                 ThreadPool.QueueUserWorkItem (delegate {
304                                                         ce.Signal ();
305                                                 });
306                                         }
307
308                                         Assert.IsTrue (ce.Wait (1000), "#1");
309                                 }
310                         }
311                 }
312                 
313                 [Test]
314                 public void TryAddCountTestCase()
315                 {
316                         var evt = new CountdownEvent (5);
317
318                         Assert.IsTrue(evt.TryAddCount(2), "#1");
319                         evt.Signal(7);
320                         Assert.IsFalse(evt.TryAddCount(), "#2");
321                 }
322
323                 [Test]
324                 public void TryAddCount_Invalid ()
325                 {
326                         var ev = new CountdownEvent (1);
327                         try {
328                                 ev.TryAddCount (0);
329                                 Assert.Fail ("#1");
330                         } catch (ArgumentOutOfRangeException) {
331                         }
332
333                         try {
334                                 ev.TryAddCount (-1);
335                                 Assert.Fail ("#2");
336                         } catch (ArgumentOutOfRangeException) {
337                         }
338                 }
339
340                 [Test]
341                 public void TryAddCount_HasBeenSet ()
342                 {
343                         var ev = new CountdownEvent (0);
344                         Assert.IsFalse (ev.TryAddCount (1), "#1");
345
346                         ev = new CountdownEvent (1);
347                         ev.Signal ();
348                         Assert.IsFalse (ev.TryAddCount (1), "#2");
349
350                         ev = new CountdownEvent (2);
351                         ev.Signal (2);
352                         Assert.IsFalse (ev.TryAddCount (66), "#3");
353                 }
354                 
355                 [Test]
356                 public void WaitTestCase()
357                 {
358                         var evt = new CountdownEvent (5);
359
360                         int count = 0;
361                         bool s = false;
362                         
363                         ParallelTestHelper.ParallelStressTest(evt, delegate (CountdownEvent e) {
364                                 if (Interlocked.Increment(ref count) % 2 == 0) {
365                                         Thread.Sleep(100);
366                                         while(!e.IsSet)
367                                                 e.Signal();
368                                 } else {
369                                         e.Wait();
370                                         s = true;
371                                 }
372                         }, 3);
373                         
374                         Assert.IsTrue(s, "#1");
375                         Assert.IsTrue(evt.IsSet, "#2");
376                 }
377
378                 [Test]
379                 public void ResetTest ()
380                 {
381                         var evt = new CountdownEvent (5);
382
383                         Assert.AreEqual (5, evt.CurrentCount);
384                         evt.Signal ();
385                         Assert.AreEqual (4, evt.CurrentCount);
386                         evt.Reset ();
387                         Assert.AreEqual (5, evt.CurrentCount);
388                         Assert.AreEqual (5, evt.InitialCount);
389                         evt.Signal ();
390                         evt.Signal ();
391                         Assert.AreEqual (3, evt.CurrentCount);
392                         Assert.AreEqual (5, evt.InitialCount);
393                         evt.Reset (10);
394                         Assert.AreEqual (10, evt.CurrentCount);
395                         Assert.AreEqual (10, evt.InitialCount);
396                 }
397         }
398 }
399 #endif