2008-10-11 Zoltan Varga <vargaz@gmail.com>
[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 (null, null, Timeout.Infinite, 0);
33                 }
34                 
35                 [Test]
36                 public void TestDueTime ()
37                 {
38                         Bucket bucket = new Bucket();
39                         Timer t = new Timer (new TimerCallback (Callback), bucket, 200, Timeout.Infinite);
40                         Thread.Sleep (50);
41                         Assert.AreEqual (0, bucket.count, "#1");
42                         Thread.Sleep (200);
43                         Assert.AreEqual (1, bucket.count, "#2");
44                         Thread.Sleep (500);
45                         Assert.AreEqual (1, bucket.count, "#3");
46                         t.Change (10, 10);
47                         Thread.Sleep (1000);
48                         Assert.IsTrue(bucket.count > 20, "#4");
49                         t.Dispose ();
50                 }
51
52                 [Test]
53                 public void TestChange ()
54                 {
55                         Bucket bucket = new Bucket();
56                         Timer t = new Timer (new TimerCallback (Callback), bucket, 1, 1);
57                         Thread.Sleep (500);
58                         int c = bucket.count;
59                         Assert.IsTrue(c > 20, "#1");
60                         t.Change (100, 100);
61                         Thread.Sleep (500);
62                         Assert.IsTrue(bucket.count <= c + 20, "#2");
63                         t.Dispose ();
64                 }
65
66                 [Test]
67                 public void TestZeroDueTime ()
68                 {
69                         Bucket bucket = new Bucket();
70
71                         Timer t = new Timer (new TimerCallback (Callback), bucket, 0, Timeout.Infinite);
72                         Thread.Sleep (100);
73                         Assert.AreEqual (1, bucket.count, "#1");
74                         t.Change (0, Timeout.Infinite);
75                         Thread.Sleep (100);
76                         Assert.AreEqual (2, bucket.count, "#2");
77                         t.Dispose ();
78                 }
79
80                 [Test]
81                 public void TestDispose ()
82                 {       
83                         Bucket bucket = new Bucket();
84                         Timer t = new Timer (new TimerCallback (Callback), bucket, 10, 10);
85                         Thread.Sleep (200);
86                         t.Dispose ();
87                         Thread.Sleep (20);
88                         int c = bucket.count;
89                         Assert.IsTrue (bucket.count > 5, "#1");
90                         Thread.Sleep (200);
91                         Assert.AreEqual (c, bucket.count, "#2");
92                 }
93
94                 [Test] // bug #320950
95                 public void TestDispose2 ()
96                 {
97                         Timer t = new Timer (new TimerCallback (Callback), null, 10, 10);
98                         t.Dispose ();
99                         t.Dispose ();
100                 }
101                 
102                 [Test]
103                 public void TestHeavyCreationLoad ()
104                 {
105                         Bucket b = new Bucket ();
106                         for (int i = 0; i < 500; ++i)
107                                 new Timer (new TimerCallback (Callback), b, 10,
108                                         Timeout.Infinite);
109                         // 1000 * 10 msec = 10,000 msec or 10 sec - if everything goes well
110                         // we add some slack to cope with timing issues caused by system load etc.
111                         for (int i = 0; i < 20; ++i) {
112                                 if (b.count == 500)
113                                         break;
114                                 Thread.Sleep (1000);
115                         }
116                         Assert.AreEqual (500, b.count);
117                         
118                 }
119
120                 [Test]
121                 public void TestQuickDisposeDeadlockBug ()
122                 {
123                         int i = 0;
124                         Bucket b = new Bucket ();
125                         ArrayList timers = new ArrayList();
126                         while (i < 500) {
127                                 Timer t = new Timer (new TimerCallback (Callback),
128                                         b, 10, Timeout.Infinite);
129                                 timers.Add (t);
130                                 i++;
131                                 t.Dispose ();
132                         }
133                         Thread.Sleep (11 * 500);
134                 }
135
136                 [Test]
137                 public void TestInt32MaxDelay ()
138                 {
139                         Bucket b = new Bucket ();
140                         new Timer (new TimerCallback (Callback), b, Int32.MaxValue,
141                                 Timeout.Infinite);
142                         Thread.Sleep (50);
143                         Assert.AreEqual (0, b.count);
144                 }
145
146                 [Test]
147                 public void TestInt32MaxPeriod ()
148                 {
149                         Bucket b = new Bucket ();
150                         new Timer (new TimerCallback (Callback), b, 0,
151                                 Int32.MaxValue);
152                         Thread.Sleep (50);
153                         Assert.AreEqual (1, b.count);
154                         
155                 }
156
157                 [Test]
158                 public void TestNegativeDelay ()
159                 {
160                         Bucket b = new Bucket ();
161                         try {
162                                 new Timer (new TimerCallback (Callback), b, -10,
163                                         Timeout.Infinite);
164                                 Assert.Fail ();
165                         } catch (ArgumentOutOfRangeException) {
166                                 return;
167                         }
168                 }
169
170                 [Test]
171                 public void TestNegativePeriod ()
172                 {
173                         Bucket b = new Bucket ();
174                         try {
175                                 new Timer (new TimerCallback (Callback), b, 0,
176                                         -10);
177                                 Assert.Fail ();
178                         } catch (ArgumentOutOfRangeException) {
179                                 return;
180                         }
181                 }
182
183                 [Test]
184                 public void TestDelayZeroPeriodZero()
185                 {
186                         Bucket b = new Bucket();
187                         Timer t = new Timer(new TimerCallback(Callback),b,0,0);
188                         Thread.Sleep(100);
189                         t.Change (int.MaxValue, Timeout.Infinite);
190                         // since period is 0 the callback should happen once (bug #340212)
191                         Assert.IsTrue(b.count == 1);
192                         
193                 }
194
195                 [Test]
196                 public void TestDisposeOnCallback ()
197                 {
198                         Timer t1 = null;
199                         t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), t1, 0, 10);
200                         Thread.Sleep (200);
201                         Assert.IsNotNull (t1);
202                         
203                 }
204
205                 private void CallbackTestDisposeOnCallback (object foo)
206                 {
207                         ((Timer) foo).Dispose ();
208                 }
209                 
210                 private void Callback (object foo)
211                 {
212                         Bucket b = foo as Bucket;
213                         Interlocked.Increment (ref b.count);
214                 }
215         }
216 }