AsyncRunner { public static <RESULT> Future<AsyncResult<RESULT>> submit(Callback<RESULT> callback, Callable<RESULT> task) { if (executor == null) { executor = new DefaultAsyncExecutor(); LOGGER.log(Level.INFO, "AsyncExecutor was not set, default executor {0} will be used.", executor.getClass().getSimpleName()); } return executor.submit(callback, task); } private  AsyncRunner(); static Future<AsyncResult<RESULT>> submit(Callback<RESULT> callback, Callable<RESULT> task); static RESULT run(Callable<RESULT> task); static RESULT run(Callable<RESULT> task, long timeout, TimeUnit unit); static void setExecutor(AsyncExecutor executor);  }
@Test public void submitIsAsynchronous() throws Exception { final long timeout = 5000; final long testedCount = timeout / 5; Callable<Boolean> task = new Callable<Boolean>() { @Override public Boolean call() throws Exception { Thread.sleep(timeout); return false; } }; final CountDownLatch latch = new CountDownLatch(1); Callback<Boolean> callback = new Callback<Boolean>() { @Override public void onSuccess(Boolean data) { latch.countDown(); } @Override public void onFailure(Exception e) { } }; Future<AsyncResult<Boolean>> resultFuture = AsyncRunner.submit(callback, task); long count = 0; while (latch.getCount() > 0) { count++; Thread.sleep(1); } AsyncResult<Boolean> result = resultFuture.get(); assertThat(result.getData(), is(false)); assertThat(count, greaterThanOrEqualTo(testedCount)); }
@Test public void exceptionPassedToResult() throws Exception { final Exception exception = new Exception("Test exception!"); Callable<Boolean> task = new Callable<Boolean>() { @Override public Boolean call() throws Exception { throw exception; } }; Future<AsyncResult<Boolean>> resultFuture = AsyncRunner.submit(null, task); AsyncResult<Boolean> result = resultFuture.get(); assertThat(result.getData(), is(nullValue())); assertThat(result.getException(), is(exception)); }
@Test public void exceptionIsThrownOnUnwrap() throws Exception { final UnsupportedOperationException testedException = new UnsupportedOperationException("Test exception!"); Callable<Boolean> task = new Callable<Boolean>() { @Override public Boolean call() throws Exception { throw testedException; } }; Future<AsyncResult<Boolean>> resultFuture = AsyncRunner.submit(null, task); AsyncResult<Boolean> result = resultFuture.get(); exception.expect(AsyncExecutionException.class); result.unwrap(); }