/** * This is to provide a convince when advancing the scheduler forward an explicit amount of time. * Where tick accepts an absolute time, this accepts an amount of time to advance forward. That * way the user does not have to track the current time. * * @param timeInMillis amount in milliseconds to advance the scheduler forward * @return quantity of tasks run during this tick call */ public int advance(long timeInMillis) { return advance(timeInMillis, null); }
@Test public void executeHighPriorityTest() { TestableScheduler highScheduler = new TestableScheduler(); TestableScheduler lowScheduler = new TestableScheduler(); PriorityDelegatingScheduler delegatingScheduler = new PriorityDelegatingScheduler(highScheduler, lowScheduler, null, TaskPriority.Starvable); delegatingScheduler.execute(DoNothingRunnable.instance(), TaskPriority.High); assertEquals(1, highScheduler.tick()); assertEquals(0, lowScheduler.tick()); }
@Test public void clearTasksTest() { assertTrue(scheduler.clearTasks().isEmpty()); TestRunnable executeTask = new TestRunnable(); TestRunnable scheduleTask = new TestRunnable(); scheduler.execute(executeTask); scheduler.schedule(scheduleTask, 1); List<Runnable> result = scheduler.clearTasks(); assertEquals(2, result.size()); assertTrue(result.contains(executeTask)); assertTrue(result.contains(scheduleTask)); } }
@Test public void advanceTest() { long now = scheduler.getLastTickTime(); scheduler.advance(1000); assertEquals(now + 1000, scheduler.getLastTickTime()); }
@Test (expected = IllegalArgumentException.class) public void tickFail() { scheduler.tick(scheduler.getLastTickTime() - 1); fail("Exception should have been thrown"); }
@Test public void getDelayTillNextTaskTest() { assertEquals(Long.MAX_VALUE, scheduler.getDelayTillNextTask()); scheduler.schedule(DoNothingRunnable.instance(), 1); assertEquals(1, scheduler.getDelayTillNextTask()); scheduler.execute(DoNothingRunnable.instance()); assertEquals(0, scheduler.getDelayTillNextTask()); }
/** * Progresses tasks for the current time. This will block as it runs as many scheduled or * waiting tasks as possible. This call will NOT block if no task are currently ready to run. * <p> * If any tasks throw a {@link RuntimeException}, they will be bubbled up to this tick call. * Any tasks past that task will not run till the next call to tick. So it is important that * the implementor handle those exceptions. * * @return quantity of tasks run during this tick call */ public int tick() { return tick(null); }
TestRunnable initialDelay = new TestRunnable(); assertFalse(scheduler.remove(immediateRun)); scheduler.scheduleWithFixedDelay(immediateRun, 0, delay); assertTrue(scheduler.remove(immediateRun)); scheduler.scheduleWithFixedDelay(immediateRun, 0, delay); scheduler.scheduleWithFixedDelay(initialDelay, delay, delay); assertEquals(1, scheduler.tick()); assertTrue(scheduler.remove(immediateRun)); assertEquals(1, scheduler.advance(delay)); assertEquals(0, scheduler.tick(scheduler.getLastTickTime())); // should not execute anything
scheduler.scheduleWithFixedDelay(immediateRun, 0, delay); scheduler.scheduleWithFixedDelay(initialDelay, delay, delay); } else { scheduler.scheduleAtFixedRate(immediateRun, 0, delay); scheduler.scheduleAtFixedRate(initialDelay, delay, delay); assertEquals(1, scheduler.tick()); assertEquals(2, scheduler.advance(delay)); assertEquals(2, scheduler.advance(delay)); assertEquals(0, scheduler.tick(scheduler.getLastTickTime())); // should not execute anything
@Test public void submitScheduledCallableTest() { long scheduleDelay = 1000 * 10; TestCallable submitRun = new TestCallable(); TestCallable scheduleRun = new TestCallable(); Future<?> future = scheduler.submit(submitRun); assertNotNull(future); future = scheduler.submitScheduled(scheduleRun, scheduleDelay); assertNotNull(future); assertEquals(1, scheduler.tick()); assertTrue(submitRun.isDone()); // should have run assertFalse(scheduleRun.isDone()); // should NOT have run yet assertEquals(1, scheduler.advance(scheduleDelay)); assertTrue(scheduleRun.isDone()); // should have run assertEquals(0, scheduler.advance(scheduleDelay)); // should not execute anything }
@Test public void scheduleRunnableTest() { long scheduleDelay = 1000 * 10; TestRunnable executeRun = new TestRunnable(); TestRunnable scheduleRun = new TestRunnable(); scheduler.schedule(scheduleRun, scheduleDelay); scheduler.execute(executeRun); assertEquals(1, scheduler.tick()); assertEquals(1, executeRun.getRunCount()); // should have run assertEquals(0, scheduleRun.getRunCount()); // should NOT have run yet assertEquals(1, scheduler.advance(scheduleDelay)); assertEquals(1, executeRun.getRunCount()); // should NOT have run again assertEquals(1, scheduleRun.getRunCount()); // should have run assertEquals(scheduler.advance(scheduleDelay), 0); // should not execute anything assertEquals(1, executeRun.getRunCount()); // should NOT have run again assertEquals(1, scheduleRun.getRunCount()); // should NOT have run again }
@Test public void runOnExecutorAfterSignaledTest() { TestReschedulingOperation testOp = new TestReschedulingOperation(scheduler, false); assertEquals(0, scheduler.advance(SCHEDULE_DELAY)); testOp.signalToRun(); // should run once, but not again assertEquals(1, scheduler.tick()); assertEquals(0, scheduler.advance(SCHEDULE_DELAY)); assertEquals(0, scheduler.getQueuedTaskCount()); testOp.signalToRun(); // should run again, but not again assertEquals(1, scheduler.tick()); assertEquals(0, scheduler.advance(SCHEDULE_DELAY)); assertEquals(0, scheduler.getQueuedTaskCount()); assertEquals(2, testOp.tr.getRunCount()); }
@Test public void runnableScheduleWhileFirstRunOnSchedulerTest() throws Exception { int scheduleDelayMillis = 10; TestableScheduler scheduler = new TestableScheduler(); TestRunnable tr = new TestRunnable(); ListenableFuture<?> f = FutureUtils.scheduleWhile(scheduler, scheduleDelayMillis, true, tr, () -> tr.getRunCount() < 2); assertFalse(f.isDone()); assertEquals(1, scheduler.tick()); // first run async assertFalse(f.isDone()); assertEquals(1, scheduler.advance(scheduleDelayMillis)); assertTrue(f.isDone()); assertNull(f.get()); // verify no error state }
@Test public void tickHandlesRuntimeExceptionTest() { RuntimeException failure = new SuppressedStackRuntimeException(); final AtomicReference<Throwable> handledException = new AtomicReference<>(null); scheduler.execute(new TestRuntimeFailureRunnable(failure)); int runCount = scheduler.tick(new ExceptionHandler() { @Override public void handleException(Throwable thrown) { handledException.set(thrown); } }); assertEquals(1, runCount); assertTrue(handledException.get() == failure); }
@Test public void advanceHandlesRuntimeExceptionTest() { RuntimeException failure = new SuppressedStackRuntimeException(); final AtomicReference<Throwable> handledException = new AtomicReference<>(null); scheduler.execute(new TestRuntimeFailureRunnable(failure)); int runCount = scheduler.advance(10, new ExceptionHandler() { @Override public void handleException(Throwable thrown) { handledException.set(thrown); } }); assertEquals(1, runCount); assertTrue(handledException.get() == failure); }
@Test public void runOnSchedulerAfterSignaledTest() { TestReschedulingOperation testOp = new TestReschedulingOperation(scheduler, SCHEDULE_DELAY, false); assertEquals(0, scheduler.advance(SCHEDULE_DELAY)); testOp.signalToRun(); // should run once, but not again assertEquals(1, scheduler.advance(SCHEDULE_DELAY)); assertEquals(0, scheduler.advance(SCHEDULE_DELAY)); assertEquals(0, scheduler.getQueuedTaskCount()); testOp.signalToRun(); // should run again, but not again assertEquals(1, scheduler.advance(SCHEDULE_DELAY)); assertEquals(0, scheduler.advance(SCHEDULE_DELAY)); assertEquals(0, scheduler.getQueuedTaskCount()); assertEquals(2, testOp.tr.getRunCount()); }
@Test public void submitScheduledHighPriorityTest() { TestableScheduler highScheduler = new TestableScheduler(); TestableScheduler lowScheduler = new TestableScheduler(); PriorityDelegatingScheduler delegatingScheduler = new PriorityDelegatingScheduler(highScheduler, lowScheduler, null, TaskPriority.Starvable); delegatingScheduler.submitScheduled(DoNothingRunnable.instance(), 100, TaskPriority.High); assertEquals(1, highScheduler.advance(100)); assertEquals(0, lowScheduler.advance(100)); }
@Test public void hasTaskReadyToRunTest() { assertFalse(scheduler.hasTaskReadyToRun()); scheduler.schedule(DoNothingRunnable.instance(), 1); assertFalse(scheduler.hasTaskReadyToRun()); scheduler.execute(DoNothingRunnable.instance()); assertTrue(scheduler.hasTaskReadyToRun()); }
@Before public void setup() { executor = new TestableScheduler(); scheduler = new TestableScheduler(); delegator = new SchedulerExecutorDelegator(executor, scheduler); }