2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / corlib / Test / System.Threading / TimerTest.cs
1 //
2 // TimerTest.cs - NUnit test cases for System.Threading.Timer
3 //
4 // Author:
5 //   Zoltan Varga (vargaz@freemail.hu)
6 //   Rafael Ferreira (raf@ophion.org)
7 //
8 // (C) 2004 Novell, Inc (http://www.novell.com)
9 //
10
11 using NUnit.Framework;
12 using System;
13 using System.Threading;
14 using System.Collections;
15
16 namespace MonoTests.System.Threading {
17         [TestFixture]
18         public class TimerTest {
19                 // this bucket is used to avoid non-theadlocal issues
20                 class Bucket {
21                         public int count;
22                 }
23
24                 [SetUp]
25                 public void Setup ()
26                 {
27                         //creating a timer that will never run just to make sure the
28                         // scheduler is warm for the unit tests
29                         // this makes fair for the "DueTime" test since it 
30                         // doesn't have to wait for the scheduler thread to be 
31                         // created. 
32                         new Timer (new TimerCallback (DoNothing), null, Timeout.Infinite, 0);
33                 }
34
35                 void DoNothing (object foo)
36                 {
37                 }
38
39                 [Test]
40                 public void TestDueTime ()
41                 {
42                         Bucket bucket = new Bucket();
43                         Timer t = new Timer (new TimerCallback (Callback), bucket, 200, Timeout.Infinite);
44                         Thread.Sleep (50);
45                         Assert.AreEqual (0, bucket.count, "#1");
46                         Thread.Sleep (200);
47                         Assert.AreEqual (1, bucket.count, "#2");
48                         Thread.Sleep (500);
49                         Assert.AreEqual (1, bucket.count, "#3");
50                         t.Change (10, 10);
51                         Thread.Sleep (1000);
52                         Assert.IsTrue(bucket.count > 20, "#4");
53                         t.Dispose ();
54                 }
55
56                 [Test]
57                 public void TestChange ()
58                 {
59                         Bucket bucket = new Bucket();
60                         Timer t = new Timer (new TimerCallback (Callback), bucket, 1, 1);
61                         Thread.Sleep (500);
62                         int c = bucket.count;
63                         Assert.IsTrue(c > 20, "#1");
64                         t.Change (100, 100);
65                         Thread.Sleep (500);
66                         Assert.IsTrue(bucket.count <= c + 20, "#2");
67                         t.Dispose ();
68                 }
69
70                 [Test]
71                 public void TestZeroDueTime ()
72                 {
73                         Bucket bucket = new Bucket();
74
75                         Timer t = new Timer (new TimerCallback (Callback), bucket, 0, Timeout.Infinite);
76                         Thread.Sleep (100);
77                         Assert.AreEqual (1, bucket.count, "#1");
78                         t.Change (0, Timeout.Infinite);
79                         Thread.Sleep (100);
80                         Assert.AreEqual (2, bucket.count, "#2");
81                         t.Dispose ();
82                 }
83
84                 [Test]
85                 public void TestDispose ()
86                 {       
87                         Bucket bucket = new Bucket();
88                         Timer t = new Timer (new TimerCallback (Callback), bucket, 10, 10);
89                         Thread.Sleep (200);
90                         t.Dispose ();
91                         Thread.Sleep (20);
92                         int c = bucket.count;
93                         Assert.IsTrue (bucket.count > 5, "#1");
94                         Thread.Sleep (200);
95                         Assert.AreEqual (c, bucket.count, "#2");
96                 }
97
98                 [Test] // bug #320950
99                 public void TestDispose2 ()
100                 {
101                         Timer t = new Timer (new TimerCallback (Callback), null, 10, 10);
102                         t.Dispose ();
103                         t.Dispose ();
104                 }
105                 
106                 [Test]
107                 public void TestHeavyCreationLoad ()
108                 {
109                         Bucket b = new Bucket ();
110                         for (int i = 0; i < 500; ++i)
111                                 new Timer (new TimerCallback (Callback), b, 10,
112                                         Timeout.Infinite);
113                         // 1000 * 10 msec = 10,000 msec or 10 sec - if everything goes well
114                         // we add some slack to cope with timing issues caused by system load etc.
115                         for (int i = 0; i < 20; ++i) {
116                                 if (b.count == 500)
117                                         break;
118                                 Thread.Sleep (1000);
119                         }
120                         Assert.AreEqual (500, b.count);
121                         
122                 }
123
124                 [Test]
125                 public void TestQuickDisposeDeadlockBug ()
126                 {
127                         int i = 0;
128                         Bucket b = new Bucket ();
129                         ArrayList timers = new ArrayList();
130                         while (i < 500) {
131                                 Timer t = new Timer (new TimerCallback (Callback),
132                                         b, 10, Timeout.Infinite);
133                                 timers.Add (t);
134                                 i++;
135                                 t.Dispose ();
136                         }
137                         Thread.Sleep (11 * 500);
138                 }
139
140                 [Test]
141                 public void TestInt32MaxDelay ()
142                 {
143                         Bucket b = new Bucket ();
144                         new Timer (new TimerCallback (Callback), b, Int32.MaxValue,
145                                 Timeout.Infinite);
146                         Thread.Sleep (50);
147                         Assert.AreEqual (0, b.count);
148                 }
149
150                 [Test]
151                 public void TestInt32MaxPeriod ()
152                 {
153                         Bucket b = new Bucket ();
154                         new Timer (new TimerCallback (Callback), b, 0,
155                                 Int32.MaxValue);
156                         Thread.Sleep (50);
157                         Assert.AreEqual (1, b.count);
158                         
159                 }
160
161                 [Test]
162                 public void TestNegativeDelay ()
163                 {
164                         Bucket b = new Bucket ();
165                         try {
166                                 new Timer (new TimerCallback (Callback), b, -10,
167                                         Timeout.Infinite);
168                                 Assert.Fail ();
169                         } catch (ArgumentOutOfRangeException) {
170                                 return;
171                         }
172                 }
173
174                 [Test]
175                 public void TestNegativePeriod ()
176                 {
177                         Bucket b = new Bucket ();
178                         try {
179                                 new Timer (new TimerCallback (Callback), b, 0,
180                                         -10);
181                                 Assert.Fail ();
182                         } catch (ArgumentOutOfRangeException) {
183                                 return;
184                         }
185                 }
186
187                 [Test]
188                 public void TestDelayZeroPeriodZero()
189                 {
190                         Bucket b = new Bucket();
191                         Timer t = new Timer(new TimerCallback(Callback),b,0,0);
192                         Thread.Sleep(100);
193                         t.Change (int.MaxValue, Timeout.Infinite);
194                         // since period is 0 the callback should happen once (bug #340212)
195                         Assert.IsTrue(b.count == 1);
196                         
197                 }
198
199                 [Test]
200                 public void TestDisposeOnCallback ()
201                 {
202                         Timer t1 = null;
203                         t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), t1, 0, 10);
204                         Thread.Sleep (200);
205                         Assert.IsNotNull (t1);
206                         
207                 }
208
209                 private void CallbackTestDisposeOnCallback (object foo)
210                 {
211                         ((Timer) foo).Dispose ();
212                 }
213                 
214                 private void Callback (object foo)
215                 {
216                         Bucket b = foo as Bucket;
217                         Interlocked.Increment (ref b.count);
218                 }
219         }
220 }