//
// 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)
- // - 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");
t.Change (100, 100);
+ c = bucket.count;
Thread.Sleep (500);
- Assert ("t2", counter <= c + 6);
+ Assert.IsTrue(bucket.count <= c + 20, "#2");
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);
+
+ }
+
+ [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.IsTrue(b.count == 1);
- counter = 2;
- t1 = new Timer (new TimerCallback (CallbackTestDisposeOnCallback), null, 50, 0);
+ }
+
+ [Test]
+ public void TestDisposeOnCallback ()
+ {
+ 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);
}
}
- private void CallbackTestDispose (object foo)
+ [Test]
+ public void Change_IntInt_Infinite ()
{
- counter++;
+ using (Timer t = new Timer (DoNothing, null, 0, 0)) {
+ t.Change ((int)Timeout.Infinite, (int)Timeout.Infinite);
+ }
}
- private void Callback (object foo)
+ [Test]
+ public void Change_IntInt_MaxValue ()
+ {
+ using (Timer t = new Timer (DoNothing, null, 0, 0)) {
+ t.Change (Int32.MaxValue, Int32.MaxValue);
+ }
+ }
+
+ [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 ()
+ {
+ using (Timer t = new Timer (DoNothing, null, 0, 0)) {
+ t.Change ((long) Timeout.Infinite, (long) Timeout.Infinite);
+ }
+ }
+
+ [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 ()
{
- counter++;
+ using (Timer t = new Timer (DoNothing, null, 0, 0)) {
+ t.Change (TimeSpan.MaxValue, TimeSpan.MaxValue);
+ }
}
- Timer t1;
- int counter;
+ [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));
+ }
+ }
}
}