2007-09-14 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / corlib / Test / System.Threading / TimerTest.cs
index cc0e3976950ee738ba52fbe1cee3ed69dcb4a180..2be2ec76bbb90627951af08199623f6f41bc41d4 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Author:
 //   Zoltan Varga (vargaz@freemail.hu)
+//   Rafael Ferreira (raf@ophion.org)
 //
 // (C) 2004 Novell, Inc (http://www.novell.com)
 //
 using NUnit.Framework;
 using System;
 using System.Threading;
+using System.Collections;
 
 namespace MonoTests.System.Threading {
 
-       [TestFixture]
        //
        // This whole test seems to fail randomly. Either
        // - It is relying on a race it might not win (that the timer code runs)
@@ -22,111 +23,182 @@ namespace MonoTests.System.Threading {
        // Am going with door #1, but it would be nice to investigate this.
        // -- Ben
        //
-       public class TimerTest : Assertion {
+       [TestFixture]
+       public class TimerTest {
+               // this bucket is used to avoid non-theadlocal issues
+               class Bucket {
+                       public int count;
+               }
+               [SetUp]
+               public void setup() {
+                       //creating a timer that will never run just to make sure the
+                       // scheduler is warm for the unit tests
+                       // this makes fair for the "DueTime" test since it 
+                       // doesn't have to wait for the scheduler thread to be 
+                       // created. 
+                       new Timer(null,null,Timeout.Infinite,0);
+               }
+               
                [Test]
-               [Category ("NotWorking")]
                public void TestDueTime ()
                {
-                       counter = 0;
-                       Timer t = new Timer (new TimerCallback (Callback), null, 200, Timeout.Infinite);
+                       Bucket bucket = new Bucket();
+                       Timer t = new Timer (new TimerCallback (Callback), bucket, 200, Timeout.Infinite);
                        Thread.Sleep (50);
-                       AssertEquals ("t0", 0, counter);
+                       Assert.AreEqual (0, bucket.count);
                        Thread.Sleep (200);
-                       AssertEquals ("t1", 1, counter);
+                       Assert.AreEqual (1, bucket.count);
                        Thread.Sleep (500);
-                       AssertEquals ("t2", 1, counter);
-                       
+                       Assert.AreEqual (1, bucket.count);
                        t.Change (10, 10);
-                       Thread.Sleep (500);
-                       Assert ("t3", counter > 20);
+                       Thread.Sleep (1000);
+                       Assert.IsTrue(bucket.count > 20);
                        t.Dispose ();
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void TestChange ()
                {
-                       counter = 0;
-                       Timer t = new Timer (new TimerCallback (Callback), null, 1, 1);
+                       Bucket bucket = new Bucket();
+                       Timer t = new Timer (new TimerCallback (Callback), bucket, 1, 1);
                        Thread.Sleep (500);
-                       int c = counter;
-                       Assert ("t1", c > 20);
+                       int c = bucket.count;
+                       Assert.IsTrue(c > 20);
                        t.Change (100, 100);
                        Thread.Sleep (500);
-                       Assert ("t2", counter <= c + 6);
+                       Assert.IsTrue(bucket.count <= c + 6);
                        t.Dispose ();
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void TestZeroDueTime () {
-                       counter = 0;
+                       Bucket bucket = new Bucket();
 
-                       Timer t = new Timer (new TimerCallback (Callback), null, 0, Timeout.Infinite);
+                       Timer t = new Timer (new TimerCallback (Callback), bucket, 0, Timeout.Infinite);
                        Thread.Sleep (100);
-                       AssertEquals (1, counter);
+                       Assert.AreEqual (1, bucket.count);
                        t.Change (0, Timeout.Infinite);
                        Thread.Sleep (100);
-                       AssertEquals (2, counter);
+                       Assert.AreEqual (2, bucket.count);
                        t.Dispose ();
                }
-
                [Test]
-               [Category ("NotWorking")]
                public void TestDispose ()
-               {
-                       counter = 0;
-                       Timer t = new Timer (new TimerCallback (CallbackTestDispose), null, 10, 10);
+               {       
+                       Bucket bucket = new Bucket();
+                       Timer t = new Timer (new TimerCallback (Callback), bucket, 10, 10);
                        Thread.Sleep (200);
                        t.Dispose ();
                        Thread.Sleep (20);
-                       int c = counter;
-                       Assert (counter > 5);
+                       int c = bucket.count;
+                       Assert.IsTrue(bucket.count > 5);
                        Thread.Sleep (200);
-                       AssertEquals (c, counter);
+                       Assert.AreEqual (c, bucket.count);
                }
 
                [Test] // bug #78208
                public void TestDispose2 ()
                {
-                       Timer t = new Timer (new TimerCallback (CallbackTestDispose), null, 10, 10);
+                       Timer t = new Timer (new TimerCallback (Callback), null, 10, 10);
                        t.Dispose ();
                        t.Dispose ();
                }
                
                [Test]
-               [Category ("NotWorking")]
-               public void TestDisposeOnCallback () {
-                       counter = 0;
-                       t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), null, 0, 10);
-                       Thread.Sleep (200);
-                       AssertNull (t1);
+               public void TestHeavyCreationLoad() {
+                       Bucket b = new Bucket();
+                       for (int i = 0; i < 500; ++i)
+                               new Timer(new TimerCallback(Callback),b,10,Timeout.Infinite);
+                       // 1000 * 10 msec = 10,000 msec or 10 sec - if everything goes well
+                       // we add some slack to cope with timing issues caused by system load etc.
+                       for (int i = 0; i < 20; ++i) {
+                               if (b.count == 500)
+                                       break;
+                               Thread.Sleep(1000);
+                       }
+                       Assert.AreEqual(500,b.count);
                        
-                       counter = 2;
-                       t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), null, 50, 0);
-                       Thread.Sleep (200);
-                       AssertNull (t1);
                }
-               
-               private void CallbackTestDisposeOnCallback (object foo)
-               {
-                       if (++counter == 3) {
-                               t1.Dispose ();
-                               t1 = null;
+               [Test]
+               public void TestQuickDisposeDeadlockBug() {
+                       int i = 0;
+                       Bucket b = new Bucket();
+                       ArrayList timers = new ArrayList();
+                       while (i < 500) {
+                               Timer t = new Timer(new TimerCallback(Callback),b,10,Timeout.Infinite);
+                               timers.Add(t);
+                               i++;
+                               t.Dispose();
                        }
+                       Thread.Sleep(11*500);
+               }
+               [Test]
+               public void TestInt32MaxDelay() {
+                       Bucket b = new Bucket();
+                       new Timer(new TimerCallback(Callback),b,Int32.MaxValue,Timeout.Infinite);
+                       Thread.Sleep(50);
+                       Assert.AreEqual(0,b.count);
+                       
+               }
+               [Test]
+               public void TestInt32MaxPeriod() {
+                       Bucket b = new Bucket();
+                       new Timer(new TimerCallback(Callback),b,0,Int32.MaxValue);
+                       Thread.Sleep(50);
+                       Assert.AreEqual(1,b.count);
+                       
+               }
+               [Test]
+               public void TestNegativeDelay() {
+                       Bucket b = new Bucket();
+                       try {
+                               new Timer(new TimerCallback(Callback),b,-10,Timeout.Infinite);
+                       } catch (ArgumentOutOfRangeException) {
+                               return;
+                       }
+                       Assert.Fail();
+                       
+               }
+               [Test]
+               public void TestNegativePeriod() {
+                       Bucket b = new Bucket();
+                       try {
+                               new Timer(new TimerCallback(Callback),b,0,-10);
+                       } catch (ArgumentOutOfRangeException) {
+                               return;
+                       }
+                       Assert.Fail();
                }
 
-               private void CallbackTestDispose (object foo)
-               {
-                       counter++;
+               [Test]
+               public void TestDelayZeroPeriodZero() {
+                       Bucket b = new Bucket();
+                       Timer t = new Timer(new TimerCallback(Callback),b,0,0);
+                       Thread.Sleep(100);
+                       t.Change (int.MaxValue, Timeout.Infinite);
+                       // since period is 0 the callback should happen once (bug #340212)
+                       Assert.IsTrue(b.count == 1);
+                       
                }
 
+               [Category("NotWorking")]
+               public void TestDisposeOnCallback () {
+               
+                       Timer t1 = null;
+                       t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), t1, 0, 10);
+                       Thread.Sleep (200);
+                       Assert.IsNull(t1);
+                       
+               }
+               private void CallbackTestDisposeOnCallback (object foo)
+               {
+                       ((Timer)foo).Dispose();
+               }
+               
                private void Callback (object foo)
                {
-                       counter++;
+                       Bucket b = foo as Bucket;
+                       b.count++;
                }
-
-               Timer t1;
-               int counter;
        }
 }