package org.threadly.concurrent.future; import static org.junit.Assert.*; import java.util.concurrent.CancellationException; import java.util.concurrent.Future; import java.util.concurrent.TimeoutException; import org.junit.Test; import org.threadly.test.concurrent.AsyncVerifier; import org.threadly.test.concurrent.TestCondition; @SuppressWarnings("javadoc") public class RunnableFutureCallbackAdapterTest { @Test public void constructorTest() { Future<Object> future = new TestFutureImp(false); FutureCallback<Object> callback = new TestFutureCallback(); RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback); assertTrue(rfca.future == future); assertTrue(rfca.callback == callback); } @Test @SuppressWarnings("unused") public void constructorFail() { try { new RunnableFutureCallbackAdapter<>(null, new TestFutureCallback()); fail("Exception should have thrown"); } catch (IllegalArgumentException e) { // expected } try { new RunnableFutureCallbackAdapter<>(new TestFutureImp(false), null); fail("Exception should have thrown"); } catch (IllegalArgumentException e) { // expected } } @Test public void resultTest() { SettableListenableFuture<Object> future = new SettableListenableFuture<>(); TestFutureCallback callback = new TestFutureCallback(); Object result = new Object(); future.setResult(result); RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback); rfca.run(); assertTrue(callback.getLastResult() == result); assertNull(callback.getLastFailure()); } @Test public void executionExceptionTest() { SettableListenableFuture<Object> future = new SettableListenableFuture<>(); TestFutureCallback callback = new TestFutureCallback(); Exception failure = new Exception(); future.setFailure(failure); RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback); rfca.run(); assertTrue(callback.getLastFailure() == failure); assertNull(callback.getLastResult()); } @Test public void cancellationExceptionTest() { Future<Object> future = new TestFutureImp(false); TestFutureCallback callback = new TestFutureCallback(); future.cancel(true); RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback); rfca.run(); assertTrue(callback.getLastFailure() instanceof CancellationException); assertNull(callback.getLastResult()); } @Test public void interruptedExceptionTest() throws InterruptedException, TimeoutException { SettableListenableFuture<Object> future = new SettableListenableFuture<>(); TestFutureCallback callback = new TestFutureCallback(); final AsyncVerifier av = new AsyncVerifier(); final RunnableFutureCallbackAdapter<?> rfca = new RunnableFutureCallbackAdapter<>(future, callback); final Thread t = new Thread(new Runnable() { @Override public void run() { try { rfca.run(); av.fail("Exception did not throw"); } catch (RuntimeException expected) { av.assertTrue(Thread.currentThread().isInterrupted()); av.signalComplete(); } } }); t.start(); new TestCondition(() -> t.isAlive()).blockTillTrue(); t.interrupt(); av.waitForTest(); assertTrue(callback.getLastFailure() instanceof InterruptedException); assertNull(callback.getLastResult()); } }