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 (new TimerCallback (DoNothing), null, Timeout.Infinite, 0);
35 void DoNothing (object foo)
40 public void TestDueTime ()
42 Bucket bucket = new Bucket();
43 Timer t = new Timer (new TimerCallback (Callback), bucket, 200, Timeout.Infinite);
45 Assert.AreEqual (0, bucket.count, "#1");
47 Assert.AreEqual (1, bucket.count, "#2");
49 Assert.AreEqual (1, bucket.count, "#3");
52 Assert.IsTrue(bucket.count > 20, "#4");
57 public void TestChange ()
59 Bucket bucket = new Bucket();
60 Timer t = new Timer (new TimerCallback (Callback), bucket, 10, 10);
63 Assert.IsTrue (c > 20, "#1 " + c.ToString ());
67 Assert.IsTrue (bucket.count <= c + 20, "#2 " + c.ToString ());
72 public void TestZeroDueTime ()
74 Bucket bucket = new Bucket();
76 Timer t = new Timer (new TimerCallback (Callback), bucket, 0, Timeout.Infinite);
78 Assert.AreEqual (1, bucket.count, "#1");
79 t.Change (0, Timeout.Infinite);
81 Assert.AreEqual (2, bucket.count, "#2");
86 public void TestDispose ()
88 Bucket bucket = new Bucket();
89 Timer t = new Timer (new TimerCallback (Callback), bucket, 10, 10);
94 Assert.IsTrue (bucket.count > 5, "#1");
96 Assert.AreEqual (c, bucket.count, "#2");
100 public void TestDispose2 ()
102 Timer t = new Timer (new TimerCallback (Callback), null, 10, 10);
108 public void TestHeavyCreationLoad ()
110 Bucket b = new Bucket ();
111 for (int i = 0; i < 500; ++i)
112 new Timer (new TimerCallback (Callback), b, 10,
114 // 1000 * 10 msec = 10,000 msec or 10 sec - if everything goes well
115 // we add some slack to cope with timing issues caused by system load etc.
116 for (int i = 0; i < 20; ++i) {
121 Assert.AreEqual (500, b.count);
126 public void TestQuickDisposeDeadlockBug ()
129 Bucket b = new Bucket ();
130 ArrayList timers = new ArrayList();
132 Timer t = new Timer (new TimerCallback (Callback),
133 b, 10, Timeout.Infinite);
138 Thread.Sleep (11 * 500);
142 public void TestInt32MaxDelay ()
144 Bucket b = new Bucket ();
145 new Timer (new TimerCallback (Callback), b, Int32.MaxValue,
148 Assert.AreEqual (0, b.count);
152 public void TestInt32MaxPeriod ()
154 Bucket b = new Bucket ();
155 new Timer (new TimerCallback (Callback), b, 0,
158 Assert.AreEqual (1, b.count);
163 public void TestNegativeDelay ()
165 Bucket b = new Bucket ();
167 new Timer (new TimerCallback (Callback), b, -10,
170 } catch (ArgumentOutOfRangeException) {
176 public void TestNegativePeriod ()
178 Bucket b = new Bucket ();
180 new Timer (new TimerCallback (Callback), b, 0,
183 } catch (ArgumentOutOfRangeException) {
189 public void TestDelayZeroPeriodZero()
191 Bucket b = new Bucket();
192 Timer t = new Timer(new TimerCallback(Callback),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");
201 public void TestDisposeOnCallback ()
203 // this test is bad, as the provided `state` (t1) is null and will throw an NRE inside the callback
204 // that was ignored before 238785a3e3d510528228fc551625975bc508c2f3 and most unit test runner won't
205 // report it since the NRE will not happen on the main thread (but Touch.Unit will)
207 t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), t1, 0, 10);
209 Assert.IsNotNull (t1);
213 private void CallbackTestDisposeOnCallback (object foo)
215 ((Timer) foo).Dispose ();
218 private void Callback (object foo)
220 Bucket b = foo as Bucket;
221 Interlocked.Increment (ref b.count);
225 [ExpectedException (typeof (ArgumentNullException))]
226 public void DisposeNullWaitHandle ()
228 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
234 public void Change_IntInt_Infinite ()
236 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
237 t.Change ((int)Timeout.Infinite, (int)Timeout.Infinite);
242 public void Change_IntInt_MaxValue ()
244 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
245 t.Change (Int32.MaxValue, Int32.MaxValue);
250 public void Change_UIntUInt_Infinite ()
252 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
253 t.Change (unchecked ((uint) Timeout.Infinite), unchecked ((uint) Timeout.Infinite));
258 public void Change_UIntUInt_MaxValue ()
260 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
261 // UInt32.MaxValue == Timeout.Infinite == 0xffffffff
262 t.Change (UInt32.MaxValue, UInt32.MaxValue);
267 public void Change_LongLong_Infinite ()
269 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
270 t.Change ((long) Timeout.Infinite, (long) Timeout.Infinite);
275 [ExpectedException (typeof (ArgumentOutOfRangeException))]
276 public void Change_LongLong_MaxValue ()
278 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
279 t.Change (Int64.MaxValue, Int64.MaxValue);
284 [ExpectedException (typeof (ArgumentOutOfRangeException))]
285 public void Change_LongLong_UInt32MaxValue ()
287 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
288 // not identical to (long)-1
289 t.Change ((long)UInt32.MaxValue, (long)UInt32.MaxValue);
294 public void Change_LongLong_UInt32MaxValueMinusOne ()
296 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
297 // not identical to (long)-1
298 t.Change ((long) UInt32.MaxValue - 1, (long) UInt32.MaxValue -1);
303 public void Change_TimeSpanTimeSpan_Infinite ()
305 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
306 t.Change (new TimeSpan (-1), new TimeSpan (-1));
311 [ExpectedException (typeof (ArgumentOutOfRangeException))]
312 public void Change_TimeSpanTimeSpan_MaxValue ()
314 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
315 t.Change (TimeSpan.MaxValue, TimeSpan.MaxValue);
320 public void Change_TimeSpanTimeSpan_UInt32MaxValue ()
322 using (Timer t = new Timer (DoNothing, null, 0, 0)) {
323 t.Change (new TimeSpan (UInt32.MaxValue), new TimeSpan (UInt32.MaxValue));