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
22 public ManualResetEventSlim mre = new ManualResetEventSlim (false);
28 //creating a timer that will never run just to make sure the
29 // scheduler is warm for the unit tests
30 // this makes fair for the "DueTime" test since it
31 // doesn't have to wait for the scheduler thread to be
33 new Timer (o => DoNothing (o), null, Timeout.Infinite, 0);
36 void DoNothing (object foo)
40 private void Callback2 (object foo)
42 Bucket b = foo as Bucket;
43 Interlocked.Increment (ref b.count);
49 public void TestDueTime ()
51 Bucket bucket = new Bucket();
53 using (Timer t = new Timer (o => Callback2 (o), bucket, 200, Timeout.Infinite)) {
54 Assert.IsTrue (bucket.mre.Wait (5000), "#-1");
55 Assert.AreEqual (1, bucket.count, "#1");
60 public void TestDispose ()
62 Bucket bucket = new Bucket();
64 using (Timer t = new Timer (o => Callback2 (o), bucket, 10, 10)) {
65 Assert.IsTrue (bucket.mre.Wait (5000), "#-1");
67 //If the callback is called after dispose, it will NRE and be reported
70 Assert.IsTrue (c > 0, "#1");
74 public void TestChange ()
76 Bucket bucket = new Bucket();
78 using (Timer t = new Timer (o => Callback2 (o), bucket, 10, 10)) {
79 Assert.IsTrue (bucket.mre.Wait (5000), "#-1");
81 Assert.IsTrue (c > 0, "#1 " + c);
82 t.Change (100000, 1000000);
85 Assert.IsTrue (bucket.count <= c + 1, "#2 " + c);
90 public void TestZeroDueTime ()
92 Bucket bucket = new Bucket();
94 using (Timer t = new Timer (o => Callback2 (o), bucket, 0, Timeout.Infinite)) {
95 Assert.IsTrue (bucket.mre.Wait (5000), "#-1");
97 Assert.AreEqual (1, bucket.count, "#1");
98 t.Change (0, Timeout.Infinite);
99 Assert.IsTrue (bucket.mre.Wait (5000), "#1.5");
100 Assert.AreEqual (2, bucket.count, "#2");
104 [Test] // bug #320950
105 public void TestDispose2 ()
107 Timer t = new Timer (o => DoNothing (o), null, 10, 10);
113 public void TestHeavyCreationLoad ()
115 Bucket b = new Bucket ();
117 for (int i = 0; i < 500; ++i)
118 new Timer (o => Callback (o), b, 10, Timeout.Infinite);
120 // 1000 * 10 msec = 10,000 msec or 10 sec - if everything goes well
121 // we add some slack to cope with timing issues caused by system load etc.
122 for (int i = 0; i < 20; ++i) {
128 Assert.AreEqual (500, b.count);
132 public void TestQuickDisposeDeadlockBug ()
134 Bucket b = new Bucket ();
135 ArrayList timers = new ArrayList (500);
137 for (int i = 0; i < 500; ++i) {
138 using (Timer t = new Timer (o => Callback (o), b, 10, Timeout.Infinite)) {
143 Thread.Sleep (11 * 500);
147 public void TestInt32MaxDelay ()
149 Bucket b = new Bucket ();
151 using (new Timer (o => Callback (o), b, Int32.MaxValue, Timeout.Infinite)) {
153 Assert.AreEqual (0, b.count);
158 public void TestInt32MaxPeriod ()
160 Bucket b = new Bucket ();
162 using (new Timer (o => Callback (o), b, 0, Int32.MaxValue)) {
164 Assert.AreEqual (1, b.count);
169 [ExpectedException (typeof (ArgumentOutOfRangeException))]
170 public void TestNegativeDelay ()
172 Bucket b = new Bucket ();
174 using (new Timer (o => Callback (o), b, -10, Timeout.Infinite)) {
179 [ExpectedException (typeof (ArgumentOutOfRangeException))]
180 public void TestNegativePeriod ()
182 Bucket b = new Bucket ();
184 using (new Timer (o => Callback (o), b, 0, -10)) {
189 public void TestDelayZeroPeriodZero()
191 Bucket b = new Bucket();
193 using (Timer t = new Timer(o => Callback (o),b,0,0)) {
195 t.Change (int.MaxValue, Timeout.Infinite);
196 // since period is 0 the callback should happen once (bug #340212)
197 Assert.AreEqual (1, b.count, "only once");
203 public void TestDisposeOnCallback ()
205 // this test is bad, as the provided `state` (t1) is null and will throw an NRE inside the callback
206 // that was ignored before 238785a3e3d510528228fc551625975bc508c2f3 and most unit test runner won't
207 // report it since the NRE will not happen on the main thread (but Touch.Unit will)
209 t1 = new Timer (o => CallbackTestDisposeOnCallback (o), t1, 0, 10);
211 Assert.IsNotNull (t1);
215 private void CallbackTestDisposeOnCallback (object foo)
217 ((Timer) foo).Dispose ();
220 private void Callback (object foo)
222 Bucket b = foo as Bucket;
223 Interlocked.Increment (ref b.count);
227 [ExpectedException (typeof (ArgumentNullException))]
228 public void DisposeNullWaitHandle ()
230 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
236 public void Change_IntInt_Infinite ()
238 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
239 t.Change ((int)Timeout.Infinite, (int)Timeout.Infinite);
244 public void Change_IntInt_MaxValue ()
246 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
247 t.Change (Int32.MaxValue, Int32.MaxValue);
252 public void Change_UIntUInt_Infinite ()
254 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
255 t.Change (unchecked ((uint) Timeout.Infinite), unchecked ((uint) Timeout.Infinite));
260 public void Change_UIntUInt_MaxValue ()
262 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
263 // UInt32.MaxValue == Timeout.Infinite == 0xffffffff
264 t.Change (UInt32.MaxValue, UInt32.MaxValue);
269 public void Change_LongLong_Infinite ()
271 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
272 t.Change ((long) Timeout.Infinite, (long) Timeout.Infinite);
277 [ExpectedException (typeof (ArgumentOutOfRangeException))]
278 public void Change_LongLong_MaxValue ()
280 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
281 t.Change (Int64.MaxValue, Int64.MaxValue);
286 [ExpectedException (typeof (ArgumentOutOfRangeException))]
287 public void Change_LongLong_UInt32MaxValue ()
289 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
290 // not identical to (long)-1
291 t.Change ((long)UInt32.MaxValue, (long)UInt32.MaxValue);
296 public void Change_LongLong_UInt32MaxValueMinusOne ()
298 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
299 // not identical to (long)-1
300 t.Change ((long) UInt32.MaxValue - 1, (long) UInt32.MaxValue -1);
305 public void Change_TimeSpanTimeSpan_Infinite ()
307 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
308 t.Change (new TimeSpan (-1), new TimeSpan (-1));
313 [ExpectedException (typeof (ArgumentOutOfRangeException))]
314 public void Change_TimeSpanTimeSpan_MaxValue ()
316 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
317 t.Change (TimeSpan.MaxValue, TimeSpan.MaxValue);
322 public void Change_TimeSpanTimeSpan_UInt32MaxValue ()
324 using (Timer t = new Timer (o => DoNothing (o), null, 0, 0)) {
325 t.Change (new TimeSpan (UInt32.MaxValue), new TimeSpan (UInt32.MaxValue));