/** * Blocks until run has been called at least once. Will throw an exception if run is not called * within 10 seconds. */ public void blockTillStarted() { blockTillStarted(DEFAULT_TIMEOUT_PER_RUN); }
/** * Blocks until run has been called at least once. Will throw an exception if run is not called * within 10 seconds. */ public void blockTillStarted() { blockTillStarted(DEFAULT_TIMEOUT_PER_RUN); }
@Test public void awaitTerminationTest() throws InterruptedException { ScheduledExecutorService scheduler = makeScheduler(THREAD_COUNT); try { assertFalse(scheduler.isTerminated()); TestRunnable tr = new TestRunnable(DELAY_TIME * 2); long start = Clock.accurateForwardProgressingMillis(); scheduler.execute(tr); tr.blockTillStarted(); scheduler.shutdown(); scheduler.awaitTermination(1000, TimeUnit.MILLISECONDS); long stop = Clock.accurateForwardProgressingMillis(); assertTrue(stop - start >= (DELAY_TIME * 2) - 10); } finally { scheduler.shutdownNow(); } }
@Test public void isTerminatedShortTest() { final ScheduledExecutorService scheduler = makeScheduler(THREAD_COUNT); try { assertFalse(scheduler.isTerminated()); TestRunnable tr = new TestRunnable(); scheduler.execute(tr); tr.blockTillStarted(); scheduler.shutdownNow(); tr.blockTillFinished(); new TestCondition(() -> scheduler.isTerminated()).blockTillTrue(1000); } finally { scheduler.shutdownNow(); } }
@Test public void blockTillAvailableExecuteTest() throws InterruptedException, TimeoutException { final AsyncVerifier av = new AsyncVerifier(); TestRunnable tickRunnable = new TestRunnable() { @Override public void handleRunStart() { try { int runCount = scheduler.blockingTick(null); // should block av.assertEquals(1, runCount); av.signalComplete(); } catch (InterruptedException e) { av.fail(e); } } }; new Thread(tickRunnable).start(); // should be blocked waiting for task now tickRunnable.blockTillStarted(); TestRunnable testTask = new TestRunnable(); scheduler.execute(testTask); testTask.blockTillFinished(); // should run without issue av.waitForTest(); // our parent thread should finish quickly }
@Test public void isTerminatedLongTest() { final ScheduledExecutorService scheduler = makeScheduler(THREAD_COUNT); try { final int sleepTime = 100; assertFalse(scheduler.isTerminated()); TestRunnable tr = new TestRunnable(sleepTime); scheduler.execute(tr); tr.blockTillStarted(); scheduler.shutdownNow(); tr.blockTillFinished(); new TestCondition(() -> scheduler.isTerminated()).blockTillTrue(1000); } finally { scheduler.shutdownNow(); } }
@Test public void shutdownRecurringTest() { final SingleThreadScheduler sts = new SingleThreadScheduler(); TestRunnable tr = new TestRunnable(); sts.scheduleWithFixedDelay(tr, 0, 0); tr.blockTillStarted(); sts.shutdown(); new TestCondition(() -> ! sts.sManager.execThread.isAlive()).blockTillTrue(); }
@Test public void increasePoolSizeWithWaitingTaskTest() { PrioritySchedulerServiceFactory factory = getPrioritySchedulerFactory(); PriorityScheduler scheduler = factory.makePriorityScheduler(1); BlockingTestRunnable btr = new BlockingTestRunnable(); try { scheduler.execute(btr); btr.blockTillStarted(); // all these runnables should be blocked List<TestRunnable> executedRunnables = executeTestRunnables(scheduler, 0); // this should allow the waiting test runnables to quickly execute scheduler.setPoolSize(Math.max(2, TEST_QTY / 2)); Iterator<TestRunnable> it = executedRunnables.iterator(); while (it.hasNext()) { it.next().blockTillStarted(); // will throw exception if not ran } } finally { btr.unblock(); factory.shutdown(); } }
@Test public void isolatedPoolTest() { int testQty = 100; List<BlockingTestRunnable> blockingRunnables = new ArrayList<>(testQty); try { SubmitterExecutor executor = CentralThreadlyPool.isolatedTaskPool(); for (int i = 0; i < testQty; i++) { BlockingTestRunnable btr = new BlockingTestRunnable(); blockingRunnables.add(btr); executor.execute(btr); } for (BlockingTestRunnable btr : blockingRunnables) { btr.blockTillStarted(); } // verify we can still execute on pool with existing threads TestRunnable tr = new TestRunnable(); CentralThreadlyPool.lowPriorityPool().execute(tr); tr.blockTillStarted(); } finally { for (BlockingTestRunnable btr : blockingRunnables) { btr.unblock(); } } } }
@Test public void scheduleNoDelayTest() { SubmitterSchedulerFactory factory = getSubmitterSchedulerFactory(); try { SubmitterScheduler scheduler = factory.makeSubmitterScheduler(TEST_QTY, true); TestRunnable tr = new TestRunnable(); scheduler.schedule(tr, 0); tr.blockTillStarted(); assertEquals(1, tr.getRunCount()); } finally { factory.shutdown(); } }
@Test public void scheduleLaterThenSoonerTest() { // This test is focused around the scheduling defect fixed in 4.4.1 // The condition hit was where we would park for one scheduled task, then a future task // would not get executed in time because the first parked thread was not woken up PrioritySchedulerServiceFactory factory = getPrioritySchedulerFactory(); final PriorityScheduler scheduler = factory.makePriorityScheduler(2); try { // schedule one task a ways out scheduler.schedule(DoNothingRunnable.instance(), 1000 * 60 * 10); // ensure first thread has blocked new TestCondition(() -> scheduler.workerPool.idleWorker.get() != null).blockTillTrue(); // start second thread scheduler.prestartAllThreads(); // ensure second thread has blocked new TestCondition(() -> scheduler.workerPool.idleWorker.get().nextIdleWorker != null) .blockTillTrue(); // schedule soon to run task TestRunnable tr = new TestRunnable(); scheduler.schedule(tr, 10); tr.blockTillStarted(); } finally { factory.shutdown(); } }
private static void verifyGuaranteedThreadProtection(List<SchedulerService> executors, int expectedLimit) { List<BlockingTestRunnable> blockingRunnables = new ArrayList<>(expectedLimit); try { for (SchedulerService executor : executors) { for (int i = 0; i < expectedLimit; i++) { BlockingTestRunnable btr = new BlockingTestRunnable(); blockingRunnables.add(btr); executor.execute(btr); } for (BlockingTestRunnable btr : blockingRunnables) { btr.blockTillStarted(); } // verify additional tasks would queue int startingQueueCount = executor.getQueuedTaskCount(); executor.execute(DoNothingRunnable.instance()); TestUtils.sleep(DELAY_TIME); assertEquals(startingQueueCount + 1, executor.getQueuedTaskCount()); // verify we can still execute on pool with existing threads TestRunnable tr = new TestRunnable(); CentralThreadlyPool.lowPriorityPool().execute(tr); tr.blockTillStarted(); } } finally { for (BlockingTestRunnable btr : blockingRunnables) { btr.unblock(); } } }
@Test public void getCurrentPoolSizeTest() { PrioritySchedulerServiceFactory factory = getPrioritySchedulerFactory(); PriorityScheduler scheduler = factory.makePriorityScheduler(1); try { // verify nothing at the start assertEquals(0, scheduler.getCurrentPoolSize()); TestRunnable tr = new TestRunnable(); scheduler.execute(tr); tr.blockTillStarted(); // wait for execution assertEquals(1, scheduler.getCurrentPoolSize()); } finally { factory.shutdown(); } }
@Test public void shutdownRecurringTest() { PrioritySchedulerServiceFactory factory = getPrioritySchedulerFactory(); try { final PriorityScheduler scheduler = factory.makePriorityScheduler(1); TestRunnable tr = new TestRunnable(); scheduler.scheduleWithFixedDelay(tr, 0, 0); tr.blockTillStarted(); scheduler.shutdown(); new TestCondition(() -> scheduler.workerPool.isShutdownFinished() && scheduler.getCurrentPoolSize() == 0).blockTillTrue(); } finally { factory.shutdown(); } }
@Test public void awaitTerminationTest() throws InterruptedException { PrioritySchedulerServiceFactory factory = getPrioritySchedulerFactory(); try { PriorityScheduler scheduler = factory.makePriorityScheduler(1); TestRunnable tr = new TestRunnable(DELAY_TIME * 2); long start = Clock.accurateForwardProgressingMillis(); scheduler.execute(tr); tr.blockTillStarted(); scheduler.shutdown(); scheduler.awaitTermination(); long stop = Clock.accurateForwardProgressingMillis(); assertTrue(stop - start >= (DELAY_TIME * 2) - 10); } finally { factory.shutdown(); } }
@Test public void awaitTerminationTimeoutTest() throws InterruptedException { PrioritySchedulerServiceFactory factory = getPrioritySchedulerFactory(); try { PriorityScheduler scheduler = factory.makePriorityScheduler(1); TestRunnable tr = new TestRunnable(DELAY_TIME * 2); long start = Clock.accurateForwardProgressingMillis(); scheduler.execute(tr); tr.blockTillStarted(); scheduler.shutdown(); assertTrue(scheduler.awaitTermination(DELAY_TIME * 10)); long stop = Clock.accurateForwardProgressingMillis(); assertTrue(stop - start >= (DELAY_TIME * 2) - 10); } finally { factory.shutdown(); } }
@Test public void awaitTerminationTimeoutExcededTest() throws InterruptedException { PrioritySchedulerServiceFactory factory = getPrioritySchedulerFactory(); try { PriorityScheduler scheduler = factory.makePriorityScheduler(1); TestRunnable tr = new TestRunnable(DELAY_TIME * 100); scheduler.execute(tr); tr.blockTillStarted(); scheduler.shutdown(); long start = Clock.accurateForwardProgressingMillis(); assertFalse(scheduler.awaitTermination(DELAY_TIME)); long stop = Clock.accurateForwardProgressingMillis(); assertTrue(stop - start >= DELAY_TIME); } finally { factory.shutdown(); } }
@Test public void taskExceptionTest() { Integer key = 1; TestExceptionHandler teh = new TestExceptionHandler(); final RuntimeException testException = new SuppressedStackRuntimeException(); ExceptionUtils.setDefaultExceptionHandler(teh); TestRunnable exceptionRunnable = new TestRuntimeFailureRunnable(testException); TestRunnable followRunnable = new TestRunnable(); distributor.execute(key, exceptionRunnable); distributor.execute(key, followRunnable); exceptionRunnable.blockTillFinished(); followRunnable.blockTillStarted(); // verify that it ran despite the exception assertEquals(1, teh.getCallCount()); assertEquals(testException, teh.getLastThrowable()); }
private void removeRecurringRunnableTest(TaskPriority priority) { int runFrequency = 1; AbstractPrioritySchedulerFactory factory = getAbstractPrioritySchedulerFactory(); try { AbstractPriorityScheduler scheduler = factory.makeAbstractPriorityScheduler(1); TestRunnable removedTask = new TestRunnable(); TestRunnable keptTask = new TestRunnable(); scheduler.scheduleWithFixedDelay(removedTask, 0, runFrequency, priority); scheduler.scheduleWithFixedDelay(keptTask, 0, runFrequency, priority); removedTask.blockTillStarted(); assertFalse(scheduler.remove(new TestRunnable())); assertTrue(scheduler.remove(removedTask)); // verify removed is no longer running, and the kept task continues to run int keptRunCount = keptTask.getRunCount(); int runCount = removedTask.getRunCount(); TestUtils.sleep(runFrequency * 10); // may be +1 if the task was running while the remove was called assertTrue(removedTask.getRunCount() == runCount || removedTask.getRunCount() == runCount + 1); assertTrue(keptTask.getRunCount() >= keptRunCount); } finally { factory.shutdown(); } }