@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 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(); } }
@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 testDelayedTaskIsRemovedByShutdownNow() 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() { Assert.fail("Should not run!"); } }, 2, MINUTES); List<Runnable> remainingTasks = executor.shutdownNow(); assertThat(remainingTasks, hasSize(1)); assertThat(executor.awaitTermination(30, SECONDS), is(true)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(true)); assertThat(future.isDone(), is(false)); for (Runnable r : remainingTasks) r.run(); assertThat(future.isDone(), is(true)); } finally { worker.shutdown(); } }
@Test public void testFixedRatePeriodicTaskIsCancelledByShutdownNow() throws InterruptedException { OutOfBandScheduledExecutor scheduler = new OutOfBandScheduledExecutor(); ExecutorService worker = Executors.newSingleThreadExecutor(); try { PartitionedScheduledExecutor executor = new PartitionedScheduledExecutor(scheduler, worker); ScheduledFuture<?> future = executor.scheduleAtFixedRate( new Runnable() { @Override public void run() { // no-op } }, 2, 1, MINUTES); assertThat(executor.shutdownNow(), hasSize(1)); assertThat(executor.awaitTermination(30, SECONDS), is(true)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(true)); assertThat(future.isDone(), is(false)); } 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 testShutdownNowOfIdleExecutor() throws InterruptedException { OutOfBandScheduledExecutor scheduler = new OutOfBandScheduledExecutor(); ExecutorService worker = Executors.newCachedThreadPool(); PartitionedScheduledExecutor executor = new PartitionedScheduledExecutor(scheduler, worker); assertThat(executor.shutdownNow(), empty()); assertThat(executor.isShutdown(), is(true)); assertThat(executor.awaitTermination(2, TimeUnit.MINUTES), is(true)); assertThat(executor.isTerminated(), is(true)); }
@Test public void testRunningJobsAreInterruptedAfterShutdownNow() throws InterruptedException { final int jobCount = 4; OutOfBandScheduledExecutor scheduler = new OutOfBandScheduledExecutor(); ExecutorService worker = Executors.newCachedThreadPool(); try { PartitionedScheduledExecutor executor = new PartitionedScheduledExecutor(scheduler, worker); final Semaphore jobSemaphore = new Semaphore(0); final Semaphore testSemaphore = new Semaphore(0); final AtomicInteger interrupted = new AtomicInteger(); for (int i = 0; i < jobCount; i++) { executor.submit( new Callable<Void>() { @Override public Void call() throws Exception { testSemaphore.release(); try { jobSemaphore.acquire(); } catch (InterruptedException e) { interrupted.incrementAndGet(); } return null; } }); } testSemaphore.acquireUninterruptibly(jobCount); assertThat(executor.shutdownNow(), empty()); assertThat(executor.awaitTermination(2, MINUTES), is(true)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(true)); assertThat(jobSemaphore.availablePermits(), is(0)); assertThat(interrupted.get(), is(jobCount)); } finally { worker.shutdown(); } }
@Test public void testRunningJobIsInterruptedAfterShutdownNow() 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); final AtomicBoolean interrupted = new AtomicBoolean(); executor.submit( new Callable<Void>() { @Override public Void call() throws Exception { testSemaphore.release(); try { jobSemaphore.acquire(); } catch (InterruptedException e) { interrupted.set(true); } return null; } }); testSemaphore.acquireUninterruptibly(); assertThat(executor.shutdownNow(), empty()); assertThat(executor.awaitTermination(2, MINUTES), is(true)); assertThat(executor.isShutdown(), is(true)); assertThat(executor.isTerminated(), is(true)); assertThat(jobSemaphore.availablePermits(), is(0)); assertThat(interrupted.get(), is(true)); } finally { worker.shutdown(); } }