/** * Blocks until run has completed at least once. Will throw an exception if runnable does not * run within 10 seconds. */ public void blockTillFinished() { blockTillFinished(DEFAULT_TIMEOUT_PER_RUN, 1); }
/** * 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); }
/** * This function blocks till the first run completes then will return the time until the first * run started it's call. * * @return The amount of time between construction and run being called */ public long getDelayTillFirstRun() { return getDelayTillRun(1); }
/** * This function blocks till the run provided, and * then gets the time between creation and a given run. * * @param runNumber the run count to get delay to * @param timeout timeout to wait for given run count to finish * @return The amount of time between construction and run being called */ public long getDelayTillRun(int runNumber, int timeout) { blockTillFinished(timeout, runNumber); Collections.sort(runTime); return runTime.get(runNumber - 1) - getCreationTime(); }
@Override public final void run() { int startRunningCount = currentRunningCount.incrementAndGet(); runTime.addLast(Clock.accurateForwardProgressingMillis()); try { handleRunStart(); } catch (InterruptedException e) { // ignored, just reset status Thread.currentThread().interrupt(); } finally { if (runDelayInMillis > 0) { TestUtils.sleep(runDelayInMillis); } runCount.incrementAndGet(); try { handleRunFinish(); } finally { ranConcurrent = currentRunningCount.decrementAndGet() != 0 || // must be first to ensure decrement is called ranConcurrent || startRunningCount != 1; } } }
@Test public void invokeTwiceTest() { TestRunnable tr1 = new TestRunnable(); TestRunnable tr2 = new TestRunnable(); Runnable r = InvocationTee.tee(Runnable.class, tr1, null, tr2, null); r.run(); r.run(); assertEquals(2, tr1.getRunCount()); assertEquals(2, tr2.getRunCount()); }
@Test public void consumeAvailableTest() { ExecutorLimiter limiter = getLimiter(PARALLEL_COUNT, true); List<TestRunnable> runnables = new ArrayList<>(PARALLEL_COUNT); for (int i = 0; i < PARALLEL_COUNT; i++) { TestRunnable tr = new TestRunnable(); runnables.add(tr); limiter.waitingTasks.add(limiter.new LimiterRunnableWrapper(tr)); } limiter.consumeAvailable(); // should be fully consumed assertEquals(0, limiter.waitingTasks.size()); Iterator<TestRunnable> it = runnables.iterator(); while (it.hasNext()) { it.next().blockTillFinished(); // throws exception if it does not finish } }
@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 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 scheduleAtFixedRateConcurrentTest() { ScheduledExecutorService scheduler = makeScheduler(2); try { final int periodInMillis = DELAY_TIME; final int runnableSleepTime = DELAY_TIME * 2; TestRunnable tr = new TestRunnable(runnableSleepTime); scheduler.scheduleAtFixedRate(tr, 0, periodInMillis, TimeUnit.MILLISECONDS); // block till we have run enough times to throw exception tr.blockTillFinished(1000 * 10, CYCLE_COUNT); // let all runnables finish readily tr.setRunDelayInMillis(0); // wait a little extra to give time for additional runs TestUtils.sleep(periodInMillis * 2); assertFalse(tr.ranConcurrently()); } finally { scheduler.shutdownNow(); } }
@Test @Override // must be overridden because we can only do this test with one task for the single threaded version public void scheduleAtFixedRateTest() { ScheduledExecutorService scheduler = makeScheduler(1); try { // execute a task first in case there are any initial startup actions which may be slow scheduler.execute(DoNothingRunnable.instance()); TestRunnable tr = new TestRunnable(DELAY_TIME - 1); scheduler.scheduleAtFixedRate(tr, 0, DELAY_TIME, TimeUnit.MILLISECONDS); tr.blockTillFinished((DELAY_TIME * (CYCLE_COUNT - 1)) + 2000, CYCLE_COUNT); long executionDelay = tr.getDelayTillRun(CYCLE_COUNT); assertTrue(executionDelay >= DELAY_TIME * (CYCLE_COUNT - 1)); // should be very timely with a core pool size that matches runnable count assertTrue(executionDelay <= (DELAY_TIME * (CYCLE_COUNT - 1)) + (SLOW_MACHINE ? 2000 : 1000)); } finally { scheduler.shutdownNow(); } } }
@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 executeWithFailureRunnableTest() { SubmitterExecutorFactory factory = getSubmitterExecutorFactory(); try { SubmitterExecutor executor = factory.makeSubmitterExecutor(TEST_QTY, false); List<TestRunnable> runnables = new ArrayList<>(TEST_QTY); for (int i = 0; i < TEST_QTY; i++) { if (i % 2 == 0) { // add a failure runnable executor.execute(new TestRuntimeFailureRunnable()); } TestRunnable tr = new TestRunnable(); executor.execute(tr); runnables.add(tr); } // verify execution Iterator<TestRunnable> it = runnables.iterator(); while (it.hasNext()) { TestRunnable tr = it.next(); tr.blockTillFinished(); assertEquals(1, tr.getRunCount()); } } finally { factory.shutdown(); } }
@Test public void constructorTest() { assertEquals(0, instance.getRunCount()); assertFalse(instance.ranOnce()); assertFalse(instance.ranConcurrently()); assertEquals(0, instance.getRunDelayInMillis()); instance = new TestRunnable(DELAY_TIME); assertEquals(DELAY_TIME, instance.getRunDelayInMillis()); }
public static void addListenerTest(ListenableFuture<?> testFuture) { TestRunnable tr = new TestRunnable(); testFuture.addListener(tr); assertTrue(tr.ranOnce()); tr = new TestRunnable(); testFuture.addListener(tr, null); assertTrue(tr.ranOnce()); tr = new TestRunnable(); testFuture.addListener(tr, new SameThreadSubmitterExecutor()); assertTrue(tr.ranOnce()); }
TestRunnable key2Runnable = new TestRunnable(); distributor.execute(key2, key2Runnable); TestRunnable lastKey1Runnable = lastTestRunnable.get(); key2Runnable.blockTillStarted(); // will throw exception if not started assertFalse(lastKey1Runnable.ranOnce()); } finally { testComplete.set(true);
@Test public void setRunDelayInMillisTest() { assertEquals(0, instance.getRunDelayInMillis()); instance.setRunDelayInMillis(DELAY_TIME); assertEquals(DELAY_TIME, instance.getRunDelayInMillis()); }
@Test public void scheduleTest() { SubmitterSchedulerFactory factory = getSubmitterSchedulerFactory(); try { SubmitterScheduler scheduler = factory.makeSubmitterScheduler(TEST_QTY, true); List<TestRunnable> runnables = new ArrayList<>(TEST_QTY); for (int i = 0; i < TEST_QTY; i++) { TestRunnable tr = new TestRunnable(); scheduler.schedule(tr, DELAY_TIME); runnables.add(tr); } // verify execution and execution times Iterator<TestRunnable> it = runnables.iterator(); while (it.hasNext()) { TestRunnable tr = it.next(); long executionDelay = tr.getDelayTillFirstRun(); assertTrue(executionDelay >= DELAY_TIME); // should be very timely with a core pool size that matches runnable count assertTrue(executionDelay <= (DELAY_TIME + (SLOW_MACHINE ? 2000 : 1000))); assertEquals(1, tr.getRunCount()); } } finally { factory.shutdown(); } }
@Test public void runWithDelay() { int runCount = TEST_QTY / 2; instance.setRunDelayInMillis(DELAY_TIME); long startTime = Clock.accurateForwardProgressingMillis(); for (int i = 0; i < runCount; i++) { instance.run(); } long endTime = Clock.accurateForwardProgressingMillis(); assertTrue(endTime - startTime >= ((DELAY_TIME * runCount)- ALLOWED_VARIANCE)); }
tr.blockTillFinished(1000 * 10, runCountTillException); assertEquals(runCountTillException, tr.getRunCount()); } finally { scheduler.shutdownNow();