2007-09-14 Jb Evain <jbevain@novell.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
18         //
19         // This whole test seems to fail randomly. Either
20         // - It is relying on a race it might not win (that the timer code runs)
21         // - We have a very obscure bug with appdomains.
22         //
23         // Am going with door #1, but it would be nice to investigate this.
24         // -- Ben
25         //
26         [TestFixture]
27         public class TimerTest {
28                 // this bucket is used to avoid non-theadlocal issues
29                 class Bucket {
30                         public int count;
31                 }
32                 [SetUp]
33                 public void setup() {
34                         //creating a timer that will never run just to make sure the
35                         // scheduler is warm for the unit tests
36                         // this makes fair for the "DueTime" test since it 
37                         // doesn't have to wait for the scheduler thread to be 
38                         // created. 
39                         new Timer(null,null,Timeout.Infinite,0);
40                 }
41                 
42                 [Test]
43                 public void TestDueTime ()
44                 {
45                         Bucket bucket = new Bucket();
46                         Timer t = new Timer (new TimerCallback (Callback), bucket, 200, Timeout.Infinite);
47                         Thread.Sleep (50);
48                         Assert.AreEqual (0, bucket.count);
49                         Thread.Sleep (200);
50                         Assert.AreEqual (1, bucket.count);
51                         Thread.Sleep (500);
52                         Assert.AreEqual (1, bucket.count);
53                         t.Change (10, 10);
54                         Thread.Sleep (1000);
55                         Assert.IsTrue(bucket.count > 20);
56                         t.Dispose ();
57                 }
58
59                 [Test]
60                 public void TestChange ()
61                 {
62                         Bucket bucket = new Bucket();
63                         Timer t = new Timer (new TimerCallback (Callback), bucket, 1, 1);
64                         Thread.Sleep (500);
65                         int c = bucket.count;
66                         Assert.IsTrue(c > 20);
67                         t.Change (100, 100);
68                         Thread.Sleep (500);
69                         Assert.IsTrue(bucket.count <= c + 6);
70                         t.Dispose ();
71                 }
72
73                 [Test]
74                 public void TestZeroDueTime () {
75                         Bucket bucket = new Bucket();
76
77                         Timer t = new Timer (new TimerCallback (Callback), bucket, 0, Timeout.Infinite);
78                         Thread.Sleep (100);
79                         Assert.AreEqual (1, bucket.count);
80                         t.Change (0, Timeout.Infinite);
81                         Thread.Sleep (100);
82                         Assert.AreEqual (2, bucket.count);
83                         t.Dispose ();
84                 }
85                 [Test]
86                 public void TestDispose ()
87                 {       
88                         Bucket bucket = new Bucket();
89                         Timer t = new Timer (new TimerCallback (Callback), bucket, 10, 10);
90                         Thread.Sleep (200);
91                         t.Dispose ();
92                         Thread.Sleep (20);
93                         int c = bucket.count;
94                         Assert.IsTrue(bucket.count > 5);
95                         Thread.Sleep (200);
96                         Assert.AreEqual (c, bucket.count);
97                 }
98
99                 [Test] // bug #78208
100                 public void TestDispose2 ()
101                 {
102                         Timer t = new Timer (new TimerCallback (Callback), null, 10, 10);
103                         t.Dispose ();
104                         t.Dispose ();
105                 }
106                 
107                 [Test]
108                 public void TestHeavyCreationLoad() {
109                         Bucket b = new Bucket();
110                         for (int i = 0; i < 500; ++i)
111                                 new Timer(new TimerCallback(Callback),b,10,Timeout.Infinite);
112                         // 1000 * 10 msec = 10,000 msec or 10 sec - if everything goes well
113                         // we add some slack to cope with timing issues caused by system load etc.
114                         for (int i = 0; i < 20; ++i) {
115                                 if (b.count == 500)
116                                         break;
117                                 Thread.Sleep(1000);
118                         }
119                         Assert.AreEqual(500,b.count);
120                         
121                 }
122                 [Test]
123                 public void TestQuickDisposeDeadlockBug() {
124                         int i = 0;
125                         Bucket b = new Bucket();
126                         ArrayList timers = new ArrayList();
127                         while (i < 500) {
128                                 Timer t = new Timer(new TimerCallback(Callback),b,10,Timeout.Infinite);
129                                 timers.Add(t);
130                                 i++;
131                                 t.Dispose();
132                         }
133                         Thread.Sleep(11*500);
134                 }
135                 [Test]
136                 public void TestInt32MaxDelay() {
137                         Bucket b = new Bucket();
138                         new Timer(new TimerCallback(Callback),b,Int32.MaxValue,Timeout.Infinite);
139                         Thread.Sleep(50);
140                         Assert.AreEqual(0,b.count);
141                         
142                 }
143                 [Test]
144                 public void TestInt32MaxPeriod() {
145                         Bucket b = new Bucket();
146                         new Timer(new TimerCallback(Callback),b,0,Int32.MaxValue);
147                         Thread.Sleep(50);
148                         Assert.AreEqual(1,b.count);
149                         
150                 }
151                 [Test]
152                 public void TestNegativeDelay() {
153                         Bucket b = new Bucket();
154                         try {
155                                 new Timer(new TimerCallback(Callback),b,-10,Timeout.Infinite);
156                         } catch (ArgumentOutOfRangeException) {
157                                 return;
158                         }
159                         Assert.Fail();
160                         
161                 }
162                 [Test]
163                 public void TestNegativePeriod() {
164                         Bucket b = new Bucket();
165                         try {
166                                 new Timer(new TimerCallback(Callback),b,0,-10);
167                         } catch (ArgumentOutOfRangeException) {
168                                 return;
169                         }
170                         Assert.Fail();
171                 }
172
173                 [Test]
174                 public void TestDelayZeroPeriodZero() {
175                         Bucket b = new Bucket();
176                         Timer t = new Timer(new TimerCallback(Callback),b,0,0);
177                         Thread.Sleep(100);
178                         t.Change (int.MaxValue, Timeout.Infinite);
179                         // since period is 0 the callback should happen once (bug #340212)
180                         Assert.IsTrue(b.count == 1);
181                         
182                 }
183
184                 [Category("NotWorking")]
185                 public void TestDisposeOnCallback () {
186                 
187                         Timer t1 = null;
188                         t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), t1, 0, 10);
189                         Thread.Sleep (200);
190                         Assert.IsNull(t1);
191                         
192                 }
193                 private void CallbackTestDisposeOnCallback (object foo)
194                 {
195                         ((Timer)foo).Dispose();
196                 }
197                 
198                 private void Callback (object foo)
199                 {
200                         Bucket b = foo as Bucket;
201                         b.count++;
202                 }
203         }
204 }