| /* |
| * 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(); |
| } |
| } |
| } |
| } |
| } |
| |