ProgressableUtils { private ProgressableUtils() { } private  ProgressableUtils(); static void awaitExecutorTermination(ExecutorService executor,
      Progressable progressable, int msecsPeriod); static void awaitExecutorTermination(ExecutorService executor,
      Progressable progressable); static void awaitTerminationFuture(EventExecutorGroup group,
                                            Progressable progressable); static T getFutureResult(Future<T> future,
      Progressable progressable); static void awaitChannelGroupFuture(ChannelGroupFuture future,
      Progressable progressable); static void awaitChannelFuture(ChannelFuture future,
      Progressable progressable); static void awaitSemaphorePermits(final Semaphore semaphore,
      int permits, Progressable progressable); static List<R> getResultsWithNCallables(
      CallableFactory<R> callableFactory, int numThreads,
      String threadNameFormat, Progressable progressable);  }
@Test public void testProgressableUtils() throws NoSuchFieldException, IllegalAccessException { final int sleepTime = 1800; final int msecPeriod = 500; ExecutorService executor = Executors.newFixedThreadPool(1); executor.submit(new Runnable() { @Override public void run() { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { throw new IllegalStateException(); } } }); executor.shutdown(); CountProgressable countProgressable = new CountProgressable(); ProgressableUtils.awaitExecutorTermination(executor, countProgressable, msecPeriod); Assert.assertTrue(countProgressable.counter >= sleepTime / msecPeriod); Assert.assertTrue( countProgressable.counter <= (sleepTime + msecPeriod) / msecPeriod); }