/akka-actor-tests/src/test/java/akka/dispatch/JavaFutureTests.java

https://github.com/GunioRobot/akka · Java · 261 lines · 220 code · 39 blank · 2 comment · 8 complexity · 8427109f28d41bb3f400a97159115ed6 MD5 · raw file

  1. package akka.dispatch;
  2. import akka.actor.Timeout;
  3. import akka.AkkaApplication;
  4. import org.junit.Test;
  5. import static org.junit.Assert.*;
  6. import java.util.concurrent.Callable;
  7. import java.util.LinkedList;
  8. import java.lang.Iterable;
  9. import java.util.concurrent.CountDownLatch;
  10. import java.util.concurrent.TimeUnit;
  11. import akka.japi.Function;
  12. import akka.japi.Function2;
  13. import akka.japi.Procedure;
  14. import akka.japi.Option;
  15. import scala.Some;
  16. import scala.Right;
  17. public class JavaFutureTests {
  18. private final AkkaApplication app = new AkkaApplication();
  19. private final Timeout t = app.AkkaConfig().ActorTimeout();
  20. private final FutureFactory ff = new FutureFactory(app.dispatcher(), t);
  21. @Test public void mustBeAbleToMapAFuture() {
  22. Future<String> f1 = ff.future(new Callable<String>() {
  23. public String call() {
  24. return "Hello";
  25. }
  26. });
  27. Future<String> f2 = f1.map(new Function<String, String>() {
  28. public String apply(String s) {
  29. return s + " World";
  30. }
  31. }, t);
  32. assertEquals("Hello World", f2.get());
  33. }
  34. @Test public void mustBeAbleToExecuteAnOnResultCallback() throws Throwable {
  35. final CountDownLatch latch = new CountDownLatch(1);
  36. Promise<String> cf = new akka.dispatch.DefaultPromise<String>(1000, TimeUnit.MILLISECONDS, app.dispatcherFactory().defaultGlobalDispatcher());
  37. Future<String> f = cf;
  38. f.onResult(new Procedure<String>() {
  39. public void apply(String result) {
  40. if(result.equals("foo"))
  41. latch.countDown();
  42. }
  43. });
  44. cf.completeWithResult("foo");
  45. assertTrue(latch.await(5000, TimeUnit.MILLISECONDS));
  46. assertEquals(f.get(), "foo");
  47. }
  48. @Test public void mustBeAbleToExecuteAnOnExceptionCallback() throws Throwable {
  49. final CountDownLatch latch = new CountDownLatch(1);
  50. Promise<String> cf = new akka.dispatch.DefaultPromise<String>(1000, TimeUnit.MILLISECONDS, app.dispatcherFactory().defaultGlobalDispatcher());
  51. Future<String> f = cf;
  52. f.onException(new Procedure<Throwable>() {
  53. public void apply(Throwable t) {
  54. if(t instanceof NullPointerException)
  55. latch.countDown();
  56. }
  57. });
  58. Throwable exception = new NullPointerException();
  59. cf.completeWithException(exception);
  60. assertTrue(latch.await(5000, TimeUnit.MILLISECONDS));
  61. assertEquals(f.exception().get(), exception);
  62. }
  63. @Test public void mustBeAbleToExecuteAnOnTimeoutCallback() throws Throwable {
  64. final CountDownLatch latch = new CountDownLatch(1);
  65. Promise<String> cf = new akka.dispatch.DefaultPromise<String>(1000, TimeUnit.MILLISECONDS, app.dispatcherFactory().defaultGlobalDispatcher());
  66. Future<String> f = cf;
  67. f.onTimeout(new Procedure<Future<String>>() {
  68. public void apply(Future<String> future) {
  69. latch.countDown();
  70. }
  71. });
  72. assertTrue(latch.await(5000, TimeUnit.MILLISECONDS));
  73. assertTrue(f.value().isEmpty());
  74. }
  75. @Test public void mustBeAbleToExecuteAnOnCompleteCallback() throws Throwable {
  76. final CountDownLatch latch = new CountDownLatch(1);
  77. Promise<String> cf = new akka.dispatch.DefaultPromise<String>(1000, TimeUnit.MILLISECONDS, app.dispatcherFactory().defaultGlobalDispatcher());
  78. Future<String> f = cf;
  79. f.onComplete(new Procedure<Future<String>>() {
  80. public void apply(akka.dispatch.Future<String> future) {
  81. latch.countDown();
  82. }
  83. });
  84. cf.completeWithResult("foo");
  85. assertTrue(latch.await(5000, TimeUnit.MILLISECONDS));
  86. assertEquals(f.get(), "foo");
  87. }
  88. @Test public void mustBeAbleToForeachAFuture() throws Throwable {
  89. final CountDownLatch latch = new CountDownLatch(1);
  90. Promise<String> cf = new akka.dispatch.DefaultPromise<String>(1000, TimeUnit.MILLISECONDS, app.dispatcherFactory().defaultGlobalDispatcher());
  91. Future<String> f = cf;
  92. f.foreach(new Procedure<String>() {
  93. public void apply(String future) {
  94. latch.countDown();
  95. }
  96. });
  97. cf.completeWithResult("foo");
  98. assertTrue(latch.await(5000, TimeUnit.MILLISECONDS));
  99. assertEquals(f.get(), "foo");
  100. }
  101. @Test public void mustBeAbleToFlatMapAFuture() throws Throwable {
  102. final CountDownLatch latch = new CountDownLatch(1);
  103. Promise<String> cf = new akka.dispatch.DefaultPromise<String>(1000, TimeUnit.MILLISECONDS, app.dispatcherFactory().defaultGlobalDispatcher());
  104. cf.completeWithResult("1000");
  105. Future<String> f = cf;
  106. Future<Integer> r = f.flatMap(new Function<String, Future<Integer>>() {
  107. public Future<Integer> apply(String r) {
  108. latch.countDown();
  109. Promise<Integer> cf = new akka.dispatch.DefaultPromise<Integer>(1000, TimeUnit.MILLISECONDS, app.dispatcherFactory().defaultGlobalDispatcher());
  110. cf.completeWithResult(Integer.parseInt(r));
  111. return cf;
  112. }
  113. }, t);
  114. assertEquals(f.get(), "1000");
  115. assertEquals(r.get().intValue(), 1000);
  116. assertTrue(latch.await(5000, TimeUnit.MILLISECONDS));
  117. }
  118. @Test public void mustBeAbleToFilterAFuture() throws Throwable {
  119. final CountDownLatch latch = new CountDownLatch(1);
  120. Promise<String> cf = new akka.dispatch.DefaultPromise<String>(1000, TimeUnit.MILLISECONDS, app.dispatcherFactory().defaultGlobalDispatcher());
  121. Future<String> f = cf;
  122. Future<String> r = f.filter(new Function<String, Boolean>() {
  123. public Boolean apply(String r) {
  124. latch.countDown();
  125. return r.equals("foo");
  126. }
  127. }, t);
  128. cf.completeWithResult("foo");
  129. assertTrue(latch.await(5000, TimeUnit.MILLISECONDS));
  130. assertEquals(f.get(), "foo");
  131. assertEquals(r.get(), "foo");
  132. }
  133. // TODO: Improve this test, perhaps with an Actor
  134. @Test public void mustSequenceAFutureList() {
  135. LinkedList<Future<String>> listFutures = new LinkedList<Future<String>>();
  136. LinkedList<String> listExpected = new LinkedList<String>();
  137. for (int i = 0; i < 10; i++) {
  138. listExpected.add("test");
  139. listFutures.add(ff.future(new Callable<String>() {
  140. public String call() {
  141. return "test";
  142. }
  143. }));
  144. }
  145. Future<Iterable<String>> futureList = ff.sequence(listFutures, t);
  146. assertEquals(futureList.get(), listExpected);
  147. }
  148. // TODO: Improve this test, perhaps with an Actor
  149. @Test public void foldForJavaApiMustWork() {
  150. LinkedList<Future<String>> listFutures = new LinkedList<Future<String>>();
  151. StringBuilder expected = new StringBuilder();
  152. for (int i = 0; i < 10; i++) {
  153. expected.append("test");
  154. listFutures.add(ff.future(new Callable<String>() {
  155. public String call() {
  156. return "test";
  157. }
  158. }));
  159. }
  160. Future<String> result = ff.fold("", 15000,listFutures, new Function2<String,String,String>() {
  161. public String apply(String r, String t) {
  162. return r + t;
  163. }
  164. });
  165. assertEquals(result.get(), expected.toString());
  166. }
  167. @Test public void reduceForJavaApiMustWork() {
  168. LinkedList<Future<String>> listFutures = new LinkedList<Future<String>>();
  169. StringBuilder expected = new StringBuilder();
  170. for (int i = 0; i < 10; i++) {
  171. expected.append("test");
  172. listFutures.add(ff.future(new Callable<String>() {
  173. public String call() {
  174. return "test";
  175. }
  176. }));
  177. }
  178. Future<String> result = ff.reduce(listFutures, 15000, new Function2<String,String,String>() {
  179. public String apply(String r, String t) {
  180. return r + t;
  181. }
  182. });
  183. assertEquals(result.get(), expected.toString());
  184. }
  185. @Test public void traverseForJavaApiMustWork() {
  186. LinkedList<String> listStrings = new LinkedList<String>();
  187. LinkedList<String> expectedStrings = new LinkedList<String>();
  188. for (int i = 0; i < 10; i++) {
  189. expectedStrings.add("TEST");
  190. listStrings.add("test");
  191. }
  192. Future<Iterable<String>> result = ff.traverse(listStrings, t, new Function<String,Future<String>>() {
  193. public Future<String> apply(final String r) {
  194. return ff.future(new Callable<String>() {
  195. public String call() {
  196. return r.toUpperCase();
  197. }
  198. });
  199. }
  200. });
  201. assertEquals(result.get(), expectedStrings);
  202. }
  203. @Test public void findForJavaApiMustWork() {
  204. LinkedList<Future<Integer>> listFutures = new LinkedList<Future<Integer>>();
  205. for (int i = 0; i < 10; i++) {
  206. final Integer fi = i;
  207. listFutures.add(ff.future(new Callable<Integer>() {
  208. public Integer call() {
  209. return fi;
  210. }
  211. }));
  212. }
  213. final Integer expect = 5;
  214. Future<Option<Integer>> f = ff.find(listFutures, new Function<Integer,Boolean>() {
  215. public Boolean apply(Integer i) {
  216. return i == 5;
  217. }
  218. }, t);
  219. final Integer got = f.get().get();
  220. assertEquals(expect, got);
  221. }
  222. }