ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CompletableFutureTest.java
Revision: 1.195
Committed: Sun Jul 22 20:09:31 2018 UTC (5 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.194: +5 -1 lines
Log Message:
Fix errorprone warning [AssertionFailureIgnored]

File Contents

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