ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CompletableFutureTest.java
Revision: 1.148
Committed: Sun Jun 26 15:46:22 2016 UTC (7 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.147: +5 -0 lines
Log Message:
testExceptionPropagationReusesResultObject: add missing funs

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