ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CompletableFutureTest.java
Revision: 1.151
Committed: Sun Jun 26 17:45:35 2016 UTC (7 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.150: +65 -58 lines
Log Message:
precisely test exception propagation from failing actions

File Contents

# Content
1 /*
2 * Written by Doug Lea and Martin Buchholz with assistance from
3 * members of JCP JSR-166 Expert Group and released to the public
4 * domain, as explained at
5 * http://creativecommons.org/publicdomain/zero/1.0/
6 */
7
8 import static java.util.concurrent.TimeUnit.MILLISECONDS;
9 import static java.util.concurrent.TimeUnit.SECONDS;
10 import static java.util.concurrent.CompletableFuture.completedFuture;
11 import static java.util.concurrent.CompletableFuture.failedFuture;
12
13 import java.lang.reflect.Method;
14 import java.lang.reflect.Modifier;
15
16 import java.util.stream.Collectors;
17 import java.util.stream.Stream;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.List;
22 import java.util.Objects;
23 import java.util.Set;
24 import java.util.concurrent.Callable;
25 import java.util.concurrent.CancellationException;
26 import java.util.concurrent.CompletableFuture;
27 import java.util.concurrent.CompletionException;
28 import java.util.concurrent.CompletionStage;
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.Executor;
31 import java.util.concurrent.ForkJoinPool;
32 import java.util.concurrent.ForkJoinTask;
33 import java.util.concurrent.TimeoutException;
34 import java.util.concurrent.TimeUnit;
35 import java.util.concurrent.atomic.AtomicInteger;
36 import java.util.concurrent.atomic.AtomicReference;
37 import java.util.function.BiConsumer;
38 import java.util.function.BiFunction;
39 import java.util.function.Consumer;
40 import java.util.function.Function;
41 import java.util.function.Predicate;
42 import java.util.function.Supplier;
43
44 import junit.framework.AssertionFailedError;
45 import junit.framework.Test;
46 import junit.framework.TestSuite;
47
48 public class CompletableFutureTest extends JSR166TestCase {
49
50 public static void main(String[] args) {
51 main(suite(), args);
52 }
53 public static Test suite() {
54 return new TestSuite(CompletableFutureTest.class);
55 }
56
57 static class CFException extends RuntimeException {}
58
59 void checkIncomplete(CompletableFuture<?> f) {
60 assertFalse(f.isDone());
61 assertFalse(f.isCancelled());
62 assertTrue(f.toString().contains("Not completed"));
63 try {
64 assertNull(f.getNow(null));
65 } catch (Throwable fail) { threadUnexpectedException(fail); }
66 try {
67 f.get(0L, SECONDS);
68 shouldThrow();
69 }
70 catch (TimeoutException success) {}
71 catch (Throwable fail) { threadUnexpectedException(fail); }
72 }
73
74 <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
75 checkTimedGet(f, value);
76
77 try {
78 assertEquals(value, f.join());
79 } catch (Throwable fail) { threadUnexpectedException(fail); }
80 try {
81 assertEquals(value, f.getNow(null));
82 } catch (Throwable fail) { threadUnexpectedException(fail); }
83 try {
84 assertEquals(value, f.get());
85 } catch (Throwable fail) { threadUnexpectedException(fail); }
86 assertTrue(f.isDone());
87 assertFalse(f.isCancelled());
88 assertFalse(f.isCompletedExceptionally());
89 assertTrue(f.toString().contains("[Completed normally]"));
90 }
91
92 /**
93 * Returns the "raw" internal exceptional completion of f,
94 * without any additional wrapping with CompletionException.
95 */
96 <U> Throwable exceptionalCompletion(CompletableFuture<U> f) {
97 // handle (and whenComplete) can distinguish between "direct"
98 // and "wrapped" exceptional completion
99 return f.handle((U u, Throwable t) -> t).join();
100 }
101
102 void checkCompletedExceptionally(CompletableFuture<?> f,
103 boolean wrapped,
104 Consumer<Throwable> checker) {
105 Throwable cause = exceptionalCompletion(f);
106 if (wrapped) {
107 assertTrue(cause instanceof CompletionException);
108 cause = cause.getCause();
109 }
110 checker.accept(cause);
111
112 long startTime = System.nanoTime();
113 try {
114 f.get(LONG_DELAY_MS, MILLISECONDS);
115 shouldThrow();
116 } catch (ExecutionException success) {
117 assertSame(cause, success.getCause());
118 } catch (Throwable fail) { threadUnexpectedException(fail); }
119 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
120
121 try {
122 f.join();
123 shouldThrow();
124 } catch (CompletionException success) {
125 assertSame(cause, success.getCause());
126 } catch (Throwable fail) { threadUnexpectedException(fail); }
127
128 try {
129 f.getNow(null);
130 shouldThrow();
131 } catch (CompletionException success) {
132 assertSame(cause, success.getCause());
133 } catch (Throwable fail) { threadUnexpectedException(fail); }
134
135 try {
136 f.get();
137 shouldThrow();
138 } catch (ExecutionException success) {
139 assertSame(cause, success.getCause());
140 } catch (Throwable fail) { threadUnexpectedException(fail); }
141
142 assertFalse(f.isCancelled());
143 assertTrue(f.isDone());
144 assertTrue(f.isCompletedExceptionally());
145 assertTrue(f.toString().contains("[Completed exceptionally]"));
146 }
147
148 void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
149 checkCompletedExceptionally(f, true,
150 (t) -> assertTrue(t instanceof CFException));
151 }
152
153 void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
154 checkCompletedExceptionally(f, true,
155 (t) -> assertTrue(t instanceof CancellationException));
156 }
157
158 void checkCompletedWithTimeoutException(CompletableFuture<?> f) {
159 checkCompletedExceptionally(f, false,
160 (t) -> assertTrue(t instanceof TimeoutException));
161 }
162
163 void checkCompletedWithWrappedException(CompletableFuture<?> f,
164 Throwable ex) {
165 checkCompletedExceptionally(f, true, (t) -> assertSame(t, ex));
166 }
167
168 void checkCompletedExceptionally(CompletableFuture<?> f, Throwable ex) {
169 checkCompletedExceptionally(f, false, (t) -> assertSame(t, ex));
170 }
171
172 void checkCancelled(CompletableFuture<?> f) {
173 long startTime = System.nanoTime();
174 try {
175 f.get(LONG_DELAY_MS, MILLISECONDS);
176 shouldThrow();
177 } catch (CancellationException success) {
178 } catch (Throwable fail) { threadUnexpectedException(fail); }
179 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
180
181 try {
182 f.join();
183 shouldThrow();
184 } catch (CancellationException success) {}
185 try {
186 f.getNow(null);
187 shouldThrow();
188 } catch (CancellationException success) {}
189 try {
190 f.get();
191 shouldThrow();
192 } catch (CancellationException success) {
193 } catch (Throwable fail) { threadUnexpectedException(fail); }
194
195 assertTrue(exceptionalCompletion(f) instanceof CancellationException);
196
197 assertTrue(f.isDone());
198 assertTrue(f.isCompletedExceptionally());
199 assertTrue(f.isCancelled());
200 assertTrue(f.toString().contains("[Completed exceptionally]"));
201 }
202
203 /**
204 * A newly constructed CompletableFuture is incomplete, as indicated
205 * by methods isDone, isCancelled, and getNow
206 */
207 public void testConstructor() {
208 CompletableFuture<Integer> f = new CompletableFuture<>();
209 checkIncomplete(f);
210 }
211
212 /**
213 * complete completes normally, as indicated by methods isDone,
214 * isCancelled, join, get, and getNow
215 */
216 public void testComplete() {
217 for (Integer v1 : new Integer[] { 1, null })
218 {
219 CompletableFuture<Integer> f = new CompletableFuture<>();
220 checkIncomplete(f);
221 assertTrue(f.complete(v1));
222 assertFalse(f.complete(v1));
223 checkCompletedNormally(f, v1);
224 }}
225
226 /**
227 * completeExceptionally completes exceptionally, as indicated by
228 * methods isDone, isCancelled, join, get, and getNow
229 */
230 public void testCompleteExceptionally() {
231 CompletableFuture<Integer> f = new CompletableFuture<>();
232 CFException ex = new CFException();
233 checkIncomplete(f);
234 f.completeExceptionally(ex);
235 checkCompletedExceptionally(f, ex);
236 }
237
238 /**
239 * cancel completes exceptionally and reports cancelled, as indicated by
240 * methods isDone, isCancelled, join, get, and getNow
241 */
242 public void testCancel() {
243 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
244 {
245 CompletableFuture<Integer> f = new CompletableFuture<>();
246 checkIncomplete(f);
247 assertTrue(f.cancel(mayInterruptIfRunning));
248 assertTrue(f.cancel(mayInterruptIfRunning));
249 assertTrue(f.cancel(!mayInterruptIfRunning));
250 checkCancelled(f);
251 }}
252
253 /**
254 * obtrudeValue forces completion with given value
255 */
256 public void testObtrudeValue() {
257 CompletableFuture<Integer> f = new CompletableFuture<>();
258 checkIncomplete(f);
259 assertTrue(f.complete(one));
260 checkCompletedNormally(f, one);
261 f.obtrudeValue(three);
262 checkCompletedNormally(f, three);
263 f.obtrudeValue(two);
264 checkCompletedNormally(f, two);
265 f = new CompletableFuture<>();
266 f.obtrudeValue(three);
267 checkCompletedNormally(f, three);
268 f.obtrudeValue(null);
269 checkCompletedNormally(f, null);
270 f = new CompletableFuture<>();
271 f.completeExceptionally(new CFException());
272 f.obtrudeValue(four);
273 checkCompletedNormally(f, four);
274 }
275
276 /**
277 * obtrudeException forces completion with given exception
278 */
279 public void testObtrudeException() {
280 for (Integer v1 : new Integer[] { 1, null })
281 {
282 CFException ex;
283 CompletableFuture<Integer> f;
284
285 f = new CompletableFuture<>();
286 assertTrue(f.complete(v1));
287 for (int i = 0; i < 2; i++) {
288 f.obtrudeException(ex = new CFException());
289 checkCompletedExceptionally(f, ex);
290 }
291
292 f = new CompletableFuture<>();
293 for (int i = 0; i < 2; i++) {
294 f.obtrudeException(ex = new CFException());
295 checkCompletedExceptionally(f, ex);
296 }
297
298 f = new CompletableFuture<>();
299 f.completeExceptionally(ex = new CFException());
300 f.obtrudeValue(v1);
301 checkCompletedNormally(f, v1);
302 f.obtrudeException(ex = new CFException());
303 checkCompletedExceptionally(f, ex);
304 f.completeExceptionally(new CFException());
305 checkCompletedExceptionally(f, ex);
306 assertFalse(f.complete(v1));
307 checkCompletedExceptionally(f, ex);
308 }}
309
310 /**
311 * getNumberOfDependents returns number of dependent tasks
312 */
313 public void testGetNumberOfDependents() {
314 for (ExecutionMode m : ExecutionMode.values())
315 for (Integer v1 : new Integer[] { 1, null })
316 {
317 CompletableFuture<Integer> f = new CompletableFuture<>();
318 assertEquals(0, f.getNumberOfDependents());
319 final CompletableFuture<Void> g = m.thenRun(f, new Noop(m));
320 assertEquals(1, f.getNumberOfDependents());
321 assertEquals(0, g.getNumberOfDependents());
322 final CompletableFuture<Void> h = m.thenRun(f, new Noop(m));
323 assertEquals(2, f.getNumberOfDependents());
324 assertEquals(0, h.getNumberOfDependents());
325 assertTrue(f.complete(v1));
326 checkCompletedNormally(g, null);
327 checkCompletedNormally(h, null);
328 assertEquals(0, f.getNumberOfDependents());
329 assertEquals(0, g.getNumberOfDependents());
330 assertEquals(0, h.getNumberOfDependents());
331 }}
332
333 /**
334 * toString indicates current completion state
335 */
336 public void testToString() {
337 CompletableFuture<String> f;
338
339 f = new CompletableFuture<String>();
340 assertTrue(f.toString().contains("[Not completed]"));
341
342 assertTrue(f.complete("foo"));
343 assertTrue(f.toString().contains("[Completed normally]"));
344
345 f = new CompletableFuture<String>();
346 assertTrue(f.completeExceptionally(new IndexOutOfBoundsException()));
347 assertTrue(f.toString().contains("[Completed exceptionally]"));
348
349 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
350 f = new CompletableFuture<String>();
351 assertTrue(f.cancel(mayInterruptIfRunning));
352 assertTrue(f.toString().contains("[Completed exceptionally]"));
353 }
354 }
355
356 /**
357 * completedFuture returns a completed CompletableFuture with given value
358 */
359 public void testCompletedFuture() {
360 CompletableFuture<String> f = CompletableFuture.completedFuture("test");
361 checkCompletedNormally(f, "test");
362 }
363
364 abstract class CheckedAction {
365 int invocationCount = 0;
366 final ExecutionMode m;
367 CheckedAction(ExecutionMode m) { this.m = m; }
368 void invoked() {
369 m.checkExecutionMode();
370 assertEquals(0, invocationCount++);
371 }
372 void assertNotInvoked() { assertEquals(0, invocationCount); }
373 void assertInvoked() { assertEquals(1, invocationCount); }
374 }
375
376 abstract class CheckedIntegerAction extends CheckedAction {
377 Integer value;
378 CheckedIntegerAction(ExecutionMode m) { super(m); }
379 void assertValue(Integer expected) {
380 assertInvoked();
381 assertEquals(expected, value);
382 }
383 }
384
385 class IntegerSupplier extends CheckedAction
386 implements Supplier<Integer>
387 {
388 final Integer value;
389 IntegerSupplier(ExecutionMode m, Integer value) {
390 super(m);
391 this.value = value;
392 }
393 public Integer get() {
394 invoked();
395 return value;
396 }
397 }
398
399 // A function that handles and produces null values as well.
400 static Integer inc(Integer x) {
401 return (x == null) ? null : x + 1;
402 }
403
404 class NoopConsumer extends CheckedIntegerAction
405 implements Consumer<Integer>
406 {
407 NoopConsumer(ExecutionMode m) { super(m); }
408 public void accept(Integer x) {
409 invoked();
410 value = x;
411 }
412 }
413
414 class IncFunction extends CheckedIntegerAction
415 implements Function<Integer,Integer>
416 {
417 IncFunction(ExecutionMode m) { super(m); }
418 public Integer apply(Integer x) {
419 invoked();
420 return value = inc(x);
421 }
422 }
423
424 // Choose non-commutative actions for better coverage
425 // A non-commutative function that handles and produces null values as well.
426 static Integer subtract(Integer x, Integer y) {
427 return (x == null && y == null) ? null :
428 ((x == null) ? 42 : x.intValue())
429 - ((y == null) ? 99 : y.intValue());
430 }
431
432 class SubtractAction extends CheckedIntegerAction
433 implements BiConsumer<Integer, Integer>
434 {
435 SubtractAction(ExecutionMode m) { super(m); }
436 public void accept(Integer x, Integer y) {
437 invoked();
438 value = subtract(x, y);
439 }
440 }
441
442 class SubtractFunction extends CheckedIntegerAction
443 implements BiFunction<Integer, Integer, Integer>
444 {
445 SubtractFunction(ExecutionMode m) { super(m); }
446 public Integer apply(Integer x, Integer y) {
447 invoked();
448 return value = subtract(x, y);
449 }
450 }
451
452 class Noop extends CheckedAction implements Runnable {
453 Noop(ExecutionMode m) { super(m); }
454 public void run() {
455 invoked();
456 }
457 }
458
459 class FailingSupplier extends CheckedAction
460 implements Supplier<Integer>
461 {
462 final CFException ex;
463 FailingSupplier(ExecutionMode m) { super(m); ex = new CFException(); }
464 public Integer get() {
465 invoked();
466 throw ex;
467 }
468 }
469
470 class FailingConsumer extends CheckedIntegerAction
471 implements Consumer<Integer>
472 {
473 final CFException ex;
474 FailingConsumer(ExecutionMode m) { super(m); ex = new CFException(); }
475 public void accept(Integer x) {
476 invoked();
477 value = x;
478 throw ex;
479 }
480 }
481
482 class FailingBiConsumer extends CheckedIntegerAction
483 implements BiConsumer<Integer, Integer>
484 {
485 final CFException ex;
486 FailingBiConsumer(ExecutionMode m) { super(m); ex = new CFException(); }
487 public void accept(Integer x, Integer y) {
488 invoked();
489 value = subtract(x, y);
490 throw ex;
491 }
492 }
493
494 class FailingFunction extends CheckedIntegerAction
495 implements Function<Integer, Integer>
496 {
497 final CFException ex;
498 FailingFunction(ExecutionMode m) { super(m); ex = new CFException(); }
499 public Integer apply(Integer x) {
500 invoked();
501 value = x;
502 throw ex;
503 }
504 }
505
506 class FailingBiFunction extends CheckedIntegerAction
507 implements BiFunction<Integer, Integer, Integer>
508 {
509 final CFException ex;
510 FailingBiFunction(ExecutionMode m) { super(m); ex = new CFException(); }
511 public Integer apply(Integer x, Integer y) {
512 invoked();
513 value = subtract(x, y);
514 throw ex;
515 }
516 }
517
518 class FailingRunnable extends CheckedAction implements Runnable {
519 final CFException ex;
520 FailingRunnable(ExecutionMode m) { super(m); ex = new CFException(); }
521 public void run() {
522 invoked();
523 throw ex;
524 }
525 }
526
527 class CompletableFutureInc extends CheckedIntegerAction
528 implements Function<Integer, CompletableFuture<Integer>>
529 {
530 CompletableFutureInc(ExecutionMode m) { super(m); }
531 public CompletableFuture<Integer> apply(Integer x) {
532 invoked();
533 value = x;
534 CompletableFuture<Integer> f = new CompletableFuture<>();
535 assertTrue(f.complete(inc(x)));
536 return f;
537 }
538 }
539
540 class FailingCompletableFutureFunction extends CheckedIntegerAction
541 implements Function<Integer, CompletableFuture<Integer>>
542 {
543 final CFException ex;
544 FailingCompletableFutureFunction(ExecutionMode m) { super(m); ex = new CFException(); }
545 public CompletableFuture<Integer> apply(Integer x) {
546 invoked();
547 value = x;
548 throw ex;
549 }
550 }
551
552 // Used for explicit executor tests
553 static final class ThreadExecutor implements Executor {
554 final AtomicInteger count = new AtomicInteger(0);
555 static final ThreadGroup tg = new ThreadGroup("ThreadExecutor");
556 static boolean startedCurrentThread() {
557 return Thread.currentThread().getThreadGroup() == tg;
558 }
559
560 public void execute(Runnable r) {
561 count.getAndIncrement();
562 new Thread(tg, r).start();
563 }
564 }
565
566 static final boolean defaultExecutorIsCommonPool
567 = ForkJoinPool.getCommonPoolParallelism() > 1;
568
569 /**
570 * Permits the testing of parallel code for the 3 different
571 * execution modes without copy/pasting all the test methods.
572 */
573 enum ExecutionMode {
574 SYNC {
575 public void checkExecutionMode() {
576 assertFalse(ThreadExecutor.startedCurrentThread());
577 assertNull(ForkJoinTask.getPool());
578 }
579 public CompletableFuture<Void> runAsync(Runnable a) {
580 throw new UnsupportedOperationException();
581 }
582 public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
583 throw new UnsupportedOperationException();
584 }
585 public <T> CompletableFuture<Void> thenRun
586 (CompletableFuture<T> f, Runnable a) {
587 return f.thenRun(a);
588 }
589 public <T> CompletableFuture<Void> thenAccept
590 (CompletableFuture<T> f, Consumer<? super T> a) {
591 return f.thenAccept(a);
592 }
593 public <T,U> CompletableFuture<U> thenApply
594 (CompletableFuture<T> f, Function<? super T,U> a) {
595 return f.thenApply(a);
596 }
597 public <T,U> CompletableFuture<U> thenCompose
598 (CompletableFuture<T> f,
599 Function<? super T,? extends CompletionStage<U>> a) {
600 return f.thenCompose(a);
601 }
602 public <T,U> CompletableFuture<U> handle
603 (CompletableFuture<T> f,
604 BiFunction<? super T,Throwable,? extends U> a) {
605 return f.handle(a);
606 }
607 public <T> CompletableFuture<T> whenComplete
608 (CompletableFuture<T> f,
609 BiConsumer<? super T,? super Throwable> a) {
610 return f.whenComplete(a);
611 }
612 public <T,U> CompletableFuture<Void> runAfterBoth
613 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
614 return f.runAfterBoth(g, a);
615 }
616 public <T,U> CompletableFuture<Void> thenAcceptBoth
617 (CompletableFuture<T> f,
618 CompletionStage<? extends U> g,
619 BiConsumer<? super T,? super U> a) {
620 return f.thenAcceptBoth(g, a);
621 }
622 public <T,U,V> CompletableFuture<V> thenCombine
623 (CompletableFuture<T> f,
624 CompletionStage<? extends U> g,
625 BiFunction<? super T,? super U,? extends V> a) {
626 return f.thenCombine(g, a);
627 }
628 public <T> CompletableFuture<Void> runAfterEither
629 (CompletableFuture<T> f,
630 CompletionStage<?> g,
631 java.lang.Runnable a) {
632 return f.runAfterEither(g, a);
633 }
634 public <T> CompletableFuture<Void> acceptEither
635 (CompletableFuture<T> f,
636 CompletionStage<? extends T> g,
637 Consumer<? super T> a) {
638 return f.acceptEither(g, a);
639 }
640 public <T,U> CompletableFuture<U> applyToEither
641 (CompletableFuture<T> f,
642 CompletionStage<? extends T> g,
643 Function<? super T,U> a) {
644 return f.applyToEither(g, a);
645 }
646 },
647
648 ASYNC {
649 public void checkExecutionMode() {
650 assertEquals(defaultExecutorIsCommonPool,
651 (ForkJoinPool.commonPool() == ForkJoinTask.getPool()));
652 }
653 public CompletableFuture<Void> runAsync(Runnable a) {
654 return CompletableFuture.runAsync(a);
655 }
656 public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
657 return CompletableFuture.supplyAsync(a);
658 }
659 public <T> CompletableFuture<Void> thenRun
660 (CompletableFuture<T> f, Runnable a) {
661 return f.thenRunAsync(a);
662 }
663 public <T> CompletableFuture<Void> thenAccept
664 (CompletableFuture<T> f, Consumer<? super T> a) {
665 return f.thenAcceptAsync(a);
666 }
667 public <T,U> CompletableFuture<U> thenApply
668 (CompletableFuture<T> f, Function<? super T,U> a) {
669 return f.thenApplyAsync(a);
670 }
671 public <T,U> CompletableFuture<U> thenCompose
672 (CompletableFuture<T> f,
673 Function<? super T,? extends CompletionStage<U>> a) {
674 return f.thenComposeAsync(a);
675 }
676 public <T,U> CompletableFuture<U> handle
677 (CompletableFuture<T> f,
678 BiFunction<? super T,Throwable,? extends U> a) {
679 return f.handleAsync(a);
680 }
681 public <T> CompletableFuture<T> whenComplete
682 (CompletableFuture<T> f,
683 BiConsumer<? super T,? super Throwable> a) {
684 return f.whenCompleteAsync(a);
685 }
686 public <T,U> CompletableFuture<Void> runAfterBoth
687 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
688 return f.runAfterBothAsync(g, a);
689 }
690 public <T,U> CompletableFuture<Void> thenAcceptBoth
691 (CompletableFuture<T> f,
692 CompletionStage<? extends U> g,
693 BiConsumer<? super T,? super U> a) {
694 return f.thenAcceptBothAsync(g, a);
695 }
696 public <T,U,V> CompletableFuture<V> thenCombine
697 (CompletableFuture<T> f,
698 CompletionStage<? extends U> g,
699 BiFunction<? super T,? super U,? extends V> a) {
700 return f.thenCombineAsync(g, a);
701 }
702 public <T> CompletableFuture<Void> runAfterEither
703 (CompletableFuture<T> f,
704 CompletionStage<?> g,
705 java.lang.Runnable a) {
706 return f.runAfterEitherAsync(g, a);
707 }
708 public <T> CompletableFuture<Void> acceptEither
709 (CompletableFuture<T> f,
710 CompletionStage<? extends T> g,
711 Consumer<? super T> a) {
712 return f.acceptEitherAsync(g, a);
713 }
714 public <T,U> CompletableFuture<U> applyToEither
715 (CompletableFuture<T> f,
716 CompletionStage<? extends T> g,
717 Function<? super T,U> a) {
718 return f.applyToEitherAsync(g, a);
719 }
720 },
721
722 EXECUTOR {
723 public void checkExecutionMode() {
724 assertTrue(ThreadExecutor.startedCurrentThread());
725 }
726 public CompletableFuture<Void> runAsync(Runnable a) {
727 return CompletableFuture.runAsync(a, new ThreadExecutor());
728 }
729 public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
730 return CompletableFuture.supplyAsync(a, new ThreadExecutor());
731 }
732 public <T> CompletableFuture<Void> thenRun
733 (CompletableFuture<T> f, Runnable a) {
734 return f.thenRunAsync(a, new ThreadExecutor());
735 }
736 public <T> CompletableFuture<Void> thenAccept
737 (CompletableFuture<T> f, Consumer<? super T> a) {
738 return f.thenAcceptAsync(a, new ThreadExecutor());
739 }
740 public <T,U> CompletableFuture<U> thenApply
741 (CompletableFuture<T> f, Function<? super T,U> a) {
742 return f.thenApplyAsync(a, new ThreadExecutor());
743 }
744 public <T,U> CompletableFuture<U> thenCompose
745 (CompletableFuture<T> f,
746 Function<? super T,? extends CompletionStage<U>> a) {
747 return f.thenComposeAsync(a, new ThreadExecutor());
748 }
749 public <T,U> CompletableFuture<U> handle
750 (CompletableFuture<T> f,
751 BiFunction<? super T,Throwable,? extends U> a) {
752 return f.handleAsync(a, new ThreadExecutor());
753 }
754 public <T> CompletableFuture<T> whenComplete
755 (CompletableFuture<T> f,
756 BiConsumer<? super T,? super Throwable> a) {
757 return f.whenCompleteAsync(a, new ThreadExecutor());
758 }
759 public <T,U> CompletableFuture<Void> runAfterBoth
760 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
761 return f.runAfterBothAsync(g, a, new ThreadExecutor());
762 }
763 public <T,U> CompletableFuture<Void> thenAcceptBoth
764 (CompletableFuture<T> f,
765 CompletionStage<? extends U> g,
766 BiConsumer<? super T,? super U> a) {
767 return f.thenAcceptBothAsync(g, a, new ThreadExecutor());
768 }
769 public <T,U,V> CompletableFuture<V> thenCombine
770 (CompletableFuture<T> f,
771 CompletionStage<? extends U> g,
772 BiFunction<? super T,? super U,? extends V> a) {
773 return f.thenCombineAsync(g, a, new ThreadExecutor());
774 }
775 public <T> CompletableFuture<Void> runAfterEither
776 (CompletableFuture<T> f,
777 CompletionStage<?> g,
778 java.lang.Runnable a) {
779 return f.runAfterEitherAsync(g, a, new ThreadExecutor());
780 }
781 public <T> CompletableFuture<Void> acceptEither
782 (CompletableFuture<T> f,
783 CompletionStage<? extends T> g,
784 Consumer<? super T> a) {
785 return f.acceptEitherAsync(g, a, new ThreadExecutor());
786 }
787 public <T,U> CompletableFuture<U> applyToEither
788 (CompletableFuture<T> f,
789 CompletionStage<? extends T> g,
790 Function<? super T,U> a) {
791 return f.applyToEitherAsync(g, a, new ThreadExecutor());
792 }
793 };
794
795 public abstract void checkExecutionMode();
796 public abstract CompletableFuture<Void> runAsync(Runnable a);
797 public abstract <U> CompletableFuture<U> supplyAsync(Supplier<U> a);
798 public abstract <T> CompletableFuture<Void> thenRun
799 (CompletableFuture<T> f, Runnable a);
800 public abstract <T> CompletableFuture<Void> thenAccept
801 (CompletableFuture<T> f, Consumer<? super T> a);
802 public abstract <T,U> CompletableFuture<U> thenApply
803 (CompletableFuture<T> f, Function<? super T,U> a);
804 public abstract <T,U> CompletableFuture<U> thenCompose
805 (CompletableFuture<T> f,
806 Function<? super T,? extends CompletionStage<U>> a);
807 public abstract <T,U> CompletableFuture<U> handle
808 (CompletableFuture<T> f,
809 BiFunction<? super T,Throwable,? extends U> a);
810 public abstract <T> CompletableFuture<T> whenComplete
811 (CompletableFuture<T> f,
812 BiConsumer<? super T,? super Throwable> a);
813 public abstract <T,U> CompletableFuture<Void> runAfterBoth
814 (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a);
815 public abstract <T,U> CompletableFuture<Void> thenAcceptBoth
816 (CompletableFuture<T> f,
817 CompletionStage<? extends U> g,
818 BiConsumer<? super T,? super U> a);
819 public abstract <T,U,V> CompletableFuture<V> thenCombine
820 (CompletableFuture<T> f,
821 CompletionStage<? extends U> g,
822 BiFunction<? super T,? super U,? extends V> a);
823 public abstract <T> CompletableFuture<Void> runAfterEither
824 (CompletableFuture<T> f,
825 CompletionStage<?> g,
826 java.lang.Runnable a);
827 public abstract <T> CompletableFuture<Void> acceptEither
828 (CompletableFuture<T> f,
829 CompletionStage<? extends T> g,
830 Consumer<? super T> a);
831 public abstract <T,U> CompletableFuture<U> applyToEither
832 (CompletableFuture<T> f,
833 CompletionStage<? extends T> g,
834 Function<? super T,U> a);
835 }
836
837 /**
838 * exceptionally action is not invoked when source completes
839 * normally, and source result is propagated
840 */
841 public void testExceptionally_normalCompletion() {
842 for (boolean createIncomplete : new boolean[] { true, false })
843 for (Integer v1 : new Integer[] { 1, null })
844 {
845 final AtomicInteger a = new AtomicInteger(0);
846 final CompletableFuture<Integer> f = new CompletableFuture<>();
847 if (!createIncomplete) assertTrue(f.complete(v1));
848 final CompletableFuture<Integer> g = f.exceptionally
849 ((Throwable t) -> {
850 a.getAndIncrement();
851 threadFail("should not be called");
852 return null; // unreached
853 });
854 if (createIncomplete) assertTrue(f.complete(v1));
855
856 checkCompletedNormally(g, v1);
857 checkCompletedNormally(f, v1);
858 assertEquals(0, a.get());
859 }}
860
861 /**
862 * exceptionally action completes with function value on source
863 * exception
864 */
865 public void testExceptionally_exceptionalCompletion() {
866 for (boolean createIncomplete : new boolean[] { true, false })
867 for (Integer v1 : new Integer[] { 1, null })
868 {
869 final AtomicInteger a = new AtomicInteger(0);
870 final CFException ex = new CFException();
871 final CompletableFuture<Integer> f = new CompletableFuture<>();
872 if (!createIncomplete) f.completeExceptionally(ex);
873 final CompletableFuture<Integer> g = f.exceptionally
874 ((Throwable t) -> {
875 ExecutionMode.SYNC.checkExecutionMode();
876 threadAssertSame(t, ex);
877 a.getAndIncrement();
878 return v1;
879 });
880 if (createIncomplete) f.completeExceptionally(ex);
881
882 checkCompletedNormally(g, v1);
883 assertEquals(1, a.get());
884 }}
885
886 /**
887 * If an "exceptionally action" throws an exception, it completes
888 * exceptionally with that exception
889 */
890 public void testExceptionally_exceptionalCompletionActionFailed() {
891 for (boolean createIncomplete : new boolean[] { true, false })
892 {
893 final AtomicInteger a = new AtomicInteger(0);
894 final CFException ex1 = new CFException();
895 final CFException ex2 = new CFException();
896 final CompletableFuture<Integer> f = new CompletableFuture<>();
897 if (!createIncomplete) f.completeExceptionally(ex1);
898 final CompletableFuture<Integer> g = f.exceptionally
899 ((Throwable t) -> {
900 ExecutionMode.SYNC.checkExecutionMode();
901 threadAssertSame(t, ex1);
902 a.getAndIncrement();
903 throw ex2;
904 });
905 if (createIncomplete) f.completeExceptionally(ex1);
906
907 checkCompletedWithWrappedException(g, ex2);
908 checkCompletedExceptionally(f, ex1);
909 assertEquals(1, a.get());
910 }}
911
912 /**
913 * whenComplete action executes on normal completion, propagating
914 * source result.
915 */
916 public void testWhenComplete_normalCompletion() {
917 for (ExecutionMode m : ExecutionMode.values())
918 for (boolean createIncomplete : new boolean[] { true, false })
919 for (Integer v1 : new Integer[] { 1, null })
920 {
921 final AtomicInteger a = new AtomicInteger(0);
922 final CompletableFuture<Integer> f = new CompletableFuture<>();
923 if (!createIncomplete) assertTrue(f.complete(v1));
924 final CompletableFuture<Integer> g = m.whenComplete
925 (f,
926 (Integer result, Throwable t) -> {
927 m.checkExecutionMode();
928 threadAssertSame(result, v1);
929 threadAssertNull(t);
930 a.getAndIncrement();
931 });
932 if (createIncomplete) assertTrue(f.complete(v1));
933
934 checkCompletedNormally(g, v1);
935 checkCompletedNormally(f, v1);
936 assertEquals(1, a.get());
937 }}
938
939 /**
940 * whenComplete action executes on exceptional completion, propagating
941 * source result.
942 */
943 public void testWhenComplete_exceptionalCompletion() {
944 for (ExecutionMode m : ExecutionMode.values())
945 for (boolean createIncomplete : new boolean[] { true, false })
946 {
947 final AtomicInteger a = new AtomicInteger(0);
948 final CFException ex = new CFException();
949 final CompletableFuture<Integer> f = new CompletableFuture<>();
950 if (!createIncomplete) f.completeExceptionally(ex);
951 final CompletableFuture<Integer> g = m.whenComplete
952 (f,
953 (Integer result, Throwable t) -> {
954 m.checkExecutionMode();
955 threadAssertNull(result);
956 threadAssertSame(t, ex);
957 a.getAndIncrement();
958 });
959 if (createIncomplete) f.completeExceptionally(ex);
960
961 checkCompletedWithWrappedException(g, ex);
962 checkCompletedExceptionally(f, ex);
963 assertEquals(1, a.get());
964 }}
965
966 /**
967 * whenComplete action executes on cancelled source, propagating
968 * CancellationException.
969 */
970 public void testWhenComplete_sourceCancelled() {
971 for (ExecutionMode m : ExecutionMode.values())
972 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
973 for (boolean createIncomplete : new boolean[] { true, false })
974 {
975 final AtomicInteger a = new AtomicInteger(0);
976 final CompletableFuture<Integer> f = new CompletableFuture<>();
977 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
978 final CompletableFuture<Integer> g = m.whenComplete
979 (f,
980 (Integer result, Throwable t) -> {
981 m.checkExecutionMode();
982 threadAssertNull(result);
983 threadAssertTrue(t instanceof CancellationException);
984 a.getAndIncrement();
985 });
986 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
987
988 checkCompletedWithWrappedCancellationException(g);
989 checkCancelled(f);
990 assertEquals(1, a.get());
991 }}
992
993 /**
994 * If a whenComplete action throws an exception when triggered by
995 * a normal completion, it completes exceptionally
996 */
997 public void testWhenComplete_sourceCompletedNormallyActionFailed() {
998 for (boolean createIncomplete : new boolean[] { true, false })
999 for (ExecutionMode m : ExecutionMode.values())
1000 for (Integer v1 : new Integer[] { 1, null })
1001 {
1002 final AtomicInteger a = new AtomicInteger(0);
1003 final CFException ex = new CFException();
1004 final CompletableFuture<Integer> f = new CompletableFuture<>();
1005 if (!createIncomplete) assertTrue(f.complete(v1));
1006 final CompletableFuture<Integer> g = m.whenComplete
1007 (f,
1008 (Integer result, Throwable t) -> {
1009 m.checkExecutionMode();
1010 threadAssertSame(result, v1);
1011 threadAssertNull(t);
1012 a.getAndIncrement();
1013 throw ex;
1014 });
1015 if (createIncomplete) assertTrue(f.complete(v1));
1016
1017 checkCompletedWithWrappedException(g, ex);
1018 checkCompletedNormally(f, v1);
1019 assertEquals(1, a.get());
1020 }}
1021
1022 /**
1023 * If a whenComplete action throws an exception when triggered by
1024 * a source completion that also throws an exception, the source
1025 * exception takes precedence (unlike handle)
1026 */
1027 public void testWhenComplete_sourceFailedActionFailed() {
1028 for (boolean createIncomplete : new boolean[] { true, false })
1029 for (ExecutionMode m : ExecutionMode.values())
1030 {
1031 final AtomicInteger a = new AtomicInteger(0);
1032 final CFException ex1 = new CFException();
1033 final CFException ex2 = new CFException();
1034 final CompletableFuture<Integer> f = new CompletableFuture<>();
1035
1036 if (!createIncomplete) f.completeExceptionally(ex1);
1037 final CompletableFuture<Integer> g = m.whenComplete
1038 (f,
1039 (Integer result, Throwable t) -> {
1040 m.checkExecutionMode();
1041 threadAssertSame(t, ex1);
1042 threadAssertNull(result);
1043 a.getAndIncrement();
1044 throw ex2;
1045 });
1046 if (createIncomplete) f.completeExceptionally(ex1);
1047
1048 checkCompletedWithWrappedException(g, ex1);
1049 checkCompletedExceptionally(f, ex1);
1050 if (testImplementationDetails) {
1051 assertEquals(1, ex1.getSuppressed().length);
1052 assertSame(ex2, ex1.getSuppressed()[0]);
1053 }
1054 assertEquals(1, a.get());
1055 }}
1056
1057 /**
1058 * handle action completes normally with function value on normal
1059 * completion of source
1060 */
1061 public void testHandle_normalCompletion() {
1062 for (ExecutionMode m : ExecutionMode.values())
1063 for (boolean createIncomplete : new boolean[] { true, false })
1064 for (Integer v1 : new Integer[] { 1, null })
1065 {
1066 final CompletableFuture<Integer> f = new CompletableFuture<>();
1067 final AtomicInteger a = new AtomicInteger(0);
1068 if (!createIncomplete) assertTrue(f.complete(v1));
1069 final CompletableFuture<Integer> g = m.handle
1070 (f,
1071 (Integer result, Throwable t) -> {
1072 m.checkExecutionMode();
1073 threadAssertSame(result, v1);
1074 threadAssertNull(t);
1075 a.getAndIncrement();
1076 return inc(v1);
1077 });
1078 if (createIncomplete) assertTrue(f.complete(v1));
1079
1080 checkCompletedNormally(g, inc(v1));
1081 checkCompletedNormally(f, v1);
1082 assertEquals(1, a.get());
1083 }}
1084
1085 /**
1086 * handle action completes normally with function value on
1087 * exceptional completion of source
1088 */
1089 public void testHandle_exceptionalCompletion() {
1090 for (ExecutionMode m : ExecutionMode.values())
1091 for (boolean createIncomplete : new boolean[] { true, false })
1092 for (Integer v1 : new Integer[] { 1, null })
1093 {
1094 final CompletableFuture<Integer> f = new CompletableFuture<>();
1095 final AtomicInteger a = new AtomicInteger(0);
1096 final CFException ex = new CFException();
1097 if (!createIncomplete) f.completeExceptionally(ex);
1098 final CompletableFuture<Integer> g = m.handle
1099 (f,
1100 (Integer result, Throwable t) -> {
1101 m.checkExecutionMode();
1102 threadAssertNull(result);
1103 threadAssertSame(t, ex);
1104 a.getAndIncrement();
1105 return v1;
1106 });
1107 if (createIncomplete) f.completeExceptionally(ex);
1108
1109 checkCompletedNormally(g, v1);
1110 checkCompletedExceptionally(f, ex);
1111 assertEquals(1, a.get());
1112 }}
1113
1114 /**
1115 * handle action completes normally with function value on
1116 * cancelled source
1117 */
1118 public void testHandle_sourceCancelled() {
1119 for (ExecutionMode m : ExecutionMode.values())
1120 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1121 for (boolean createIncomplete : new boolean[] { true, false })
1122 for (Integer v1 : new Integer[] { 1, null })
1123 {
1124 final CompletableFuture<Integer> f = new CompletableFuture<>();
1125 final AtomicInteger a = new AtomicInteger(0);
1126 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1127 final CompletableFuture<Integer> g = m.handle
1128 (f,
1129 (Integer result, Throwable t) -> {
1130 m.checkExecutionMode();
1131 threadAssertNull(result);
1132 threadAssertTrue(t instanceof CancellationException);
1133 a.getAndIncrement();
1134 return v1;
1135 });
1136 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1137
1138 checkCompletedNormally(g, v1);
1139 checkCancelled(f);
1140 assertEquals(1, a.get());
1141 }}
1142
1143 /**
1144 * If a "handle action" throws an exception when triggered by
1145 * a normal completion, it completes exceptionally
1146 */
1147 public void testHandle_sourceCompletedNormallyActionFailed() {
1148 for (ExecutionMode m : ExecutionMode.values())
1149 for (boolean createIncomplete : new boolean[] { true, false })
1150 for (Integer v1 : new Integer[] { 1, null })
1151 {
1152 final CompletableFuture<Integer> f = new CompletableFuture<>();
1153 final AtomicInteger a = new AtomicInteger(0);
1154 final CFException ex = new CFException();
1155 if (!createIncomplete) assertTrue(f.complete(v1));
1156 final CompletableFuture<Integer> g = m.handle
1157 (f,
1158 (Integer result, Throwable t) -> {
1159 m.checkExecutionMode();
1160 threadAssertSame(result, v1);
1161 threadAssertNull(t);
1162 a.getAndIncrement();
1163 throw ex;
1164 });
1165 if (createIncomplete) assertTrue(f.complete(v1));
1166
1167 checkCompletedWithWrappedException(g, ex);
1168 checkCompletedNormally(f, v1);
1169 assertEquals(1, a.get());
1170 }}
1171
1172 /**
1173 * If a "handle action" throws an exception when triggered by
1174 * a source completion that also throws an exception, the action
1175 * exception takes precedence (unlike whenComplete)
1176 */
1177 public void testHandle_sourceFailedActionFailed() {
1178 for (boolean createIncomplete : new boolean[] { true, false })
1179 for (ExecutionMode m : ExecutionMode.values())
1180 {
1181 final AtomicInteger a = new AtomicInteger(0);
1182 final CFException ex1 = new CFException();
1183 final CFException ex2 = new CFException();
1184 final CompletableFuture<Integer> f = new CompletableFuture<>();
1185
1186 if (!createIncomplete) f.completeExceptionally(ex1);
1187 final CompletableFuture<Integer> g = m.handle
1188 (f,
1189 (Integer result, Throwable t) -> {
1190 m.checkExecutionMode();
1191 threadAssertNull(result);
1192 threadAssertSame(ex1, t);
1193 a.getAndIncrement();
1194 throw ex2;
1195 });
1196 if (createIncomplete) f.completeExceptionally(ex1);
1197
1198 checkCompletedWithWrappedException(g, ex2);
1199 checkCompletedExceptionally(f, ex1);
1200 assertEquals(1, a.get());
1201 }}
1202
1203 /**
1204 * runAsync completes after running Runnable
1205 */
1206 public void testRunAsync_normalCompletion() {
1207 ExecutionMode[] executionModes = {
1208 ExecutionMode.ASYNC,
1209 ExecutionMode.EXECUTOR,
1210 };
1211 for (ExecutionMode m : executionModes)
1212 {
1213 final Noop r = new Noop(m);
1214 final CompletableFuture<Void> f = m.runAsync(r);
1215 assertNull(f.join());
1216 checkCompletedNormally(f, null);
1217 r.assertInvoked();
1218 }}
1219
1220 /**
1221 * failing runAsync completes exceptionally after running Runnable
1222 */
1223 public void testRunAsync_exceptionalCompletion() {
1224 ExecutionMode[] executionModes = {
1225 ExecutionMode.ASYNC,
1226 ExecutionMode.EXECUTOR,
1227 };
1228 for (ExecutionMode m : executionModes)
1229 {
1230 final FailingRunnable r = new FailingRunnable(m);
1231 final CompletableFuture<Void> f = m.runAsync(r);
1232 checkCompletedWithWrappedException(f, r.ex);
1233 r.assertInvoked();
1234 }}
1235
1236 /**
1237 * supplyAsync completes with result of supplier
1238 */
1239 public void testSupplyAsync_normalCompletion() {
1240 ExecutionMode[] executionModes = {
1241 ExecutionMode.ASYNC,
1242 ExecutionMode.EXECUTOR,
1243 };
1244 for (ExecutionMode m : executionModes)
1245 for (Integer v1 : new Integer[] { 1, null })
1246 {
1247 final IntegerSupplier r = new IntegerSupplier(m, v1);
1248 final CompletableFuture<Integer> f = m.supplyAsync(r);
1249 assertSame(v1, f.join());
1250 checkCompletedNormally(f, v1);
1251 r.assertInvoked();
1252 }}
1253
1254 /**
1255 * Failing supplyAsync completes exceptionally
1256 */
1257 public void testSupplyAsync_exceptionalCompletion() {
1258 ExecutionMode[] executionModes = {
1259 ExecutionMode.ASYNC,
1260 ExecutionMode.EXECUTOR,
1261 };
1262 for (ExecutionMode m : executionModes)
1263 {
1264 FailingSupplier r = new FailingSupplier(m);
1265 CompletableFuture<Integer> f = m.supplyAsync(r);
1266 checkCompletedWithWrappedException(f, r.ex);
1267 r.assertInvoked();
1268 }}
1269
1270 // seq completion methods
1271
1272 /**
1273 * thenRun result completes normally after normal completion of source
1274 */
1275 public void testThenRun_normalCompletion() {
1276 for (ExecutionMode m : ExecutionMode.values())
1277 for (Integer v1 : new Integer[] { 1, null })
1278 {
1279 final CompletableFuture<Integer> f = new CompletableFuture<>();
1280 final Noop[] rs = new Noop[6];
1281 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1282
1283 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1284 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1285 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1286 checkIncomplete(h0);
1287 checkIncomplete(h1);
1288 checkIncomplete(h2);
1289 assertTrue(f.complete(v1));
1290 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1291 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1292 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1293
1294 checkCompletedNormally(h0, null);
1295 checkCompletedNormally(h1, null);
1296 checkCompletedNormally(h2, null);
1297 checkCompletedNormally(h3, null);
1298 checkCompletedNormally(h4, null);
1299 checkCompletedNormally(h5, null);
1300 checkCompletedNormally(f, v1);
1301 for (Noop r : rs) r.assertInvoked();
1302 }}
1303
1304 /**
1305 * thenRun result completes exceptionally after exceptional
1306 * completion of source
1307 */
1308 public void testThenRun_exceptionalCompletion() {
1309 for (ExecutionMode m : ExecutionMode.values())
1310 {
1311 final CFException ex = new CFException();
1312 final CompletableFuture<Integer> f = new CompletableFuture<>();
1313 final Noop[] rs = new Noop[6];
1314 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1315
1316 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1317 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1318 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1319 checkIncomplete(h0);
1320 checkIncomplete(h1);
1321 checkIncomplete(h2);
1322 assertTrue(f.completeExceptionally(ex));
1323 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1324 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1325 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1326
1327 checkCompletedWithWrappedException(h0, ex);
1328 checkCompletedWithWrappedException(h1, ex);
1329 checkCompletedWithWrappedException(h2, ex);
1330 checkCompletedWithWrappedException(h3, ex);
1331 checkCompletedWithWrappedException(h4, ex);
1332 checkCompletedWithWrappedException(h5, ex);
1333 checkCompletedExceptionally(f, ex);
1334 for (Noop r : rs) r.assertNotInvoked();
1335 }}
1336
1337 /**
1338 * thenRun result completes exceptionally if source cancelled
1339 */
1340 public void testThenRun_sourceCancelled() {
1341 for (ExecutionMode m : ExecutionMode.values())
1342 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1343 {
1344 final CompletableFuture<Integer> f = new CompletableFuture<>();
1345 final Noop[] rs = new Noop[6];
1346 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1347
1348 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1349 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1350 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1351 checkIncomplete(h0);
1352 checkIncomplete(h1);
1353 checkIncomplete(h2);
1354 assertTrue(f.cancel(mayInterruptIfRunning));
1355 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1356 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1357 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1358
1359 checkCompletedWithWrappedCancellationException(h0);
1360 checkCompletedWithWrappedCancellationException(h1);
1361 checkCompletedWithWrappedCancellationException(h2);
1362 checkCompletedWithWrappedCancellationException(h3);
1363 checkCompletedWithWrappedCancellationException(h4);
1364 checkCompletedWithWrappedCancellationException(h5);
1365 checkCancelled(f);
1366 for (Noop r : rs) r.assertNotInvoked();
1367 }}
1368
1369 /**
1370 * thenRun result completes exceptionally if action does
1371 */
1372 public void testThenRun_actionFailed() {
1373 for (ExecutionMode m : ExecutionMode.values())
1374 for (Integer v1 : new Integer[] { 1, null })
1375 {
1376 final CompletableFuture<Integer> f = new CompletableFuture<>();
1377 final FailingRunnable[] rs = new FailingRunnable[6];
1378 for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
1379
1380 final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1381 final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1382 final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1383 assertTrue(f.complete(v1));
1384 final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1385 final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1386 final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1387
1388 checkCompletedWithWrappedException(h0, rs[0].ex);
1389 checkCompletedWithWrappedException(h1, rs[1].ex);
1390 checkCompletedWithWrappedException(h2, rs[2].ex);
1391 checkCompletedWithWrappedException(h3, rs[3].ex);
1392 checkCompletedWithWrappedException(h4, rs[4].ex);
1393 checkCompletedWithWrappedException(h5, rs[5].ex);
1394 checkCompletedNormally(f, v1);
1395 }}
1396
1397 /**
1398 * thenApply result completes normally after normal completion of source
1399 */
1400 public void testThenApply_normalCompletion() {
1401 for (ExecutionMode m : ExecutionMode.values())
1402 for (Integer v1 : new Integer[] { 1, null })
1403 {
1404 final CompletableFuture<Integer> f = new CompletableFuture<>();
1405 final IncFunction[] rs = new IncFunction[4];
1406 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1407
1408 final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1409 final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1410 checkIncomplete(h0);
1411 checkIncomplete(h1);
1412 assertTrue(f.complete(v1));
1413 final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1414 final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1415
1416 checkCompletedNormally(h0, inc(v1));
1417 checkCompletedNormally(h1, inc(v1));
1418 checkCompletedNormally(h2, inc(v1));
1419 checkCompletedNormally(h3, inc(v1));
1420 checkCompletedNormally(f, v1);
1421 for (IncFunction r : rs) r.assertValue(inc(v1));
1422 }}
1423
1424 /**
1425 * thenApply result completes exceptionally after exceptional
1426 * completion of source
1427 */
1428 public void testThenApply_exceptionalCompletion() {
1429 for (ExecutionMode m : ExecutionMode.values())
1430 {
1431 final CFException ex = new CFException();
1432 final CompletableFuture<Integer> f = new CompletableFuture<>();
1433 final IncFunction[] rs = new IncFunction[4];
1434 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1435
1436 final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1437 final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1438 assertTrue(f.completeExceptionally(ex));
1439 final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1440 final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1441
1442 checkCompletedWithWrappedException(h0, ex);
1443 checkCompletedWithWrappedException(h1, ex);
1444 checkCompletedWithWrappedException(h2, ex);
1445 checkCompletedWithWrappedException(h3, ex);
1446 checkCompletedExceptionally(f, ex);
1447 for (IncFunction r : rs) r.assertNotInvoked();
1448 }}
1449
1450 /**
1451 * thenApply result completes exceptionally if source cancelled
1452 */
1453 public void testThenApply_sourceCancelled() {
1454 for (ExecutionMode m : ExecutionMode.values())
1455 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1456 {
1457 final CompletableFuture<Integer> f = new CompletableFuture<>();
1458 final IncFunction[] rs = new IncFunction[4];
1459 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1460
1461 final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1462 final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1463 assertTrue(f.cancel(mayInterruptIfRunning));
1464 final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1465 final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1466
1467 checkCompletedWithWrappedCancellationException(h0);
1468 checkCompletedWithWrappedCancellationException(h1);
1469 checkCompletedWithWrappedCancellationException(h2);
1470 checkCompletedWithWrappedCancellationException(h3);
1471 checkCancelled(f);
1472 for (IncFunction r : rs) r.assertNotInvoked();
1473 }}
1474
1475 /**
1476 * thenApply result completes exceptionally if action does
1477 */
1478 public void testThenApply_actionFailed() {
1479 for (ExecutionMode m : ExecutionMode.values())
1480 for (Integer v1 : new Integer[] { 1, null })
1481 {
1482 final CompletableFuture<Integer> f = new CompletableFuture<>();
1483 final FailingFunction[] rs = new FailingFunction[4];
1484 for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
1485
1486 final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1487 final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1488 assertTrue(f.complete(v1));
1489 final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1490 final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1491
1492 checkCompletedWithWrappedException(h0, rs[0].ex);
1493 checkCompletedWithWrappedException(h1, rs[1].ex);
1494 checkCompletedWithWrappedException(h2, rs[2].ex);
1495 checkCompletedWithWrappedException(h3, rs[3].ex);
1496 checkCompletedNormally(f, v1);
1497 }}
1498
1499 /**
1500 * thenAccept result completes normally after normal completion of source
1501 */
1502 public void testThenAccept_normalCompletion() {
1503 for (ExecutionMode m : ExecutionMode.values())
1504 for (Integer v1 : new Integer[] { 1, null })
1505 {
1506 final CompletableFuture<Integer> f = new CompletableFuture<>();
1507 final NoopConsumer[] rs = new NoopConsumer[4];
1508 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1509
1510 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1511 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1512 checkIncomplete(h0);
1513 checkIncomplete(h1);
1514 assertTrue(f.complete(v1));
1515 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1516 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1517
1518 checkCompletedNormally(h0, null);
1519 checkCompletedNormally(h1, null);
1520 checkCompletedNormally(h2, null);
1521 checkCompletedNormally(h3, null);
1522 checkCompletedNormally(f, v1);
1523 for (NoopConsumer r : rs) r.assertValue(v1);
1524 }}
1525
1526 /**
1527 * thenAccept result completes exceptionally after exceptional
1528 * completion of source
1529 */
1530 public void testThenAccept_exceptionalCompletion() {
1531 for (ExecutionMode m : ExecutionMode.values())
1532 {
1533 final CFException ex = new CFException();
1534 final CompletableFuture<Integer> f = new CompletableFuture<>();
1535 final NoopConsumer[] rs = new NoopConsumer[4];
1536 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1537
1538 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1539 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1540 assertTrue(f.completeExceptionally(ex));
1541 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1542 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1543
1544 checkCompletedWithWrappedException(h0, ex);
1545 checkCompletedWithWrappedException(h1, ex);
1546 checkCompletedWithWrappedException(h2, ex);
1547 checkCompletedWithWrappedException(h3, ex);
1548 checkCompletedExceptionally(f, ex);
1549 for (NoopConsumer r : rs) r.assertNotInvoked();
1550 }}
1551
1552 /**
1553 * thenAccept result completes exceptionally if source cancelled
1554 */
1555 public void testThenAccept_sourceCancelled() {
1556 for (ExecutionMode m : ExecutionMode.values())
1557 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1558 {
1559 final CompletableFuture<Integer> f = new CompletableFuture<>();
1560 final NoopConsumer[] rs = new NoopConsumer[4];
1561 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1562
1563 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1564 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1565 assertTrue(f.cancel(mayInterruptIfRunning));
1566 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1567 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1568
1569 checkCompletedWithWrappedCancellationException(h0);
1570 checkCompletedWithWrappedCancellationException(h1);
1571 checkCompletedWithWrappedCancellationException(h2);
1572 checkCompletedWithWrappedCancellationException(h3);
1573 checkCancelled(f);
1574 for (NoopConsumer r : rs) r.assertNotInvoked();
1575 }}
1576
1577 /**
1578 * thenAccept result completes exceptionally if action does
1579 */
1580 public void testThenAccept_actionFailed() {
1581 for (ExecutionMode m : ExecutionMode.values())
1582 for (Integer v1 : new Integer[] { 1, null })
1583 {
1584 final CompletableFuture<Integer> f = new CompletableFuture<>();
1585 final FailingConsumer[] rs = new FailingConsumer[4];
1586 for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
1587
1588 final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1589 final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1590 assertTrue(f.complete(v1));
1591 final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1592 final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1593
1594 checkCompletedWithWrappedException(h0, rs[0].ex);
1595 checkCompletedWithWrappedException(h1, rs[1].ex);
1596 checkCompletedWithWrappedException(h2, rs[2].ex);
1597 checkCompletedWithWrappedException(h3, rs[3].ex);
1598 checkCompletedNormally(f, v1);
1599 }}
1600
1601 /**
1602 * thenCombine result completes normally after normal completion
1603 * of sources
1604 */
1605 public void testThenCombine_normalCompletion() {
1606 for (ExecutionMode m : ExecutionMode.values())
1607 for (boolean fFirst : new boolean[] { true, false })
1608 for (Integer v1 : new Integer[] { 1, null })
1609 for (Integer v2 : new Integer[] { 2, null })
1610 {
1611 final CompletableFuture<Integer> f = new CompletableFuture<>();
1612 final CompletableFuture<Integer> g = new CompletableFuture<>();
1613 final SubtractFunction[] rs = new SubtractFunction[6];
1614 for (int i = 0; i < rs.length; i++) rs[i] = new SubtractFunction(m);
1615
1616 final CompletableFuture<Integer> fst = fFirst ? f : g;
1617 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1618 final Integer w1 = fFirst ? v1 : v2;
1619 final Integer w2 = !fFirst ? v1 : v2;
1620
1621 final CompletableFuture<Integer> h0 = m.thenCombine(f, g, rs[0]);
1622 final CompletableFuture<Integer> h1 = m.thenCombine(fst, fst, rs[1]);
1623 assertTrue(fst.complete(w1));
1624 final CompletableFuture<Integer> h2 = m.thenCombine(f, g, rs[2]);
1625 final CompletableFuture<Integer> h3 = m.thenCombine(fst, fst, rs[3]);
1626 checkIncomplete(h0); rs[0].assertNotInvoked();
1627 checkIncomplete(h2); rs[2].assertNotInvoked();
1628 checkCompletedNormally(h1, subtract(w1, w1));
1629 checkCompletedNormally(h3, subtract(w1, w1));
1630 rs[1].assertValue(subtract(w1, w1));
1631 rs[3].assertValue(subtract(w1, w1));
1632 assertTrue(snd.complete(w2));
1633 final CompletableFuture<Integer> h4 = m.thenCombine(f, g, rs[4]);
1634
1635 checkCompletedNormally(h0, subtract(v1, v2));
1636 checkCompletedNormally(h2, subtract(v1, v2));
1637 checkCompletedNormally(h4, subtract(v1, v2));
1638 rs[0].assertValue(subtract(v1, v2));
1639 rs[2].assertValue(subtract(v1, v2));
1640 rs[4].assertValue(subtract(v1, v2));
1641
1642 checkCompletedNormally(f, v1);
1643 checkCompletedNormally(g, v2);
1644 }}
1645
1646 /**
1647 * thenCombine result completes exceptionally after exceptional
1648 * completion of either source
1649 */
1650 public void testThenCombine_exceptionalCompletion() throws Throwable {
1651 for (ExecutionMode m : ExecutionMode.values())
1652 for (boolean fFirst : new boolean[] { true, false })
1653 for (boolean failFirst : new boolean[] { true, false })
1654 for (Integer v1 : new Integer[] { 1, null })
1655 {
1656 final CompletableFuture<Integer> f = new CompletableFuture<>();
1657 final CompletableFuture<Integer> g = new CompletableFuture<>();
1658 final CFException ex = new CFException();
1659 final SubtractFunction r1 = new SubtractFunction(m);
1660 final SubtractFunction r2 = new SubtractFunction(m);
1661 final SubtractFunction r3 = new SubtractFunction(m);
1662
1663 final CompletableFuture<Integer> fst = fFirst ? f : g;
1664 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1665 final Callable<Boolean> complete1 = failFirst ?
1666 () -> fst.completeExceptionally(ex) :
1667 () -> fst.complete(v1);
1668 final Callable<Boolean> complete2 = failFirst ?
1669 () -> snd.complete(v1) :
1670 () -> snd.completeExceptionally(ex);
1671
1672 final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1673 assertTrue(complete1.call());
1674 final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1675 checkIncomplete(h1);
1676 checkIncomplete(h2);
1677 assertTrue(complete2.call());
1678 final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1679
1680 checkCompletedWithWrappedException(h1, ex);
1681 checkCompletedWithWrappedException(h2, ex);
1682 checkCompletedWithWrappedException(h3, ex);
1683 r1.assertNotInvoked();
1684 r2.assertNotInvoked();
1685 r3.assertNotInvoked();
1686 checkCompletedNormally(failFirst ? snd : fst, v1);
1687 checkCompletedExceptionally(failFirst ? fst : snd, ex);
1688 }}
1689
1690 /**
1691 * thenCombine result completes exceptionally if either source cancelled
1692 */
1693 public void testThenCombine_sourceCancelled() throws Throwable {
1694 for (ExecutionMode m : ExecutionMode.values())
1695 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1696 for (boolean fFirst : new boolean[] { true, false })
1697 for (boolean failFirst : new boolean[] { true, false })
1698 for (Integer v1 : new Integer[] { 1, null })
1699 {
1700 final CompletableFuture<Integer> f = new CompletableFuture<>();
1701 final CompletableFuture<Integer> g = new CompletableFuture<>();
1702 final SubtractFunction r1 = new SubtractFunction(m);
1703 final SubtractFunction r2 = new SubtractFunction(m);
1704 final SubtractFunction r3 = new SubtractFunction(m);
1705
1706 final CompletableFuture<Integer> fst = fFirst ? f : g;
1707 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1708 final Callable<Boolean> complete1 = failFirst ?
1709 () -> fst.cancel(mayInterruptIfRunning) :
1710 () -> fst.complete(v1);
1711 final Callable<Boolean> complete2 = failFirst ?
1712 () -> snd.complete(v1) :
1713 () -> snd.cancel(mayInterruptIfRunning);
1714
1715 final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1716 assertTrue(complete1.call());
1717 final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1718 checkIncomplete(h1);
1719 checkIncomplete(h2);
1720 assertTrue(complete2.call());
1721 final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1722
1723 checkCompletedWithWrappedCancellationException(h1);
1724 checkCompletedWithWrappedCancellationException(h2);
1725 checkCompletedWithWrappedCancellationException(h3);
1726 r1.assertNotInvoked();
1727 r2.assertNotInvoked();
1728 r3.assertNotInvoked();
1729 checkCompletedNormally(failFirst ? snd : fst, v1);
1730 checkCancelled(failFirst ? fst : snd);
1731 }}
1732
1733 /**
1734 * thenCombine result completes exceptionally if action does
1735 */
1736 public void testThenCombine_actionFailed() {
1737 for (ExecutionMode m : ExecutionMode.values())
1738 for (boolean fFirst : new boolean[] { true, false })
1739 for (Integer v1 : new Integer[] { 1, null })
1740 for (Integer v2 : new Integer[] { 2, null })
1741 {
1742 final CompletableFuture<Integer> f = new CompletableFuture<>();
1743 final CompletableFuture<Integer> g = new CompletableFuture<>();
1744 final FailingBiFunction r1 = new FailingBiFunction(m);
1745 final FailingBiFunction r2 = new FailingBiFunction(m);
1746 final FailingBiFunction r3 = new FailingBiFunction(m);
1747
1748 final CompletableFuture<Integer> fst = fFirst ? f : g;
1749 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1750 final Integer w1 = fFirst ? v1 : v2;
1751 final Integer w2 = !fFirst ? v1 : v2;
1752
1753 final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1754 assertTrue(fst.complete(w1));
1755 final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1756 assertTrue(snd.complete(w2));
1757 final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1758
1759 checkCompletedWithWrappedException(h1, r1.ex);
1760 checkCompletedWithWrappedException(h2, r2.ex);
1761 checkCompletedWithWrappedException(h3, r3.ex);
1762 r1.assertInvoked();
1763 r2.assertInvoked();
1764 r3.assertInvoked();
1765 checkCompletedNormally(f, v1);
1766 checkCompletedNormally(g, v2);
1767 }}
1768
1769 /**
1770 * thenAcceptBoth result completes normally after normal
1771 * completion of sources
1772 */
1773 public void testThenAcceptBoth_normalCompletion() {
1774 for (ExecutionMode m : ExecutionMode.values())
1775 for (boolean fFirst : new boolean[] { true, false })
1776 for (Integer v1 : new Integer[] { 1, null })
1777 for (Integer v2 : new Integer[] { 2, null })
1778 {
1779 final CompletableFuture<Integer> f = new CompletableFuture<>();
1780 final CompletableFuture<Integer> g = new CompletableFuture<>();
1781 final SubtractAction r1 = new SubtractAction(m);
1782 final SubtractAction r2 = new SubtractAction(m);
1783 final SubtractAction r3 = new SubtractAction(m);
1784
1785 final CompletableFuture<Integer> fst = fFirst ? f : g;
1786 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1787 final Integer w1 = fFirst ? v1 : v2;
1788 final Integer w2 = !fFirst ? v1 : v2;
1789
1790 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1791 assertTrue(fst.complete(w1));
1792 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1793 checkIncomplete(h1);
1794 checkIncomplete(h2);
1795 r1.assertNotInvoked();
1796 r2.assertNotInvoked();
1797 assertTrue(snd.complete(w2));
1798 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1799
1800 checkCompletedNormally(h1, null);
1801 checkCompletedNormally(h2, null);
1802 checkCompletedNormally(h3, null);
1803 r1.assertValue(subtract(v1, v2));
1804 r2.assertValue(subtract(v1, v2));
1805 r3.assertValue(subtract(v1, v2));
1806 checkCompletedNormally(f, v1);
1807 checkCompletedNormally(g, v2);
1808 }}
1809
1810 /**
1811 * thenAcceptBoth result completes exceptionally after exceptional
1812 * completion of either source
1813 */
1814 public void testThenAcceptBoth_exceptionalCompletion() throws Throwable {
1815 for (ExecutionMode m : ExecutionMode.values())
1816 for (boolean fFirst : new boolean[] { true, false })
1817 for (boolean failFirst : new boolean[] { true, false })
1818 for (Integer v1 : new Integer[] { 1, null })
1819 {
1820 final CompletableFuture<Integer> f = new CompletableFuture<>();
1821 final CompletableFuture<Integer> g = new CompletableFuture<>();
1822 final CFException ex = new CFException();
1823 final SubtractAction r1 = new SubtractAction(m);
1824 final SubtractAction r2 = new SubtractAction(m);
1825 final SubtractAction r3 = new SubtractAction(m);
1826
1827 final CompletableFuture<Integer> fst = fFirst ? f : g;
1828 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1829 final Callable<Boolean> complete1 = failFirst ?
1830 () -> fst.completeExceptionally(ex) :
1831 () -> fst.complete(v1);
1832 final Callable<Boolean> complete2 = failFirst ?
1833 () -> snd.complete(v1) :
1834 () -> snd.completeExceptionally(ex);
1835
1836 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1837 assertTrue(complete1.call());
1838 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1839 checkIncomplete(h1);
1840 checkIncomplete(h2);
1841 assertTrue(complete2.call());
1842 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1843
1844 checkCompletedWithWrappedException(h1, ex);
1845 checkCompletedWithWrappedException(h2, ex);
1846 checkCompletedWithWrappedException(h3, ex);
1847 r1.assertNotInvoked();
1848 r2.assertNotInvoked();
1849 r3.assertNotInvoked();
1850 checkCompletedNormally(failFirst ? snd : fst, v1);
1851 checkCompletedExceptionally(failFirst ? fst : snd, ex);
1852 }}
1853
1854 /**
1855 * thenAcceptBoth result completes exceptionally if either source cancelled
1856 */
1857 public void testThenAcceptBoth_sourceCancelled() throws Throwable {
1858 for (ExecutionMode m : ExecutionMode.values())
1859 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1860 for (boolean fFirst : new boolean[] { true, false })
1861 for (boolean failFirst : new boolean[] { true, false })
1862 for (Integer v1 : new Integer[] { 1, null })
1863 {
1864 final CompletableFuture<Integer> f = new CompletableFuture<>();
1865 final CompletableFuture<Integer> g = new CompletableFuture<>();
1866 final SubtractAction r1 = new SubtractAction(m);
1867 final SubtractAction r2 = new SubtractAction(m);
1868 final SubtractAction r3 = new SubtractAction(m);
1869
1870 final CompletableFuture<Integer> fst = fFirst ? f : g;
1871 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1872 final Callable<Boolean> complete1 = failFirst ?
1873 () -> fst.cancel(mayInterruptIfRunning) :
1874 () -> fst.complete(v1);
1875 final Callable<Boolean> complete2 = failFirst ?
1876 () -> snd.complete(v1) :
1877 () -> snd.cancel(mayInterruptIfRunning);
1878
1879 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1880 assertTrue(complete1.call());
1881 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1882 checkIncomplete(h1);
1883 checkIncomplete(h2);
1884 assertTrue(complete2.call());
1885 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1886
1887 checkCompletedWithWrappedCancellationException(h1);
1888 checkCompletedWithWrappedCancellationException(h2);
1889 checkCompletedWithWrappedCancellationException(h3);
1890 r1.assertNotInvoked();
1891 r2.assertNotInvoked();
1892 r3.assertNotInvoked();
1893 checkCompletedNormally(failFirst ? snd : fst, v1);
1894 checkCancelled(failFirst ? fst : snd);
1895 }}
1896
1897 /**
1898 * thenAcceptBoth result completes exceptionally if action does
1899 */
1900 public void testThenAcceptBoth_actionFailed() {
1901 for (ExecutionMode m : ExecutionMode.values())
1902 for (boolean fFirst : new boolean[] { true, false })
1903 for (Integer v1 : new Integer[] { 1, null })
1904 for (Integer v2 : new Integer[] { 2, null })
1905 {
1906 final CompletableFuture<Integer> f = new CompletableFuture<>();
1907 final CompletableFuture<Integer> g = new CompletableFuture<>();
1908 final FailingBiConsumer r1 = new FailingBiConsumer(m);
1909 final FailingBiConsumer r2 = new FailingBiConsumer(m);
1910 final FailingBiConsumer r3 = new FailingBiConsumer(m);
1911
1912 final CompletableFuture<Integer> fst = fFirst ? f : g;
1913 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1914 final Integer w1 = fFirst ? v1 : v2;
1915 final Integer w2 = !fFirst ? v1 : v2;
1916
1917 final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1918 assertTrue(fst.complete(w1));
1919 final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1920 assertTrue(snd.complete(w2));
1921 final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1922
1923 checkCompletedWithWrappedException(h1, r1.ex);
1924 checkCompletedWithWrappedException(h2, r2.ex);
1925 checkCompletedWithWrappedException(h3, r3.ex);
1926 r1.assertInvoked();
1927 r2.assertInvoked();
1928 r3.assertInvoked();
1929 checkCompletedNormally(f, v1);
1930 checkCompletedNormally(g, v2);
1931 }}
1932
1933 /**
1934 * runAfterBoth result completes normally after normal
1935 * completion of sources
1936 */
1937 public void testRunAfterBoth_normalCompletion() {
1938 for (ExecutionMode m : ExecutionMode.values())
1939 for (boolean fFirst : new boolean[] { true, false })
1940 for (Integer v1 : new Integer[] { 1, null })
1941 for (Integer v2 : new Integer[] { 2, null })
1942 {
1943 final CompletableFuture<Integer> f = new CompletableFuture<>();
1944 final CompletableFuture<Integer> g = new CompletableFuture<>();
1945 final Noop r1 = new Noop(m);
1946 final Noop r2 = new Noop(m);
1947 final Noop r3 = new Noop(m);
1948
1949 final CompletableFuture<Integer> fst = fFirst ? f : g;
1950 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1951 final Integer w1 = fFirst ? v1 : v2;
1952 final Integer w2 = !fFirst ? v1 : v2;
1953
1954 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
1955 assertTrue(fst.complete(w1));
1956 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
1957 checkIncomplete(h1);
1958 checkIncomplete(h2);
1959 r1.assertNotInvoked();
1960 r2.assertNotInvoked();
1961 assertTrue(snd.complete(w2));
1962 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
1963
1964 checkCompletedNormally(h1, null);
1965 checkCompletedNormally(h2, null);
1966 checkCompletedNormally(h3, null);
1967 r1.assertInvoked();
1968 r2.assertInvoked();
1969 r3.assertInvoked();
1970 checkCompletedNormally(f, v1);
1971 checkCompletedNormally(g, v2);
1972 }}
1973
1974 /**
1975 * runAfterBoth result completes exceptionally after exceptional
1976 * completion of either source
1977 */
1978 public void testRunAfterBoth_exceptionalCompletion() throws Throwable {
1979 for (ExecutionMode m : ExecutionMode.values())
1980 for (boolean fFirst : new boolean[] { true, false })
1981 for (boolean failFirst : new boolean[] { true, false })
1982 for (Integer v1 : new Integer[] { 1, null })
1983 {
1984 final CompletableFuture<Integer> f = new CompletableFuture<>();
1985 final CompletableFuture<Integer> g = new CompletableFuture<>();
1986 final CFException ex = new CFException();
1987 final Noop r1 = new Noop(m);
1988 final Noop r2 = new Noop(m);
1989 final Noop r3 = new Noop(m);
1990
1991 final CompletableFuture<Integer> fst = fFirst ? f : g;
1992 final CompletableFuture<Integer> snd = !fFirst ? f : g;
1993 final Callable<Boolean> complete1 = failFirst ?
1994 () -> fst.completeExceptionally(ex) :
1995 () -> fst.complete(v1);
1996 final Callable<Boolean> complete2 = failFirst ?
1997 () -> snd.complete(v1) :
1998 () -> snd.completeExceptionally(ex);
1999
2000 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2001 assertTrue(complete1.call());
2002 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2003 checkIncomplete(h1);
2004 checkIncomplete(h2);
2005 assertTrue(complete2.call());
2006 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2007
2008 checkCompletedWithWrappedException(h1, ex);
2009 checkCompletedWithWrappedException(h2, ex);
2010 checkCompletedWithWrappedException(h3, ex);
2011 r1.assertNotInvoked();
2012 r2.assertNotInvoked();
2013 r3.assertNotInvoked();
2014 checkCompletedNormally(failFirst ? snd : fst, v1);
2015 checkCompletedExceptionally(failFirst ? fst : snd, ex);
2016 }}
2017
2018 /**
2019 * runAfterBoth result completes exceptionally if either source cancelled
2020 */
2021 public void testRunAfterBoth_sourceCancelled() throws Throwable {
2022 for (ExecutionMode m : ExecutionMode.values())
2023 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2024 for (boolean fFirst : new boolean[] { true, false })
2025 for (boolean failFirst : new boolean[] { true, false })
2026 for (Integer v1 : new Integer[] { 1, null })
2027 {
2028 final CompletableFuture<Integer> f = new CompletableFuture<>();
2029 final CompletableFuture<Integer> g = new CompletableFuture<>();
2030 final Noop r1 = new Noop(m);
2031 final Noop r2 = new Noop(m);
2032 final Noop r3 = new Noop(m);
2033
2034 final CompletableFuture<Integer> fst = fFirst ? f : g;
2035 final CompletableFuture<Integer> snd = !fFirst ? f : g;
2036 final Callable<Boolean> complete1 = failFirst ?
2037 () -> fst.cancel(mayInterruptIfRunning) :
2038 () -> fst.complete(v1);
2039 final Callable<Boolean> complete2 = failFirst ?
2040 () -> snd.complete(v1) :
2041 () -> snd.cancel(mayInterruptIfRunning);
2042
2043 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2044 assertTrue(complete1.call());
2045 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2046 checkIncomplete(h1);
2047 checkIncomplete(h2);
2048 assertTrue(complete2.call());
2049 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2050
2051 checkCompletedWithWrappedCancellationException(h1);
2052 checkCompletedWithWrappedCancellationException(h2);
2053 checkCompletedWithWrappedCancellationException(h3);
2054 r1.assertNotInvoked();
2055 r2.assertNotInvoked();
2056 r3.assertNotInvoked();
2057 checkCompletedNormally(failFirst ? snd : fst, v1);
2058 checkCancelled(failFirst ? fst : snd);
2059 }}
2060
2061 /**
2062 * runAfterBoth result completes exceptionally if action does
2063 */
2064 public void testRunAfterBoth_actionFailed() {
2065 for (ExecutionMode m : ExecutionMode.values())
2066 for (boolean fFirst : new boolean[] { true, false })
2067 for (Integer v1 : new Integer[] { 1, null })
2068 for (Integer v2 : new Integer[] { 2, null })
2069 {
2070 final CompletableFuture<Integer> f = new CompletableFuture<>();
2071 final CompletableFuture<Integer> g = new CompletableFuture<>();
2072 final FailingRunnable r1 = new FailingRunnable(m);
2073 final FailingRunnable r2 = new FailingRunnable(m);
2074 final FailingRunnable r3 = new FailingRunnable(m);
2075
2076 final CompletableFuture<Integer> fst = fFirst ? f : g;
2077 final CompletableFuture<Integer> snd = !fFirst ? f : g;
2078 final Integer w1 = fFirst ? v1 : v2;
2079 final Integer w2 = !fFirst ? v1 : v2;
2080
2081 final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2082 assertTrue(fst.complete(w1));
2083 final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2084 assertTrue(snd.complete(w2));
2085 final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2086
2087 checkCompletedWithWrappedException(h1, r1.ex);
2088 checkCompletedWithWrappedException(h2, r2.ex);
2089 checkCompletedWithWrappedException(h3, r3.ex);
2090 r1.assertInvoked();
2091 r2.assertInvoked();
2092 r3.assertInvoked();
2093 checkCompletedNormally(f, v1);
2094 checkCompletedNormally(g, v2);
2095 }}
2096
2097 /**
2098 * applyToEither result completes normally after normal completion
2099 * of either source
2100 */
2101 public void testApplyToEither_normalCompletion() {
2102 for (ExecutionMode m : ExecutionMode.values())
2103 for (Integer v1 : new Integer[] { 1, null })
2104 for (Integer v2 : new Integer[] { 2, null })
2105 {
2106 final CompletableFuture<Integer> f = new CompletableFuture<>();
2107 final CompletableFuture<Integer> g = new CompletableFuture<>();
2108 final IncFunction[] rs = new IncFunction[6];
2109 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2110
2111 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2112 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2113 checkIncomplete(h0);
2114 checkIncomplete(h1);
2115 rs[0].assertNotInvoked();
2116 rs[1].assertNotInvoked();
2117 f.complete(v1);
2118 checkCompletedNormally(h0, inc(v1));
2119 checkCompletedNormally(h1, inc(v1));
2120 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2121 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2122 checkCompletedNormally(h2, inc(v1));
2123 checkCompletedNormally(h3, inc(v1));
2124 g.complete(v2);
2125
2126 // unspecified behavior - both source completions available
2127 final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2128 final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2129 rs[4].assertValue(h4.join());
2130 rs[5].assertValue(h5.join());
2131 assertTrue(Objects.equals(inc(v1), h4.join()) ||
2132 Objects.equals(inc(v2), h4.join()));
2133 assertTrue(Objects.equals(inc(v1), h5.join()) ||
2134 Objects.equals(inc(v2), h5.join()));
2135
2136 checkCompletedNormally(f, v1);
2137 checkCompletedNormally(g, v2);
2138 checkCompletedNormally(h0, inc(v1));
2139 checkCompletedNormally(h1, inc(v1));
2140 checkCompletedNormally(h2, inc(v1));
2141 checkCompletedNormally(h3, inc(v1));
2142 for (int i = 0; i < 4; i++) rs[i].assertValue(inc(v1));
2143 }}
2144
2145 /**
2146 * applyToEither result completes exceptionally after exceptional
2147 * completion of either source
2148 */
2149 public void testApplyToEither_exceptionalCompletion() {
2150 for (ExecutionMode m : ExecutionMode.values())
2151 for (Integer v1 : new Integer[] { 1, null })
2152 {
2153 final CompletableFuture<Integer> f = new CompletableFuture<>();
2154 final CompletableFuture<Integer> g = new CompletableFuture<>();
2155 final CFException ex = new CFException();
2156 final IncFunction[] rs = new IncFunction[6];
2157 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2158
2159 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2160 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2161 checkIncomplete(h0);
2162 checkIncomplete(h1);
2163 rs[0].assertNotInvoked();
2164 rs[1].assertNotInvoked();
2165 f.completeExceptionally(ex);
2166 checkCompletedWithWrappedException(h0, ex);
2167 checkCompletedWithWrappedException(h1, ex);
2168 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2169 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2170 checkCompletedWithWrappedException(h2, ex);
2171 checkCompletedWithWrappedException(h3, ex);
2172 g.complete(v1);
2173
2174 // unspecified behavior - both source completions available
2175 final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2176 final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2177 try {
2178 assertEquals(inc(v1), h4.join());
2179 rs[4].assertValue(inc(v1));
2180 } catch (CompletionException ok) {
2181 checkCompletedWithWrappedException(h4, ex);
2182 rs[4].assertNotInvoked();
2183 }
2184 try {
2185 assertEquals(inc(v1), h5.join());
2186 rs[5].assertValue(inc(v1));
2187 } catch (CompletionException ok) {
2188 checkCompletedWithWrappedException(h5, ex);
2189 rs[5].assertNotInvoked();
2190 }
2191
2192 checkCompletedExceptionally(f, ex);
2193 checkCompletedNormally(g, v1);
2194 checkCompletedWithWrappedException(h0, ex);
2195 checkCompletedWithWrappedException(h1, ex);
2196 checkCompletedWithWrappedException(h2, ex);
2197 checkCompletedWithWrappedException(h3, ex);
2198 checkCompletedWithWrappedException(h4, ex);
2199 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2200 }}
2201
2202 public void testApplyToEither_exceptionalCompletion2() {
2203 for (ExecutionMode m : ExecutionMode.values())
2204 for (boolean fFirst : new boolean[] { true, false })
2205 for (Integer v1 : new Integer[] { 1, null })
2206 {
2207 final CompletableFuture<Integer> f = new CompletableFuture<>();
2208 final CompletableFuture<Integer> g = new CompletableFuture<>();
2209 final CFException ex = new CFException();
2210 final IncFunction[] rs = new IncFunction[6];
2211 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2212
2213 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2214 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2215 assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2216 assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2217 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2218 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2219
2220 // unspecified behavior - both source completions available
2221 try {
2222 assertEquals(inc(v1), h0.join());
2223 rs[0].assertValue(inc(v1));
2224 } catch (CompletionException ok) {
2225 checkCompletedWithWrappedException(h0, ex);
2226 rs[0].assertNotInvoked();
2227 }
2228 try {
2229 assertEquals(inc(v1), h1.join());
2230 rs[1].assertValue(inc(v1));
2231 } catch (CompletionException ok) {
2232 checkCompletedWithWrappedException(h1, ex);
2233 rs[1].assertNotInvoked();
2234 }
2235 try {
2236 assertEquals(inc(v1), h2.join());
2237 rs[2].assertValue(inc(v1));
2238 } catch (CompletionException ok) {
2239 checkCompletedWithWrappedException(h2, ex);
2240 rs[2].assertNotInvoked();
2241 }
2242 try {
2243 assertEquals(inc(v1), h3.join());
2244 rs[3].assertValue(inc(v1));
2245 } catch (CompletionException ok) {
2246 checkCompletedWithWrappedException(h3, ex);
2247 rs[3].assertNotInvoked();
2248 }
2249
2250 checkCompletedNormally(f, v1);
2251 checkCompletedExceptionally(g, ex);
2252 }}
2253
2254 /**
2255 * applyToEither result completes exceptionally if either source cancelled
2256 */
2257 public void testApplyToEither_sourceCancelled() {
2258 for (ExecutionMode m : ExecutionMode.values())
2259 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2260 for (Integer v1 : new Integer[] { 1, null })
2261 {
2262 final CompletableFuture<Integer> f = new CompletableFuture<>();
2263 final CompletableFuture<Integer> g = new CompletableFuture<>();
2264 final IncFunction[] rs = new IncFunction[6];
2265 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2266
2267 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2268 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2269 checkIncomplete(h0);
2270 checkIncomplete(h1);
2271 rs[0].assertNotInvoked();
2272 rs[1].assertNotInvoked();
2273 f.cancel(mayInterruptIfRunning);
2274 checkCompletedWithWrappedCancellationException(h0);
2275 checkCompletedWithWrappedCancellationException(h1);
2276 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2277 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2278 checkCompletedWithWrappedCancellationException(h2);
2279 checkCompletedWithWrappedCancellationException(h3);
2280 g.complete(v1);
2281
2282 // unspecified behavior - both source completions available
2283 final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2284 final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2285 try {
2286 assertEquals(inc(v1), h4.join());
2287 rs[4].assertValue(inc(v1));
2288 } catch (CompletionException ok) {
2289 checkCompletedWithWrappedCancellationException(h4);
2290 rs[4].assertNotInvoked();
2291 }
2292 try {
2293 assertEquals(inc(v1), h5.join());
2294 rs[5].assertValue(inc(v1));
2295 } catch (CompletionException ok) {
2296 checkCompletedWithWrappedCancellationException(h5);
2297 rs[5].assertNotInvoked();
2298 }
2299
2300 checkCancelled(f);
2301 checkCompletedNormally(g, v1);
2302 checkCompletedWithWrappedCancellationException(h0);
2303 checkCompletedWithWrappedCancellationException(h1);
2304 checkCompletedWithWrappedCancellationException(h2);
2305 checkCompletedWithWrappedCancellationException(h3);
2306 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2307 }}
2308
2309 public void testApplyToEither_sourceCancelled2() {
2310 for (ExecutionMode m : ExecutionMode.values())
2311 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2312 for (boolean fFirst : new boolean[] { true, false })
2313 for (Integer v1 : new Integer[] { 1, null })
2314 {
2315 final CompletableFuture<Integer> f = new CompletableFuture<>();
2316 final CompletableFuture<Integer> g = new CompletableFuture<>();
2317 final IncFunction[] rs = new IncFunction[6];
2318 for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2319
2320 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2321 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2322 assertTrue(fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
2323 assertTrue(!fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
2324 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2325 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2326
2327 // unspecified behavior - both source completions available
2328 try {
2329 assertEquals(inc(v1), h0.join());
2330 rs[0].assertValue(inc(v1));
2331 } catch (CompletionException ok) {
2332 checkCompletedWithWrappedCancellationException(h0);
2333 rs[0].assertNotInvoked();
2334 }
2335 try {
2336 assertEquals(inc(v1), h1.join());
2337 rs[1].assertValue(inc(v1));
2338 } catch (CompletionException ok) {
2339 checkCompletedWithWrappedCancellationException(h1);
2340 rs[1].assertNotInvoked();
2341 }
2342 try {
2343 assertEquals(inc(v1), h2.join());
2344 rs[2].assertValue(inc(v1));
2345 } catch (CompletionException ok) {
2346 checkCompletedWithWrappedCancellationException(h2);
2347 rs[2].assertNotInvoked();
2348 }
2349 try {
2350 assertEquals(inc(v1), h3.join());
2351 rs[3].assertValue(inc(v1));
2352 } catch (CompletionException ok) {
2353 checkCompletedWithWrappedCancellationException(h3);
2354 rs[3].assertNotInvoked();
2355 }
2356
2357 checkCompletedNormally(f, v1);
2358 checkCancelled(g);
2359 }}
2360
2361 /**
2362 * applyToEither result completes exceptionally if action does
2363 */
2364 public void testApplyToEither_actionFailed() {
2365 for (ExecutionMode m : ExecutionMode.values())
2366 for (Integer v1 : new Integer[] { 1, null })
2367 for (Integer v2 : new Integer[] { 2, null })
2368 {
2369 final CompletableFuture<Integer> f = new CompletableFuture<>();
2370 final CompletableFuture<Integer> g = new CompletableFuture<>();
2371 final FailingFunction[] rs = new FailingFunction[6];
2372 for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
2373
2374 final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2375 final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2376 f.complete(v1);
2377 final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2378 final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2379 checkCompletedWithWrappedException(h0, rs[0].ex);
2380 checkCompletedWithWrappedException(h1, rs[1].ex);
2381 checkCompletedWithWrappedException(h2, rs[2].ex);
2382 checkCompletedWithWrappedException(h3, rs[3].ex);
2383 for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2384
2385 g.complete(v2);
2386
2387 // unspecified behavior - both source completions available
2388 final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2389 final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2390
2391 checkCompletedWithWrappedException(h4, rs[4].ex);
2392 assertTrue(Objects.equals(v1, rs[4].value) ||
2393 Objects.equals(v2, rs[4].value));
2394 checkCompletedWithWrappedException(h5, rs[5].ex);
2395 assertTrue(Objects.equals(v1, rs[5].value) ||
2396 Objects.equals(v2, rs[5].value));
2397
2398 checkCompletedNormally(f, v1);
2399 checkCompletedNormally(g, v2);
2400 }}
2401
2402 /**
2403 * acceptEither result completes normally after normal completion
2404 * of either source
2405 */
2406 public void testAcceptEither_normalCompletion() {
2407 for (ExecutionMode m : ExecutionMode.values())
2408 for (Integer v1 : new Integer[] { 1, null })
2409 for (Integer v2 : new Integer[] { 2, null })
2410 {
2411 final CompletableFuture<Integer> f = new CompletableFuture<>();
2412 final CompletableFuture<Integer> g = new CompletableFuture<>();
2413 final NoopConsumer[] rs = new NoopConsumer[6];
2414 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2415
2416 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2417 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2418 checkIncomplete(h0);
2419 checkIncomplete(h1);
2420 rs[0].assertNotInvoked();
2421 rs[1].assertNotInvoked();
2422 f.complete(v1);
2423 checkCompletedNormally(h0, null);
2424 checkCompletedNormally(h1, null);
2425 rs[0].assertValue(v1);
2426 rs[1].assertValue(v1);
2427 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2428 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2429 checkCompletedNormally(h2, null);
2430 checkCompletedNormally(h3, null);
2431 rs[2].assertValue(v1);
2432 rs[3].assertValue(v1);
2433 g.complete(v2);
2434
2435 // unspecified behavior - both source completions available
2436 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2437 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2438 checkCompletedNormally(h4, null);
2439 checkCompletedNormally(h5, null);
2440 assertTrue(Objects.equals(v1, rs[4].value) ||
2441 Objects.equals(v2, rs[4].value));
2442 assertTrue(Objects.equals(v1, rs[5].value) ||
2443 Objects.equals(v2, rs[5].value));
2444
2445 checkCompletedNormally(f, v1);
2446 checkCompletedNormally(g, v2);
2447 checkCompletedNormally(h0, null);
2448 checkCompletedNormally(h1, null);
2449 checkCompletedNormally(h2, null);
2450 checkCompletedNormally(h3, null);
2451 for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2452 }}
2453
2454 /**
2455 * acceptEither result completes exceptionally after exceptional
2456 * completion of either source
2457 */
2458 public void testAcceptEither_exceptionalCompletion() {
2459 for (ExecutionMode m : ExecutionMode.values())
2460 for (Integer v1 : new Integer[] { 1, null })
2461 {
2462 final CompletableFuture<Integer> f = new CompletableFuture<>();
2463 final CompletableFuture<Integer> g = new CompletableFuture<>();
2464 final CFException ex = new CFException();
2465 final NoopConsumer[] rs = new NoopConsumer[6];
2466 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2467
2468 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2469 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2470 checkIncomplete(h0);
2471 checkIncomplete(h1);
2472 rs[0].assertNotInvoked();
2473 rs[1].assertNotInvoked();
2474 f.completeExceptionally(ex);
2475 checkCompletedWithWrappedException(h0, ex);
2476 checkCompletedWithWrappedException(h1, ex);
2477 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2478 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2479 checkCompletedWithWrappedException(h2, ex);
2480 checkCompletedWithWrappedException(h3, ex);
2481
2482 g.complete(v1);
2483
2484 // unspecified behavior - both source completions available
2485 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2486 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2487 try {
2488 assertNull(h4.join());
2489 rs[4].assertValue(v1);
2490 } catch (CompletionException ok) {
2491 checkCompletedWithWrappedException(h4, ex);
2492 rs[4].assertNotInvoked();
2493 }
2494 try {
2495 assertNull(h5.join());
2496 rs[5].assertValue(v1);
2497 } catch (CompletionException ok) {
2498 checkCompletedWithWrappedException(h5, ex);
2499 rs[5].assertNotInvoked();
2500 }
2501
2502 checkCompletedExceptionally(f, ex);
2503 checkCompletedNormally(g, v1);
2504 checkCompletedWithWrappedException(h0, ex);
2505 checkCompletedWithWrappedException(h1, ex);
2506 checkCompletedWithWrappedException(h2, ex);
2507 checkCompletedWithWrappedException(h3, ex);
2508 checkCompletedWithWrappedException(h4, ex);
2509 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2510 }}
2511
2512 public void testAcceptEither_exceptionalCompletion2() {
2513 for (ExecutionMode m : ExecutionMode.values())
2514 for (boolean fFirst : new boolean[] { true, false })
2515 for (Integer v1 : new Integer[] { 1, null })
2516 {
2517 final CompletableFuture<Integer> f = new CompletableFuture<>();
2518 final CompletableFuture<Integer> g = new CompletableFuture<>();
2519 final CFException ex = new CFException();
2520 final NoopConsumer[] rs = new NoopConsumer[6];
2521 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2522
2523 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2524 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2525 assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2526 assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2527 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2528 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2529
2530 // unspecified behavior - both source completions available
2531 try {
2532 assertEquals(null, h0.join());
2533 rs[0].assertValue(v1);
2534 } catch (CompletionException ok) {
2535 checkCompletedWithWrappedException(h0, ex);
2536 rs[0].assertNotInvoked();
2537 }
2538 try {
2539 assertEquals(null, h1.join());
2540 rs[1].assertValue(v1);
2541 } catch (CompletionException ok) {
2542 checkCompletedWithWrappedException(h1, ex);
2543 rs[1].assertNotInvoked();
2544 }
2545 try {
2546 assertEquals(null, h2.join());
2547 rs[2].assertValue(v1);
2548 } catch (CompletionException ok) {
2549 checkCompletedWithWrappedException(h2, ex);
2550 rs[2].assertNotInvoked();
2551 }
2552 try {
2553 assertEquals(null, h3.join());
2554 rs[3].assertValue(v1);
2555 } catch (CompletionException ok) {
2556 checkCompletedWithWrappedException(h3, ex);
2557 rs[3].assertNotInvoked();
2558 }
2559
2560 checkCompletedNormally(f, v1);
2561 checkCompletedExceptionally(g, ex);
2562 }}
2563
2564 /**
2565 * acceptEither result completes exceptionally if either source cancelled
2566 */
2567 public void testAcceptEither_sourceCancelled() {
2568 for (ExecutionMode m : ExecutionMode.values())
2569 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2570 for (Integer v1 : new Integer[] { 1, null })
2571 {
2572 final CompletableFuture<Integer> f = new CompletableFuture<>();
2573 final CompletableFuture<Integer> g = new CompletableFuture<>();
2574 final NoopConsumer[] rs = new NoopConsumer[6];
2575 for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2576
2577 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2578 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2579 checkIncomplete(h0);
2580 checkIncomplete(h1);
2581 rs[0].assertNotInvoked();
2582 rs[1].assertNotInvoked();
2583 f.cancel(mayInterruptIfRunning);
2584 checkCompletedWithWrappedCancellationException(h0);
2585 checkCompletedWithWrappedCancellationException(h1);
2586 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2587 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2588 checkCompletedWithWrappedCancellationException(h2);
2589 checkCompletedWithWrappedCancellationException(h3);
2590
2591 g.complete(v1);
2592
2593 // unspecified behavior - both source completions available
2594 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2595 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2596 try {
2597 assertNull(h4.join());
2598 rs[4].assertValue(v1);
2599 } catch (CompletionException ok) {
2600 checkCompletedWithWrappedCancellationException(h4);
2601 rs[4].assertNotInvoked();
2602 }
2603 try {
2604 assertNull(h5.join());
2605 rs[5].assertValue(v1);
2606 } catch (CompletionException ok) {
2607 checkCompletedWithWrappedCancellationException(h5);
2608 rs[5].assertNotInvoked();
2609 }
2610
2611 checkCancelled(f);
2612 checkCompletedNormally(g, v1);
2613 checkCompletedWithWrappedCancellationException(h0);
2614 checkCompletedWithWrappedCancellationException(h1);
2615 checkCompletedWithWrappedCancellationException(h2);
2616 checkCompletedWithWrappedCancellationException(h3);
2617 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2618 }}
2619
2620 /**
2621 * acceptEither result completes exceptionally if action does
2622 */
2623 public void testAcceptEither_actionFailed() {
2624 for (ExecutionMode m : ExecutionMode.values())
2625 for (Integer v1 : new Integer[] { 1, null })
2626 for (Integer v2 : new Integer[] { 2, null })
2627 {
2628 final CompletableFuture<Integer> f = new CompletableFuture<>();
2629 final CompletableFuture<Integer> g = new CompletableFuture<>();
2630 final FailingConsumer[] rs = new FailingConsumer[6];
2631 for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
2632
2633 final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2634 final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2635 f.complete(v1);
2636 final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2637 final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2638 checkCompletedWithWrappedException(h0, rs[0].ex);
2639 checkCompletedWithWrappedException(h1, rs[1].ex);
2640 checkCompletedWithWrappedException(h2, rs[2].ex);
2641 checkCompletedWithWrappedException(h3, rs[3].ex);
2642 for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2643
2644 g.complete(v2);
2645
2646 // unspecified behavior - both source completions available
2647 final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2648 final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2649
2650 checkCompletedWithWrappedException(h4, rs[4].ex);
2651 assertTrue(Objects.equals(v1, rs[4].value) ||
2652 Objects.equals(v2, rs[4].value));
2653 checkCompletedWithWrappedException(h5, rs[5].ex);
2654 assertTrue(Objects.equals(v1, rs[5].value) ||
2655 Objects.equals(v2, rs[5].value));
2656
2657 checkCompletedNormally(f, v1);
2658 checkCompletedNormally(g, v2);
2659 }}
2660
2661 /**
2662 * runAfterEither result completes normally after normal completion
2663 * of either source
2664 */
2665 public void testRunAfterEither_normalCompletion() {
2666 for (ExecutionMode m : ExecutionMode.values())
2667 for (Integer v1 : new Integer[] { 1, null })
2668 for (Integer v2 : new Integer[] { 2, null })
2669 {
2670 final CompletableFuture<Integer> f = new CompletableFuture<>();
2671 final CompletableFuture<Integer> g = new CompletableFuture<>();
2672 final Noop[] rs = new Noop[6];
2673 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2674
2675 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2676 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2677 checkIncomplete(h0);
2678 checkIncomplete(h1);
2679 rs[0].assertNotInvoked();
2680 rs[1].assertNotInvoked();
2681 f.complete(v1);
2682 checkCompletedNormally(h0, null);
2683 checkCompletedNormally(h1, null);
2684 rs[0].assertInvoked();
2685 rs[1].assertInvoked();
2686 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2687 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2688 checkCompletedNormally(h2, null);
2689 checkCompletedNormally(h3, null);
2690 rs[2].assertInvoked();
2691 rs[3].assertInvoked();
2692
2693 g.complete(v2);
2694
2695 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2696 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2697
2698 checkCompletedNormally(f, v1);
2699 checkCompletedNormally(g, v2);
2700 checkCompletedNormally(h0, null);
2701 checkCompletedNormally(h1, null);
2702 checkCompletedNormally(h2, null);
2703 checkCompletedNormally(h3, null);
2704 checkCompletedNormally(h4, null);
2705 checkCompletedNormally(h5, null);
2706 for (int i = 0; i < 6; i++) rs[i].assertInvoked();
2707 }}
2708
2709 /**
2710 * runAfterEither result completes exceptionally after exceptional
2711 * completion of either source
2712 */
2713 public void testRunAfterEither_exceptionalCompletion() {
2714 for (ExecutionMode m : ExecutionMode.values())
2715 for (Integer v1 : new Integer[] { 1, null })
2716 {
2717 final CompletableFuture<Integer> f = new CompletableFuture<>();
2718 final CompletableFuture<Integer> g = new CompletableFuture<>();
2719 final CFException ex = new CFException();
2720 final Noop[] rs = new Noop[6];
2721 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2722
2723 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2724 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2725 checkIncomplete(h0);
2726 checkIncomplete(h1);
2727 rs[0].assertNotInvoked();
2728 rs[1].assertNotInvoked();
2729 assertTrue(f.completeExceptionally(ex));
2730 checkCompletedWithWrappedException(h0, ex);
2731 checkCompletedWithWrappedException(h1, ex);
2732 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2733 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2734 checkCompletedWithWrappedException(h2, ex);
2735 checkCompletedWithWrappedException(h3, ex);
2736
2737 assertTrue(g.complete(v1));
2738
2739 // unspecified behavior - both source completions available
2740 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2741 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2742 try {
2743 assertNull(h4.join());
2744 rs[4].assertInvoked();
2745 } catch (CompletionException ok) {
2746 checkCompletedWithWrappedException(h4, ex);
2747 rs[4].assertNotInvoked();
2748 }
2749 try {
2750 assertNull(h5.join());
2751 rs[5].assertInvoked();
2752 } catch (CompletionException ok) {
2753 checkCompletedWithWrappedException(h5, ex);
2754 rs[5].assertNotInvoked();
2755 }
2756
2757 checkCompletedExceptionally(f, ex);
2758 checkCompletedNormally(g, v1);
2759 checkCompletedWithWrappedException(h0, ex);
2760 checkCompletedWithWrappedException(h1, ex);
2761 checkCompletedWithWrappedException(h2, ex);
2762 checkCompletedWithWrappedException(h3, ex);
2763 checkCompletedWithWrappedException(h4, ex);
2764 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2765 }}
2766
2767 public void testRunAfterEither_exceptionalCompletion2() {
2768 for (ExecutionMode m : ExecutionMode.values())
2769 for (boolean fFirst : new boolean[] { true, false })
2770 for (Integer v1 : new Integer[] { 1, null })
2771 {
2772 final CompletableFuture<Integer> f = new CompletableFuture<>();
2773 final CompletableFuture<Integer> g = new CompletableFuture<>();
2774 final CFException ex = new CFException();
2775 final Noop[] rs = new Noop[6];
2776 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2777
2778 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2779 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2780 assertTrue( fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2781 assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2782 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2783 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2784
2785 // unspecified behavior - both source completions available
2786 try {
2787 assertEquals(null, h0.join());
2788 rs[0].assertInvoked();
2789 } catch (CompletionException ok) {
2790 checkCompletedWithWrappedException(h0, ex);
2791 rs[0].assertNotInvoked();
2792 }
2793 try {
2794 assertEquals(null, h1.join());
2795 rs[1].assertInvoked();
2796 } catch (CompletionException ok) {
2797 checkCompletedWithWrappedException(h1, ex);
2798 rs[1].assertNotInvoked();
2799 }
2800 try {
2801 assertEquals(null, h2.join());
2802 rs[2].assertInvoked();
2803 } catch (CompletionException ok) {
2804 checkCompletedWithWrappedException(h2, ex);
2805 rs[2].assertNotInvoked();
2806 }
2807 try {
2808 assertEquals(null, h3.join());
2809 rs[3].assertInvoked();
2810 } catch (CompletionException ok) {
2811 checkCompletedWithWrappedException(h3, ex);
2812 rs[3].assertNotInvoked();
2813 }
2814
2815 checkCompletedNormally(f, v1);
2816 checkCompletedExceptionally(g, ex);
2817 }}
2818
2819 /**
2820 * runAfterEither result completes exceptionally if either source cancelled
2821 */
2822 public void testRunAfterEither_sourceCancelled() {
2823 for (ExecutionMode m : ExecutionMode.values())
2824 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2825 for (Integer v1 : new Integer[] { 1, null })
2826 {
2827 final CompletableFuture<Integer> f = new CompletableFuture<>();
2828 final CompletableFuture<Integer> g = new CompletableFuture<>();
2829 final Noop[] rs = new Noop[6];
2830 for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2831
2832 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2833 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2834 checkIncomplete(h0);
2835 checkIncomplete(h1);
2836 rs[0].assertNotInvoked();
2837 rs[1].assertNotInvoked();
2838 f.cancel(mayInterruptIfRunning);
2839 checkCompletedWithWrappedCancellationException(h0);
2840 checkCompletedWithWrappedCancellationException(h1);
2841 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2842 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2843 checkCompletedWithWrappedCancellationException(h2);
2844 checkCompletedWithWrappedCancellationException(h3);
2845
2846 assertTrue(g.complete(v1));
2847
2848 // unspecified behavior - both source completions available
2849 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2850 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2851 try {
2852 assertNull(h4.join());
2853 rs[4].assertInvoked();
2854 } catch (CompletionException ok) {
2855 checkCompletedWithWrappedCancellationException(h4);
2856 rs[4].assertNotInvoked();
2857 }
2858 try {
2859 assertNull(h5.join());
2860 rs[5].assertInvoked();
2861 } catch (CompletionException ok) {
2862 checkCompletedWithWrappedCancellationException(h5);
2863 rs[5].assertNotInvoked();
2864 }
2865
2866 checkCancelled(f);
2867 checkCompletedNormally(g, v1);
2868 checkCompletedWithWrappedCancellationException(h0);
2869 checkCompletedWithWrappedCancellationException(h1);
2870 checkCompletedWithWrappedCancellationException(h2);
2871 checkCompletedWithWrappedCancellationException(h3);
2872 for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2873 }}
2874
2875 /**
2876 * runAfterEither result completes exceptionally if action does
2877 */
2878 public void testRunAfterEither_actionFailed() {
2879 for (ExecutionMode m : ExecutionMode.values())
2880 for (Integer v1 : new Integer[] { 1, null })
2881 for (Integer v2 : new Integer[] { 2, null })
2882 {
2883 final CompletableFuture<Integer> f = new CompletableFuture<>();
2884 final CompletableFuture<Integer> g = new CompletableFuture<>();
2885 final FailingRunnable[] rs = new FailingRunnable[6];
2886 for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
2887
2888 final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2889 final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2890 assertTrue(f.complete(v1));
2891 final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2892 final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2893 checkCompletedWithWrappedException(h0, rs[0].ex);
2894 checkCompletedWithWrappedException(h1, rs[1].ex);
2895 checkCompletedWithWrappedException(h2, rs[2].ex);
2896 checkCompletedWithWrappedException(h3, rs[3].ex);
2897 for (int i = 0; i < 4; i++) rs[i].assertInvoked();
2898 assertTrue(g.complete(v2));
2899 final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2900 final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2901 checkCompletedWithWrappedException(h4, rs[4].ex);
2902 checkCompletedWithWrappedException(h5, rs[5].ex);
2903
2904 checkCompletedNormally(f, v1);
2905 checkCompletedNormally(g, v2);
2906 for (int i = 0; i < 6; i++) rs[i].assertInvoked();
2907 }}
2908
2909 /**
2910 * thenCompose result completes normally after normal completion of source
2911 */
2912 public void testThenCompose_normalCompletion() {
2913 for (ExecutionMode m : ExecutionMode.values())
2914 for (boolean createIncomplete : new boolean[] { true, false })
2915 for (Integer v1 : new Integer[] { 1, null })
2916 {
2917 final CompletableFuture<Integer> f = new CompletableFuture<>();
2918 final CompletableFutureInc r = new CompletableFutureInc(m);
2919 if (!createIncomplete) assertTrue(f.complete(v1));
2920 final CompletableFuture<Integer> g = m.thenCompose(f, r);
2921 if (createIncomplete) assertTrue(f.complete(v1));
2922
2923 checkCompletedNormally(g, inc(v1));
2924 checkCompletedNormally(f, v1);
2925 r.assertValue(v1);
2926 }}
2927
2928 /**
2929 * thenCompose result completes exceptionally after exceptional
2930 * completion of source
2931 */
2932 public void testThenCompose_exceptionalCompletion() {
2933 for (ExecutionMode m : ExecutionMode.values())
2934 for (boolean createIncomplete : new boolean[] { true, false })
2935 {
2936 final CFException ex = new CFException();
2937 final CompletableFutureInc r = new CompletableFutureInc(m);
2938 final CompletableFuture<Integer> f = new CompletableFuture<>();
2939 if (!createIncomplete) f.completeExceptionally(ex);
2940 final CompletableFuture<Integer> g = m.thenCompose(f, r);
2941 if (createIncomplete) f.completeExceptionally(ex);
2942
2943 checkCompletedWithWrappedException(g, ex);
2944 checkCompletedExceptionally(f, ex);
2945 r.assertNotInvoked();
2946 }}
2947
2948 /**
2949 * thenCompose result completes exceptionally if action does
2950 */
2951 public void testThenCompose_actionFailed() {
2952 for (ExecutionMode m : ExecutionMode.values())
2953 for (boolean createIncomplete : new boolean[] { true, false })
2954 for (Integer v1 : new Integer[] { 1, null })
2955 {
2956 final CompletableFuture<Integer> f = new CompletableFuture<>();
2957 final FailingCompletableFutureFunction r
2958 = new FailingCompletableFutureFunction(m);
2959 if (!createIncomplete) assertTrue(f.complete(v1));
2960 final CompletableFuture<Integer> g = m.thenCompose(f, r);
2961 if (createIncomplete) assertTrue(f.complete(v1));
2962
2963 checkCompletedWithWrappedException(g, r.ex);
2964 checkCompletedNormally(f, v1);
2965 }}
2966
2967 /**
2968 * thenCompose result completes exceptionally if source cancelled
2969 */
2970 public void testThenCompose_sourceCancelled() {
2971 for (ExecutionMode m : ExecutionMode.values())
2972 for (boolean createIncomplete : new boolean[] { true, false })
2973 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2974 {
2975 final CompletableFuture<Integer> f = new CompletableFuture<>();
2976 final CompletableFutureInc r = new CompletableFutureInc(m);
2977 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
2978 final CompletableFuture<Integer> g = m.thenCompose(f, r);
2979 if (createIncomplete) {
2980 checkIncomplete(g);
2981 assertTrue(f.cancel(mayInterruptIfRunning));
2982 }
2983
2984 checkCompletedWithWrappedCancellationException(g);
2985 checkCancelled(f);
2986 }}
2987
2988 /**
2989 * thenCompose result completes exceptionally if the result of the action does
2990 */
2991 public void testThenCompose_actionReturnsFailingFuture() {
2992 for (ExecutionMode m : ExecutionMode.values())
2993 for (int order = 0; order < 6; order++)
2994 for (Integer v1 : new Integer[] { 1, null })
2995 {
2996 final CFException ex = new CFException();
2997 final CompletableFuture<Integer> f = new CompletableFuture<>();
2998 final CompletableFuture<Integer> g = new CompletableFuture<>();
2999 final CompletableFuture<Integer> h;
3000 // Test all permutations of orders
3001 switch (order) {
3002 case 0:
3003 assertTrue(f.complete(v1));
3004 assertTrue(g.completeExceptionally(ex));
3005 h = m.thenCompose(f, (x -> g));
3006 break;
3007 case 1:
3008 assertTrue(f.complete(v1));
3009 h = m.thenCompose(f, (x -> g));
3010 assertTrue(g.completeExceptionally(ex));
3011 break;
3012 case 2:
3013 assertTrue(g.completeExceptionally(ex));
3014 assertTrue(f.complete(v1));
3015 h = m.thenCompose(f, (x -> g));
3016 break;
3017 case 3:
3018 assertTrue(g.completeExceptionally(ex));
3019 h = m.thenCompose(f, (x -> g));
3020 assertTrue(f.complete(v1));
3021 break;
3022 case 4:
3023 h = m.thenCompose(f, (x -> g));
3024 assertTrue(f.complete(v1));
3025 assertTrue(g.completeExceptionally(ex));
3026 break;
3027 case 5:
3028 h = m.thenCompose(f, (x -> g));
3029 assertTrue(f.complete(v1));
3030 assertTrue(g.completeExceptionally(ex));
3031 break;
3032 default: throw new AssertionError();
3033 }
3034
3035 checkCompletedExceptionally(g, ex);
3036 checkCompletedWithWrappedException(h, ex);
3037 checkCompletedNormally(f, v1);
3038 }}
3039
3040 // other static methods
3041
3042 /**
3043 * allOf(no component futures) returns a future completed normally
3044 * with the value null
3045 */
3046 public void testAllOf_empty() throws Exception {
3047 CompletableFuture<Void> f = CompletableFuture.allOf();
3048 checkCompletedNormally(f, null);
3049 }
3050
3051 /**
3052 * allOf returns a future completed normally with the value null
3053 * when all components complete normally
3054 */
3055 public void testAllOf_normal() throws Exception {
3056 for (int k = 1; k < 10; k++) {
3057 CompletableFuture<Integer>[] fs
3058 = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3059 for (int i = 0; i < k; i++)
3060 fs[i] = new CompletableFuture<>();
3061 CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3062 for (int i = 0; i < k; i++) {
3063 checkIncomplete(f);
3064 checkIncomplete(CompletableFuture.allOf(fs));
3065 fs[i].complete(one);
3066 }
3067 checkCompletedNormally(f, null);
3068 checkCompletedNormally(CompletableFuture.allOf(fs), null);
3069 }
3070 }
3071
3072 public void testAllOf_normal_backwards() throws Exception {
3073 for (int k = 1; k < 10; k++) {
3074 CompletableFuture<Integer>[] fs
3075 = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3076 for (int i = 0; i < k; i++)
3077 fs[i] = new CompletableFuture<>();
3078 CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3079 for (int i = k - 1; i >= 0; i--) {
3080 checkIncomplete(f);
3081 checkIncomplete(CompletableFuture.allOf(fs));
3082 fs[i].complete(one);
3083 }
3084 checkCompletedNormally(f, null);
3085 checkCompletedNormally(CompletableFuture.allOf(fs), null);
3086 }
3087 }
3088
3089 public void testAllOf_exceptional() throws Exception {
3090 for (int k = 1; k < 10; k++) {
3091 CompletableFuture<Integer>[] fs
3092 = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3093 CFException ex = new CFException();
3094 for (int i = 0; i < k; i++)
3095 fs[i] = new CompletableFuture<>();
3096 CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3097 for (int i = 0; i < k; i++) {
3098 checkIncomplete(f);
3099 checkIncomplete(CompletableFuture.allOf(fs));
3100 if (i != k / 2) {
3101 fs[i].complete(i);
3102 checkCompletedNormally(fs[i], i);
3103 } else {
3104 fs[i].completeExceptionally(ex);
3105 checkCompletedExceptionally(fs[i], ex);
3106 }
3107 }
3108 checkCompletedWithWrappedException(f, ex);
3109 checkCompletedWithWrappedException(CompletableFuture.allOf(fs), ex);
3110 }
3111 }
3112
3113 /**
3114 * anyOf(no component futures) returns an incomplete future
3115 */
3116 public void testAnyOf_empty() throws Exception {
3117 for (Integer v1 : new Integer[] { 1, null })
3118 {
3119 CompletableFuture<Object> f = CompletableFuture.anyOf();
3120 checkIncomplete(f);
3121
3122 f.complete(v1);
3123 checkCompletedNormally(f, v1);
3124 }}
3125
3126 /**
3127 * anyOf returns a future completed normally with a value when
3128 * a component future does
3129 */
3130 public void testAnyOf_normal() throws Exception {
3131 for (int k = 0; k < 10; k++) {
3132 CompletableFuture[] fs = new CompletableFuture[k];
3133 for (int i = 0; i < k; i++)
3134 fs[i] = new CompletableFuture<>();
3135 CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3136 checkIncomplete(f);
3137 for (int i = 0; i < k; i++) {
3138 fs[i].complete(i);
3139 checkCompletedNormally(f, 0);
3140 int x = (int) CompletableFuture.anyOf(fs).join();
3141 assertTrue(0 <= x && x <= i);
3142 }
3143 }
3144 }
3145 public void testAnyOf_normal_backwards() throws Exception {
3146 for (int k = 0; k < 10; k++) {
3147 CompletableFuture[] fs = new CompletableFuture[k];
3148 for (int i = 0; i < k; i++)
3149 fs[i] = new CompletableFuture<>();
3150 CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3151 checkIncomplete(f);
3152 for (int i = k - 1; i >= 0; i--) {
3153 fs[i].complete(i);
3154 checkCompletedNormally(f, k - 1);
3155 int x = (int) CompletableFuture.anyOf(fs).join();
3156 assertTrue(i <= x && x <= k - 1);
3157 }
3158 }
3159 }
3160
3161 /**
3162 * anyOf result completes exceptionally when any component does.
3163 */
3164 public void testAnyOf_exceptional() throws Exception {
3165 for (int k = 0; k < 10; k++) {
3166 CompletableFuture[] fs = new CompletableFuture[k];
3167 CFException[] exs = new CFException[k];
3168 for (int i = 0; i < k; i++) {
3169 fs[i] = new CompletableFuture<>();
3170 exs[i] = new CFException();
3171 }
3172 CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3173 checkIncomplete(f);
3174 for (int i = 0; i < k; i++) {
3175 fs[i].completeExceptionally(exs[i]);
3176 checkCompletedWithWrappedException(f, exs[0]);
3177 checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3178 }
3179 }
3180 }
3181
3182 public void testAnyOf_exceptional_backwards() throws Exception {
3183 for (int k = 0; k < 10; k++) {
3184 CompletableFuture[] fs = new CompletableFuture[k];
3185 CFException[] exs = new CFException[k];
3186 for (int i = 0; i < k; i++) {
3187 fs[i] = new CompletableFuture<>();
3188 exs[i] = new CFException();
3189 }
3190 CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3191 checkIncomplete(f);
3192 for (int i = k - 1; i >= 0; i--) {
3193 fs[i].completeExceptionally(exs[i]);
3194 checkCompletedWithWrappedException(f, exs[k - 1]);
3195 checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3196 }
3197 }
3198 }
3199
3200 /**
3201 * Completion methods throw NullPointerException with null arguments
3202 */
3203 public void testNPE() {
3204 CompletableFuture<Integer> f = new CompletableFuture<>();
3205 CompletableFuture<Integer> g = new CompletableFuture<>();
3206 CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
3207 ThreadExecutor exec = new ThreadExecutor();
3208
3209 Runnable[] throwingActions = {
3210 () -> CompletableFuture.supplyAsync(null),
3211 () -> CompletableFuture.supplyAsync(null, exec),
3212 () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.SYNC, 42), null),
3213
3214 () -> CompletableFuture.runAsync(null),
3215 () -> CompletableFuture.runAsync(null, exec),
3216 () -> CompletableFuture.runAsync(() -> {}, null),
3217
3218 () -> f.completeExceptionally(null),
3219
3220 () -> f.thenApply(null),
3221 () -> f.thenApplyAsync(null),
3222 () -> f.thenApplyAsync((x) -> x, null),
3223 () -> f.thenApplyAsync(null, exec),
3224
3225 () -> f.thenAccept(null),
3226 () -> f.thenAcceptAsync(null),
3227 () -> f.thenAcceptAsync((x) -> {} , null),
3228 () -> f.thenAcceptAsync(null, exec),
3229
3230 () -> f.thenRun(null),
3231 () -> f.thenRunAsync(null),
3232 () -> f.thenRunAsync(() -> {} , null),
3233 () -> f.thenRunAsync(null, exec),
3234
3235 () -> f.thenCombine(g, null),
3236 () -> f.thenCombineAsync(g, null),
3237 () -> f.thenCombineAsync(g, null, exec),
3238 () -> f.thenCombine(nullFuture, (x, y) -> x),
3239 () -> f.thenCombineAsync(nullFuture, (x, y) -> x),
3240 () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec),
3241 () -> f.thenCombineAsync(g, (x, y) -> x, null),
3242
3243 () -> f.thenAcceptBoth(g, null),
3244 () -> f.thenAcceptBothAsync(g, null),
3245 () -> f.thenAcceptBothAsync(g, null, exec),
3246 () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}),
3247 () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}),
3248 () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec),
3249 () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null),
3250
3251 () -> f.runAfterBoth(g, null),
3252 () -> f.runAfterBothAsync(g, null),
3253 () -> f.runAfterBothAsync(g, null, exec),
3254 () -> f.runAfterBoth(nullFuture, () -> {}),
3255 () -> f.runAfterBothAsync(nullFuture, () -> {}),
3256 () -> f.runAfterBothAsync(nullFuture, () -> {}, exec),
3257 () -> f.runAfterBothAsync(g, () -> {}, null),
3258
3259 () -> f.applyToEither(g, null),
3260 () -> f.applyToEitherAsync(g, null),
3261 () -> f.applyToEitherAsync(g, null, exec),
3262 () -> f.applyToEither(nullFuture, (x) -> x),
3263 () -> f.applyToEitherAsync(nullFuture, (x) -> x),
3264 () -> f.applyToEitherAsync(nullFuture, (x) -> x, exec),
3265 () -> f.applyToEitherAsync(g, (x) -> x, null),
3266
3267 () -> f.acceptEither(g, null),
3268 () -> f.acceptEitherAsync(g, null),
3269 () -> f.acceptEitherAsync(g, null, exec),
3270 () -> f.acceptEither(nullFuture, (x) -> {}),
3271 () -> f.acceptEitherAsync(nullFuture, (x) -> {}),
3272 () -> f.acceptEitherAsync(nullFuture, (x) -> {}, exec),
3273 () -> f.acceptEitherAsync(g, (x) -> {}, null),
3274
3275 () -> f.runAfterEither(g, null),
3276 () -> f.runAfterEitherAsync(g, null),
3277 () -> f.runAfterEitherAsync(g, null, exec),
3278 () -> f.runAfterEither(nullFuture, () -> {}),
3279 () -> f.runAfterEitherAsync(nullFuture, () -> {}),
3280 () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec),
3281 () -> f.runAfterEitherAsync(g, () -> {}, null),
3282
3283 () -> f.thenCompose(null),
3284 () -> f.thenComposeAsync(null),
3285 () -> f.thenComposeAsync(new CompletableFutureInc(ExecutionMode.EXECUTOR), null),
3286 () -> f.thenComposeAsync(null, exec),
3287
3288 () -> f.exceptionally(null),
3289
3290 () -> f.handle(null),
3291
3292 () -> CompletableFuture.allOf((CompletableFuture<?>)null),
3293 () -> CompletableFuture.allOf((CompletableFuture<?>[])null),
3294 () -> CompletableFuture.allOf(f, null),
3295 () -> CompletableFuture.allOf(null, f),
3296
3297 () -> CompletableFuture.anyOf((CompletableFuture<?>)null),
3298 () -> CompletableFuture.anyOf((CompletableFuture<?>[])null),
3299 () -> CompletableFuture.anyOf(f, null),
3300 () -> CompletableFuture.anyOf(null, f),
3301
3302 () -> f.obtrudeException(null),
3303
3304 () -> CompletableFuture.delayedExecutor(1L, SECONDS, null),
3305 () -> CompletableFuture.delayedExecutor(1L, null, exec),
3306 () -> CompletableFuture.delayedExecutor(1L, null),
3307
3308 () -> f.orTimeout(1L, null),
3309 () -> f.completeOnTimeout(42, 1L, null),
3310
3311 () -> CompletableFuture.failedFuture(null),
3312 () -> CompletableFuture.failedStage(null),
3313 };
3314
3315 assertThrows(NullPointerException.class, throwingActions);
3316 assertEquals(0, exec.count.get());
3317 }
3318
3319 /**
3320 * toCompletableFuture returns this CompletableFuture.
3321 */
3322 public void testToCompletableFuture() {
3323 CompletableFuture<Integer> f = new CompletableFuture<>();
3324 assertSame(f, f.toCompletableFuture());
3325 }
3326
3327 // jdk9
3328
3329 /**
3330 * newIncompleteFuture returns an incomplete CompletableFuture
3331 */
3332 public void testNewIncompleteFuture() {
3333 for (Integer v1 : new Integer[] { 1, null })
3334 {
3335 CompletableFuture<Integer> f = new CompletableFuture<>();
3336 CompletableFuture<Integer> g = f.newIncompleteFuture();
3337 checkIncomplete(f);
3338 checkIncomplete(g);
3339 f.complete(v1);
3340 checkCompletedNormally(f, v1);
3341 checkIncomplete(g);
3342 g.complete(v1);
3343 checkCompletedNormally(g, v1);
3344 assertSame(g.getClass(), CompletableFuture.class);
3345 }}
3346
3347 /**
3348 * completedStage returns a completed CompletionStage
3349 */
3350 public void testCompletedStage() {
3351 AtomicInteger x = new AtomicInteger(0);
3352 AtomicReference<Throwable> r = new AtomicReference<Throwable>();
3353 CompletionStage<Integer> f = CompletableFuture.completedStage(1);
3354 f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
3355 assertEquals(x.get(), 1);
3356 assertNull(r.get());
3357 }
3358
3359 /**
3360 * defaultExecutor by default returns the commonPool if
3361 * it supports more than one thread.
3362 */
3363 public void testDefaultExecutor() {
3364 CompletableFuture<Integer> f = new CompletableFuture<>();
3365 Executor e = f.defaultExecutor();
3366 Executor c = ForkJoinPool.commonPool();
3367 if (ForkJoinPool.getCommonPoolParallelism() > 1)
3368 assertSame(e, c);
3369 else
3370 assertNotSame(e, c);
3371 }
3372
3373 /**
3374 * failedFuture returns a CompletableFuture completed
3375 * exceptionally with the given Exception
3376 */
3377 public void testFailedFuture() {
3378 CFException ex = new CFException();
3379 CompletableFuture<Integer> f = CompletableFuture.failedFuture(ex);
3380 checkCompletedExceptionally(f, ex);
3381 }
3382
3383 /**
3384 * failedFuture(null) throws NPE
3385 */
3386 public void testFailedFuture_null() {
3387 try {
3388 CompletableFuture<Integer> f = CompletableFuture.failedFuture(null);
3389 shouldThrow();
3390 } catch (NullPointerException success) {}
3391 }
3392
3393 /**
3394 * copy returns a CompletableFuture that is completed normally,
3395 * with the same value, when source is.
3396 */
3397 public void testCopy() {
3398 CompletableFuture<Integer> f = new CompletableFuture<>();
3399 CompletableFuture<Integer> g = f.copy();
3400 checkIncomplete(f);
3401 checkIncomplete(g);
3402 f.complete(1);
3403 checkCompletedNormally(f, 1);
3404 checkCompletedNormally(g, 1);
3405 }
3406
3407 /**
3408 * copy returns a CompletableFuture that is completed exceptionally
3409 * when source is.
3410 */
3411 public void testCopy2() {
3412 CompletableFuture<Integer> f = new CompletableFuture<>();
3413 CompletableFuture<Integer> g = f.copy();
3414 checkIncomplete(f);
3415 checkIncomplete(g);
3416 CFException ex = new CFException();
3417 f.completeExceptionally(ex);
3418 checkCompletedExceptionally(f, ex);
3419 checkCompletedWithWrappedException(g, ex);
3420 }
3421
3422 /**
3423 * minimalCompletionStage returns a CompletableFuture that is
3424 * completed normally, with the same value, when source is.
3425 */
3426 public void testMinimalCompletionStage() {
3427 CompletableFuture<Integer> f = new CompletableFuture<>();
3428 CompletionStage<Integer> g = f.minimalCompletionStage();
3429 AtomicInteger x = new AtomicInteger(0);
3430 AtomicReference<Throwable> r = new AtomicReference<Throwable>();
3431 checkIncomplete(f);
3432 g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
3433 f.complete(1);
3434 checkCompletedNormally(f, 1);
3435 assertEquals(x.get(), 1);
3436 assertNull(r.get());
3437 }
3438
3439 /**
3440 * minimalCompletionStage returns a CompletableFuture that is
3441 * completed exceptionally when source is.
3442 */
3443 public void testMinimalCompletionStage2() {
3444 CompletableFuture<Integer> f = new CompletableFuture<>();
3445 CompletionStage<Integer> g = f.minimalCompletionStage();
3446 AtomicInteger x = new AtomicInteger(0);
3447 AtomicReference<Throwable> r = new AtomicReference<Throwable>();
3448 g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
3449 checkIncomplete(f);
3450 CFException ex = new CFException();
3451 f.completeExceptionally(ex);
3452 checkCompletedExceptionally(f, ex);
3453 assertEquals(x.get(), 0);
3454 assertEquals(r.get().getCause(), ex);
3455 }
3456
3457 /**
3458 * failedStage returns a CompletionStage completed
3459 * exceptionally with the given Exception
3460 */
3461 public void testFailedStage() {
3462 CFException ex = new CFException();
3463 CompletionStage<Integer> f = CompletableFuture.failedStage(ex);
3464 AtomicInteger x = new AtomicInteger(0);
3465 AtomicReference<Throwable> r = new AtomicReference<Throwable>();
3466 f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
3467 assertEquals(x.get(), 0);
3468 assertEquals(r.get(), ex);
3469 }
3470
3471 /**
3472 * completeAsync completes with value of given supplier
3473 */
3474 public void testCompleteAsync() {
3475 for (Integer v1 : new Integer[] { 1, null })
3476 {
3477 CompletableFuture<Integer> f = new CompletableFuture<>();
3478 f.completeAsync(() -> v1);
3479 f.join();
3480 checkCompletedNormally(f, v1);
3481 }}
3482
3483 /**
3484 * completeAsync completes exceptionally if given supplier throws
3485 */
3486 public void testCompleteAsync2() {
3487 CompletableFuture<Integer> f = new CompletableFuture<>();
3488 CFException ex = new CFException();
3489 f.completeAsync(() -> {if (true) throw ex; return 1;});
3490 try {
3491 f.join();
3492 shouldThrow();
3493 } catch (CompletionException success) {}
3494 checkCompletedWithWrappedException(f, ex);
3495 }
3496
3497 /**
3498 * completeAsync with given executor completes with value of given supplier
3499 */
3500 public void testCompleteAsync3() {
3501 for (Integer v1 : new Integer[] { 1, null })
3502 {
3503 CompletableFuture<Integer> f = new CompletableFuture<>();
3504 ThreadExecutor executor = new ThreadExecutor();
3505 f.completeAsync(() -> v1, executor);
3506 assertSame(v1, f.join());
3507 checkCompletedNormally(f, v1);
3508 assertEquals(1, executor.count.get());
3509 }}
3510
3511 /**
3512 * completeAsync with given executor completes exceptionally if
3513 * given supplier throws
3514 */
3515 public void testCompleteAsync4() {
3516 CompletableFuture<Integer> f = new CompletableFuture<>();
3517 CFException ex = new CFException();
3518 ThreadExecutor executor = new ThreadExecutor();
3519 f.completeAsync(() -> {if (true) throw ex; return 1;}, executor);
3520 try {
3521 f.join();
3522 shouldThrow();
3523 } catch (CompletionException success) {}
3524 checkCompletedWithWrappedException(f, ex);
3525 assertEquals(1, executor.count.get());
3526 }
3527
3528 /**
3529 * orTimeout completes with TimeoutException if not complete
3530 */
3531 public void testOrTimeout_timesOut() {
3532 long timeoutMillis = timeoutMillis();
3533 CompletableFuture<Integer> f = new CompletableFuture<>();
3534 long startTime = System.nanoTime();
3535 assertSame(f, f.orTimeout(timeoutMillis, MILLISECONDS));
3536 checkCompletedWithTimeoutException(f);
3537 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
3538 }
3539
3540 /**
3541 * orTimeout completes normally if completed before timeout
3542 */
3543 public void testOrTimeout_completed() {
3544 for (Integer v1 : new Integer[] { 1, null })
3545 {
3546 CompletableFuture<Integer> f = new CompletableFuture<>();
3547 CompletableFuture<Integer> g = new CompletableFuture<>();
3548 long startTime = System.nanoTime();
3549 f.complete(v1);
3550 assertSame(f, f.orTimeout(LONG_DELAY_MS, MILLISECONDS));
3551 assertSame(g, g.orTimeout(LONG_DELAY_MS, MILLISECONDS));
3552 g.complete(v1);
3553 checkCompletedNormally(f, v1);
3554 checkCompletedNormally(g, v1);
3555 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
3556 }}
3557
3558 /**
3559 * completeOnTimeout completes with given value if not complete
3560 */
3561 public void testCompleteOnTimeout_timesOut() {
3562 testInParallel(() -> testCompleteOnTimeout_timesOut(42),
3563 () -> testCompleteOnTimeout_timesOut(null));
3564 }
3565
3566 /**
3567 * completeOnTimeout completes with given value if not complete
3568 */
3569 public void testCompleteOnTimeout_timesOut(Integer v) {
3570 long timeoutMillis = timeoutMillis();
3571 CompletableFuture<Integer> f = new CompletableFuture<>();
3572 long startTime = System.nanoTime();
3573 assertSame(f, f.completeOnTimeout(v, timeoutMillis, MILLISECONDS));
3574 assertSame(v, f.join());
3575 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
3576 f.complete(99); // should have no effect
3577 checkCompletedNormally(f, v);
3578 }
3579
3580 /**
3581 * completeOnTimeout has no effect if completed within timeout
3582 */
3583 public void testCompleteOnTimeout_completed() {
3584 for (Integer v1 : new Integer[] { 1, null })
3585 {
3586 CompletableFuture<Integer> f = new CompletableFuture<>();
3587 CompletableFuture<Integer> g = new CompletableFuture<>();
3588 long startTime = System.nanoTime();
3589 f.complete(v1);
3590 assertSame(f, f.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS));
3591 assertSame(g, g.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS));
3592 g.complete(v1);
3593 checkCompletedNormally(f, v1);
3594 checkCompletedNormally(g, v1);
3595 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
3596 }}
3597
3598 /**
3599 * delayedExecutor returns an executor that delays submission
3600 */
3601 public void testDelayedExecutor() {
3602 testInParallel(() -> testDelayedExecutor(null, null),
3603 () -> testDelayedExecutor(null, 1),
3604 () -> testDelayedExecutor(new ThreadExecutor(), 1),
3605 () -> testDelayedExecutor(new ThreadExecutor(), 1));
3606 }
3607
3608 public void testDelayedExecutor(Executor executor, Integer v) throws Exception {
3609 long timeoutMillis = timeoutMillis();
3610 // Use an "unreasonably long" long timeout to catch lingering threads
3611 long longTimeoutMillis = 1000 * 60 * 60 * 24;
3612 final Executor delayer, longDelayer;
3613 if (executor == null) {
3614 delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS);
3615 longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS);
3616 } else {
3617 delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS, executor);
3618 longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS, executor);
3619 }
3620 long startTime = System.nanoTime();
3621 CompletableFuture<Integer> f =
3622 CompletableFuture.supplyAsync(() -> v, delayer);
3623 CompletableFuture<Integer> g =
3624 CompletableFuture.supplyAsync(() -> v, longDelayer);
3625
3626 assertNull(g.getNow(null));
3627
3628 assertSame(v, f.get(LONG_DELAY_MS, MILLISECONDS));
3629 long millisElapsed = millisElapsedSince(startTime);
3630 assertTrue(millisElapsed >= timeoutMillis);
3631 assertTrue(millisElapsed < LONG_DELAY_MS / 2);
3632
3633 checkCompletedNormally(f, v);
3634
3635 checkIncomplete(g);
3636 assertTrue(g.cancel(true));
3637 }
3638
3639 //--- tests of implementation details; not part of official tck ---
3640
3641 Object resultOf(CompletableFuture<?> f) {
3642 SecurityManager sm = System.getSecurityManager();
3643 if (sm != null) {
3644 try {
3645 System.setSecurityManager(null);
3646 } catch (SecurityException giveUp) {
3647 return "Reflection not available";
3648 }
3649 }
3650
3651 try {
3652 java.lang.reflect.Field resultField
3653 = CompletableFuture.class.getDeclaredField("result");
3654 resultField.setAccessible(true);
3655 return resultField.get(f);
3656 } catch (Throwable t) {
3657 throw new AssertionError(t);
3658 } finally {
3659 if (sm != null) System.setSecurityManager(sm);
3660 }
3661 }
3662
3663 public void testExceptionPropagationReusesResultObject() {
3664 if (!testImplementationDetails) return;
3665 for (ExecutionMode m : ExecutionMode.values())
3666 {
3667 final CFException ex = new CFException();
3668 final CompletableFuture<Integer> v42 = CompletableFuture.completedFuture(42);
3669 final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
3670
3671 List<Function<CompletableFuture<Integer>, CompletableFuture<?>>> funs
3672 = new ArrayList<>();
3673
3674 funs.add((y) -> m.thenRun(y, new Noop(m)));
3675 funs.add((y) -> m.thenAccept(y, new NoopConsumer(m)));
3676 funs.add((y) -> m.thenApply(y, new IncFunction(m)));
3677
3678 funs.add((y) -> m.runAfterEither(y, incomplete, new Noop(m)));
3679 funs.add((y) -> m.acceptEither(y, incomplete, new NoopConsumer(m)));
3680 funs.add((y) -> m.applyToEither(y, incomplete, new IncFunction(m)));
3681
3682 funs.add((y) -> m.runAfterBoth(y, v42, new Noop(m)));
3683 funs.add((y) -> m.runAfterBoth(v42, y, new Noop(m)));
3684 funs.add((y) -> m.thenAcceptBoth(y, v42, new SubtractAction(m)));
3685 funs.add((y) -> m.thenAcceptBoth(v42, y, new SubtractAction(m)));
3686 funs.add((y) -> m.thenCombine(y, v42, new SubtractFunction(m)));
3687 funs.add((y) -> m.thenCombine(v42, y, new SubtractFunction(m)));
3688
3689 funs.add((y) -> m.whenComplete(y, (Integer r, Throwable t) -> {}));
3690
3691 funs.add((y) -> m.thenCompose(y, new CompletableFutureInc(m)));
3692
3693 funs.add((y) -> CompletableFuture.allOf(new CompletableFuture<?>[] {y}));
3694 funs.add((y) -> CompletableFuture.allOf(new CompletableFuture<?>[] {y, v42}));
3695 funs.add((y) -> CompletableFuture.allOf(new CompletableFuture<?>[] {v42, y}));
3696 funs.add((y) -> CompletableFuture.anyOf(new CompletableFuture<?>[] {y}));
3697 funs.add((y) -> CompletableFuture.anyOf(new CompletableFuture<?>[] {y, incomplete}));
3698 funs.add((y) -> CompletableFuture.anyOf(new CompletableFuture<?>[] {incomplete, y}));
3699
3700 for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3701 fun : funs) {
3702 CompletableFuture<Integer> f = new CompletableFuture<>();
3703 f.completeExceptionally(ex);
3704 CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3705 checkCompletedWithWrappedException(src, ex);
3706 CompletableFuture<?> dep = fun.apply(src);
3707 checkCompletedWithWrappedException(dep, ex);
3708 assertSame(resultOf(src), resultOf(dep));
3709 }
3710
3711 for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3712 fun : funs) {
3713 CompletableFuture<Integer> f = new CompletableFuture<>();
3714 CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3715 CompletableFuture<?> dep = fun.apply(src);
3716 f.completeExceptionally(ex);
3717 checkCompletedWithWrappedException(src, ex);
3718 checkCompletedWithWrappedException(dep, ex);
3719 assertSame(resultOf(src), resultOf(dep));
3720 }
3721
3722 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
3723 for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3724 fun : funs) {
3725 CompletableFuture<Integer> f = new CompletableFuture<>();
3726 f.cancel(mayInterruptIfRunning);
3727 checkCancelled(f);
3728 CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3729 checkCompletedWithWrappedCancellationException(src);
3730 CompletableFuture<?> dep = fun.apply(src);
3731 checkCompletedWithWrappedCancellationException(dep);
3732 assertSame(resultOf(src), resultOf(dep));
3733 }
3734
3735 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
3736 for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3737 fun : funs) {
3738 CompletableFuture<Integer> f = new CompletableFuture<>();
3739 CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3740 CompletableFuture<?> dep = fun.apply(src);
3741 f.cancel(mayInterruptIfRunning);
3742 checkCancelled(f);
3743 checkCompletedWithWrappedCancellationException(src);
3744 checkCompletedWithWrappedCancellationException(dep);
3745 assertSame(resultOf(src), resultOf(dep));
3746 }
3747 }}
3748
3749 /**
3750 * Minimal completion stages throw UOE for all non-CompletionStage methods
3751 */
3752 public void testMinimalCompletionStage_minimality() {
3753 if (!testImplementationDetails) return;
3754 Function<Method, String> toSignature =
3755 (method) -> method.getName() + Arrays.toString(method.getParameterTypes());
3756 Predicate<Method> isNotStatic =
3757 (method) -> (method.getModifiers() & Modifier.STATIC) == 0;
3758 List<Method> minimalMethods =
3759 Stream.of(Object.class, CompletionStage.class)
3760 .flatMap((klazz) -> Stream.of(klazz.getMethods()))
3761 .filter(isNotStatic)
3762 .collect(Collectors.toList());
3763 // Methods from CompletableFuture permitted NOT to throw UOE
3764 String[] signatureWhitelist = {
3765 "newIncompleteFuture[]",
3766 "defaultExecutor[]",
3767 "minimalCompletionStage[]",
3768 "copy[]",
3769 };
3770 Set<String> permittedMethodSignatures =
3771 Stream.concat(minimalMethods.stream().map(toSignature),
3772 Stream.of(signatureWhitelist))
3773 .collect(Collectors.toSet());
3774 List<Method> allMethods = Stream.of(CompletableFuture.class.getMethods())
3775 .filter(isNotStatic)
3776 .filter((method) -> !permittedMethodSignatures.contains(toSignature.apply(method)))
3777 .collect(Collectors.toList());
3778
3779 CompletionStage<Integer> minimalStage =
3780 new CompletableFuture<Integer>().minimalCompletionStage();
3781
3782 List<Method> bugs = new ArrayList<>();
3783 for (Method method : allMethods) {
3784 Class<?>[] parameterTypes = method.getParameterTypes();
3785 Object[] args = new Object[parameterTypes.length];
3786 // Manufacture boxed primitives for primitive params
3787 for (int i = 0; i < args.length; i++) {
3788 Class<?> type = parameterTypes[i];
3789 if (parameterTypes[i] == boolean.class)
3790 args[i] = false;
3791 else if (parameterTypes[i] == int.class)
3792 args[i] = 0;
3793 else if (parameterTypes[i] == long.class)
3794 args[i] = 0L;
3795 }
3796 try {
3797 method.invoke(minimalStage, args);
3798 bugs.add(method);
3799 }
3800 catch (java.lang.reflect.InvocationTargetException expected) {
3801 if (! (expected.getCause() instanceof UnsupportedOperationException)) {
3802 bugs.add(method);
3803 // expected.getCause().printStackTrace();
3804 }
3805 }
3806 catch (ReflectiveOperationException bad) { throw new Error(bad); }
3807 }
3808 if (!bugs.isEmpty())
3809 throw new Error("Methods did not throw UOE: " + bugs.toString());
3810 }
3811
3812 static class Monad {
3813 static class ZeroException extends RuntimeException {
3814 public ZeroException() { super("monadic zero"); }
3815 }
3816 // "return", "unit"
3817 static <T> CompletableFuture<T> unit(T value) {
3818 return completedFuture(value);
3819 }
3820 // monadic zero ?
3821 static <T> CompletableFuture<T> zero() {
3822 return failedFuture(new ZeroException());
3823 }
3824 // >=>
3825 static <T,U,V> Function<T, CompletableFuture<V>> compose
3826 (Function<T, CompletableFuture<U>> f,
3827 Function<U, CompletableFuture<V>> g) {
3828 return (x) -> f.apply(x).thenCompose(g);
3829 }
3830
3831 static void assertZero(CompletableFuture<?> f) {
3832 try {
3833 f.getNow(null);
3834 throw new AssertionFailedError("should throw");
3835 } catch (CompletionException success) {
3836 assertTrue(success.getCause() instanceof ZeroException);
3837 }
3838 }
3839
3840 static <T> void assertFutureEquals(CompletableFuture<T> f,
3841 CompletableFuture<T> g) {
3842 T fval = null, gval = null;
3843 Throwable fex = null, gex = null;
3844
3845 try { fval = f.get(); }
3846 catch (ExecutionException ex) { fex = ex.getCause(); }
3847 catch (Throwable ex) { fex = ex; }
3848
3849 try { gval = g.get(); }
3850 catch (ExecutionException ex) { gex = ex.getCause(); }
3851 catch (Throwable ex) { gex = ex; }
3852
3853 if (fex != null || gex != null)
3854 assertSame(fex.getClass(), gex.getClass());
3855 else
3856 assertEquals(fval, gval);
3857 }
3858
3859 static class PlusFuture<T> extends CompletableFuture<T> {
3860 AtomicReference<Throwable> firstFailure = new AtomicReference<>(null);
3861 }
3862
3863 /** Implements "monadic plus". */
3864 static <T> CompletableFuture<T> plus(CompletableFuture<? extends T> f,
3865 CompletableFuture<? extends T> g) {
3866 PlusFuture<T> plus = new PlusFuture<T>();
3867 BiConsumer<T, Throwable> action = (T result, Throwable ex) -> {
3868 try {
3869 if (ex == null) {
3870 if (plus.complete(result))
3871 if (plus.firstFailure.get() != null)
3872 plus.firstFailure.set(null);
3873 }
3874 else if (plus.firstFailure.compareAndSet(null, ex)) {
3875 if (plus.isDone())
3876 plus.firstFailure.set(null);
3877 }
3878 else {
3879 // first failure has precedence
3880 Throwable first = plus.firstFailure.getAndSet(null);
3881
3882 // may fail with "Self-suppression not permitted"
3883 try { first.addSuppressed(ex); }
3884 catch (Exception ignored) {}
3885
3886 plus.completeExceptionally(first);
3887 }
3888 } catch (Throwable unexpected) {
3889 plus.completeExceptionally(unexpected);
3890 }
3891 };
3892 f.whenComplete(action);
3893 g.whenComplete(action);
3894 return plus;
3895 }
3896 }
3897
3898 /**
3899 * CompletableFuture is an additive monad - sort of.
3900 * https://en.wikipedia.org/wiki/Monad_(functional_programming)#Additive_monads
3901 */
3902 public void testAdditiveMonad() throws Throwable {
3903 Function<Long, CompletableFuture<Long>> unit = Monad::unit;
3904 CompletableFuture<Long> zero = Monad.zero();
3905
3906 // Some mutually non-commutative functions
3907 Function<Long, CompletableFuture<Long>> triple
3908 = (x) -> Monad.unit(3 * x);
3909 Function<Long, CompletableFuture<Long>> inc
3910 = (x) -> Monad.unit(x + 1);
3911
3912 // unit is a right identity: m >>= unit === m
3913 Monad.assertFutureEquals(inc.apply(5L).thenCompose(unit),
3914 inc.apply(5L));
3915 // unit is a left identity: (unit x) >>= f === f x
3916 Monad.assertFutureEquals(unit.apply(5L).thenCompose(inc),
3917 inc.apply(5L));
3918
3919 // associativity: (m >>= f) >>= g === m >>= ( \x -> (f x >>= g) )
3920 Monad.assertFutureEquals(
3921 unit.apply(5L).thenCompose(inc).thenCompose(triple),
3922 unit.apply(5L).thenCompose((x) -> inc.apply(x).thenCompose(triple)));
3923
3924 // The case for CompletableFuture as an additive monad is weaker...
3925
3926 // zero is a monadic zero
3927 Monad.assertZero(zero);
3928
3929 // left zero: zero >>= f === zero
3930 Monad.assertZero(zero.thenCompose(inc));
3931 // right zero: f >>= (\x -> zero) === zero
3932 Monad.assertZero(inc.apply(5L).thenCompose((x) -> zero));
3933
3934 // f plus zero === f
3935 Monad.assertFutureEquals(Monad.unit(5L),
3936 Monad.plus(Monad.unit(5L), zero));
3937 // zero plus f === f
3938 Monad.assertFutureEquals(Monad.unit(5L),
3939 Monad.plus(zero, Monad.unit(5L)));
3940 // zero plus zero === zero
3941 Monad.assertZero(Monad.plus(zero, zero));
3942 {
3943 CompletableFuture<Long> f = Monad.plus(Monad.unit(5L),
3944 Monad.unit(8L));
3945 // non-determinism
3946 assertTrue(f.get() == 5L || f.get() == 8L);
3947 }
3948
3949 CompletableFuture<Long> godot = new CompletableFuture<>();
3950 // f plus godot === f (doesn't wait for godot)
3951 Monad.assertFutureEquals(Monad.unit(5L),
3952 Monad.plus(Monad.unit(5L), godot));
3953 // godot plus f === f (doesn't wait for godot)
3954 Monad.assertFutureEquals(Monad.unit(5L),
3955 Monad.plus(godot, Monad.unit(5L)));
3956 }
3957
3958 /**
3959 * A single CompletableFuture with many dependents.
3960 * A demo of scalability - runtime is O(n).
3961 */
3962 public void testManyDependents() throws Throwable {
3963 final int n = 1_000;
3964 final CompletableFuture<Void> head = new CompletableFuture<>();
3965 final CompletableFuture<Void> complete = CompletableFuture.completedFuture((Void)null);
3966 final AtomicInteger count = new AtomicInteger(0);
3967 for (int i = 0; i < n; i++) {
3968 head.thenRun(() -> count.getAndIncrement());
3969 head.thenAccept((x) -> count.getAndIncrement());
3970 head.thenApply((x) -> count.getAndIncrement());
3971
3972 head.runAfterBoth(complete, () -> count.getAndIncrement());
3973 head.thenAcceptBoth(complete, (x, y) -> count.getAndIncrement());
3974 head.thenCombine(complete, (x, y) -> count.getAndIncrement());
3975 complete.runAfterBoth(head, () -> count.getAndIncrement());
3976 complete.thenAcceptBoth(head, (x, y) -> count.getAndIncrement());
3977 complete.thenCombine(head, (x, y) -> count.getAndIncrement());
3978
3979 head.runAfterEither(new CompletableFuture<Void>(), () -> count.getAndIncrement());
3980 head.acceptEither(new CompletableFuture<Void>(), (x) -> count.getAndIncrement());
3981 head.applyToEither(new CompletableFuture<Void>(), (x) -> count.getAndIncrement());
3982 new CompletableFuture<Void>().runAfterEither(head, () -> count.getAndIncrement());
3983 new CompletableFuture<Void>().acceptEither(head, (x) -> count.getAndIncrement());
3984 new CompletableFuture<Void>().applyToEither(head, (x) -> count.getAndIncrement());
3985 }
3986 head.complete(null);
3987 assertEquals(5 * 3 * n, count.get());
3988 }
3989
3990 // static <U> U join(CompletionStage<U> stage) {
3991 // CompletableFuture<U> f = new CompletableFuture<>();
3992 // stage.whenComplete((v, ex) -> {
3993 // if (ex != null) f.completeExceptionally(ex); else f.complete(v);
3994 // });
3995 // return f.join();
3996 // }
3997
3998 // static <U> boolean isDone(CompletionStage<U> stage) {
3999 // CompletableFuture<U> f = new CompletableFuture<>();
4000 // stage.whenComplete((v, ex) -> {
4001 // if (ex != null) f.completeExceptionally(ex); else f.complete(v);
4002 // });
4003 // return f.isDone();
4004 // }
4005
4006 // static <U> U join2(CompletionStage<U> stage) {
4007 // return stage.toCompletableFuture().copy().join();
4008 // }
4009
4010 // static <U> boolean isDone2(CompletionStage<U> stage) {
4011 // return stage.toCompletableFuture().copy().isDone();
4012 // }
4013
4014 }