diff options
Diffstat (limited to 'framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimerTest.java')
-rw-r--r-- | framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimerTest.java | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimerTest.java b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimerTest.java new file mode 100644 index 00000000..b8e1e85e --- /dev/null +++ b/framework/src/onos/utils/misc/src/test/java/org/onlab/util/ManuallyAdvancingTimerTest.java @@ -0,0 +1,263 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed 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. + */ + +package org.onlab.util; + +import com.google.common.collect.Lists; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Date; +import java.util.TimerTask; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.onlab.junit.TestTools.delay; + +/** + * Testing class for manually advancing timer. + */ +public class ManuallyAdvancingTimerTest { + + private ManuallyAdvancingTimer timer; + + /* Generates unique id's for TestTasks */ + private AtomicInteger idGenerator; + + /* Tracks TestTasks in order of creation, tasks are automatically added at creation. */ + private ArrayList<TestTask> taskList; + + /* Total number of tasks run */ + private AtomicInteger tasksRunCount; + + // FIXME if this class fails first try increasing the real time delay to account for heavy system load. + private static final int REAL_TIME_DELAY = 1; + + /** + * Sets up the testing environment. + */ + @Before + public void setup() { + timer = new ManuallyAdvancingTimer(); + idGenerator = new AtomicInteger(1); + tasksRunCount = new AtomicInteger(0); + taskList = Lists.newArrayList(); + } + + /** + * Tests the one time schedule with delay. + * + * @throws Exception throws an exception if the test fails + */ + @Test + public void testScheduleByDelay() throws Exception { + /* Test scheduling in the future as normal. */ + timer.schedule(new TestTask(), 10); + timer.advanceTimeMillis(5); + assertFalse(taskList.get(0).hasRun()); + timer.advanceTimeMillis(10, REAL_TIME_DELAY); + assertTrue(taskList.get(0).hasRun()); + + /* Test scheduling with negative numbers */ + timer.schedule(new TestTask(), -10); + timer.advanceTimeMillis(5); + assertFalse(taskList.get(1).hasRun()); + timer.advanceTimeMillis(10, REAL_TIME_DELAY); + assertTrue(taskList.get(1).hasRun()); + + /* Reset list, counter and timer for next test */ + taskList.clear(); + idGenerator.set(1); + tasksRunCount.set(0); + + for (int i = 0; i < 50; i++) { + timer.schedule(new TestTask(), i); + } + /* Test that a task scheduled for present is run and not placed in the queue */ + assertEquals("Only the first task should have run.", 1, tasksRunCount.get()); + + for (int i = 2; i <= 50; i++) { + timer.advanceTimeMillis(1, REAL_TIME_DELAY); + assertEquals("One task should be executed per loop", i, tasksRunCount.get()); + } + /* Below tests ordered insertion, this will only be done once, it is the same for all schedule methods. */ + + tasksRunCount.set(0); + + for (int i = 0; i < 10; i++) { + timer.schedule(new TestTask(), 500); + } + + assertEquals("No new tasks should have been run since run count reset.", 0, tasksRunCount.get()); + timer.schedule(new TestTask(), 10); + assertEquals("No new tasks should have been run since run count reset.", 0, tasksRunCount.get()); + timer.advanceTimeMillis(10, REAL_TIME_DELAY); + assertEquals("One new tasks should have been run since run count reset.", 1, tasksRunCount.get()); + timer.advanceTimeMillis(510, REAL_TIME_DELAY); + assertEquals("Eleven new tasks should have been run since run count reset.", 11, tasksRunCount.get()); + } + + /** + * Tests scheduling for a particular date or time which may be in the past. + * + * @throws Exception throws an exception if the test fails + */ + @Test + public void testScheduleByDate() throws Exception { + /* Tests basic scheduling for future times. */ + timer.schedule(new TestTask(), new Date(10)); + timer.advanceTimeMillis(5); + assertFalse(taskList.get(0).hasRun()); + timer.advanceTimeMillis(10, REAL_TIME_DELAY); + assertTrue(taskList.get(0).hasRun()); + + /* Test scheduling with past times numbers */ + timer.schedule(new TestTask(), new Date(0)); + delay(REAL_TIME_DELAY); + assertTrue(taskList.get(1).hasRun()); + + /* Tests cancellation on non-periodic events */ + TestTask task = new TestTask(); + timer.schedule(task, new Date(timer.currentTimeInMillis() + 10)); + task.cancel(); + timer.advanceTimeMillis(12, REAL_TIME_DELAY); + assertFalse(task.hasRun()); + + } + + /** + * Test scheduling beginning after a delay and recurring periodically. + * + * @throws Exception throws an exception if the test fails + */ + @Test + public void testScheduleByDelayPeriodic() throws Exception { + /* Test straightforward periodic execution */ + timer.schedule(new TestTask(), 0, 10); + delay(REAL_TIME_DELAY); + assertEquals("Task should have run once when added.", 1, taskList.get(0).timesRun()); + + /* Tests whether things that are not added to the queue are scheduled for future executions (ones which execute + immediately on add). */ + timer.advanceTimeMillis(10, REAL_TIME_DELAY); + assertEquals("Task should have run once when added.", 2, taskList.get(0).timesRun()); + + /* Tests whether cancellation works on periodic events. */ + taskList.get(0).cancel(); + + timer.advanceTimeMillis(10, REAL_TIME_DELAY); + assertEquals("The task should not have run another time.", 2, taskList.get(0).timesRun()); + + TestTask task = new TestTask(); + timer.schedule(task, 0, 10); + timer.advanceTimeMillis(100, REAL_TIME_DELAY); + assertEquals("Should have run immeditaley and subsequently once during the larger skip", task.timesRun(), 2); + + } + + /** + * Test scheduling beginning at a specified date and recurring periodically. + * + * @throws Exception throws an exception if the test fails + */ + @Test + public void testScheduleByDatePeriodic() throws Exception { + /* Test straightforward periodic execution */ + timer.schedule(new TestTask(), new Date(timer.currentTimeInMillis()), 10); + delay(REAL_TIME_DELAY); + assertEquals("Task should have run once when added.", 1, taskList.get(0).timesRun()); + + /* Tests whether things that are not added to the queue are scheduled for future executions (ones which execute + immediately on add). */ + timer.advanceTimeMillis(10, REAL_TIME_DELAY); + assertEquals("Task should have run once when added.", 2, taskList.get(0).timesRun()); + + /* Tests whether cancellation works on periodic events. */ + taskList.get(0).cancel(); + + timer.advanceTimeMillis(10, REAL_TIME_DELAY); + assertEquals("The task should not have run another time.", 2, taskList.get(0).timesRun()); + + TestTask task = new TestTask(); + timer.schedule(task, new Date(timer.currentTimeInMillis()), 10); + timer.advanceTimeMillis(100, REAL_TIME_DELAY); + assertEquals("Should have run immediately and subsequently once during the larger skip", task.timesRun(), 2); + } + + /* Schedule at fixed rate runs exactly like the two scheduling methods just tested so tests are not included */ + + /** + * Timer task with added functions to make it better for testing. + */ + private class TestTask extends TimerTask { + + /* Remains true once the task has been run at least once */ + private boolean hasRun; + + /* Unique id per event. */ + private int id; + + /* Specifies the number of times an event has run */ + private int timesRun; + + /** + * Constructor initializes id, timesRun, and id fields. + */ + public TestTask() { + id = idGenerator.getAndIncrement(); + timesRun = 0; + hasRun = false; + taskList.add(this); + } + + @Override + public void run() { + this.hasRun = true; + tasksRunCount.incrementAndGet(); + timesRun++; + } + + /** + * Returns whether this event has run. + * + * @return true if the event has run, false otherwise. + */ + public boolean hasRun() { + return hasRun; + } + + /** + * Returns the number of times this task has run. + * + * @return an int representing the number of times this task has been run + */ + public int timesRun() { + return timesRun; + } + + /** + * Returns the unique identifier of this task. + * + * @return a unique integer identifier + */ + public int getId() { + return id; + } + } +}
\ No newline at end of file |