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