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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines