ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CompletableFutureTest.java
(Generate patch)

Comparing jsr166/src/test/tck/CompletableFutureTest.java (file contents):
Revision 1.2 by jsr166, Wed Feb 6 20:29:55 2013 UTC vs.
Revision 1.16 by jsr166, Thu Apr 4 04:01:05 2013 UTC

# Line 1 | Line 1
1   /*
2 < * Written by Doug Lea with assistance from members of JCP JSR-166
3 < * Expert Group and released to the public domain, as explained at
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/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
6   */
7  
8   import junit.framework.*;
9   import java.util.concurrent.Callable;
10 + import java.util.concurrent.Executor;
11 + import java.util.concurrent.ExecutorService;
12 + import java.util.concurrent.Executors;
13   import java.util.concurrent.CancellationException;
14   import java.util.concurrent.CountDownLatch;
15   import java.util.concurrent.ExecutionException;
16   import java.util.concurrent.Future;
17   import java.util.concurrent.CompletableFuture;
18 + import java.util.concurrent.CompletionException;
19   import java.util.concurrent.TimeoutException;
20   import java.util.concurrent.atomic.AtomicInteger;
21   import static java.util.concurrent.TimeUnit.MILLISECONDS;
22   import static java.util.concurrent.TimeUnit.SECONDS;
23   import java.util.*;
24 + import java.util.function.Supplier;
25 + import java.util.function.Consumer;
26 + import java.util.function.BiConsumer;
27 + import java.util.function.Function;
28 + import java.util.function.BiFunction;
29  
30   public class CompletableFutureTest extends JSR166TestCase {
31  
# Line 28 | Line 36 | public class CompletableFutureTest exten
36          return new TestSuite(CompletableFutureTest.class);
37      }
38  
39 +    static class CFException extends RuntimeException {}
40 +
41 +    void checkIncomplete(CompletableFuture<?> f) {
42 +        assertFalse(f.isDone());
43 +        assertFalse(f.isCancelled());
44 +        assertTrue(f.toString().contains("[Not completed]"));
45 +        try {
46 +            assertNull(f.getNow(null));
47 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
48 +        try {
49 +            f.get(0L, SECONDS);
50 +            shouldThrow();
51 +        }
52 +        catch (TimeoutException success) {}
53 +        catch (Throwable fail) { threadUnexpectedException(fail); }
54 +    }
55 +
56 +    <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
57 +        try {
58 +            assertEquals(value, f.join());
59 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
60 +        try {
61 +            assertEquals(value, f.getNow(null));
62 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
63 +        try {
64 +            assertEquals(value, f.get());
65 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
66 +        try {
67 +            assertEquals(value, f.get(0L, SECONDS));
68 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
69 +        assertTrue(f.isDone());
70 +        assertFalse(f.isCancelled());
71 +        assertTrue(f.toString().contains("[Completed normally]"));
72 +    }
73 +
74 +    void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
75 +        try {
76 +            f.join();
77 +            shouldThrow();
78 +        } catch (CompletionException success) {
79 +            assertTrue(success.getCause() instanceof CFException);
80 +        }
81 +        try {
82 +            f.getNow(null);
83 +            shouldThrow();
84 +        } catch (CompletionException success) {
85 +            assertTrue(success.getCause() instanceof CFException);
86 +        }
87 +        try {
88 +            f.get();
89 +            shouldThrow();
90 +        } catch (ExecutionException success) {
91 +            assertTrue(success.getCause() instanceof CFException);
92 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
93 +        try {
94 +            f.get(0L, SECONDS);
95 +            shouldThrow();
96 +        } catch (ExecutionException success) {
97 +            assertTrue(success.getCause() instanceof CFException);
98 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
99 +        assertTrue(f.isDone());
100 +        assertFalse(f.isCancelled());
101 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
102 +    }
103 +
104 +    void checkCancelled(CompletableFuture<?> f) {
105 +        try {
106 +            f.join();
107 +            shouldThrow();
108 +        } catch (CancellationException success) {}
109 +        try {
110 +            f.getNow(null);
111 +            shouldThrow();
112 +        } catch (CancellationException success) {}
113 +        try {
114 +            f.get();
115 +            shouldThrow();
116 +        } catch (CancellationException success) {
117 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
118 +        try {
119 +            f.get(0L, SECONDS);
120 +            shouldThrow();
121 +        } catch (CancellationException success) {
122 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
123 +        assertTrue(f.isDone());
124 +        assertTrue(f.isCancelled());
125 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
126 +    }
127 +
128 +    void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
129 +        try {
130 +            f.join();
131 +            shouldThrow();
132 +        } catch (CompletionException success) {
133 +            assertTrue(success.getCause() instanceof CancellationException);
134 +        }
135 +        try {
136 +            f.getNow(null);
137 +            shouldThrow();
138 +        } catch (CompletionException success) {
139 +            assertTrue(success.getCause() instanceof CancellationException);
140 +        }
141 +        try {
142 +            f.get();
143 +            shouldThrow();
144 +        } catch (ExecutionException success) {
145 +            assertTrue(success.getCause() instanceof CancellationException);
146 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
147 +        try {
148 +            f.get(0L, SECONDS);
149 +            shouldThrow();
150 +        } catch (ExecutionException success) {
151 +            assertTrue(success.getCause() instanceof CancellationException);
152 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
153 +        assertTrue(f.isDone());
154 +        assertFalse(f.isCancelled());
155 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
156 +    }
157 +
158 +    /**
159 +     * A newly constructed CompletableFuture is incomplete, as indicated
160 +     * by methods isDone, isCancelled, and getNow
161 +     */
162 +    public void testConstructor() {
163 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
164 +        checkIncomplete(f);
165 +    }
166 +
167 +    /**
168 +     * complete completes normally, as indicated by methods isDone,
169 +     * isCancelled, join, get, and getNow
170 +     */
171 +    public void testComplete() {
172 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
173 +        checkIncomplete(f);
174 +        f.complete(one);
175 +        checkCompletedNormally(f, one);
176 +    }
177 +
178 +    /**
179 +     * completeExceptionally completes exceptionally, as indicated by
180 +     * methods isDone, isCancelled, join, get, and getNow
181 +     */
182 +    public void testCompleteExceptionally() {
183 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
184 +        checkIncomplete(f);
185 +        f.completeExceptionally(new CFException());
186 +        checkCompletedWithWrappedCFException(f);
187 +    }
188 +
189 +    /**
190 +     * cancel completes exceptionally and reports cancelled, as indicated by
191 +     * methods isDone, isCancelled, join, get, and getNow
192 +     */
193 +    public void testCancel() {
194 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
195 +        checkIncomplete(f);
196 +        assertTrue(f.cancel(true));
197 +        checkCancelled(f);
198 +    }
199 +
200 +    /**
201 +     * obtrudeValue forces completion with given value
202 +     */
203 +    public void testObtrudeValue() {
204 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
205 +        checkIncomplete(f);
206 +        f.complete(one);
207 +        checkCompletedNormally(f, one);
208 +        f.obtrudeValue(three);
209 +        checkCompletedNormally(f, three);
210 +        f.obtrudeValue(two);
211 +        checkCompletedNormally(f, two);
212 +        f = new CompletableFuture<Integer>();
213 +        f.obtrudeValue(three);
214 +        checkCompletedNormally(f, three);
215 +        f = new CompletableFuture<Integer>();
216 +        f.completeExceptionally(new CFException());
217 +        f.obtrudeValue(four);
218 +        checkCompletedNormally(f, four);
219 +    }
220 +
221 +    /**
222 +     * obtrudeException forces completion with given exception
223 +     */
224 +    public void testObtrudeException() {
225 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
226 +        checkIncomplete(f);
227 +        f.complete(one);
228 +        checkCompletedNormally(f, one);
229 +        f.obtrudeException(new CFException());
230 +        checkCompletedWithWrappedCFException(f);
231 +        f = new CompletableFuture<Integer>();
232 +        f.obtrudeException(new CFException());
233 +        checkCompletedWithWrappedCFException(f);
234 +        f = new CompletableFuture<Integer>();
235 +        f.completeExceptionally(new CFException());
236 +        f.obtrudeValue(four);
237 +        checkCompletedNormally(f, four);
238 +        f.obtrudeException(new CFException());
239 +        checkCompletedWithWrappedCFException(f);
240 +    }
241 +
242 +    /**
243 +     * getNumberOfDependents returns number of dependent tasks
244 +     */
245 +    public void testGetNumberOfDependents() {
246 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
247 +        assertEquals(f.getNumberOfDependents(), 0);
248 +        CompletableFuture g = f.thenRun(new Noop());
249 +        assertEquals(f.getNumberOfDependents(), 1);
250 +        assertEquals(g.getNumberOfDependents(), 0);
251 +        CompletableFuture h = f.thenRun(new Noop());
252 +        assertEquals(f.getNumberOfDependents(), 2);
253 +        f.complete(1);
254 +        checkCompletedNormally(g, null);
255 +        assertEquals(f.getNumberOfDependents(), 0);
256 +        assertEquals(g.getNumberOfDependents(), 0);
257 +    }
258 +
259 +
260 +    /**
261 +     * toString indicates current completion state
262 +     */
263      public void testToString() {
264          CompletableFuture<String> f;
265  
# Line 41 | Line 273 | public class CompletableFutureTest exten
273          f.completeExceptionally(new IndexOutOfBoundsException());
274          assertTrue(f.toString().contains("[Completed exceptionally]"));
275      }
276 +
277 +    /**
278 +     * completedFuture returns a completed CompletableFuture with given value
279 +     */
280 +    public void testCompletedFuture() {
281 +        CompletableFuture<String> f = CompletableFuture.completedFuture("test");
282 +        checkCompletedNormally(f, "test");
283 +    }
284 +
285 +    static final Supplier<Integer> supplyOne =
286 +        () -> Integer.valueOf(1);
287 +    static final Function<Integer, Integer> inc =
288 +        (Integer x) -> Integer.valueOf(x.intValue() + 1);
289 +    static final BiFunction<Integer, Integer, Integer> add =
290 +        (Integer x, Integer y) -> Integer.valueOf(x.intValue() + y.intValue());
291 +    static final class IncAction implements Consumer<Integer> {
292 +        int value;
293 +        public void accept(Integer x) { value = x.intValue() + 1; }
294 +    }
295 +    static final class AddAction implements BiConsumer<Integer, Integer> {
296 +        int value;
297 +        public void accept(Integer x, Integer y) {
298 +            value = x.intValue() + y.intValue();
299 +        }
300 +    }
301 +    static final class Noop implements Runnable {
302 +        boolean ran;
303 +        public void run() { ran = true; }
304 +    }
305 +
306 +    static final class FailingSupplier implements Supplier<Integer> {
307 +        boolean ran;
308 +        public Integer get() { ran = true; throw new CFException(); }
309 +    }
310 +    static final class FailingConsumer implements Consumer<Integer> {
311 +        boolean ran;
312 +        public void accept(Integer x) { ran = true; throw new CFException(); }
313 +    }
314 +    static final class FailingBiConsumer implements BiConsumer<Integer, Integer> {
315 +        boolean ran;
316 +        public void accept(Integer x, Integer y) { ran = true; throw new CFException(); }
317 +    }
318 +    static final class FailingFunction implements Function<Integer, Integer> {
319 +        boolean ran;
320 +        public Integer apply(Integer x) { ran = true; throw new CFException(); }
321 +    }
322 +    static final class FailingBiFunction implements BiFunction<Integer, Integer, Integer> {
323 +        boolean ran;
324 +        public Integer apply(Integer x, Integer y) { ran = true; throw new CFException(); }
325 +    }
326 +    static final class FailingNoop implements Runnable {
327 +        boolean ran;
328 +        public void run() { ran = true; throw new CFException(); }
329 +    }
330 +
331 +    static final class CompletableFutureInc implements Function<Integer, CompletableFuture<Integer>> {
332 +        public CompletableFuture<Integer> apply(Integer x) {
333 +            CompletableFuture<Integer> f = new CompletableFuture<Integer>();
334 +            f.complete(Integer.valueOf(x.intValue() + 1));
335 +            return f;
336 +        }
337 +    }
338 +
339 +    static final class FailingCompletableFutureFunction implements Function<Integer, CompletableFuture<Integer>> {
340 +        boolean ran;
341 +        public CompletableFuture<Integer> apply(Integer x) {
342 +            ran = true; throw new CFException();
343 +        }
344 +    }
345 +
346 +    // Used for explicit executor tests
347 +    static final class ThreadExecutor implements Executor {
348 +        public void execute(Runnable r) {
349 +            new Thread(r).start();
350 +        }
351 +    }
352 +
353 +    static final class ExceptionToInteger implements Function<Throwable, Integer> {
354 +        public Integer apply(Throwable x) { return Integer.valueOf(3); }
355 +    }
356 +
357 +    static final class IntegerHandler implements BiFunction<Integer, Throwable, Integer> {
358 +        boolean ran;
359 +        public Integer apply(Integer x, Throwable t) {
360 +            ran = true;
361 +            return (t == null) ? two : three;
362 +        }
363 +    }
364 +
365 +
366 +    /**
367 +     * exceptionally action completes with function value on source
368 +     * exception;  otherwise with source value
369 +     */
370 +    public void testExceptionally() {
371 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
372 +        ExceptionToInteger r = new ExceptionToInteger();
373 +        CompletableFuture<Integer> g = f.exceptionally(r);
374 +        f.completeExceptionally(new CFException());
375 +        checkCompletedNormally(g, three);
376 +
377 +        f = new CompletableFuture<Integer>();
378 +        r = new ExceptionToInteger();
379 +        g = f.exceptionally(r);
380 +        f.complete(one);
381 +        checkCompletedNormally(g, one);
382 +    }
383 +
384 +    /**
385 +     * handle action completes normally with function value on either
386 +     * normal or exceptional completion of source
387 +     */
388 +    public void testHandle() {
389 +        CompletableFuture<Integer> f, g;
390 +        IntegerHandler r;
391 +
392 +        f = new CompletableFuture<Integer>();
393 +        f.completeExceptionally(new CFException());
394 +        g = f.handle(r = new IntegerHandler());
395 +        assertTrue(r.ran);
396 +        checkCompletedNormally(g, three);
397 +
398 +        f = new CompletableFuture<Integer>();
399 +        g = f.handle(r = new IntegerHandler());
400 +        assertFalse(r.ran);
401 +        f.completeExceptionally(new CFException());
402 +        checkCompletedNormally(g, three);
403 +        assertTrue(r.ran);
404 +
405 +        f = new CompletableFuture<Integer>();
406 +        f.complete(one);
407 +        g = f.handle(r = new IntegerHandler());
408 +        assertTrue(r.ran);
409 +        checkCompletedNormally(g, two);
410 +
411 +        f = new CompletableFuture<Integer>();
412 +        g = f.handle(r = new IntegerHandler());
413 +        assertFalse(r.ran);
414 +        f.complete(one);
415 +        assertTrue(r.ran);
416 +        checkCompletedNormally(g, two);
417 +    }
418 +
419 +    /**
420 +     * runAsync completes after running Runnable
421 +     */
422 +    public void testRunAsync() {
423 +        Noop r = new Noop();
424 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r);
425 +        assertNull(f.join());
426 +        assertTrue(r.ran);
427 +        checkCompletedNormally(f, null);
428 +    }
429 +
430 +    /**
431 +     * runAsync with executor completes after running Runnable
432 +     */
433 +    public void testRunAsync2() {
434 +        Noop r = new Noop();
435 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r, new ThreadExecutor());
436 +        assertNull(f.join());
437 +        assertTrue(r.ran);
438 +        checkCompletedNormally(f, null);
439 +    }
440 +
441 +    /**
442 +     * failing runAsync completes exceptionally after running Runnable
443 +     */
444 +    public void testRunAsync3() {
445 +        FailingNoop r = new FailingNoop();
446 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r);
447 +        checkCompletedWithWrappedCFException(f);
448 +        assertTrue(r.ran);
449 +    }
450 +
451 +    /**
452 +     * supplyAsync completes with result of supplier
453 +     */
454 +    public void testSupplyAsync() {
455 +        CompletableFuture<Integer> f = CompletableFuture.supplyAsync(supplyOne);
456 +        assertEquals(f.join(), one);
457 +    }
458 +
459 +    /**
460 +     * supplyAsync with executor completes with result of supplier
461 +     */
462 +    public void testSupplyAsync2() {
463 +        CompletableFuture<Integer> f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor());
464 +        assertEquals(f.join(), one);
465 +    }
466 +
467 +    /**
468 +     * Failing supplyAsync completes exceptionally
469 +     */
470 +    public void testSupplyAsync3() {
471 +        FailingSupplier r = new FailingSupplier();
472 +        CompletableFuture<Integer> f = CompletableFuture.supplyAsync(r);
473 +        checkCompletedWithWrappedCFException(f);
474 +        assertTrue(r.ran);
475 +    }
476 +
477 +    // seq completion methods
478 +
479 +    /**
480 +     * thenRun result completes normally after normal completion of source
481 +     */
482 +    public void testThenRun() {
483 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
484 +        Noop r = new Noop();
485 +        CompletableFuture<Void> g = f.thenRun(r);
486 +        f.complete(null);
487 +        checkCompletedNormally(g, null);
488 +        // reordered version
489 +        f = new CompletableFuture<Integer>();
490 +        f.complete(null);
491 +        r = new Noop();
492 +        g = f.thenRun(r);
493 +        checkCompletedNormally(g, null);
494 +    }
495 +
496 +    /**
497 +     * thenRun result completes exceptionally after exceptional
498 +     * completion of source
499 +     */
500 +    public void testThenRun2() {
501 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
502 +        Noop r = new Noop();
503 +        CompletableFuture<Void> g = f.thenRun(r);
504 +        f.completeExceptionally(new CFException());
505 +        checkCompletedWithWrappedCFException(g);
506 +    }
507 +
508 +    /**
509 +     * thenRun result completes exceptionally if action does
510 +     */
511 +    public void testThenRun3() {
512 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
513 +        FailingNoop r = new FailingNoop();
514 +        CompletableFuture<Void> g = f.thenRun(r);
515 +        f.complete(null);
516 +        checkCompletedWithWrappedCFException(g);
517 +    }
518 +
519 +    /**
520 +     * thenRun result completes exceptionally if source cancelled
521 +     */
522 +    public void testThenRun4() {
523 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
524 +        Noop r = new Noop();
525 +        CompletableFuture<Void> g = f.thenRun(r);
526 +        assertTrue(f.cancel(true));
527 +        checkCompletedWithWrappedCancellationException(g);
528 +    }
529 +
530 +    /**
531 +     * thenApply result completes normally after normal completion of source
532 +     */
533 +    public void testThenApply() {
534 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
535 +        CompletableFuture<Integer> g = f.thenApply(inc);
536 +        f.complete(one);
537 +        checkCompletedNormally(g, two);
538 +    }
539 +
540 +    /**
541 +     * thenApply result completes exceptionally after exceptional
542 +     * completion of source
543 +     */
544 +    public void testThenApply2() {
545 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
546 +        CompletableFuture<Integer> g = f.thenApply(inc);
547 +        f.completeExceptionally(new CFException());
548 +        checkCompletedWithWrappedCFException(g);
549 +    }
550 +
551 +    /**
552 +     * thenApply result completes exceptionally if action does
553 +     */
554 +    public void testThenApply3() {
555 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
556 +        CompletableFuture<Integer> g = f.thenApply(new FailingFunction());
557 +        f.complete(one);
558 +        checkCompletedWithWrappedCFException(g);
559 +    }
560 +
561 +    /**
562 +     * thenApply result completes exceptionally if source cancelled
563 +     */
564 +    public void testThenApply4() {
565 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
566 +        CompletableFuture<Integer> g = f.thenApply(inc);
567 +        assertTrue(f.cancel(true));
568 +        checkCompletedWithWrappedCancellationException(g);
569 +    }
570 +
571 +    /**
572 +     * thenAccept result completes normally after normal completion of source
573 +     */
574 +    public void testThenAccept() {
575 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
576 +        IncAction r = new IncAction();
577 +        CompletableFuture<Void> g = f.thenAccept(r);
578 +        f.complete(one);
579 +        checkCompletedNormally(g, null);
580 +        assertEquals(r.value, 2);
581 +    }
582 +
583 +    /**
584 +     * thenAccept result completes exceptionally after exceptional
585 +     * completion of source
586 +     */
587 +    public void testThenAccept2() {
588 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
589 +        IncAction r = new IncAction();
590 +        CompletableFuture<Void> g = f.thenAccept(r);
591 +        f.completeExceptionally(new CFException());
592 +        checkCompletedWithWrappedCFException(g);
593 +    }
594 +
595 +    /**
596 +     * thenAccept result completes exceptionally if action does
597 +     */
598 +    public void testThenAccept3() {
599 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
600 +        FailingConsumer r = new FailingConsumer();
601 +        CompletableFuture<Void> g = f.thenAccept(r);
602 +        f.complete(one);
603 +        checkCompletedWithWrappedCFException(g);
604 +        assertTrue(r.ran);
605 +    }
606 +
607 +    /**
608 +     * thenAccept result completes exceptionally if source cancelled
609 +     */
610 +    public void testThenAccept4() {
611 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
612 +        IncAction r = new IncAction();
613 +        CompletableFuture<Void> g = f.thenAccept(r);
614 +        assertTrue(f.cancel(true));
615 +        checkCompletedWithWrappedCancellationException(g);
616 +    }
617 +
618 +
619 +    /**
620 +     * thenCombine result completes normally after normal completion of sources
621 +     */
622 +    public void testThenCombine() {
623 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
624 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
625 +        CompletableFuture<Integer> g = f.thenCombine(f2, add);
626 +        f.complete(one);
627 +        checkIncomplete(g);
628 +        f2.complete(two);
629 +        checkCompletedNormally(g, three);
630 +
631 +        f = new CompletableFuture<Integer>();
632 +        f.complete(one);
633 +        f2 = new CompletableFuture<Integer>();
634 +        g = f.thenCombine(f2, add);
635 +        checkIncomplete(g);
636 +        f2.complete(two);
637 +        checkCompletedNormally(g, three);
638 +    }
639 +
640 +    /**
641 +     * thenCombine result completes exceptionally after exceptional
642 +     * completion of either source
643 +     */
644 +    public void testThenCombine2() {
645 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
646 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
647 +        CompletableFuture<Integer> g = f.thenCombine(f2, add);
648 +        f.completeExceptionally(new CFException());
649 +        f2.complete(two);
650 +        checkCompletedWithWrappedCFException(g);
651 +
652 +        f = new CompletableFuture<Integer>();
653 +        f.complete(one);
654 +        f2 = new CompletableFuture<Integer>();
655 +        g = f.thenCombine(f2, add);
656 +        f2.completeExceptionally(new CFException());
657 +        checkCompletedWithWrappedCFException(g);
658 +    }
659 +
660 +    /**
661 +     * thenCombine result completes exceptionally if action does
662 +     */
663 +    public void testThenCombine3() {
664 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
665 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
666 +        FailingBiFunction r = new FailingBiFunction();
667 +        CompletableFuture<Integer> g = f.thenCombine(f2, r);
668 +        f.complete(one);
669 +        checkIncomplete(g);
670 +        f2.complete(two);
671 +        checkCompletedWithWrappedCFException(g);
672 +    }
673 +
674 +    /**
675 +     * thenCombine result completes exceptionally if either source cancelled
676 +     */
677 +    public void testThenCombine4() {
678 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
679 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
680 +        CompletableFuture<Integer> g = f.thenCombine(f2, add);
681 +        assertTrue(f.cancel(true));
682 +        f2.complete(two);
683 +        checkCompletedWithWrappedCancellationException(g);
684 +        f = new CompletableFuture<Integer>();
685 +        f2 = new CompletableFuture<Integer>();
686 +        g = f.thenCombine(f2, add);
687 +        f.complete(one);
688 +        assertTrue(f2.cancel(true));
689 +        checkCompletedWithWrappedCancellationException(g);
690 +    }
691 +
692 +    /**
693 +     * thenAcceptBoth result completes normally after normal
694 +     * completion of sources
695 +     */
696 +    public void testThenAcceptBoth() {
697 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
698 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
699 +        AddAction r = new AddAction();
700 +        CompletableFuture<Void> g = f.thenAcceptBoth(f2, r);
701 +        f.complete(one);
702 +        checkIncomplete(g);
703 +        f2.complete(two);
704 +        checkCompletedNormally(g, null);
705 +        assertEquals(r.value, 3);
706 +
707 +        r = new AddAction();
708 +        f = new CompletableFuture<Integer>();
709 +        f.complete(one);
710 +        f2 = new CompletableFuture<Integer>();
711 +        g = f.thenAcceptBoth(f2, r);
712 +        checkIncomplete(g);
713 +        f2.complete(two);
714 +        checkCompletedNormally(g, null);
715 +        assertEquals(r.value, 3);
716 +    }
717 +
718 +    /**
719 +     * thenAcceptBoth result completes exceptionally after exceptional
720 +     * completion of either source
721 +     */
722 +    public void testThenAcceptBoth2() {
723 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
724 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
725 +        AddAction r = new AddAction();
726 +        CompletableFuture<Void> g = f.thenAcceptBoth(f2, r);
727 +        f.completeExceptionally(new CFException());
728 +        f2.complete(two);
729 +        checkCompletedWithWrappedCFException(g);
730 +
731 +        r = new AddAction();
732 +        f = new CompletableFuture<Integer>();
733 +        f.complete(one);
734 +        f2 = new CompletableFuture<Integer>();
735 +        g = f.thenAcceptBoth(f2, r);
736 +        f2.completeExceptionally(new CFException());
737 +        checkCompletedWithWrappedCFException(g);
738 +    }
739 +
740 +    /**
741 +     * thenAcceptBoth result completes exceptionally if action does
742 +     */
743 +    public void testThenAcceptBoth3() {
744 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
745 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
746 +        FailingBiConsumer r = new FailingBiConsumer();
747 +        CompletableFuture<Void> g = f.thenAcceptBoth(f2, r);
748 +        f.complete(one);
749 +        checkIncomplete(g);
750 +        f2.complete(two);
751 +        checkCompletedWithWrappedCFException(g);
752 +    }
753 +
754 +    /**
755 +     * thenAcceptBoth result completes exceptionally if either source cancelled
756 +     */
757 +    public void testThenAcceptBoth4() {
758 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
759 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
760 +        AddAction r = new AddAction();
761 +        CompletableFuture<Void> g = f.thenAcceptBoth(f2, r);
762 +        assertTrue(f.cancel(true));
763 +        f2.complete(two);
764 +        checkCompletedWithWrappedCancellationException(g);
765 +        f = new CompletableFuture<Integer>();
766 +        f2 = new CompletableFuture<Integer>();
767 +        r = new AddAction();
768 +        g = f.thenAcceptBoth(f2, r);
769 +        f.complete(one);
770 +        assertTrue(f2.cancel(true));
771 +        checkCompletedWithWrappedCancellationException(g);
772 +    }
773 +
774 +    /**
775 +     * runAfterBoth result completes normally after normal
776 +     * completion of sources
777 +     */
778 +    public void testRunAfterBoth() {
779 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
780 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
781 +        Noop r = new Noop();
782 +        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
783 +        f.complete(one);
784 +        checkIncomplete(g);
785 +        f2.complete(two);
786 +        checkCompletedNormally(g, null);
787 +        assertTrue(r.ran);
788 +
789 +        r = new Noop();
790 +        f = new CompletableFuture<Integer>();
791 +        f.complete(one);
792 +        f2 = new CompletableFuture<Integer>();
793 +        g = f.runAfterBoth(f2, r);
794 +        checkIncomplete(g);
795 +        f2.complete(two);
796 +        checkCompletedNormally(g, null);
797 +        assertTrue(r.ran);
798 +    }
799 +
800 +    /**
801 +     * runAfterBoth result completes exceptionally after exceptional
802 +     * completion of either source
803 +     */
804 +    public void testRunAfterBoth2() {
805 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
806 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
807 +        Noop r = new Noop();
808 +        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
809 +        f.completeExceptionally(new CFException());
810 +        f2.complete(two);
811 +        checkCompletedWithWrappedCFException(g);
812 +
813 +        r = new Noop();
814 +        f = new CompletableFuture<Integer>();
815 +        f.complete(one);
816 +        f2 = new CompletableFuture<Integer>();
817 +        g = f.runAfterBoth(f2, r);
818 +        f2.completeExceptionally(new CFException());
819 +        checkCompletedWithWrappedCFException(g);
820 +    }
821 +
822 +    /**
823 +     * runAfterBoth result completes exceptionally if action does
824 +     */
825 +    public void testRunAfterBoth3() {
826 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
827 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
828 +        FailingNoop r = new FailingNoop();
829 +        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
830 +        f.complete(one);
831 +        checkIncomplete(g);
832 +        f2.complete(two);
833 +        checkCompletedWithWrappedCFException(g);
834 +    }
835 +
836 +    /**
837 +     * runAfterBoth result completes exceptionally if either source cancelled
838 +     */
839 +    public void testRunAfterBoth4() {
840 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
841 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
842 +        Noop r = new Noop();
843 +        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
844 +        assertTrue(f.cancel(true));
845 +        f2.complete(two);
846 +        checkCompletedWithWrappedCancellationException(g);
847 +        f = new CompletableFuture<Integer>();
848 +        f2 = new CompletableFuture<Integer>();
849 +        r = new Noop();
850 +        g = f.runAfterBoth(f2, r);
851 +        f.complete(one);
852 +        assertTrue(f2.cancel(true));
853 +        checkCompletedWithWrappedCancellationException(g);
854 +    }
855 +
856 +    /**
857 +     * applyToEither result completes normally after normal completion
858 +     * of either source
859 +     */
860 +    public void testApplyToEither() {
861 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
862 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
863 +        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
864 +        f.complete(one);
865 +        checkCompletedNormally(g, two);
866 +        f2.complete(one);
867 +        checkCompletedNormally(g, two);
868 +
869 +        f = new CompletableFuture<Integer>();
870 +        f.complete(one);
871 +        f2 = new CompletableFuture<Integer>();
872 +        g = f.applyToEither(f2, inc);
873 +        checkCompletedNormally(g, two);
874 +    }
875 +
876 +    /**
877 +     * applyToEither result completes exceptionally after exceptional
878 +     * completion of either source
879 +     */
880 +    public void testApplyToEither2() {
881 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
882 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
883 +        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
884 +        f.completeExceptionally(new CFException());
885 +        f2.complete(one);
886 +        checkCompletedWithWrappedCFException(g);
887 +
888 +        f = new CompletableFuture<Integer>();
889 +        f2 = new CompletableFuture<Integer>();
890 +        f2.completeExceptionally(new CFException());
891 +        g = f.applyToEither(f2, inc);
892 +        checkCompletedWithWrappedCFException(g);
893 +    }
894 +
895 +    /**
896 +     * applyToEither result completes exceptionally if action does
897 +     */
898 +    public void testApplyToEither3() {
899 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
900 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
901 +        FailingFunction r = new FailingFunction();
902 +        CompletableFuture<Integer> g = f.applyToEither(f2, r);
903 +        f2.complete(two);
904 +        checkCompletedWithWrappedCFException(g);
905 +    }
906 +
907 +    /**
908 +     * applyToEither result completes exceptionally if either source cancelled
909 +     */
910 +    public void testApplyToEither4() {
911 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
912 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
913 +        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
914 +        assertTrue(f.cancel(true));
915 +        checkCompletedWithWrappedCancellationException(g);
916 +        f = new CompletableFuture<Integer>();
917 +        f2 = new CompletableFuture<Integer>();
918 +        assertTrue(f2.cancel(true));
919 +        checkCompletedWithWrappedCancellationException(g);
920 +    }
921 +
922 +    /**
923 +     * acceptEither result completes normally after normal completion
924 +     * of either source
925 +     */
926 +    public void testAcceptEither() {
927 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
928 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
929 +        IncAction r = new IncAction();
930 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
931 +        f.complete(one);
932 +        checkCompletedNormally(g, null);
933 +        f2.complete(one);
934 +        checkCompletedNormally(g, null);
935 +        assertEquals(r.value, 2);
936 +
937 +        r = new IncAction();
938 +        f = new CompletableFuture<Integer>();
939 +        f.complete(one);
940 +        f2 = new CompletableFuture<Integer>();
941 +        g = f.acceptEither(f2, r);
942 +        checkCompletedNormally(g, null);
943 +        assertEquals(r.value, 2);
944 +    }
945 +
946 +    /**
947 +     * acceptEither result completes exceptionally after exceptional
948 +     * completion of either source
949 +     */
950 +    public void testAcceptEither2() {
951 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
952 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
953 +        IncAction r = new IncAction();
954 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
955 +        f.completeExceptionally(new CFException());
956 +        f2.complete(one);
957 +        checkCompletedWithWrappedCFException(g);
958 +
959 +        r = new IncAction();
960 +        f = new CompletableFuture<Integer>();
961 +        f2 = new CompletableFuture<Integer>();
962 +        f2.completeExceptionally(new CFException());
963 +        g = f.acceptEither(f2, r);
964 +        checkCompletedWithWrappedCFException(g);
965 +    }
966 +
967 +    /**
968 +     * acceptEither result completes exceptionally if action does
969 +     */
970 +    public void testAcceptEither3() {
971 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
972 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
973 +        FailingConsumer r = new FailingConsumer();
974 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
975 +        f2.complete(two);
976 +        checkCompletedWithWrappedCFException(g);
977 +    }
978 +
979 +    /**
980 +     * acceptEither result completes exceptionally if either source cancelled
981 +     */
982 +    public void testAcceptEither4() {
983 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
984 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
985 +        IncAction r = new IncAction();
986 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
987 +        assertTrue(f.cancel(true));
988 +        checkCompletedWithWrappedCancellationException(g);
989 +        f = new CompletableFuture<Integer>();
990 +        f2 = new CompletableFuture<Integer>();
991 +        assertTrue(f2.cancel(true));
992 +        checkCompletedWithWrappedCancellationException(g);
993 +    }
994 +
995 +
996 +    /**
997 +     * runAfterEither result completes normally after normal completion
998 +     * of either source
999 +     */
1000 +    public void testRunAfterEither() {
1001 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1002 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1003 +        Noop r = new Noop();
1004 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1005 +        f.complete(one);
1006 +        checkCompletedNormally(g, null);
1007 +        f2.complete(one);
1008 +        checkCompletedNormally(g, null);
1009 +        assertTrue(r.ran);
1010 +
1011 +        r = new Noop();
1012 +        f = new CompletableFuture<Integer>();
1013 +        f.complete(one);
1014 +        f2 = new CompletableFuture<Integer>();
1015 +        g = f.runAfterEither(f2, r);
1016 +        checkCompletedNormally(g, null);
1017 +        assertTrue(r.ran);
1018 +    }
1019 +
1020 +    /**
1021 +     * runAfterEither result completes exceptionally after exceptional
1022 +     * completion of either source
1023 +     */
1024 +    public void testRunAfterEither2() {
1025 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1026 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1027 +        Noop r = new Noop();
1028 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1029 +        f.completeExceptionally(new CFException());
1030 +        f2.complete(one);
1031 +        checkCompletedWithWrappedCFException(g);
1032 +
1033 +        r = new Noop();
1034 +        f = new CompletableFuture<Integer>();
1035 +        f2 = new CompletableFuture<Integer>();
1036 +        f2.completeExceptionally(new CFException());
1037 +        g = f.runAfterEither(f2, r);
1038 +        checkCompletedWithWrappedCFException(g);
1039 +    }
1040 +
1041 +    /**
1042 +     * runAfterEither result completes exceptionally if action does
1043 +     */
1044 +    public void testRunAfterEither3() {
1045 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1046 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1047 +        FailingNoop r = new FailingNoop();
1048 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1049 +        f2.complete(two);
1050 +        checkCompletedWithWrappedCFException(g);
1051 +    }
1052 +
1053 +    /**
1054 +     * runAfterEither result completes exceptionally if either source cancelled
1055 +     */
1056 +    public void testRunAfterEither4() {
1057 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1058 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1059 +        Noop r = new Noop();
1060 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1061 +        assertTrue(f.cancel(true));
1062 +        checkCompletedWithWrappedCancellationException(g);
1063 +        f = new CompletableFuture<Integer>();
1064 +        f2 = new CompletableFuture<Integer>();
1065 +        assertTrue(f2.cancel(true));
1066 +        checkCompletedWithWrappedCancellationException(g);
1067 +    }
1068 +
1069 +    /**
1070 +     * thenCompose result completes normally after normal completion of source
1071 +     */
1072 +    public void testThenCompose() {
1073 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1074 +        CompletableFutureInc r = new CompletableFutureInc();
1075 +        CompletableFuture<Integer> g = f.thenCompose(r);
1076 +        f.complete(one);
1077 +        checkCompletedNormally(g, two);
1078 +    }
1079 +
1080 +    /**
1081 +     * thenCompose result completes exceptionally after exceptional
1082 +     * completion of source
1083 +     */
1084 +    public void testThenCompose2() {
1085 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1086 +        CompletableFutureInc r = new CompletableFutureInc();
1087 +        CompletableFuture<Integer> g = f.thenCompose(r);
1088 +        f.completeExceptionally(new CFException());
1089 +        checkCompletedWithWrappedCFException(g);
1090 +    }
1091 +
1092 +    /**
1093 +     * thenCompose result completes exceptionally if action does
1094 +     */
1095 +    public void testThenCompose3() {
1096 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1097 +        FailingCompletableFutureFunction r = new FailingCompletableFutureFunction();
1098 +        CompletableFuture<Integer> g = f.thenCompose(r);
1099 +        f.complete(one);
1100 +        checkCompletedWithWrappedCFException(g);
1101 +    }
1102 +
1103 +    /**
1104 +     * thenCompose result completes exceptionally if source cancelled
1105 +     */
1106 +    public void testThenCompose4() {
1107 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1108 +        CompletableFutureInc r = new CompletableFutureInc();
1109 +        CompletableFuture<Integer> g = f.thenCompose(r);
1110 +        assertTrue(f.cancel(true));
1111 +        checkCompletedWithWrappedCancellationException(g);
1112 +    }
1113 +
1114 +
1115 +    // asyncs
1116 +
1117 +    /**
1118 +     * thenRunAsync result completes normally after normal completion of source
1119 +     */
1120 +    public void testThenRunAsync() {
1121 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1122 +        Noop r = new Noop();
1123 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1124 +        f.complete(null);
1125 +        checkCompletedNormally(g, null);
1126 +
1127 +        // reordered version
1128 +        f = new CompletableFuture<Integer>();
1129 +        f.complete(null);
1130 +        r = new Noop();
1131 +        g = f.thenRunAsync(r);
1132 +        checkCompletedNormally(g, null);
1133 +    }
1134 +
1135 +    /**
1136 +     * thenRunAsync result completes exceptionally after exceptional
1137 +     * completion of source
1138 +     */
1139 +    public void testThenRunAsync2() {
1140 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1141 +        Noop r = new Noop();
1142 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1143 +        f.completeExceptionally(new CFException());
1144 +        try {
1145 +            g.join();
1146 +            shouldThrow();
1147 +        } catch (Exception ok) {
1148 +        }
1149 +        checkCompletedWithWrappedCFException(g);
1150 +    }
1151 +
1152 +    /**
1153 +     * thenRunAsync result completes exceptionally if action does
1154 +     */
1155 +    public void testThenRunAsync3() {
1156 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1157 +        FailingNoop r = new FailingNoop();
1158 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1159 +        f.complete(null);
1160 +        checkCompletedWithWrappedCFException(g);
1161 +    }
1162 +
1163 +    /**
1164 +     * thenRunAsync result completes exceptionally if source cancelled
1165 +     */
1166 +    public void testThenRunAsync4() {
1167 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1168 +        Noop r = new Noop();
1169 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1170 +        assertTrue(f.cancel(true));
1171 +        checkCompletedWithWrappedCancellationException(g);
1172 +    }
1173 +
1174 +    /**
1175 +     * thenApplyAsync result completes normally after normal completion of source
1176 +     */
1177 +    public void testThenApplyAsync() {
1178 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1179 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1180 +        f.complete(one);
1181 +        checkCompletedNormally(g, two);
1182 +    }
1183 +
1184 +    /**
1185 +     * thenApplyAsync result completes exceptionally after exceptional
1186 +     * completion of source
1187 +     */
1188 +    public void testThenApplyAsync2() {
1189 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1190 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1191 +        f.completeExceptionally(new CFException());
1192 +        checkCompletedWithWrappedCFException(g);
1193 +    }
1194 +
1195 +    /**
1196 +     * thenApplyAsync result completes exceptionally if action does
1197 +     */
1198 +    public void testThenApplyAsync3() {
1199 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1200 +        FailingFunction r = new FailingFunction();
1201 +        CompletableFuture<Integer> g = f.thenApplyAsync(r);
1202 +        f.complete(null);
1203 +        checkCompletedWithWrappedCFException(g);
1204 +    }
1205 +
1206 +    /**
1207 +     * thenApplyAsync result completes exceptionally if source cancelled
1208 +     */
1209 +    public void testThenApplyAsync4() {
1210 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1211 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1212 +        assertTrue(f.cancel(true));
1213 +        checkCompletedWithWrappedCancellationException(g);
1214 +    }
1215 +
1216 +    /**
1217 +     * thenAcceptAsync result completes normally after normal
1218 +     * completion of source
1219 +     */
1220 +    public void testThenAcceptAsync() {
1221 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1222 +        IncAction r = new IncAction();
1223 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1224 +        f.complete(one);
1225 +        checkCompletedNormally(g, null);
1226 +        assertEquals(r.value, 2);
1227 +    }
1228 +
1229 +    /**
1230 +     * thenAcceptAsync result completes exceptionally after exceptional
1231 +     * completion of source
1232 +     */
1233 +    public void testThenAcceptAsync2() {
1234 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1235 +        IncAction r = new IncAction();
1236 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1237 +        f.completeExceptionally(new CFException());
1238 +        checkCompletedWithWrappedCFException(g);
1239 +    }
1240 +
1241 +    /**
1242 +     * thenAcceptAsync result completes exceptionally if action does
1243 +     */
1244 +    public void testThenAcceptAsync3() {
1245 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1246 +        FailingConsumer r = new FailingConsumer();
1247 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1248 +        f.complete(null);
1249 +        checkCompletedWithWrappedCFException(g);
1250 +    }
1251 +
1252 +    /**
1253 +     * thenAcceptAsync result completes exceptionally if source cancelled
1254 +     */
1255 +    public void testThenAcceptAsync4() {
1256 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1257 +        IncAction r = new IncAction();
1258 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1259 +        assertTrue(f.cancel(true));
1260 +        checkCompletedWithWrappedCancellationException(g);
1261 +    }
1262 +    /**
1263 +     * thenCombineAsync result completes normally after normal
1264 +     * completion of sources
1265 +     */
1266 +    public void testThenCombineAsync() {
1267 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1268 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1269 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add);
1270 +        f.complete(one);
1271 +        checkIncomplete(g);
1272 +        f2.complete(two);
1273 +        checkCompletedNormally(g, three);
1274 +    }
1275 +
1276 +    /**
1277 +     * thenCombineAsync result completes exceptionally after exceptional
1278 +     * completion of source
1279 +     */
1280 +    public void testThenCombineAsync2() {
1281 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1282 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1283 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add);
1284 +        f.completeExceptionally(new CFException());
1285 +        f2.complete(two);
1286 +        checkCompletedWithWrappedCFException(g);
1287 +
1288 +        f = new CompletableFuture<Integer>();
1289 +        f2 = new CompletableFuture<Integer>();
1290 +        g = f.thenCombineAsync(f2, add);
1291 +        f.complete(one);
1292 +        f2.completeExceptionally(new CFException());
1293 +        checkCompletedWithWrappedCFException(g);
1294 +    }
1295 +
1296 +    /**
1297 +     * thenCombineAsync result completes exceptionally if action does
1298 +     */
1299 +    public void testThenCombineAsync3() {
1300 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1301 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1302 +        FailingBiFunction r = new FailingBiFunction();
1303 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r);
1304 +        f.complete(one);
1305 +        checkIncomplete(g);
1306 +        f2.complete(two);
1307 +        checkCompletedWithWrappedCFException(g);
1308 +    }
1309 +
1310 +    /**
1311 +     * thenCombineAsync result completes exceptionally if either source cancelled
1312 +     */
1313 +    public void testThenCombineAsync4() {
1314 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1315 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1316 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add);
1317 +        assertTrue(f.cancel(true));
1318 +        f2.complete(two);
1319 +        checkCompletedWithWrappedCancellationException(g);
1320 +
1321 +        f = new CompletableFuture<Integer>();
1322 +        f2 = new CompletableFuture<Integer>();
1323 +        g = f.thenCombineAsync(f2, add);
1324 +        f.complete(one);
1325 +        assertTrue(f2.cancel(true));
1326 +        checkCompletedWithWrappedCancellationException(g);
1327 +    }
1328 +
1329 +    /**
1330 +     * thenAcceptBothAsync result completes normally after normal
1331 +     * completion of sources
1332 +     */
1333 +    public void testThenAcceptBothAsync() {
1334 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1335 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1336 +        AddAction r = new AddAction();
1337 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r);
1338 +        f.complete(one);
1339 +        checkIncomplete(g);
1340 +        f2.complete(two);
1341 +        checkCompletedNormally(g, null);
1342 +        assertEquals(r.value, 3);
1343 +    }
1344 +
1345 +    /**
1346 +     * thenAcceptBothAsync result completes exceptionally after exceptional
1347 +     * completion of source
1348 +     */
1349 +    public void testThenAcceptBothAsync2() {
1350 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1351 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1352 +        AddAction r = new AddAction();
1353 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r);
1354 +        f.completeExceptionally(new CFException());
1355 +        f2.complete(two);
1356 +        checkCompletedWithWrappedCFException(g);
1357 +
1358 +        r = new AddAction();
1359 +        f = new CompletableFuture<Integer>();
1360 +        f2 = new CompletableFuture<Integer>();
1361 +        g = f.thenAcceptBothAsync(f2, r);
1362 +        f.complete(one);
1363 +        f2.completeExceptionally(new CFException());
1364 +        checkCompletedWithWrappedCFException(g);
1365 +    }
1366 +
1367 +    /**
1368 +     * thenAcceptBothAsync result completes exceptionally if action does
1369 +     */
1370 +    public void testThenAcceptBothAsync3() {
1371 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1372 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1373 +        FailingBiConsumer r = new FailingBiConsumer();
1374 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r);
1375 +        f.complete(one);
1376 +        checkIncomplete(g);
1377 +        f2.complete(two);
1378 +        checkCompletedWithWrappedCFException(g);
1379 +    }
1380 +
1381 +    /**
1382 +     * thenAcceptBothAsync result completes exceptionally if either source cancelled
1383 +     */
1384 +    public void testThenAcceptBothAsync4() {
1385 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1386 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1387 +        AddAction r = new AddAction();
1388 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r);
1389 +        assertTrue(f.cancel(true));
1390 +        f2.complete(two);
1391 +        checkCompletedWithWrappedCancellationException(g);
1392 +
1393 +        r = new AddAction();
1394 +        f = new CompletableFuture<Integer>();
1395 +        f2 = new CompletableFuture<Integer>();
1396 +        g = f.thenAcceptBothAsync(f2, r);
1397 +        f.complete(one);
1398 +        assertTrue(f2.cancel(true));
1399 +        checkCompletedWithWrappedCancellationException(g);
1400 +    }
1401 +
1402 +    /**
1403 +     * runAfterBothAsync result completes normally after normal
1404 +     * completion of sources
1405 +     */
1406 +    public void testRunAfterBothAsync() {
1407 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1408 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1409 +        Noop r = new Noop();
1410 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1411 +        f.complete(one);
1412 +        checkIncomplete(g);
1413 +        f2.complete(two);
1414 +        checkCompletedNormally(g, null);
1415 +        assertTrue(r.ran);
1416 +    }
1417 +
1418 +    /**
1419 +     * runAfterBothAsync result completes exceptionally after exceptional
1420 +     * completion of source
1421 +     */
1422 +    public void testRunAfterBothAsync2() {
1423 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1424 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1425 +        Noop r = new Noop();
1426 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1427 +        f.completeExceptionally(new CFException());
1428 +        f2.complete(two);
1429 +        checkCompletedWithWrappedCFException(g);
1430 +
1431 +        r = new Noop();
1432 +        f = new CompletableFuture<Integer>();
1433 +        f2 = new CompletableFuture<Integer>();
1434 +        g = f.runAfterBothAsync(f2, r);
1435 +        f.complete(one);
1436 +        f2.completeExceptionally(new CFException());
1437 +        checkCompletedWithWrappedCFException(g);
1438 +    }
1439 +
1440 +    /**
1441 +     * runAfterBothAsync result completes exceptionally if action does
1442 +     */
1443 +    public void testRunAfterBothAsync3() {
1444 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1445 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1446 +        FailingNoop r = new FailingNoop();
1447 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1448 +        f.complete(one);
1449 +        checkIncomplete(g);
1450 +        f2.complete(two);
1451 +        checkCompletedWithWrappedCFException(g);
1452 +    }
1453 +
1454 +    /**
1455 +     * runAfterBothAsync result completes exceptionally if either source cancelled
1456 +     */
1457 +    public void testRunAfterBothAsync4() {
1458 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1459 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1460 +        Noop r = new Noop();
1461 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1462 +        assertTrue(f.cancel(true));
1463 +        f2.complete(two);
1464 +        checkCompletedWithWrappedCancellationException(g);
1465 +
1466 +        r = new Noop();
1467 +        f = new CompletableFuture<Integer>();
1468 +        f2 = new CompletableFuture<Integer>();
1469 +        g = f.runAfterBothAsync(f2, r);
1470 +        f.complete(one);
1471 +        assertTrue(f2.cancel(true));
1472 +        checkCompletedWithWrappedCancellationException(g);
1473 +    }
1474 +
1475 +    /**
1476 +     * applyToEitherAsync result completes normally after normal
1477 +     * completion of sources
1478 +     */
1479 +    public void testApplyToEitherAsync() {
1480 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1481 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1482 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1483 +        f.complete(one);
1484 +        checkCompletedNormally(g, two);
1485 +
1486 +        f = new CompletableFuture<Integer>();
1487 +        f.complete(one);
1488 +        f2 = new CompletableFuture<Integer>();
1489 +        g = f.applyToEitherAsync(f2, inc);
1490 +        checkCompletedNormally(g, two);
1491 +    }
1492 +
1493 +    /**
1494 +     * applyToEitherAsync result completes exceptionally after exceptional
1495 +     * completion of source
1496 +     */
1497 +    public void testApplyToEitherAsync2() {
1498 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1499 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1500 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1501 +        f.completeExceptionally(new CFException());
1502 +        checkCompletedWithWrappedCFException(g);
1503 +
1504 +        f = new CompletableFuture<Integer>();
1505 +        f2 = new CompletableFuture<Integer>();
1506 +        f2.completeExceptionally(new CFException());
1507 +        g = f.applyToEitherAsync(f2, inc);
1508 +        f.complete(one);
1509 +        checkCompletedWithWrappedCFException(g);
1510 +    }
1511 +
1512 +    /**
1513 +     * applyToEitherAsync result completes exceptionally if action does
1514 +     */
1515 +    public void testApplyToEitherAsync3() {
1516 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1517 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1518 +        FailingFunction r = new FailingFunction();
1519 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r);
1520 +        f.complete(one);
1521 +        checkCompletedWithWrappedCFException(g);
1522 +    }
1523 +
1524 +    /**
1525 +     * applyToEitherAsync result completes exceptionally if either source cancelled
1526 +     */
1527 +    public void testApplyToEitherAsync4() {
1528 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1529 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1530 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1531 +        assertTrue(f.cancel(true));
1532 +        checkCompletedWithWrappedCancellationException(g);
1533 +
1534 +        f = new CompletableFuture<Integer>();
1535 +        f2 = new CompletableFuture<Integer>();
1536 +        assertTrue(f2.cancel(true));
1537 +        g = f.applyToEitherAsync(f2, inc);
1538 +        checkCompletedWithWrappedCancellationException(g);
1539 +    }
1540 +
1541 +    /**
1542 +     * acceptEitherAsync result completes normally after normal
1543 +     * completion of sources
1544 +     */
1545 +    public void testAcceptEitherAsync() {
1546 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1547 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1548 +        IncAction r = new IncAction();
1549 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1550 +        f.complete(one);
1551 +        checkCompletedNormally(g, null);
1552 +        assertEquals(r.value, 2);
1553 +
1554 +        r = new IncAction();
1555 +        f = new CompletableFuture<Integer>();
1556 +        f.complete(one);
1557 +        f2 = new CompletableFuture<Integer>();
1558 +        g = f.acceptEitherAsync(f2, r);
1559 +        checkCompletedNormally(g, null);
1560 +        assertEquals(r.value, 2);
1561 +    }
1562 +
1563 +    /**
1564 +     * acceptEitherAsync result completes exceptionally after exceptional
1565 +     * completion of source
1566 +     */
1567 +    public void testAcceptEitherAsync2() {
1568 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1569 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1570 +        IncAction r = new IncAction();
1571 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1572 +        f.completeExceptionally(new CFException());
1573 +        checkCompletedWithWrappedCFException(g);
1574 +
1575 +        r = new IncAction();
1576 +        f = new CompletableFuture<Integer>();
1577 +        f2 = new CompletableFuture<Integer>();
1578 +        f2.completeExceptionally(new CFException());
1579 +        g = f.acceptEitherAsync(f2, r);
1580 +        f.complete(one);
1581 +        checkCompletedWithWrappedCFException(g);
1582 +    }
1583 +
1584 +    /**
1585 +     * acceptEitherAsync result completes exceptionally if action does
1586 +     */
1587 +    public void testAcceptEitherAsync3() {
1588 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1589 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1590 +        FailingConsumer r = new FailingConsumer();
1591 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1592 +        f.complete(one);
1593 +        checkCompletedWithWrappedCFException(g);
1594 +    }
1595 +
1596 +    /**
1597 +     * acceptEitherAsync result completes exceptionally if either
1598 +     * source cancelled
1599 +     */
1600 +    public void testAcceptEitherAsync4() {
1601 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1602 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1603 +        IncAction r = new IncAction();
1604 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1605 +        assertTrue(f.cancel(true));
1606 +        checkCompletedWithWrappedCancellationException(g);
1607 +
1608 +        r = new IncAction();
1609 +        f = new CompletableFuture<Integer>();
1610 +        f2 = new CompletableFuture<Integer>();
1611 +        assertTrue(f2.cancel(true));
1612 +        g = f.acceptEitherAsync(f2, r);
1613 +        checkCompletedWithWrappedCancellationException(g);
1614 +    }
1615 +
1616 +    /**
1617 +     * runAfterEitherAsync result completes normally after normal
1618 +     * completion of sources
1619 +     */
1620 +    public void testRunAfterEitherAsync() {
1621 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1622 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1623 +        Noop r = new Noop();
1624 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1625 +        f.complete(one);
1626 +        checkCompletedNormally(g, null);
1627 +        assertTrue(r.ran);
1628 +
1629 +        r = new Noop();
1630 +        f = new CompletableFuture<Integer>();
1631 +        f.complete(one);
1632 +        f2 = new CompletableFuture<Integer>();
1633 +        g = f.runAfterEitherAsync(f2, r);
1634 +        checkCompletedNormally(g, null);
1635 +        assertTrue(r.ran);
1636 +    }
1637 +
1638 +    /**
1639 +     * runAfterEitherAsync result completes exceptionally after exceptional
1640 +     * completion of source
1641 +     */
1642 +    public void testRunAfterEitherAsync2() {
1643 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1644 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1645 +        Noop r = new Noop();
1646 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1647 +        f.completeExceptionally(new CFException());
1648 +        checkCompletedWithWrappedCFException(g);
1649 +
1650 +        r = new Noop();
1651 +        f = new CompletableFuture<Integer>();
1652 +        f2 = new CompletableFuture<Integer>();
1653 +        f2.completeExceptionally(new CFException());
1654 +        g = f.runAfterEitherAsync(f2, r);
1655 +        f.complete(one);
1656 +        checkCompletedWithWrappedCFException(g);
1657 +    }
1658 +
1659 +    /**
1660 +     * runAfterEitherAsync result completes exceptionally if action does
1661 +     */
1662 +    public void testRunAfterEitherAsync3() {
1663 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1664 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1665 +        FailingNoop r = new FailingNoop();
1666 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1667 +        f.complete(one);
1668 +        checkCompletedWithWrappedCFException(g);
1669 +    }
1670 +
1671 +    /**
1672 +     * runAfterEitherAsync result completes exceptionally if either
1673 +     * source cancelled
1674 +     */
1675 +    public void testRunAfterEitherAsync4() {
1676 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1677 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1678 +        Noop r = new Noop();
1679 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1680 +        assertTrue(f.cancel(true));
1681 +        checkCompletedWithWrappedCancellationException(g);
1682 +
1683 +        r = new Noop();
1684 +        f = new CompletableFuture<Integer>();
1685 +        f2 = new CompletableFuture<Integer>();
1686 +        assertTrue(f2.cancel(true));
1687 +        g = f.runAfterEitherAsync(f2, r);
1688 +        checkCompletedWithWrappedCancellationException(g);
1689 +    }
1690 +
1691 +    /**
1692 +     * thenComposeAsync result completes normally after normal
1693 +     * completion of source
1694 +     */
1695 +    public void testThenComposeAsync() {
1696 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1697 +        CompletableFutureInc r = new CompletableFutureInc();
1698 +        CompletableFuture<Integer> g = f.thenComposeAsync(r);
1699 +        f.complete(one);
1700 +        checkCompletedNormally(g, two);
1701 +    }
1702 +
1703 +    /**
1704 +     * thenComposeAsync result completes exceptionally after
1705 +     * exceptional completion of source
1706 +     */
1707 +    public void testThenComposeAsync2() {
1708 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1709 +        CompletableFutureInc r = new CompletableFutureInc();
1710 +        CompletableFuture<Integer> g = f.thenComposeAsync(r);
1711 +        f.completeExceptionally(new CFException());
1712 +        checkCompletedWithWrappedCFException(g);
1713 +    }
1714 +
1715 +    /**
1716 +     * thenComposeAsync result completes exceptionally if action does
1717 +     */
1718 +    public void testThenComposeAsync3() {
1719 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1720 +        FailingCompletableFutureFunction r = new FailingCompletableFutureFunction();
1721 +        CompletableFuture<Integer> g = f.thenComposeAsync(r);
1722 +        f.complete(one);
1723 +        checkCompletedWithWrappedCFException(g);
1724 +    }
1725 +
1726 +    /**
1727 +     * thenComposeAsync result completes exceptionally if source cancelled
1728 +     */
1729 +    public void testThenComposeAsync4() {
1730 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1731 +        CompletableFutureInc r = new CompletableFutureInc();
1732 +        CompletableFuture<Integer> g = f.thenComposeAsync(r);
1733 +        assertTrue(f.cancel(true));
1734 +        checkCompletedWithWrappedCancellationException(g);
1735 +    }
1736 +
1737 +
1738 +    // async with explicit executors
1739 +
1740 +    /**
1741 +     * thenRunAsync result completes normally after normal completion of source
1742 +     */
1743 +    public void testThenRunAsyncE() {
1744 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1745 +        Noop r = new Noop();
1746 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
1747 +        f.complete(null);
1748 +        checkCompletedNormally(g, null);
1749 +
1750 +        // reordered version
1751 +        f = new CompletableFuture<Integer>();
1752 +        f.complete(null);
1753 +        r = new Noop();
1754 +        g = f.thenRunAsync(r, new ThreadExecutor());
1755 +        checkCompletedNormally(g, null);
1756 +    }
1757 +
1758 +    /**
1759 +     * thenRunAsync result completes exceptionally after exceptional
1760 +     * completion of source
1761 +     */
1762 +    public void testThenRunAsync2E() {
1763 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1764 +        Noop r = new Noop();
1765 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
1766 +        f.completeExceptionally(new CFException());
1767 +        try {
1768 +            g.join();
1769 +            shouldThrow();
1770 +        } catch (Exception ok) {
1771 +        }
1772 +        checkCompletedWithWrappedCFException(g);
1773 +    }
1774 +
1775 +    /**
1776 +     * thenRunAsync result completes exceptionally if action does
1777 +     */
1778 +    public void testThenRunAsync3E() {
1779 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1780 +        FailingNoop r = new FailingNoop();
1781 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
1782 +        f.complete(null);
1783 +        checkCompletedWithWrappedCFException(g);
1784 +    }
1785 +
1786 +    /**
1787 +     * thenRunAsync result completes exceptionally if source cancelled
1788 +     */
1789 +    public void testThenRunAsync4E() {
1790 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1791 +        Noop r = new Noop();
1792 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
1793 +        assertTrue(f.cancel(true));
1794 +        checkCompletedWithWrappedCancellationException(g);
1795 +    }
1796 +
1797 +    /**
1798 +     * thenApplyAsync result completes normally after normal completion of source
1799 +     */
1800 +    public void testThenApplyAsyncE() {
1801 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1802 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
1803 +        f.complete(one);
1804 +        checkCompletedNormally(g, two);
1805 +    }
1806 +
1807 +    /**
1808 +     * thenApplyAsync result completes exceptionally after exceptional
1809 +     * completion of source
1810 +     */
1811 +    public void testThenApplyAsync2E() {
1812 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1813 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
1814 +        f.completeExceptionally(new CFException());
1815 +        checkCompletedWithWrappedCFException(g);
1816 +    }
1817 +
1818 +    /**
1819 +     * thenApplyAsync result completes exceptionally if action does
1820 +     */
1821 +    public void testThenApplyAsync3E() {
1822 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1823 +        FailingFunction r = new FailingFunction();
1824 +        CompletableFuture<Integer> g = f.thenApplyAsync(r, new ThreadExecutor());
1825 +        f.complete(null);
1826 +        checkCompletedWithWrappedCFException(g);
1827 +    }
1828 +
1829 +    /**
1830 +     * thenApplyAsync result completes exceptionally if source cancelled
1831 +     */
1832 +    public void testThenApplyAsync4E() {
1833 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1834 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
1835 +        assertTrue(f.cancel(true));
1836 +        checkCompletedWithWrappedCancellationException(g);
1837 +    }
1838 +
1839 +    /**
1840 +     * thenAcceptAsync result completes normally after normal
1841 +     * completion of source
1842 +     */
1843 +    public void testThenAcceptAsyncE() {
1844 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1845 +        IncAction r = new IncAction();
1846 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
1847 +        f.complete(one);
1848 +        checkCompletedNormally(g, null);
1849 +        assertEquals(r.value, 2);
1850 +    }
1851 +
1852 +    /**
1853 +     * thenAcceptAsync result completes exceptionally after exceptional
1854 +     * completion of source
1855 +     */
1856 +    public void testThenAcceptAsync2E() {
1857 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1858 +        IncAction r = new IncAction();
1859 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
1860 +        f.completeExceptionally(new CFException());
1861 +        checkCompletedWithWrappedCFException(g);
1862 +    }
1863 +
1864 +    /**
1865 +     * thenAcceptAsync result completes exceptionally if action does
1866 +     */
1867 +    public void testThenAcceptAsync3E() {
1868 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1869 +        FailingConsumer r = new FailingConsumer();
1870 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
1871 +        f.complete(null);
1872 +        checkCompletedWithWrappedCFException(g);
1873 +    }
1874 +
1875 +    /**
1876 +     * thenAcceptAsync result completes exceptionally if source cancelled
1877 +     */
1878 +    public void testThenAcceptAsync4E() {
1879 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1880 +        IncAction r = new IncAction();
1881 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
1882 +        assertTrue(f.cancel(true));
1883 +        checkCompletedWithWrappedCancellationException(g);
1884 +    }
1885 +    /**
1886 +     * thenCombineAsync result completes normally after normal
1887 +     * completion of sources
1888 +     */
1889 +    public void testThenCombineAsyncE() {
1890 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1891 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1892 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add, new ThreadExecutor());
1893 +        f.complete(one);
1894 +        checkIncomplete(g);
1895 +        f2.complete(two);
1896 +        checkCompletedNormally(g, three);
1897 +    }
1898 +
1899 +    /**
1900 +     * thenCombineAsync result completes exceptionally after exceptional
1901 +     * completion of source
1902 +     */
1903 +    public void testThenCombineAsync2E() {
1904 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1905 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1906 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add, new ThreadExecutor());
1907 +        f.completeExceptionally(new CFException());
1908 +        f2.complete(two);
1909 +        checkCompletedWithWrappedCFException(g);
1910 +
1911 +        f = new CompletableFuture<Integer>();
1912 +        f2 = new CompletableFuture<Integer>();
1913 +        g = f.thenCombineAsync(f2, add, new ThreadExecutor());
1914 +        f.complete(one);
1915 +        f2.completeExceptionally(new CFException());
1916 +        checkCompletedWithWrappedCFException(g);
1917 +    }
1918 +
1919 +    /**
1920 +     * thenCombineAsync result completes exceptionally if action does
1921 +     */
1922 +    public void testThenCombineAsync3E() {
1923 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1924 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1925 +        FailingBiFunction r = new FailingBiFunction();
1926 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r, new ThreadExecutor());
1927 +        f.complete(one);
1928 +        checkIncomplete(g);
1929 +        f2.complete(two);
1930 +        checkCompletedWithWrappedCFException(g);
1931 +    }
1932 +
1933 +    /**
1934 +     * thenCombineAsync result completes exceptionally if either source cancelled
1935 +     */
1936 +    public void testThenCombineAsync4E() {
1937 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1938 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1939 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, add, new ThreadExecutor());
1940 +        assertTrue(f.cancel(true));
1941 +        f2.complete(two);
1942 +        checkCompletedWithWrappedCancellationException(g);
1943 +
1944 +        f = new CompletableFuture<Integer>();
1945 +        f2 = new CompletableFuture<Integer>();
1946 +        g = f.thenCombineAsync(f2, add, new ThreadExecutor());
1947 +        f.complete(one);
1948 +        assertTrue(f2.cancel(true));
1949 +        checkCompletedWithWrappedCancellationException(g);
1950 +    }
1951 +
1952 +    /**
1953 +     * thenAcceptBothAsync result completes normally after normal
1954 +     * completion of sources
1955 +     */
1956 +    public void testThenAcceptBothAsyncE() {
1957 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1958 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1959 +        AddAction r = new AddAction();
1960 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
1961 +        f.complete(one);
1962 +        checkIncomplete(g);
1963 +        f2.complete(two);
1964 +        checkCompletedNormally(g, null);
1965 +        assertEquals(r.value, 3);
1966 +    }
1967 +
1968 +    /**
1969 +     * thenAcceptBothAsync result completes exceptionally after exceptional
1970 +     * completion of source
1971 +     */
1972 +    public void testThenAcceptBothAsync2E() {
1973 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1974 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1975 +        AddAction r = new AddAction();
1976 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
1977 +        f.completeExceptionally(new CFException());
1978 +        f2.complete(two);
1979 +        checkCompletedWithWrappedCFException(g);
1980 +
1981 +        r = new AddAction();
1982 +        f = new CompletableFuture<Integer>();
1983 +        f2 = new CompletableFuture<Integer>();
1984 +        g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
1985 +        f.complete(one);
1986 +        f2.completeExceptionally(new CFException());
1987 +        checkCompletedWithWrappedCFException(g);
1988 +    }
1989 +
1990 +    /**
1991 +     * thenAcceptBothAsync result completes exceptionally if action does
1992 +     */
1993 +    public void testThenAcceptBothAsync3E() {
1994 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1995 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1996 +        FailingBiConsumer r = new FailingBiConsumer();
1997 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
1998 +        f.complete(one);
1999 +        checkIncomplete(g);
2000 +        f2.complete(two);
2001 +        checkCompletedWithWrappedCFException(g);
2002 +    }
2003 +
2004 +    /**
2005 +     * thenAcceptBothAsync result completes exceptionally if either source cancelled
2006 +     */
2007 +    public void testThenAcceptBothAsync4E() {
2008 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2009 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2010 +        AddAction r = new AddAction();
2011 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
2012 +        assertTrue(f.cancel(true));
2013 +        f2.complete(two);
2014 +        checkCompletedWithWrappedCancellationException(g);
2015 +
2016 +        r = new AddAction();
2017 +        f = new CompletableFuture<Integer>();
2018 +        f2 = new CompletableFuture<Integer>();
2019 +        g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
2020 +        f.complete(one);
2021 +        assertTrue(f2.cancel(true));
2022 +        checkCompletedWithWrappedCancellationException(g);
2023 +    }
2024 +
2025 +    /**
2026 +     * runAfterBothAsync result completes normally after normal
2027 +     * completion of sources
2028 +     */
2029 +    public void testRunAfterBothAsyncE() {
2030 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2031 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2032 +        Noop r = new Noop();
2033 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2034 +        f.complete(one);
2035 +        checkIncomplete(g);
2036 +        f2.complete(two);
2037 +        checkCompletedNormally(g, null);
2038 +        assertTrue(r.ran);
2039 +    }
2040 +
2041 +    /**
2042 +     * runAfterBothAsync result completes exceptionally after exceptional
2043 +     * completion of source
2044 +     */
2045 +    public void testRunAfterBothAsync2E() {
2046 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2047 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2048 +        Noop r = new Noop();
2049 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2050 +        f.completeExceptionally(new CFException());
2051 +        f2.complete(two);
2052 +        checkCompletedWithWrappedCFException(g);
2053 +
2054 +        r = new Noop();
2055 +        f = new CompletableFuture<Integer>();
2056 +        f2 = new CompletableFuture<Integer>();
2057 +        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2058 +        f.complete(one);
2059 +        f2.completeExceptionally(new CFException());
2060 +        checkCompletedWithWrappedCFException(g);
2061 +    }
2062 +
2063 +    /**
2064 +     * runAfterBothAsync result completes exceptionally if action does
2065 +     */
2066 +    public void testRunAfterBothAsync3E() {
2067 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2068 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2069 +        FailingNoop r = new FailingNoop();
2070 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2071 +        f.complete(one);
2072 +        checkIncomplete(g);
2073 +        f2.complete(two);
2074 +        checkCompletedWithWrappedCFException(g);
2075 +    }
2076 +
2077 +    /**
2078 +     * runAfterBothAsync result completes exceptionally if either source cancelled
2079 +     */
2080 +    public void testRunAfterBothAsync4E() {
2081 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2082 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2083 +        Noop r = new Noop();
2084 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2085 +        assertTrue(f.cancel(true));
2086 +        f2.complete(two);
2087 +        checkCompletedWithWrappedCancellationException(g);
2088 +
2089 +        r = new Noop();
2090 +        f = new CompletableFuture<Integer>();
2091 +        f2 = new CompletableFuture<Integer>();
2092 +        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2093 +        f.complete(one);
2094 +        assertTrue(f2.cancel(true));
2095 +        checkCompletedWithWrappedCancellationException(g);
2096 +    }
2097 +
2098 +    /**
2099 +     * applyToEitherAsync result completes normally after normal
2100 +     * completion of sources
2101 +     */
2102 +    public void testApplyToEitherAsyncE() {
2103 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2104 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2105 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2106 +        f.complete(one);
2107 +        checkCompletedNormally(g, two);
2108 +
2109 +        f = new CompletableFuture<Integer>();
2110 +        f.complete(one);
2111 +        f2 = new CompletableFuture<Integer>();
2112 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2113 +        checkCompletedNormally(g, two);
2114 +    }
2115 +
2116 +    /**
2117 +     * applyToEitherAsync result completes exceptionally after exceptional
2118 +     * completion of source
2119 +     */
2120 +    public void testApplyToEitherAsync2E() {
2121 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2122 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2123 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2124 +        f.completeExceptionally(new CFException());
2125 +        checkCompletedWithWrappedCFException(g);
2126 +
2127 +        f = new CompletableFuture<Integer>();
2128 +        f2 = new CompletableFuture<Integer>();
2129 +        f2.completeExceptionally(new CFException());
2130 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2131 +        f.complete(one);
2132 +        checkCompletedWithWrappedCFException(g);
2133 +    }
2134 +
2135 +    /**
2136 +     * applyToEitherAsync result completes exceptionally if action does
2137 +     */
2138 +    public void testApplyToEitherAsync3E() {
2139 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2140 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2141 +        FailingFunction r = new FailingFunction();
2142 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r, new ThreadExecutor());
2143 +        f.complete(one);
2144 +        checkCompletedWithWrappedCFException(g);
2145 +    }
2146 +
2147 +    /**
2148 +     * applyToEitherAsync result completes exceptionally if either source cancelled
2149 +     */
2150 +    public void testApplyToEitherAsync4E() {
2151 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2152 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2153 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2154 +        assertTrue(f.cancel(true));
2155 +        checkCompletedWithWrappedCancellationException(g);
2156 +
2157 +        f = new CompletableFuture<Integer>();
2158 +        f2 = new CompletableFuture<Integer>();
2159 +        assertTrue(f2.cancel(true));
2160 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2161 +        checkCompletedWithWrappedCancellationException(g);
2162 +    }
2163 +
2164 +    /**
2165 +     * acceptEitherAsync result completes normally after normal
2166 +     * completion of sources
2167 +     */
2168 +    public void testAcceptEitherAsyncE() {
2169 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2170 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2171 +        IncAction r = new IncAction();
2172 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2173 +        f.complete(one);
2174 +        checkCompletedNormally(g, null);
2175 +        assertEquals(r.value, 2);
2176 +
2177 +        r = new IncAction();
2178 +        f = new CompletableFuture<Integer>();
2179 +        f.complete(one);
2180 +        f2 = new CompletableFuture<Integer>();
2181 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2182 +        checkCompletedNormally(g, null);
2183 +        assertEquals(r.value, 2);
2184 +    }
2185 +
2186 +    /**
2187 +     * acceptEitherAsync result completes exceptionally after exceptional
2188 +     * completion of source
2189 +     */
2190 +    public void testAcceptEitherAsync2E() {
2191 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2192 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2193 +        IncAction r = new IncAction();
2194 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2195 +        f.completeExceptionally(new CFException());
2196 +        checkCompletedWithWrappedCFException(g);
2197 +
2198 +        r = new IncAction();
2199 +        f = new CompletableFuture<Integer>();
2200 +        f2 = new CompletableFuture<Integer>();
2201 +        f2.completeExceptionally(new CFException());
2202 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2203 +        f.complete(one);
2204 +        checkCompletedWithWrappedCFException(g);
2205 +    }
2206 +
2207 +    /**
2208 +     * acceptEitherAsync result completes exceptionally if action does
2209 +     */
2210 +    public void testAcceptEitherAsync3E() {
2211 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2212 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2213 +        FailingConsumer r = new FailingConsumer();
2214 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2215 +        f.complete(one);
2216 +        checkCompletedWithWrappedCFException(g);
2217 +    }
2218 +
2219 +    /**
2220 +     * acceptEitherAsync result completes exceptionally if either
2221 +     * source cancelled
2222 +     */
2223 +    public void testAcceptEitherAsync4E() {
2224 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2225 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2226 +        IncAction r = new IncAction();
2227 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2228 +        assertTrue(f.cancel(true));
2229 +        checkCompletedWithWrappedCancellationException(g);
2230 +
2231 +        r = new IncAction();
2232 +        f = new CompletableFuture<Integer>();
2233 +        f2 = new CompletableFuture<Integer>();
2234 +        assertTrue(f2.cancel(true));
2235 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2236 +        checkCompletedWithWrappedCancellationException(g);
2237 +    }
2238 +
2239 +    /**
2240 +     * runAfterEitherAsync result completes normally after normal
2241 +     * completion of sources
2242 +     */
2243 +    public void testRunAfterEitherAsyncE() {
2244 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2245 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2246 +        Noop r = new Noop();
2247 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2248 +        f.complete(one);
2249 +        checkCompletedNormally(g, null);
2250 +        assertTrue(r.ran);
2251 +
2252 +        r = new Noop();
2253 +        f = new CompletableFuture<Integer>();
2254 +        f.complete(one);
2255 +        f2 = new CompletableFuture<Integer>();
2256 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2257 +        checkCompletedNormally(g, null);
2258 +        assertTrue(r.ran);
2259 +    }
2260 +
2261 +    /**
2262 +     * runAfterEitherAsync result completes exceptionally after exceptional
2263 +     * completion of source
2264 +     */
2265 +    public void testRunAfterEitherAsync2E() {
2266 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2267 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2268 +        Noop r = new Noop();
2269 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2270 +        f.completeExceptionally(new CFException());
2271 +        checkCompletedWithWrappedCFException(g);
2272 +
2273 +        r = new Noop();
2274 +        f = new CompletableFuture<Integer>();
2275 +        f2 = new CompletableFuture<Integer>();
2276 +        f2.completeExceptionally(new CFException());
2277 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2278 +        f.complete(one);
2279 +        checkCompletedWithWrappedCFException(g);
2280 +    }
2281 +
2282 +    /**
2283 +     * runAfterEitherAsync result completes exceptionally if action does
2284 +     */
2285 +    public void testRunAfterEitherAsync3E() {
2286 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2287 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2288 +        FailingNoop r = new FailingNoop();
2289 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2290 +        f.complete(one);
2291 +        checkCompletedWithWrappedCFException(g);
2292 +    }
2293 +
2294 +    /**
2295 +     * runAfterEitherAsync result completes exceptionally if either
2296 +     * source cancelled
2297 +     */
2298 +    public void testRunAfterEitherAsync4E() {
2299 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2300 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2301 +        Noop r = new Noop();
2302 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2303 +        assertTrue(f.cancel(true));
2304 +        checkCompletedWithWrappedCancellationException(g);
2305 +
2306 +        r = new Noop();
2307 +        f = new CompletableFuture<Integer>();
2308 +        f2 = new CompletableFuture<Integer>();
2309 +        assertTrue(f2.cancel(true));
2310 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2311 +        checkCompletedWithWrappedCancellationException(g);
2312 +    }
2313 +
2314 +    /**
2315 +     * thenComposeAsync result completes normally after normal
2316 +     * completion of source
2317 +     */
2318 +    public void testThenComposeAsyncE() {
2319 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2320 +        CompletableFutureInc r = new CompletableFutureInc();
2321 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2322 +        f.complete(one);
2323 +        checkCompletedNormally(g, two);
2324 +    }
2325 +
2326 +    /**
2327 +     * thenComposeAsync result completes exceptionally after
2328 +     * exceptional completion of source
2329 +     */
2330 +    public void testThenComposeAsync2E() {
2331 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2332 +        CompletableFutureInc r = new CompletableFutureInc();
2333 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2334 +        f.completeExceptionally(new CFException());
2335 +        checkCompletedWithWrappedCFException(g);
2336 +    }
2337 +
2338 +    /**
2339 +     * thenComposeAsync result completes exceptionally if action does
2340 +     */
2341 +    public void testThenComposeAsync3E() {
2342 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2343 +        FailingCompletableFutureFunction r = new FailingCompletableFutureFunction();
2344 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2345 +        f.complete(one);
2346 +        checkCompletedWithWrappedCFException(g);
2347 +    }
2348 +
2349 +    /**
2350 +     * thenComposeAsync result completes exceptionally if source cancelled
2351 +     */
2352 +    public void testThenComposeAsync4E() {
2353 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2354 +        CompletableFutureInc r = new CompletableFutureInc();
2355 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2356 +        assertTrue(f.cancel(true));
2357 +        checkCompletedWithWrappedCancellationException(g);
2358 +    }
2359 +
2360 +    // other static methods
2361 +
2362 +    /**
2363 +     * allOf(no component futures) returns a future completed normally
2364 +     * with the value null
2365 +     */
2366 +    public void testAllOf_empty() throws Exception {
2367 +        CompletableFuture<?> f = CompletableFuture.allOf();
2368 +        checkCompletedNormally(f, null);
2369 +    }
2370 +
2371 +    /**
2372 +     * allOf returns a future completed when all components complete
2373 +     */
2374 +    public void testAllOf() throws Exception {
2375 +        for (int k = 1; k < 20; ++k) {
2376 +            CompletableFuture[] fs = new CompletableFuture[k];
2377 +            for (int i = 0; i < k; ++i)
2378 +                fs[i] = new CompletableFuture<Integer>();
2379 +            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
2380 +            for (int i = 0; i < k; ++i) {
2381 +                checkIncomplete(f);
2382 +                fs[i].complete(one);
2383 +            }
2384 +            checkCompletedNormally(f, null);
2385 +        }
2386 +    }
2387 +
2388 +    /**
2389 +     * anyOf(no component futures) returns an incomplete future
2390 +     */
2391 +    public void testAnyOf_empty() throws Exception {
2392 +        CompletableFuture<?> f = CompletableFuture.anyOf();
2393 +        checkIncomplete(f);
2394 +    }
2395 +
2396 +    /**
2397 +     * anyOf returns a future completed when any components complete
2398 +     */
2399 +    public void testAnyOf() throws Exception {
2400 +        for (int k = 1; k < 20; ++k) {
2401 +            CompletableFuture[] fs = new CompletableFuture[k];
2402 +            for (int i = 0; i < k; ++i)
2403 +                fs[i] = new CompletableFuture<Integer>();
2404 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
2405 +            checkIncomplete(f);
2406 +            for (int i = 0; i < k; ++i) {
2407 +                fs[i].complete(one);
2408 +                checkCompletedNormally(f, one);
2409 +            }
2410 +        }
2411 +    }
2412 +
2413 +    /**
2414 +     * Completion methods throw NullPointerException with null arguments
2415 +     */
2416 +    public void testNPE() {
2417 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2418 +        CompletableFuture<Integer> g = new CompletableFuture<Integer>();
2419 +        CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
2420 +        CompletableFuture<?> h;
2421 +        Executor exec = new ThreadExecutor();
2422 +
2423 +        Runnable[] throwingActions = {
2424 +            () -> { CompletableFuture.supplyAsync(null); },
2425 +            () -> { CompletableFuture.supplyAsync(null, exec); },
2426 +            () -> { CompletableFuture.supplyAsync(supplyOne, null); },
2427 +
2428 +            () -> { CompletableFuture.runAsync(null); },
2429 +            () -> { CompletableFuture.runAsync(null, exec); },
2430 +            () -> { CompletableFuture.runAsync(() -> {}, null); },
2431 +
2432 +            () -> { f.completeExceptionally(null); },
2433 +
2434 +            () -> { f.thenApply(null); },
2435 +            () -> { f.thenApplyAsync(null); },
2436 +            () -> { f.thenApplyAsync((x) -> x, null); },
2437 +            () -> { f.thenApplyAsync(null, exec); },
2438 +
2439 +            () -> { f.thenAccept(null); },
2440 +            () -> { f.thenAcceptAsync(null); },
2441 +            () -> { f.thenAcceptAsync((x) -> { ; }, null); },
2442 +            () -> { f.thenAcceptAsync(null, exec); },
2443 +
2444 +            () -> { f.thenRun(null); },
2445 +            () -> { f.thenRunAsync(null); },
2446 +            () -> { f.thenRunAsync(() -> { ; }, null); },
2447 +            () -> { f.thenRunAsync(null, exec); },
2448 +
2449 +            () -> { f.thenCombine(g, null); },
2450 +            () -> { f.thenCombineAsync(g, null); },
2451 +            () -> { f.thenCombineAsync(g, null, exec); },
2452 +            () -> { f.thenCombine(nullFuture, (x, y) -> x); },
2453 +            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x); },
2454 +            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x, exec); },
2455 +            () -> { f.thenCombineAsync(g, (x, y) -> x, null); },
2456 +
2457 +            () -> { f.thenAcceptBoth(g, null); },
2458 +            () -> { f.thenAcceptBothAsync(g, null); },
2459 +            () -> { f.thenAcceptBothAsync(g, null, exec); },
2460 +            () -> { f.thenAcceptBoth(nullFuture, (x, y) -> {}); },
2461 +            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}); },
2462 +            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec); },
2463 +            () -> { f.thenAcceptBothAsync(g, (x, y) -> {}, null); },
2464 +
2465 +            () -> { f.runAfterBoth(g, null); },
2466 +            () -> { f.runAfterBothAsync(g, null); },
2467 +            () -> { f.runAfterBothAsync(g, null, exec); },
2468 +            () -> { f.runAfterBoth(nullFuture, () -> {}); },
2469 +            () -> { f.runAfterBothAsync(nullFuture, () -> {}); },
2470 +            () -> { f.runAfterBothAsync(nullFuture, () -> {}, exec); },
2471 +            () -> { f.runAfterBothAsync(g, () -> {}, null); },
2472 +
2473 +            () -> { f.applyToEither(g, null); },
2474 +            () -> { f.applyToEitherAsync(g, null); },
2475 +            () -> { f.applyToEitherAsync(g, null, exec); },
2476 +            () -> { f.applyToEither(nullFuture, (x) -> x); },
2477 +            () -> { f.applyToEitherAsync(nullFuture, (x) -> x); },
2478 +            () -> { f.applyToEitherAsync(nullFuture, (x) -> x, exec); },
2479 +            () -> { f.applyToEitherAsync(g, (x) -> x, null); },
2480 +
2481 +            () -> { f.acceptEither(g, null); },
2482 +            () -> { f.acceptEitherAsync(g, null); },
2483 +            () -> { f.acceptEitherAsync(g, null, exec); },
2484 +            () -> { f.acceptEither(nullFuture, (x) -> {}); },
2485 +            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}); },
2486 +            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}, exec); },
2487 +            () -> { f.acceptEitherAsync(g, (x) -> {}, null); },
2488 +
2489 +            () -> { f.runAfterEither(g, null); },
2490 +            () -> { f.runAfterEitherAsync(g, null); },
2491 +            () -> { f.runAfterEitherAsync(g, null, exec); },
2492 +            () -> { f.runAfterEither(nullFuture, () -> {}); },
2493 +            () -> { f.runAfterEitherAsync(nullFuture, () -> {}); },
2494 +            () -> { f.runAfterEitherAsync(nullFuture, () -> {}, exec); },
2495 +            () -> { f.runAfterEitherAsync(g, () -> {}, null); },
2496 +
2497 +            () -> { f.thenCompose(null); },
2498 +            () -> { f.thenComposeAsync(null); },
2499 +            () -> { f.thenComposeAsync(new CompletableFutureInc(), null); },
2500 +            () -> { f.thenComposeAsync(null, exec); },
2501 +
2502 +            () -> { f.exceptionally(null); },
2503 +
2504 +            () -> { f.handle(null); },
2505 +
2506 +            () -> { CompletableFuture.allOf((CompletableFuture<?>)null); },
2507 +            () -> { CompletableFuture.allOf((CompletableFuture<?>[])null); },
2508 +            () -> { CompletableFuture.allOf(f, null); },
2509 +            () -> { CompletableFuture.allOf(null, f); },
2510 +
2511 +            () -> { CompletableFuture.anyOf((CompletableFuture<?>)null); },
2512 +            () -> { CompletableFuture.anyOf((CompletableFuture<?>[])null); },
2513 +            () -> { CompletableFuture.anyOf(f, null); },
2514 +            () -> { CompletableFuture.anyOf(null, f); },
2515 +        };
2516 +
2517 +        assertThrows(NullPointerException.class, throwingActions);
2518 +    }
2519 +
2520   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines