X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FTest%2FSystem.Threading%2FTimerTest.cs;h=ee60eb53aa23b42e028e1c2d69ca64e41bb92602;hb=055495c537473805859a4db627918347be547ee3;hp=cc0e3976950ee738ba52fbe1cee3ed69dcb4a180;hpb=9869ae24b88761ab261c4311e24f7383b4af3f02;p=mono.git diff --git a/mcs/class/corlib/Test/System.Threading/TimerTest.cs b/mcs/class/corlib/Test/System.Threading/TimerTest.cs index cc0e3976950..ee60eb53aa2 100644 --- a/mcs/class/corlib/Test/System.Threading/TimerTest.cs +++ b/mcs/class/corlib/Test/System.Threading/TimerTest.cs @@ -3,6 +3,7 @@ // // Author: // Zoltan Varga (vargaz@freemail.hu) +// Rafael Ferreira (raf@ophion.org) // // (C) 2004 Novell, Inc (http://www.novell.com) // @@ -10,123 +11,317 @@ 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) - // - We have a very obscure bug with appdomains. - // - // Am going with door #1, but it would be nice to investigate this. - // -- Ben - // - public class TimerTest : Assertion { - [Test] - [Category ("NotWorking")] + 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 (new TimerCallback (DoNothing), null, Timeout.Infinite, 0); + } + + void DoNothing (object foo) + { + } + + [Test] 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, "#1"); Thread.Sleep (200); - AssertEquals ("t1", 1, counter); + Assert.AreEqual (1, bucket.count, "#2"); Thread.Sleep (500); - AssertEquals ("t2", 1, counter); - + Assert.AreEqual (1, bucket.count, "#3"); t.Change (10, 10); - Thread.Sleep (500); - Assert ("t3", counter > 20); + Thread.Sleep (1000); + Assert.IsTrue(bucket.count > 20, "#4"); 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, 10, 10); Thread.Sleep (500); - int c = counter; - Assert ("t1", c > 20); + int c = bucket.count; + Assert.IsTrue (c > 20, "#1 " + c.ToString ()); t.Change (100, 100); + c = bucket.count; Thread.Sleep (500); - Assert ("t2", counter <= c + 6); + Assert.IsTrue (bucket.count <= c + 20, "#2 " + c.ToString ()); t.Dispose (); } [Test] - [Category ("NotWorking")] - public void TestZeroDueTime () { - counter = 0; + public void TestZeroDueTime () + { + 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, "#1"); t.Change (0, Timeout.Infinite); Thread.Sleep (100); - AssertEquals (2, counter); + Assert.AreEqual (2, bucket.count, "#2"); 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, "#1"); Thread.Sleep (200); - AssertEquals (c, counter); + Assert.AreEqual (c, bucket.count, "#2"); } - [Test] // bug #78208 + [Test] // bug #320950 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); + + } + + [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); - counter = 2; - t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), null, 50, 0); + } + + [Test] + public void TestNegativeDelay () + { + Bucket b = new Bucket (); + try { + new Timer (new TimerCallback (Callback), b, -10, + Timeout.Infinite); + Assert.Fail (); + } catch (ArgumentOutOfRangeException) { + return; + } + } + + [Test] + public void TestNegativePeriod () + { + Bucket b = new Bucket (); + try { + new Timer (new TimerCallback (Callback), b, 0, + -10); + Assert.Fail (); + } catch (ArgumentOutOfRangeException) { + return; + } + } + + [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.AreEqual (1, b.count, "only once"); + } + + [Test] + [Ignore ()] + public void TestDisposeOnCallback () + { + // this test is bad, as the provided `state` (t1) is null and will throw an NRE inside the callback + // that was ignored before 238785a3e3d510528228fc551625975bc508c2f3 and most unit test runner won't + // report it since the NRE will not happen on the main thread (but Touch.Unit will) + Timer t1 = null; + t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), t1, 0, 10); Thread.Sleep (200); - AssertNull (t1); + Assert.IsNotNull (t1); + } - + private void CallbackTestDisposeOnCallback (object foo) { - if (++counter == 3) { - t1.Dispose (); - t1 = null; + ((Timer) foo).Dispose (); + } + + private void Callback (object foo) + { + Bucket b = foo as Bucket; + Interlocked.Increment (ref b.count); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void DisposeNullWaitHandle () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + t.Dispose (null); + } + } + + [Test] + public void Change_IntInt_Infinite () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + t.Change ((int)Timeout.Infinite, (int)Timeout.Infinite); } } - private void CallbackTestDispose (object foo) + [Test] + public void Change_IntInt_MaxValue () { - counter++; + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + t.Change (Int32.MaxValue, Int32.MaxValue); + } } - private void Callback (object foo) + [Test] + public void Change_UIntUInt_Infinite () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + t.Change (unchecked ((uint) Timeout.Infinite), unchecked ((uint) Timeout.Infinite)); + } + } + + [Test] + public void Change_UIntUInt_MaxValue () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + // UInt32.MaxValue == Timeout.Infinite == 0xffffffff + t.Change (UInt32.MaxValue, UInt32.MaxValue); + } + } + + [Test] + public void Change_LongLong_Infinite () { - counter++; + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + t.Change ((long) Timeout.Infinite, (long) Timeout.Infinite); + } } - Timer t1; - int counter; + [Test] + [ExpectedException (typeof (ArgumentOutOfRangeException))] + public void Change_LongLong_MaxValue () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + t.Change (Int64.MaxValue, Int64.MaxValue); + } + } + + [Test] + [ExpectedException (typeof (ArgumentOutOfRangeException))] + public void Change_LongLong_UInt32MaxValue () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + // not identical to (long)-1 + t.Change ((long)UInt32.MaxValue, (long)UInt32.MaxValue); + } + } + + [Test] + public void Change_LongLong_UInt32MaxValueMinusOne () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + // not identical to (long)-1 + t.Change ((long) UInt32.MaxValue - 1, (long) UInt32.MaxValue -1); + } + } + + [Test] + public void Change_TimeSpanTimeSpan_Infinite () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + t.Change (new TimeSpan (-1), new TimeSpan (-1)); + } + } + + [Test] + [ExpectedException (typeof (ArgumentOutOfRangeException))] + public void Change_TimeSpanTimeSpan_MaxValue () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + t.Change (TimeSpan.MaxValue, TimeSpan.MaxValue); + } + } + + [Test] + public void Change_TimeSpanTimeSpan_UInt32MaxValue () + { + using (Timer t = new Timer (DoNothing, null, 0, 0)) { + t.Change (new TimeSpan (UInt32.MaxValue), new TimeSpan (UInt32.MaxValue)); + } + } } }