package akka.dispatch; import akka.actor.Timeout; import akka.actor.ActorSystem; import akka.util.Duration; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; import java.util.concurrent.Callable; import java.util.LinkedList; import java.lang.Iterable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import akka.japi.Function; import akka.japi.Function2; import akka.japi.Procedure; import akka.japi.Option; import akka.testkit.AkkaSpec; public class JavaFutureTests { private static ActorSystem system; private static Timeout t; @BeforeClass public static void beforeAll() { system = ActorSystem.create("JavaFutureTests", AkkaSpec.testConf()); t = system.settings().ActorTimeout(); } @AfterClass public static void afterAll() { system.stop(); system = null; } @Test public void mustBeAbleToMapAFuture() { Future f1 = Futures.future(new Callable() { public String call() { return "Hello"; } }, system.dispatcher()); Future f2 = f1.map(new Function() { public String apply(String s) { return s + " World"; } }); assertEquals("Hello World", f2.get()); } @Test public void mustBeAbleToExecuteAnOnResultCallback() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = Futures.promise(system.dispatcher()); Future f = cf; f.onSuccess(new Procedure() { public void apply(String result) { if (result.equals("foo")) latch.countDown(); } }); cf.success("foo"); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.get(), "foo"); } @Test public void mustBeAbleToExecuteAnOnExceptionCallback() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = Futures.promise(system.dispatcher()); Future f = cf; f.onFailure(new Procedure() { public void apply(Throwable t) { if (t instanceof NullPointerException) latch.countDown(); } }); Throwable exception = new NullPointerException(); cf.failure(exception); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.value().get().left().get(), exception); } @Test public void mustBeAbleToExecuteAnOnCompleteCallback() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = Futures.promise(system.dispatcher()); Future f = cf; f.onComplete(new Procedure>() { public void apply(akka.dispatch.Future future) { latch.countDown(); } }); cf.success("foo"); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.get(), "foo"); } @Test public void mustBeAbleToForeachAFuture() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = Futures.promise(system.dispatcher()); Future f = cf; f.foreach(new Procedure() { public void apply(String future) { latch.countDown(); } }); cf.success("foo"); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.get(), "foo"); } @Test public void mustBeAbleToFlatMapAFuture() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = Futures.promise(system.dispatcher()); cf.success("1000"); Future f = cf; Future r = f.flatMap(new Function>() { public Future apply(String r) { latch.countDown(); Promise cf = Futures.promise(system.dispatcher()); cf.success(Integer.parseInt(r)); return cf; } }); assertEquals(f.get(), "1000"); assertEquals(r.get().intValue(), 1000); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); } @Test public void mustBeAbleToFilterAFuture() throws Throwable { final CountDownLatch latch = new CountDownLatch(1); Promise cf = Futures.promise(system.dispatcher()); Future f = cf; Future r = f.filter(new Function() { public Boolean apply(String r) { latch.countDown(); return r.equals("foo"); } }); cf.success("foo"); assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); assertEquals(f.get(), "foo"); assertEquals(r.get(), "foo"); } // TODO: Improve this test, perhaps with an Actor @Test public void mustSequenceAFutureList() { LinkedList> listFutures = new LinkedList>(); LinkedList listExpected = new LinkedList(); for (int i = 0; i < 10; i++) { listExpected.add("test"); listFutures.add(Futures.future(new Callable() { public String call() { return "test"; } }, system.dispatcher())); } Future> futureList = Futures.sequence(listFutures, system.dispatcher()); assertEquals(futureList.get(), listExpected); } // TODO: Improve this test, perhaps with an Actor @Test public void foldForJavaApiMustWork() { LinkedList> listFutures = new LinkedList>(); StringBuilder expected = new StringBuilder(); for (int i = 0; i < 10; i++) { expected.append("test"); listFutures.add(Futures.future(new Callable() { public String call() { return "test"; } }, system.dispatcher())); } Future result = Futures.fold("", listFutures, new Function2() { public String apply(String r, String t) { return r + t; } }, system.dispatcher()); assertEquals(result.get(), expected.toString()); } @Test public void reduceForJavaApiMustWork() { LinkedList> listFutures = new LinkedList>(); StringBuilder expected = new StringBuilder(); for (int i = 0; i < 10; i++) { expected.append("test"); listFutures.add(Futures.future(new Callable() { public String call() { return "test"; } }, system.dispatcher())); } Future result = Futures.reduce(listFutures, new Function2() { public String apply(String r, String t) { return r + t; } }, system.dispatcher()); assertEquals(result.get(), expected.toString()); } @Test public void traverseForJavaApiMustWork() { LinkedList listStrings = new LinkedList(); LinkedList expectedStrings = new LinkedList(); for (int i = 0; i < 10; i++) { expectedStrings.add("TEST"); listStrings.add("test"); } Future> result = Futures.traverse(listStrings, new Function>() { public Future apply(final String r) { return Futures.future(new Callable() { public String call() { return r.toUpperCase(); } }, system.dispatcher()); } }, system.dispatcher()); assertEquals(result.get(), expectedStrings); } @Test public void findForJavaApiMustWork() { LinkedList> listFutures = new LinkedList>(); for (int i = 0; i < 10; i++) { final Integer fi = i; listFutures.add(Futures.future(new Callable() { public Integer call() { return fi; } }, system.dispatcher())); } final Integer expect = 5; Future> f = Futures.find(listFutures, new Function() { public Boolean apply(Integer i) { return i == 5; } }, system.dispatcher()); assertEquals(expect, Block.sync(f, Duration.create(5, TimeUnit.SECONDS))); } @Test public void BlockMustBeCallable() { Promise p = Futures.promise(system.dispatcher()); Duration d = Duration.create(1, TimeUnit.SECONDS); p.success("foo"); Block.on(p, d); assertEquals(Block.sync(p, d), "foo"); } }