2 // TimerTest.cs - NUnit test cases for System.Threading.Timer
5 // Zoltan Varga (vargaz@freemail.hu)
6 // Rafael Ferreira (raf@ophion.org)
8 // (C) 2004 Novell, Inc (http://www.novell.com)
11 using NUnit.Framework;
13 using System.Threading;
14 using System.Collections;
16 namespace MonoTests.System.Threading {
18 public class TimerTest {
19 // this bucket is used to avoid non-theadlocal issues
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
32 new Timer (o => DoNothing (o), null, Timeout.Infinite, 0);
35 void DoNothing (object foo)
40 public void TestDueTime ()
42 Bucket bucket = new Bucket();
44 using (Timer t = new Timer (o => Callback (o), bucket, 200, Timeout.Infinite)) {
46 Assert.AreEqual (0, bucket.count, "#1");
48 Assert.AreEqual (1, bucket.count, "#2");
50 Assert.AreEqual (1, bucket.count, "#3");
53 Assert.IsTrue(bucket.count > 20, "#4");
58 public void TestChange ()
60 Bucket bucket = new Bucket();
62 using (Timer t = new Timer (o => Callback (o), bucket, 10, 10)) {
65 Assert.IsTrue (c > 20, "#1 " + c.ToString ());
69 Assert.IsTrue (bucket.count <= c + 20, "#2 " + c.ToString ());
74 public void TestZeroDueTime ()
76 Bucket bucket = new Bucket();
78 using (Timer t = new Timer (o => Callback (o), bucket, 0, Timeout.Infinite)) {
80 Assert.AreEqual (1, bucket.count, "#1");
81 t.Change (0, Timeout.Infinite);
83 Assert.AreEqual (2, bucket.count, "#2");
88 public void TestDispose ()
90 Bucket bucket = new Bucket();
92 using (Timer t = new Timer (o => Callback (o), bucket, 10, 10)) {
98 Assert.IsTrue (bucket.count > 5, "#1");
100 Assert.AreEqual (c, bucket.count, "#2");
103 [Test] // bug #320950
104 public void TestDispose2 ()
106 Timer t = new Timer (o => DoNothing (o), null, 10, 10);
112 public void TestHeavyCreationLoad ()
114 Bucket b = new Bucket ();
116 for (int i = 0; i < 500; ++i)
117 new Timer (o => Callback (o), b, 10, Timeout.Infinite);
119 // 1000 * 10 msec = 10,000 msec or 10 sec - if everything goes well
120 // we add some slack to cope with timing issues caused by system load etc.
121 for (int i = 0; i < 20; ++i) {
127 Assert.AreEqual (500, b.count);
131 public void TestQuickDisposeDeadlockBug ()
133 Bucket b = new Bucket ();
134 ArrayList timers = new ArrayList (500);
136 for (int i = 0; i < 500; ++i) {
137 using (Timer t = new Timer (o => Callback (o), b, 10, Timeout.Infinite)) {
142 Thread.Sleep (11 * 500);
146 public void TestInt32MaxDelay ()
148 Bucket b = new Bucket ();
150 using (new Timer (o => Callback (o), b, Int32.MaxValue, Timeout.Infinite)) {
152 Assert.AreEqual (0, b.count);
157 public void TestInt32MaxPeriod ()
159 Bucket b = new Bucket ();
161 using (new Timer (o => Callback (o), b, 0, Int32.MaxValue)) {
163 Assert.AreEqual (1, b.count);
168 [ExpectedException (typeof (ArgumentOutOfRangeException))]
169 public void TestNegativeDelay ()
171 Bucket b = new Bucket ();
173 using (new Timer (o => Callback (o), b, -10, Timeout.Infinite)) {
178 [ExpectedException (typeof (ArgumentOutOfRangeException))]
179 public void TestNegativePeriod ()
181 Bucket b = new Bucket ();
183 using (new Timer (o => Callback (o), b, 0, -10)) {
188 public void TestDelayZeroPeriodZero()
190 Bucket b = new Bucket();
192 using (Timer t = new Timer(o => Callback (o),b,0,0)) {
194 t.Change (int.MaxValue, Timeout.Infinite);
195 // since period is 0 the callback should happen once (bug #340212)
196 Assert.AreEqual (1, b.count, "only once");
202 public void TestDisposeOnCallback ()
204 // this test is bad, as the provided `state` (t1) is null and will throw an NRE inside the callback
205 // that was ignored before 238785a3e3d510528228fc551625975bc508c2f3 and most unit test runner won't
206 // report it since the NRE will not happen on the main thread (but Touch.Unit will)
208 t1 = new Timer (o => CallbackTestDisposeOnCallback (o), t1, 0, 10);
210 Assert.IsNotNull (t1);
214 private void CallbackTestDisposeOnCallback (object foo)
216 ((Timer) foo).Dispose ();
219 private void Callback (object foo)
221 Bucket b = foo as Bucket;
222 Interlocked.Increment (ref b.count);
226 [ExpectedException (typeof (ArgumentNullException))]
227 public void DisposeNullWaitHandle ()
229 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
235 public void Change_IntInt_Infinite ()
237 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
238 t.Change ((int)Timeout.Infinite, (int)Timeout.Infinite);
243 public void Change_IntInt_MaxValue ()
245 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
246 t.Change (Int32.MaxValue, Int32.MaxValue);
251 public void Change_UIntUInt_Infinite ()
253 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
254 t.Change (unchecked ((uint) Timeout.Infinite), unchecked ((uint) Timeout.Infinite));
259 public void Change_UIntUInt_MaxValue ()
261 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
262 // UInt32.MaxValue == Timeout.Infinite == 0xffffffff
263 t.Change (UInt32.MaxValue, UInt32.MaxValue);
268 public void Change_LongLong_Infinite ()
270 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
271 t.Change ((long) Timeout.Infinite, (long) Timeout.Infinite);
276 [ExpectedException (typeof (ArgumentOutOfRangeException))]
277 public void Change_LongLong_MaxValue ()
279 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
280 t.Change (Int64.MaxValue, Int64.MaxValue);
285 [ExpectedException (typeof (ArgumentOutOfRangeException))]
286 public void Change_LongLong_UInt32MaxValue ()
288 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
289 // not identical to (long)-1
290 t.Change ((long)UInt32.MaxValue, (long)UInt32.MaxValue);
295 public void Change_LongLong_UInt32MaxValueMinusOne ()
297 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
298 // not identical to (long)-1
299 t.Change ((long) UInt32.MaxValue - 1, (long) UInt32.MaxValue -1);
304 public void Change_TimeSpanTimeSpan_Infinite ()
306 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
307 t.Change (new TimeSpan (-1), new TimeSpan (-1));
312 [ExpectedException (typeof (ArgumentOutOfRangeException))]
313 public void Change_TimeSpanTimeSpan_MaxValue ()
315 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
316 t.Change (TimeSpan.MaxValue, TimeSpan.MaxValue);
321 public void Change_TimeSpanTimeSpan_UInt32MaxValue ()
323 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
324 t.Change (new TimeSpan (UInt32.MaxValue), new TimeSpan (UInt32.MaxValue));