@Test public void testShutdownLeavesJobRunning() throws InterruptedException { OutOfBandScheduledExecutor scheduler = new OutOfBandScheduledExecutor(); ExecutorService worker = Executors.newSingleThreadExecutor(); try { PartitionedScheduledExecutor executor = new PartitionedScheduledExecutor(scheduler, worker); final Semaphore semaphore = new Semaphore(0); executor.execute( new Runnable() { @Override public void run() { semaphore.acquireUninterruptibly(); } }); executor.shutdown(); assertThat(executor.awaitTermination(100, MILLISECONDS), is(false)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(false)); semaphore.release(); assertThat(executor.awaitTermination(2, MINUTES), is(true)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(true)); assertThat(semaphore.availablePermits(), is(0)); } finally { worker.shutdown(); } }
@Test public void testScheduledTasksRunOnDeclaredPool() throws InterruptedException, ExecutionException { OutOfBandScheduledExecutor scheduler = new OutOfBandScheduledExecutor(); ExecutorService worker = Executors.newSingleThreadExecutor( new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r, "testScheduledTasksRunOnDeclaredPool"); } }); try { PartitionedScheduledExecutor executor = new PartitionedScheduledExecutor(scheduler, worker); ScheduledFuture<Thread> future = executor.schedule( new Callable<Thread>() { @Override public Thread call() { return Thread.currentThread(); } }, 0, MILLISECONDS); assertThat(waitFor(future).getName(), is("testScheduledTasksRunOnDeclaredPool")); executor.shutdown(); } finally { worker.shutdown(); } }
@Test public void testTerminationAfterShutdownWaitsForDelayedTask() throws InterruptedException { OutOfBandScheduledExecutor scheduler = new OutOfBandScheduledExecutor(); ExecutorService worker = Executors.newSingleThreadExecutor(); try { PartitionedScheduledExecutor executor = new PartitionedScheduledExecutor(scheduler, worker); ScheduledFuture<?> future = executor.schedule( new Runnable() { @Override public void run() { // no-op } }, 200, MILLISECONDS); executor.shutdown(); assertThat(executor.awaitTermination(30, SECONDS), is(true)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(true)); assertThat(future.isDone(), is(true)); } finally { worker.shutdown(); } }
@Test public void testFixedDelayPeriodicTaskIsCancelledByShutdown() throws InterruptedException { OutOfBandScheduledExecutor scheduler = new OutOfBandScheduledExecutor(); ExecutorService worker = Executors.newSingleThreadExecutor(); try { PartitionedScheduledExecutor executor = new PartitionedScheduledExecutor(scheduler, worker); ScheduledFuture<?> future = executor.scheduleWithFixedDelay( new Runnable() { @Override public void run() { Assert.fail("Should not run!"); } }, 2, 1, MINUTES); executor.shutdown(); assertThat(executor.awaitTermination(30, SECONDS), is(true)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(true)); assertThat(future.isCancelled(), is(true)); } finally { worker.shutdown(); } }
@Test public void testShutdownOfIdleExecutor() throws InterruptedException { OutOfBandScheduledExecutor scheduler = new OutOfBandScheduledExecutor(); ExecutorService worker = Executors.newCachedThreadPool(); PartitionedScheduledExecutor executor = new PartitionedScheduledExecutor(scheduler, worker); executor.shutdown(); assertThat(executor.isShutdown(), is(true)); assertThat(executor.awaitTermination(2, TimeUnit.MINUTES), is(true)); assertThat(executor.isTerminated(), is(true)); }
@Test public void testQueuedJobRunsAfterShutdown() throws InterruptedException { OutOfBandScheduledExecutor scheduler = new OutOfBandScheduledExecutor(); ExecutorService worker = Executors.newSingleThreadExecutor(); try { PartitionedScheduledExecutor executor = new PartitionedScheduledExecutor(scheduler, worker); final Semaphore jobSemaphore = new Semaphore(0); final Semaphore testSemaphore = new Semaphore(0); executor.submit( new Callable<Void>() { @Override public Void call() throws Exception { testSemaphore.release(); jobSemaphore.acquireUninterruptibly(); return null; } }); executor.submit( new Callable<Void>() { @Override public Void call() throws Exception { jobSemaphore.acquireUninterruptibly(); return null; } }); testSemaphore.acquireUninterruptibly(); executor.shutdown(); assertThat(executor.awaitTermination(100, MILLISECONDS), is(false)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(false)); jobSemaphore.release(); assertThat(executor.awaitTermination(100, MILLISECONDS), is(false)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(false)); jobSemaphore.release(); assertThat(executor.awaitTermination(2, MINUTES), is(true)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(true)); assertThat(jobSemaphore.availablePermits(), is(0)); } finally { worker.shutdown(); } }