@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 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 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();
    }
  }