blob: 7e9fb4bf998958ce842a24ad273dbc792fca645e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Threading;
using Apache.NMS.Util;
using Apache.NMS.ActiveMQ.Threads;
using NUnit.Framework;
namespace Apache.NMS.ActiveMQ.Test
{
[TestFixture]
public class TimerExTest
{
TestData data;
class TestData
{
public object sync = new object();
public int timerCounter = 0;
}
class TimerTestTask : TimerTask
{
int wasRun = 0;
// Should we sleep for 200 ms each run()?
bool sleepInRun = false;
// Should we increment the timerCounter?
bool incrementCount = false;
// Should we terminate the timer at a specific timerCounter?
int terminateCount = -1;
// The timer we belong to
TimerEx timer = null;
TestData data;
public TimerTestTask(TestData data)
{
this.data = data;
}
public TimerTestTask(TimerEx t, TestData data)
{
this.timer = t;
this.data = data;
}
public override void Run()
{
lock(this)
{
wasRun++;
}
if (incrementCount)
{
data.timerCounter++;
}
if (terminateCount == data.timerCounter && timer != null)
{
timer.Cancel();
}
if (sleepInRun)
{
try
{
Thread.Sleep(200);
}
catch (ThreadInterruptedException)
{
}
}
lock(data.sync)
{
Monitor.Pulse(data.sync);
}
}
public int WasRun()
{
lock(this)
{
return wasRun;
}
}
public void SleepInRun(bool sleepInRun)
{
this.sleepInRun = sleepInRun;
}
public void IncrementCount(bool incrementCount)
{
this.incrementCount = incrementCount;
}
public void TerminateCount(int terminateCount)
{
this.terminateCount = terminateCount;
}
}
private void WaitCallbackTask(object arg)
{
TimerTestTask task = arg as TimerTestTask;
task.Run();
}
class SlowThenFastTask : TimerTask
{
int wasRun = 0;
DateTime startedAt;
TimeSpan lastDelta;
public override void Run()
{
if (wasRun == 0)
{
startedAt = DateTime.Now;
}
lastDelta = DateTime.Now -
(startedAt + (TimeSpan.FromMilliseconds(100 * wasRun)));
wasRun++;
if (wasRun == 2)
{
try
{
Thread.Sleep(200);
}
catch (ThreadInterruptedException)
{
}
}
}
public TimeSpan LastDelta
{
get { return lastDelta; }
}
public int WasRun()
{
return wasRun;
}
}
private void Sleep(int milliseconds)
{
try
{
Thread.Sleep(milliseconds);
}
catch (ThreadInterruptedException)
{
}
}
private void Wait(int milliseconds)
{
lock (data.sync)
{
try
{
Monitor.Wait(data.sync, milliseconds);
}
catch (ThreadInterruptedException)
{
}
}
}
[SetUp]
public void SetUp()
{
this.data = new TestData();
}
[Test]
public void TestConstructorBool()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx(true);
TimerTestTask testTask = new TimerTestTask(data);
t.Schedule(testTask, TimeSpan.FromMilliseconds(200));
Wait(1000);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.Run() method not called after 200ms");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestConstructor()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
t.Schedule(testTask, TimeSpan.FromMilliseconds(200));
Wait(1000);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.Run() method not called after 200ms");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestConstructorStringBool()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx("TestConstructorStringBool", true);
TimerTestTask testTask = new TimerTestTask(data);
t.Schedule(testTask, TimeSpan.FromMilliseconds(200));
Wait(1000);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.Run() method not called after 200ms");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestConstructorString()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx("TestConstructorString");
TimerTestTask testTask = new TimerTestTask(data);
t.Schedule(testTask, TimeSpan.FromMilliseconds(200));
Wait(1000);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.Run() method not called after 200ms");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestConstructorThrowsException()
{
try
{
new TimerEx(null, true);
Assert.Fail("NullReferenceException expected");
}
catch (NullReferenceException)
{
//expected
}
try
{
new TimerEx(null, false);
Assert.Fail("NullReferenceException expected");
}
catch (NullReferenceException)
{
//expected
}
}
[Test]
public void TestCancel()
{
TimerEx t = null;
try
{
// Ensure a task throws an InvalidOperationException after cancelled
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
t.Cancel();
bool exception = false;
try
{
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(200));
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception, "Scheduling a task after Timer.Cancel() should throw exception");
// Ensure a task is run but not after cancel
t = new TimerEx();
testTask = new TimerTestTask(data);
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(500));
Wait(1000);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.run() method not called after 200ms");
t.Cancel();
Wait(500);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.run() method should not have been called after cancel");
// Ensure you can call cancel more than once
t = new TimerEx();
testTask = new TimerTestTask(data);
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(500));
Wait(500);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.run() method not called after 200ms");
t.Cancel();
t.Cancel();
t.Cancel();
Wait(500);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.run() method should not have been called after cancel");
// Ensure that a call to cancel from within a timer ensures no more
// run
t = new TimerEx();
testTask = new TimerTestTask(t, data);
testTask.IncrementCount(true);
testTask.TerminateCount(5); // Terminate after 5 runs
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100));
lock (data.sync)
{
try
{
Monitor.Wait(data.sync, 500);
Monitor.Wait(data.sync, 500);
Monitor.Wait(data.sync, 500);
Monitor.Wait(data.sync, 500);
Monitor.Wait(data.sync, 500);
Monitor.Wait(data.sync, 500);
}
catch (ThreadInterruptedException)
{
}
}
Assert.AreEqual(5, testTask.WasRun(),
"TimerTask.run() method should be called 5 times not " + testTask.WasRun());
t.Cancel();
Sleep(200);
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestPurge()
{
TimerEx t = null;
try
{
t = new TimerEx();
Assert.AreEqual(0, t.Purge());
TimerTestTask[] tasks = new TimerTestTask[100];
int[] delayTime = { 50, 80, 20, 70, 40, 10, 90, 30, 60 };
int j = 0;
for (int i = 0; i < 100; i++)
{
tasks[i] = new TimerTestTask(data);
t.Schedule(tasks[i], TimeSpan.FromMilliseconds(delayTime[j++]), TimeSpan.FromMilliseconds(200));
if (j == 9)
{
j = 0;
}
}
for (int i = 0; i < 50; i++)
{
tasks[i].Cancel();
}
Assert.IsTrue(t.Purge() <= 50);
Assert.AreEqual(0, t.Purge());
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleWaitCallbackDateTime()
{
TimerEx t = null;
try
{
// Ensure a TimerEx throws an InvalidOperationException after cancelled
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
DateTime d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.Cancel();
bool exception = false;
try
{
t.Schedule(callback, testTask, d);
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after Timer.Cancel() should throw exception");
// Ensure that the returned task from the WaitCallback schedule method
// cancel the task and prevent it from being run.
t = new TimerEx();
testTask = new TimerTestTask(data);
d = DateTime.Now + TimeSpan.FromMilliseconds(200);
TimerTask scheduled = t.Schedule(callback, testTask, d);
scheduled.Cancel();
Sleep(1000);
Assert.AreEqual(0, testTask.WasRun(), "Cancelled task shouldn't have run.");
// Ensure a TimerEx throws a ArgumentNullException if the task is null
t = new TimerEx();
exception = false;
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
try
{
t.Schedule(null, testTask, d);
}
catch (ArgumentNullException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a null task should throw ArgumentNullException");
t.Cancel();
// Ensure a task is run
t = new TimerEx();
testTask = new TimerTestTask(data);
d = DateTime.Now + TimeSpan.FromMilliseconds(200);
t.Schedule(callback, testTask, d);
Sleep(400);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.run() method not called after 200ms");
t.Cancel();
// Ensure multiple tasks are run
t = new TimerEx();
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.Schedule(callback, testTask, d);
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(150);
t.Schedule(callback, testTask, d);
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(70);
t.Schedule(callback, testTask, d);
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(10);
t.Schedule(callback, testTask, d);
Sleep(400);
Assert.AreEqual(4, data.timerCounter,
"Multiple tasks should have incremented counter 4 times not " + data.timerCounter);
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleWaitCallbackWithDelay()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
t.Schedule(callback, testTask, 200);
Sleep(1000);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.run() method not called after 200ms");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleWaitCallbackWithDelayAsTimeSpan()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
t.Schedule(callback, testTask, TimeSpan.FromMilliseconds(200));
Sleep(1000);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.run() method not called after 200ms");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleWaitCallbackWithDelayAndPeriod()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
t.Schedule(callback, testTask, 200, 100);
Sleep(1000);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method not called at least twice after 1 second sleep");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleWaitCallbackWithDelayAndPeriodTimeSpan()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
t.Schedule(callback, testTask, TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(100));
Sleep(1000);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method not called at least twice after 1 second sleep");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleWaitCallbackWithDateTimePeriod()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
DateTime d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.Schedule(callback, testTask, d, 100);
Sleep(1000);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method not called at least twice after 1 second sleep");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleWaitCallbackWithDateTimePeriodTimeSpan()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
DateTime d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.Schedule(callback, testTask, d, TimeSpan.FromMilliseconds(100));
Sleep(1000);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method not called at least twice after 1 second sleep");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleAtFixedRateWaitCallbackWithDelayPeriod()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
t.ScheduleAtFixedRate(callback, testTask, 200, 100);
Sleep(1000);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method not called at least twice after 1 second sleep");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleAtFixedRateWaitCallbackWithDelayPeriodTimeSpan()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
t.ScheduleAtFixedRate(
callback, testTask, TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(100));
Sleep(1000);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method not called at least twice after 1 second sleep");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleAtFixedRateWaitCallbackWithDateTimePeriod()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
DateTime d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.ScheduleAtFixedRate(callback, testTask, d, 100);
Sleep(1000);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method not called at least twice after 1 second sleep");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleAtFixedRateWaitCallbackWithDateTimePeriodTimeSpan()
{
TimerEx t = null;
try
{
// Ensure a task is run
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
WaitCallback callback = new WaitCallback(WaitCallbackTask);
DateTime d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.ScheduleAtFixedRate(callback, testTask, d, TimeSpan.FromMilliseconds(100));
Sleep(1000);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method not called at least twice after 1 second sleep");
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleTimerTaskDateTime()
{
TimerEx t = null;
try
{
// Ensure a TimerEx throws an InvalidOperationException after cancelled
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
DateTime d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.Cancel();
bool exception = false;
try
{
t.Schedule(testTask, d);
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after Timer.Cancel() should throw exception");
// Ensure a TimerEx throws an InvalidOperationException if task already cancelled
t = new TimerEx();
testTask = new TimerTestTask(data);
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
testTask.Cancel();
exception = false;
try
{
t.Schedule(testTask, d);
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after cancelling it should throw exception");
t.Cancel();
// Ensure a TimerEx throws a ArgumentNullException if the task is null
t = new TimerEx();
exception = false;
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
try
{
t.Schedule(null, d);
}
catch (ArgumentNullException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a null task should throw ArgumentNullException");
t.Cancel();
// Ensure a task is run
t = new TimerEx();
testTask = new TimerTestTask(data);
d = DateTime.Now + TimeSpan.FromMilliseconds(200);
t.Schedule(testTask, d);
Sleep(400);
Assert.AreEqual(1, testTask.WasRun(), "TimerTask.run() method not called after 200ms");
t.Cancel();
// Ensure multiple tasks are run
t = new TimerEx();
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.Schedule(testTask, d);
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(150);
t.Schedule(testTask, d);
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(70);
t.Schedule(testTask, d);
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(10);
t.Schedule(testTask, d);
Sleep(400);
Assert.AreEqual(4, data.timerCounter,
"Multiple tasks should have incremented counter 4 times not " + data.timerCounter);
t.Cancel();
}
finally
{
if (t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleTimerTaskDelay()
{
TimerEx t = null;
try
{
// Ensure a TimerEx throws an InvalidOperationException after cancelled
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
t.Cancel();
bool exception = false;
try
{
t.Schedule(testTask, 100);
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after Timer.Cancel() should throw exception");
// Ensure a TimerEx throws an InvalidOperationException if task already
// cancelled
t = new TimerEx();
testTask = new TimerTestTask(data);
testTask.Cancel();
exception = false;
try
{
t.Schedule(testTask, 100);
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after cancelling it should throw exception");
t.Cancel();
// Ensure a TimerEx throws an ArgumentOutOfRangeException if delay is
// negative
t = new TimerEx();
testTask = new TimerTestTask(data);
exception = false;
try
{
t.Schedule(testTask, -100);
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task with negative delay should throw IllegalArgumentException");
t.Cancel();
// Ensure a TimerEx throws a ArgumentNullException if the task is null
t = new TimerEx();
exception = false;
try
{
t.Schedule(null, 10);
}
catch (ArgumentNullException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a null task should throw ArgumentNullException");
t.Cancel();
// Ensure proper sequence of exceptions
t = new TimerEx();
exception = false;
try
{
t.Schedule(null, -10);
}
catch (ArgumentNullException)
{
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a null task with negative delays should throw IllegalArgumentException first");
t.Cancel();
// Ensure a task is run
t = new TimerEx();
testTask = new TimerTestTask(data);
t.Schedule(testTask, 200);
Sleep(400);
Assert.AreEqual(1, testTask.WasRun(),
"TimerTask.run() method not called after 200ms");
t.Cancel();
// Ensure multiple tasks are run
t = new TimerEx();
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, 100);
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, 150);
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, 70);
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, 10);
Sleep(400);
Assert.AreEqual(4, data.timerCounter,
"Multiple tasks should have incremented counter 4 times not " + data.timerCounter);
t.Cancel();
}
finally
{
if(t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleTimerTaskDelayTimeSpan()
{
TimerEx t = null;
try
{
// Ensure a TimerEx throws an InvalidOperationException after cancelled
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
t.Cancel();
bool exception = false;
try
{
t.Schedule(testTask, TimeSpan.FromMilliseconds(100));
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after Timer.Cancel() should throw exception");
// Ensure a TimerEx throws an InvalidOperationException if task already
// cancelled
t = new TimerEx();
testTask = new TimerTestTask(data);
testTask.Cancel();
exception = false;
try
{
t.Schedule(testTask, TimeSpan.FromMilliseconds(100));
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after cancelling it should throw exception");
t.Cancel();
// Ensure a TimerEx throws an ArgumentOutOfRangeException if delay is
// negative
t = new TimerEx();
testTask = new TimerTestTask(data);
exception = false;
try
{
t.Schedule(testTask, TimeSpan.FromMilliseconds(-100));
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task with negative delay should throw IllegalArgumentException");
t.Cancel();
// Ensure a TimerEx throws a ArgumentNullException if the task is null
t = new TimerEx();
exception = false;
try
{
t.Schedule(null, TimeSpan.FromMilliseconds(10));
}
catch (ArgumentNullException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a null task should throw ArgumentNullException");
t.Cancel();
// Ensure proper sequence of exceptions
t = new TimerEx();
exception = false;
try
{
t.Schedule(null, TimeSpan.FromMilliseconds(-10));
}
catch (ArgumentNullException)
{
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a null task with negative delays should throw IllegalArgumentException first");
t.Cancel();
// Ensure a task is run
t = new TimerEx();
testTask = new TimerTestTask(data);
t.Schedule(testTask, TimeSpan.FromMilliseconds(200));
Sleep(400);
Assert.AreEqual(1, testTask.WasRun(),
"TimerTask.run() method not called after 200ms");
t.Cancel();
// Ensure multiple tasks are run
t = new TimerEx();
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, TimeSpan.FromMilliseconds(100));
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, TimeSpan.FromMilliseconds(150));
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, TimeSpan.FromMilliseconds(70));
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, TimeSpan.FromMilliseconds(10));
Sleep(400);
Assert.AreEqual(4, data.timerCounter,
"Multiple tasks should have incremented counter 4 times not " + data.timerCounter);
t.Cancel();
}
finally
{
if(t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleTimerTaskDelayPeriod()
{
TimerEx t = null;
try
{
// Ensure a TimerEx throws an InvalidOperationException after cancelled
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
t.Cancel();
bool exception = false;
try
{
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100));
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after Timer.Cancel() should throw exception");
// Ensure a TimerEx throws an InvalidOperationException if task already
// cancelled
t = new TimerEx();
testTask = new TimerTestTask(data);
testTask.Cancel();
exception = false;
try
{
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100));
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after cancelling it should throw exception");
t.Cancel();
// Ensure a TimerEx throws an ArgumentOutOfRangeException if delay is negative
t = new TimerEx();
testTask = new TimerTestTask(data);
exception = false;
try
{
t.Schedule(testTask, TimeSpan.FromMilliseconds(-100), TimeSpan.FromMilliseconds(100));
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task with negative delay should throw IllegalArgumentException");
t.Cancel();
// Ensure a TimerEx throws an ArgumentOutOfRangeException if period is negative
t = new TimerEx();
testTask = new TimerTestTask(data);
exception = false;
try
{
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(-100));
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task with negative period should throw IllegalArgumentException");
t.Cancel();
// Ensure a TimerEx throws an ArgumentOutOfRangeException if period is
// zero
t = new TimerEx();
testTask = new TimerTestTask(data);
exception = false;
try
{
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(0));
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task with 0 period should throw IllegalArgumentException");
t.Cancel();
// Ensure a TimerEx throws a ArgumentNullException if the task is null
t = new TimerEx();
exception = false;
try
{
t.Schedule(null, TimeSpan.FromMilliseconds(10), TimeSpan.FromMilliseconds(10));
}
catch (ArgumentNullException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a null task should throw ArgumentNullException");
t.Cancel();
// Ensure proper sequence of exceptions
t = new TimerEx();
exception = false;
try
{
t.Schedule(null, TimeSpan.FromMilliseconds(-10), TimeSpan.FromMilliseconds(-10));
}
catch (ArgumentNullException)
{
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a null task with negative delays should throw ArgumentOutOfRangeException first");
t.Cancel();
// Ensure a task is run at least twice
t = new TimerEx();
testTask = new TimerTestTask(data);
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100));
Sleep(400);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method should have been called at least twice (" + testTask.WasRun() + ")");
t.Cancel();
// Ensure multiple tasks are run
t = new TimerEx();
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100)); // at least 9 times
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, TimeSpan.FromMilliseconds(200), TimeSpan.FromMilliseconds(100)); // at least 7 times
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, TimeSpan.FromMilliseconds(300), TimeSpan.FromMilliseconds(200)); // at least 4 times
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
t.Schedule(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(200)); // at least 4 times
Sleep(1200);
Assert.IsTrue(data.timerCounter >= 24,
"Multiple tasks should have incremented counter 24 times not " + data.timerCounter);
t.Cancel();
}
finally
{
if(t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleTimerTaskDateTimePeriod()
{
TimerEx t = null;
try
{
// Ensure a TimerEx throws an InvalidOperationException after cancelled
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
DateTime d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.Cancel();
bool exception = false;
try
{
t.Schedule(testTask, d, TimeSpan.FromMilliseconds(100));
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after Timer.Cancel() should throw exception");
// Ensure a TimerEx throws an InvalidOperationException if task already cancelled
t = new TimerEx();
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
testTask = new TimerTestTask(data);
testTask.Cancel();
exception = false;
try
{
t.Schedule(testTask, d, TimeSpan.FromMilliseconds(100));
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task after cancelling it should throw exception");
t.Cancel();
// Ensure a TimerEx throws an ArgumentOutOfRangeException if period is
// negative
t = new TimerEx();
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
testTask = new TimerTestTask(data);
exception = false;
try
{
t.Schedule(testTask, d, TimeSpan.FromMilliseconds(-100));
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a task with negative period should throw IllegalArgumentException");
t.Cancel();
// Ensure a TimerEx throws a ArgumentNullException if the task is null
t = new TimerEx();
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
exception = false;
try
{
t.Schedule(null, d, TimeSpan.FromMilliseconds(10));
}
catch (ArgumentNullException)
{
exception = true;
}
Assert.IsTrue(exception,
"Scheduling a null task should throw ArgumentNullException");
t.Cancel();
// Ensure a task is run at least twice
t = new TimerEx();
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
testTask = new TimerTestTask(data);
t.Schedule(testTask, d, TimeSpan.FromMilliseconds(100));
Sleep(800);
Assert.IsTrue( testTask.WasRun() >= 2,
"TimerTask.Run() method should have been called at least twice (" + testTask.WasRun() + ")");
t.Cancel();
// Ensure multiple tasks are run
t = new TimerEx();
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.Schedule(testTask, d, TimeSpan.FromMilliseconds(100)); // at least 9 times
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(200);
t.Schedule(testTask, d, TimeSpan.FromMilliseconds(100)); // at least 7 times
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(300);
t.Schedule(testTask, d, TimeSpan.FromMilliseconds(200)); // at least 4 times
testTask = new TimerTestTask(data);
testTask.IncrementCount(true);
d = DateTime.Now + TimeSpan.FromMilliseconds(400);
t.Schedule(testTask, d, TimeSpan.FromMilliseconds(200)); // at least 4 times
Sleep(3000);
Assert.IsTrue(data.timerCounter >= 24,
"Multiple tasks should have incremented counter 24 times not " + data.timerCounter);
t.Cancel();
}
finally
{
if(t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleAtFixedRateTimerTaskDelayPeriod()
{
TimerEx t = null;
try
{
// Ensure a TimerEx throws an InvalidOperationException after cancelled
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
t.Cancel();
bool exception = false;
try
{
t.ScheduleAtFixedRate(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100));
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"scheduleAtFixedRate after Timer.Cancel() should throw exception");
// Ensure a TimerEx throws an ArgumentOutOfRangeException if delay is
// negative
t = new TimerEx();
testTask = new TimerTestTask(data);
exception = false;
try
{
t.ScheduleAtFixedRate(testTask, TimeSpan.FromMilliseconds(-100), TimeSpan.FromMilliseconds(100));
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"scheduleAtFixedRate with negative delay should throw IllegalArgumentException");
t.Cancel();
// Ensure a TimerEx throws an ArgumentOutOfRangeException if period is
// negative
t = new TimerEx();
testTask = new TimerTestTask(data);
exception = false;
try
{
t.ScheduleAtFixedRate(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(-100));
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"scheduleAtFixedRate with negative period should throw IllegalArgumentException");
t.Cancel();
// Ensure a task is run at least twice
t = new TimerEx();
testTask = new TimerTestTask(data);
t.ScheduleAtFixedRate(testTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100));
Sleep(400);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method should have been called at least twice (" + testTask.WasRun() + ")");
t.Cancel();
// Ensure multiple tasks are run
t = new TimerEx();
SlowThenFastTask slowThenFastTask = new SlowThenFastTask();
// at least 9 times even when asleep
t.ScheduleAtFixedRate(slowThenFastTask, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100));
Sleep(1000);
long lastDelta = (long) slowThenFastTask.LastDelta.TotalMilliseconds;
Assert.IsTrue(lastDelta < 300,
"Fixed Rate Schedule should catch up, but is off by " + lastDelta + " ms");
t.Cancel();
}
finally
{
if(t != null)
{
t.Cancel();
}
}
}
[Test]
public void TestScheduleAtFixedRateTimerTaskDateTimePeriod()
{
TimerEx t = null;
try
{
// Ensure a TimerEx throws an InvalidOperationException after cancelled
t = new TimerEx();
TimerTestTask testTask = new TimerTestTask(data);
t.Cancel();
bool exception = false;
DateTime d = DateTime.Now + TimeSpan.FromMilliseconds(100);
try
{
t.ScheduleAtFixedRate(testTask, d, TimeSpan.FromMilliseconds(100));
}
catch (InvalidOperationException)
{
exception = true;
}
Assert.IsTrue(exception,
"scheduleAtFixedRate after Timer.Cancel() should throw exception");
// Ensure a TimerEx throws an IllegalArgumentException if period is
// negative
t = new TimerEx();
testTask = new TimerTestTask(data);
exception = false;
try
{
t.ScheduleAtFixedRate(testTask, d, TimeSpan.FromMilliseconds(-100));
}
catch (ArgumentOutOfRangeException)
{
exception = true;
}
Assert.IsTrue(exception,
"scheduleAtFixedRate with negative period should throw ArgumentOutOfRangeException");
t.Cancel();
// Ensure a task is run at least twice
t = new TimerEx();
testTask = new TimerTestTask(data);
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
t.ScheduleAtFixedRate(testTask, d, TimeSpan.FromMilliseconds(100));
Sleep(400);
Assert.IsTrue(testTask.WasRun() >= 2,
"TimerTask.run() method should have been called at least twice (" + testTask.WasRun() + ")");
t.Cancel();
// Ensure multiple tasks are run
t = new TimerEx();
SlowThenFastTask slowThenFastTask = new SlowThenFastTask();
d = DateTime.Now + TimeSpan.FromMilliseconds(100);
// at least 9 times even when asleep
t.ScheduleAtFixedRate(slowThenFastTask, d, TimeSpan.FromMilliseconds(100));
Sleep(1000);
long lastDelta = (long) slowThenFastTask.LastDelta.TotalMilliseconds;
Assert.IsTrue(lastDelta < 300,
"Fixed Rate Schedule should catch up, but is off by " + lastDelta + " ms");
t.Cancel();
}
finally
{
if(t != null)
{
t.Cancel();
}
}
}
}
}