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.3 by jsr166, Sat Feb 9 19:33:08 2013 UTC vs.
Revision 1.21 by jsr166, Mon Apr 8 16:58:17 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 <    // XXXX Just a skeleton implementation for now.
40 <    public void testTODO() {
41 <        fail("Please add some real tests!");
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  
# Line 46 | Line 273 | public class CompletableFutureTest exten
273          f.completeExceptionally(new IndexOutOfBoundsException());
274          assertTrue(f.toString().contains("[Completed exceptionally]"));
275      }
276 +
277 +    /**
278 +     * completedFuture returns a completed CompletableFuture with given value
279 +     */
280 +    public void testCompletedFuture() {
281 +        CompletableFuture<String> f = CompletableFuture.completedFuture("test");
282 +        checkCompletedNormally(f, "test");
283 +    }
284 +
285 +    // 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, g;
1131 +        CompletableFutureInc r;
1132 +
1133 +        f = new CompletableFuture<Integer>();
1134 +        g = f.thenCompose(r = new CompletableFutureInc());
1135 +        f.complete(one);
1136 +        checkCompletedNormally(g, two);
1137 +        assertTrue(r.ran);
1138 +
1139 +        f = new CompletableFuture<Integer>();
1140 +        f.complete(one);
1141 +        g = f.thenCompose(r = new CompletableFutureInc());
1142 +        checkCompletedNormally(g, two);
1143 +        assertTrue(r.ran);
1144 +    }
1145 +
1146 +    /**
1147 +     * thenCompose result completes exceptionally after exceptional
1148 +     * completion of source
1149 +     */
1150 +    public void testThenCompose2() {
1151 +        CompletableFuture<Integer> f, g;
1152 +        CompletableFutureInc r;
1153 +
1154 +        f = new CompletableFuture<Integer>();
1155 +        g = f.thenCompose(r = new CompletableFutureInc());
1156 +        f.completeExceptionally(new CFException());
1157 +        checkCompletedWithWrappedCFException(g);
1158 +
1159 +        f = new CompletableFuture<Integer>();
1160 +        f.completeExceptionally(new CFException());
1161 +        g = f.thenCompose(r = new CompletableFutureInc());
1162 +        checkCompletedWithWrappedCFException(g);
1163 +    }
1164 +
1165 +    /**
1166 +     * thenCompose result completes exceptionally if action does
1167 +     */
1168 +    public void testThenCompose3() {
1169 +        CompletableFuture<Integer> f, g;
1170 +        FailingCompletableFutureFunction r;
1171 +
1172 +        f = new CompletableFuture<Integer>();
1173 +        g = f.thenCompose(r = new FailingCompletableFutureFunction());
1174 +        f.complete(one);
1175 +        checkCompletedWithWrappedCFException(g);
1176 +
1177 +        f = new CompletableFuture<Integer>();
1178 +        f.complete(one);
1179 +        g = f.thenCompose(r = new FailingCompletableFutureFunction());
1180 +        checkCompletedWithWrappedCFException(g);
1181 +    }
1182 +
1183 +    /**
1184 +     * thenCompose result completes exceptionally if source cancelled
1185 +     */
1186 +    public void testThenCompose4() {
1187 +        CompletableFuture<Integer> f, g;
1188 +        CompletableFutureInc r;
1189 +
1190 +        f = new CompletableFuture<Integer>();
1191 +        g = f.thenCompose(r = new CompletableFutureInc());
1192 +        assertTrue(f.cancel(true));
1193 +        checkCompletedWithWrappedCancellationException(g);
1194 +
1195 +        f = new CompletableFuture<Integer>();
1196 +        assertTrue(f.cancel(true));
1197 +        g = f.thenCompose(r = new CompletableFutureInc());
1198 +        checkCompletedWithWrappedCancellationException(g);
1199 +    }
1200 +
1201 +
1202 +    // asyncs
1203 +
1204 +    /**
1205 +     * thenRunAsync result completes normally after normal completion of source
1206 +     */
1207 +    public void testThenRunAsync() {
1208 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1209 +        Noop r = new Noop();
1210 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1211 +        f.complete(null);
1212 +        checkCompletedNormally(g, null);
1213 +
1214 +        // reordered version
1215 +        f = new CompletableFuture<Integer>();
1216 +        f.complete(null);
1217 +        r = new Noop();
1218 +        g = f.thenRunAsync(r);
1219 +        checkCompletedNormally(g, null);
1220 +    }
1221 +
1222 +    /**
1223 +     * thenRunAsync result completes exceptionally after exceptional
1224 +     * completion of source
1225 +     */
1226 +    public void testThenRunAsync2() {
1227 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1228 +        Noop r = new Noop();
1229 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1230 +        f.completeExceptionally(new CFException());
1231 +        try {
1232 +            g.join();
1233 +            shouldThrow();
1234 +        } catch (Exception ok) {
1235 +        }
1236 +        checkCompletedWithWrappedCFException(g);
1237 +    }
1238 +
1239 +    /**
1240 +     * thenRunAsync result completes exceptionally if action does
1241 +     */
1242 +    public void testThenRunAsync3() {
1243 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1244 +        FailingNoop r = new FailingNoop();
1245 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1246 +        f.complete(null);
1247 +        checkCompletedWithWrappedCFException(g);
1248 +    }
1249 +
1250 +    /**
1251 +     * thenRunAsync result completes exceptionally if source cancelled
1252 +     */
1253 +    public void testThenRunAsync4() {
1254 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1255 +        Noop r = new Noop();
1256 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1257 +        assertTrue(f.cancel(true));
1258 +        checkCompletedWithWrappedCancellationException(g);
1259 +    }
1260 +
1261 +    /**
1262 +     * thenApplyAsync result completes normally after normal completion of source
1263 +     */
1264 +    public void testThenApplyAsync() {
1265 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1266 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1267 +        f.complete(one);
1268 +        checkCompletedNormally(g, two);
1269 +    }
1270 +
1271 +    /**
1272 +     * thenApplyAsync result completes exceptionally after exceptional
1273 +     * completion of source
1274 +     */
1275 +    public void testThenApplyAsync2() {
1276 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1277 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1278 +        f.completeExceptionally(new CFException());
1279 +        checkCompletedWithWrappedCFException(g);
1280 +    }
1281 +
1282 +    /**
1283 +     * thenApplyAsync result completes exceptionally if action does
1284 +     */
1285 +    public void testThenApplyAsync3() {
1286 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1287 +        FailingFunction r = new FailingFunction();
1288 +        CompletableFuture<Integer> g = f.thenApplyAsync(r);
1289 +        f.complete(null);
1290 +        checkCompletedWithWrappedCFException(g);
1291 +    }
1292 +
1293 +    /**
1294 +     * thenApplyAsync result completes exceptionally if source cancelled
1295 +     */
1296 +    public void testThenApplyAsync4() {
1297 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1298 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1299 +        assertTrue(f.cancel(true));
1300 +        checkCompletedWithWrappedCancellationException(g);
1301 +    }
1302 +
1303 +    /**
1304 +     * thenAcceptAsync result completes normally after normal
1305 +     * completion of source
1306 +     */
1307 +    public void testThenAcceptAsync() {
1308 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1309 +        IncAction r = new IncAction();
1310 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1311 +        f.complete(one);
1312 +        checkCompletedNormally(g, null);
1313 +        assertEquals(r.value, 2);
1314 +    }
1315 +
1316 +    /**
1317 +     * thenAcceptAsync result completes exceptionally after exceptional
1318 +     * completion of source
1319 +     */
1320 +    public void testThenAcceptAsync2() {
1321 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1322 +        IncAction r = new IncAction();
1323 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1324 +        f.completeExceptionally(new CFException());
1325 +        checkCompletedWithWrappedCFException(g);
1326 +    }
1327 +
1328 +    /**
1329 +     * thenAcceptAsync result completes exceptionally if action does
1330 +     */
1331 +    public void testThenAcceptAsync3() {
1332 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1333 +        FailingConsumer r = new FailingConsumer();
1334 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1335 +        f.complete(null);
1336 +        checkCompletedWithWrappedCFException(g);
1337 +    }
1338 +
1339 +    /**
1340 +     * thenAcceptAsync result completes exceptionally if source cancelled
1341 +     */
1342 +    public void testThenAcceptAsync4() {
1343 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1344 +        IncAction r = new IncAction();
1345 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1346 +        assertTrue(f.cancel(true));
1347 +        checkCompletedWithWrappedCancellationException(g);
1348 +    }
1349 +
1350 +    /**
1351 +     * thenCombineAsync result completes normally after normal
1352 +     * completion of sources
1353 +     */
1354 +    public void testThenCombineAsync() {
1355 +        CompletableFuture<Integer> f, g, h;
1356 +
1357 +        f = new CompletableFuture<Integer>();
1358 +        g = new CompletableFuture<Integer>();
1359 +        h = f.thenCombineAsync(g, subtract);
1360 +        f.complete(3);
1361 +        checkIncomplete(h);
1362 +        g.complete(1);
1363 +        checkCompletedNormally(h, 2);
1364 +
1365 +        f = new CompletableFuture<Integer>();
1366 +        g = new CompletableFuture<Integer>();
1367 +        h = f.thenCombineAsync(g, subtract);
1368 +        g.complete(1);
1369 +        checkIncomplete(h);
1370 +        f.complete(3);
1371 +        checkCompletedNormally(h, 2);
1372 +
1373 +        f = new CompletableFuture<Integer>();
1374 +        g = new CompletableFuture<Integer>();
1375 +        g.complete(1);
1376 +        f.complete(3);
1377 +        h = f.thenCombineAsync(g, subtract);
1378 +        checkCompletedNormally(h, 2);
1379 +    }
1380 +
1381 +    /**
1382 +     * thenCombineAsync result completes exceptionally after exceptional
1383 +     * completion of either source
1384 +     */
1385 +    public void testThenCombineAsync2() {
1386 +        CompletableFuture<Integer> f, g, h;
1387 +
1388 +        f = new CompletableFuture<Integer>();
1389 +        g = new CompletableFuture<Integer>();
1390 +        h = f.thenCombineAsync(g, subtract);
1391 +        f.completeExceptionally(new CFException());
1392 +        checkIncomplete(h);
1393 +        g.complete(1);
1394 +        checkCompletedWithWrappedCFException(h);
1395 +
1396 +        f = new CompletableFuture<Integer>();
1397 +        g = new CompletableFuture<Integer>();
1398 +        h = f.thenCombineAsync(g, subtract);
1399 +        g.completeExceptionally(new CFException());
1400 +        checkIncomplete(h);
1401 +        f.complete(3);
1402 +        checkCompletedWithWrappedCFException(h);
1403 +
1404 +        f = new CompletableFuture<Integer>();
1405 +        g = new CompletableFuture<Integer>();
1406 +        g.completeExceptionally(new CFException());
1407 +        f.complete(3);
1408 +        h = f.thenCombineAsync(g, subtract);
1409 +        checkCompletedWithWrappedCFException(h);
1410 +    }
1411 +
1412 +    /**
1413 +     * thenCombineAsync result completes exceptionally if action does
1414 +     */
1415 +    public void testThenCombineAsync3() {
1416 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1417 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1418 +        FailingBiFunction r = new FailingBiFunction();
1419 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r);
1420 +        f.complete(one);
1421 +        checkIncomplete(g);
1422 +        assertFalse(r.ran);
1423 +        f2.complete(two);
1424 +        checkCompletedWithWrappedCFException(g);
1425 +        assertTrue(r.ran);
1426 +    }
1427 +
1428 +    /**
1429 +     * thenCombineAsync result completes exceptionally if either source cancelled
1430 +     */
1431 +    public void testThenCombineAsync4() {
1432 +        CompletableFuture<Integer> f, g, h;
1433 +
1434 +        f = new CompletableFuture<Integer>();
1435 +        g = new CompletableFuture<Integer>();
1436 +        h = f.thenCombineAsync(g, subtract);
1437 +        assertTrue(f.cancel(true));
1438 +        checkIncomplete(h);
1439 +        g.complete(1);
1440 +        checkCompletedWithWrappedCancellationException(h);
1441 +
1442 +        f = new CompletableFuture<Integer>();
1443 +        g = new CompletableFuture<Integer>();
1444 +        h = f.thenCombineAsync(g, subtract);
1445 +        assertTrue(g.cancel(true));
1446 +        checkIncomplete(h);
1447 +        f.complete(3);
1448 +        checkCompletedWithWrappedCancellationException(h);
1449 +
1450 +        f = new CompletableFuture<Integer>();
1451 +        g = new CompletableFuture<Integer>();
1452 +        g.complete(3);
1453 +        assertTrue(f.cancel(true));
1454 +        h = f.thenCombineAsync(g, subtract);
1455 +        checkCompletedWithWrappedCancellationException(h);
1456 +
1457 +        f = new CompletableFuture<Integer>();
1458 +        g = new CompletableFuture<Integer>();
1459 +        f.complete(3);
1460 +        assertTrue(g.cancel(true));
1461 +        h = f.thenCombineAsync(g, subtract);
1462 +        checkCompletedWithWrappedCancellationException(h);
1463 +    }
1464 +
1465 +    /**
1466 +     * thenAcceptBothAsync result completes normally after normal
1467 +     * completion of sources
1468 +     */
1469 +    public void testThenAcceptBothAsync() {
1470 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1471 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1472 +        AddAction r = new AddAction();
1473 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r);
1474 +        f.complete(one);
1475 +        checkIncomplete(g);
1476 +        f2.complete(two);
1477 +        checkCompletedNormally(g, null);
1478 +        assertEquals(r.value, 3);
1479 +    }
1480 +
1481 +    /**
1482 +     * thenAcceptBothAsync result completes exceptionally after exceptional
1483 +     * completion of source
1484 +     */
1485 +    public void testThenAcceptBothAsync2() {
1486 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1487 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1488 +        AddAction r = new AddAction();
1489 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r);
1490 +        f.completeExceptionally(new CFException());
1491 +        f2.complete(two);
1492 +        checkCompletedWithWrappedCFException(g);
1493 +
1494 +        r = new AddAction();
1495 +        f = new CompletableFuture<Integer>();
1496 +        f2 = new CompletableFuture<Integer>();
1497 +        g = f.thenAcceptBothAsync(f2, r);
1498 +        f.complete(one);
1499 +        f2.completeExceptionally(new CFException());
1500 +        checkCompletedWithWrappedCFException(g);
1501 +    }
1502 +
1503 +    /**
1504 +     * thenAcceptBothAsync result completes exceptionally if action does
1505 +     */
1506 +    public void testThenAcceptBothAsync3() {
1507 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1508 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1509 +        FailingBiConsumer r = new FailingBiConsumer();
1510 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r);
1511 +        f.complete(one);
1512 +        checkIncomplete(g);
1513 +        f2.complete(two);
1514 +        checkCompletedWithWrappedCFException(g);
1515 +    }
1516 +
1517 +    /**
1518 +     * thenAcceptBothAsync result completes exceptionally if either source cancelled
1519 +     */
1520 +    public void testThenAcceptBothAsync4() {
1521 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1522 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1523 +        AddAction r = new AddAction();
1524 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r);
1525 +        assertTrue(f.cancel(true));
1526 +        f2.complete(two);
1527 +        checkCompletedWithWrappedCancellationException(g);
1528 +
1529 +        r = new AddAction();
1530 +        f = new CompletableFuture<Integer>();
1531 +        f2 = new CompletableFuture<Integer>();
1532 +        g = f.thenAcceptBothAsync(f2, r);
1533 +        f.complete(one);
1534 +        assertTrue(f2.cancel(true));
1535 +        checkCompletedWithWrappedCancellationException(g);
1536 +    }
1537 +
1538 +    /**
1539 +     * runAfterBothAsync result completes normally after normal
1540 +     * completion of sources
1541 +     */
1542 +    public void testRunAfterBothAsync() {
1543 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1544 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1545 +        Noop r = new Noop();
1546 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1547 +        f.complete(one);
1548 +        checkIncomplete(g);
1549 +        f2.complete(two);
1550 +        checkCompletedNormally(g, null);
1551 +        assertTrue(r.ran);
1552 +    }
1553 +
1554 +    /**
1555 +     * runAfterBothAsync result completes exceptionally after exceptional
1556 +     * completion of source
1557 +     */
1558 +    public void testRunAfterBothAsync2() {
1559 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1560 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1561 +        Noop r = new Noop();
1562 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1563 +        f.completeExceptionally(new CFException());
1564 +        f2.complete(two);
1565 +        checkCompletedWithWrappedCFException(g);
1566 +
1567 +        r = new Noop();
1568 +        f = new CompletableFuture<Integer>();
1569 +        f2 = new CompletableFuture<Integer>();
1570 +        g = f.runAfterBothAsync(f2, r);
1571 +        f.complete(one);
1572 +        f2.completeExceptionally(new CFException());
1573 +        checkCompletedWithWrappedCFException(g);
1574 +    }
1575 +
1576 +    /**
1577 +     * runAfterBothAsync result completes exceptionally if action does
1578 +     */
1579 +    public void testRunAfterBothAsync3() {
1580 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1581 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1582 +        FailingNoop r = new FailingNoop();
1583 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1584 +        f.complete(one);
1585 +        checkIncomplete(g);
1586 +        f2.complete(two);
1587 +        checkCompletedWithWrappedCFException(g);
1588 +    }
1589 +
1590 +    /**
1591 +     * runAfterBothAsync result completes exceptionally if either source cancelled
1592 +     */
1593 +    public void testRunAfterBothAsync4() {
1594 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1595 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1596 +        Noop r = new Noop();
1597 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1598 +        assertTrue(f.cancel(true));
1599 +        f2.complete(two);
1600 +        checkCompletedWithWrappedCancellationException(g);
1601 +
1602 +        r = new Noop();
1603 +        f = new CompletableFuture<Integer>();
1604 +        f2 = new CompletableFuture<Integer>();
1605 +        g = f.runAfterBothAsync(f2, r);
1606 +        f.complete(one);
1607 +        assertTrue(f2.cancel(true));
1608 +        checkCompletedWithWrappedCancellationException(g);
1609 +    }
1610 +
1611 +    /**
1612 +     * applyToEitherAsync result completes normally after normal
1613 +     * completion of sources
1614 +     */
1615 +    public void testApplyToEitherAsync() {
1616 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1617 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1618 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1619 +        f.complete(one);
1620 +        checkCompletedNormally(g, two);
1621 +
1622 +        f = new CompletableFuture<Integer>();
1623 +        f.complete(one);
1624 +        f2 = new CompletableFuture<Integer>();
1625 +        g = f.applyToEitherAsync(f2, inc);
1626 +        checkCompletedNormally(g, two);
1627 +    }
1628 +
1629 +    /**
1630 +     * applyToEitherAsync result completes exceptionally after exceptional
1631 +     * completion of source
1632 +     */
1633 +    public void testApplyToEitherAsync2() {
1634 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1635 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1636 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1637 +        f.completeExceptionally(new CFException());
1638 +        checkCompletedWithWrappedCFException(g);
1639 +
1640 +        f = new CompletableFuture<Integer>();
1641 +        f2 = new CompletableFuture<Integer>();
1642 +        f2.completeExceptionally(new CFException());
1643 +        g = f.applyToEitherAsync(f2, inc);
1644 +        f.complete(one);
1645 +        checkCompletedWithWrappedCFException(g);
1646 +    }
1647 +
1648 +    /**
1649 +     * applyToEitherAsync result completes exceptionally if action does
1650 +     */
1651 +    public void testApplyToEitherAsync3() {
1652 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1653 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1654 +        FailingFunction r = new FailingFunction();
1655 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r);
1656 +        f.complete(one);
1657 +        checkCompletedWithWrappedCFException(g);
1658 +    }
1659 +
1660 +    /**
1661 +     * applyToEitherAsync result completes exceptionally if either source cancelled
1662 +     */
1663 +    public void testApplyToEitherAsync4() {
1664 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1665 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1666 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1667 +        assertTrue(f.cancel(true));
1668 +        checkCompletedWithWrappedCancellationException(g);
1669 +
1670 +        f = new CompletableFuture<Integer>();
1671 +        f2 = new CompletableFuture<Integer>();
1672 +        assertTrue(f2.cancel(true));
1673 +        g = f.applyToEitherAsync(f2, inc);
1674 +        checkCompletedWithWrappedCancellationException(g);
1675 +    }
1676 +
1677 +    /**
1678 +     * acceptEitherAsync result completes normally after normal
1679 +     * completion of sources
1680 +     */
1681 +    public void testAcceptEitherAsync() {
1682 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1683 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1684 +        IncAction r = new IncAction();
1685 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1686 +        f.complete(one);
1687 +        checkCompletedNormally(g, null);
1688 +        assertEquals(r.value, 2);
1689 +
1690 +        r = new IncAction();
1691 +        f = new CompletableFuture<Integer>();
1692 +        f.complete(one);
1693 +        f2 = new CompletableFuture<Integer>();
1694 +        g = f.acceptEitherAsync(f2, r);
1695 +        checkCompletedNormally(g, null);
1696 +        assertEquals(r.value, 2);
1697 +    }
1698 +
1699 +    /**
1700 +     * acceptEitherAsync result completes exceptionally after exceptional
1701 +     * completion of source
1702 +     */
1703 +    public void testAcceptEitherAsync2() {
1704 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1705 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1706 +        IncAction r = new IncAction();
1707 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1708 +        f.completeExceptionally(new CFException());
1709 +        checkCompletedWithWrappedCFException(g);
1710 +
1711 +        r = new IncAction();
1712 +        f = new CompletableFuture<Integer>();
1713 +        f2 = new CompletableFuture<Integer>();
1714 +        f2.completeExceptionally(new CFException());
1715 +        g = f.acceptEitherAsync(f2, r);
1716 +        f.complete(one);
1717 +        checkCompletedWithWrappedCFException(g);
1718 +    }
1719 +
1720 +    /**
1721 +     * acceptEitherAsync result completes exceptionally if action does
1722 +     */
1723 +    public void testAcceptEitherAsync3() {
1724 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1725 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1726 +        FailingConsumer r = new FailingConsumer();
1727 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1728 +        f.complete(one);
1729 +        checkCompletedWithWrappedCFException(g);
1730 +    }
1731 +
1732 +    /**
1733 +     * acceptEitherAsync result completes exceptionally if either
1734 +     * source cancelled
1735 +     */
1736 +    public void testAcceptEitherAsync4() {
1737 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1738 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1739 +        IncAction r = new IncAction();
1740 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1741 +        assertTrue(f.cancel(true));
1742 +        checkCompletedWithWrappedCancellationException(g);
1743 +
1744 +        r = new IncAction();
1745 +        f = new CompletableFuture<Integer>();
1746 +        f2 = new CompletableFuture<Integer>();
1747 +        assertTrue(f2.cancel(true));
1748 +        g = f.acceptEitherAsync(f2, r);
1749 +        checkCompletedWithWrappedCancellationException(g);
1750 +    }
1751 +
1752 +    /**
1753 +     * runAfterEitherAsync result completes normally after normal
1754 +     * completion of sources
1755 +     */
1756 +    public void testRunAfterEitherAsync() {
1757 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1758 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1759 +        Noop r = new Noop();
1760 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1761 +        f.complete(one);
1762 +        checkCompletedNormally(g, null);
1763 +        assertTrue(r.ran);
1764 +
1765 +        r = new Noop();
1766 +        f = new CompletableFuture<Integer>();
1767 +        f.complete(one);
1768 +        f2 = new CompletableFuture<Integer>();
1769 +        g = f.runAfterEitherAsync(f2, r);
1770 +        checkCompletedNormally(g, null);
1771 +        assertTrue(r.ran);
1772 +    }
1773 +
1774 +    /**
1775 +     * runAfterEitherAsync result completes exceptionally after exceptional
1776 +     * completion of source
1777 +     */
1778 +    public void testRunAfterEitherAsync2() {
1779 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1780 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1781 +        Noop r = new Noop();
1782 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1783 +        f.completeExceptionally(new CFException());
1784 +        checkCompletedWithWrappedCFException(g);
1785 +
1786 +        r = new Noop();
1787 +        f = new CompletableFuture<Integer>();
1788 +        f2 = new CompletableFuture<Integer>();
1789 +        f2.completeExceptionally(new CFException());
1790 +        g = f.runAfterEitherAsync(f2, r);
1791 +        f.complete(one);
1792 +        checkCompletedWithWrappedCFException(g);
1793 +    }
1794 +
1795 +    /**
1796 +     * runAfterEitherAsync result completes exceptionally if action does
1797 +     */
1798 +    public void testRunAfterEitherAsync3() {
1799 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1800 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1801 +        FailingNoop r = new FailingNoop();
1802 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1803 +        f.complete(one);
1804 +        checkCompletedWithWrappedCFException(g);
1805 +    }
1806 +
1807 +    /**
1808 +     * runAfterEitherAsync result completes exceptionally if either
1809 +     * source cancelled
1810 +     */
1811 +    public void testRunAfterEitherAsync4() {
1812 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1813 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
1814 +        Noop r = new Noop();
1815 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1816 +        assertTrue(f.cancel(true));
1817 +        checkCompletedWithWrappedCancellationException(g);
1818 +
1819 +        r = new Noop();
1820 +        f = new CompletableFuture<Integer>();
1821 +        f2 = new CompletableFuture<Integer>();
1822 +        assertTrue(f2.cancel(true));
1823 +        g = f.runAfterEitherAsync(f2, r);
1824 +        checkCompletedWithWrappedCancellationException(g);
1825 +    }
1826 +
1827 +    /**
1828 +     * thenComposeAsync result completes normally after normal
1829 +     * completion of source
1830 +     */
1831 +    public void testThenComposeAsync() {
1832 +        CompletableFuture<Integer> f, g;
1833 +        CompletableFutureInc r;
1834 +
1835 +        f = new CompletableFuture<Integer>();
1836 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1837 +        f.complete(one);
1838 +        checkCompletedNormally(g, two);
1839 +
1840 +        f = new CompletableFuture<Integer>();
1841 +        f.complete(one);
1842 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1843 +        checkCompletedNormally(g, two);
1844 +    }
1845 +
1846 +    /**
1847 +     * thenComposeAsync result completes exceptionally after
1848 +     * exceptional completion of source
1849 +     */
1850 +    public void testThenComposeAsync2() {
1851 +        CompletableFuture<Integer> f, g;
1852 +        CompletableFutureInc r;
1853 +
1854 +        f = new CompletableFuture<Integer>();
1855 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1856 +        f.completeExceptionally(new CFException());
1857 +        checkCompletedWithWrappedCFException(g);
1858 +        assertFalse(r.ran);
1859 +
1860 +        f = new CompletableFuture<Integer>();
1861 +        f.completeExceptionally(new CFException());
1862 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1863 +        checkCompletedWithWrappedCFException(g);
1864 +        assertFalse(r.ran);
1865 +    }
1866 +
1867 +    /**
1868 +     * thenComposeAsync result completes exceptionally if action does
1869 +     */
1870 +    public void testThenComposeAsync3() {
1871 +        CompletableFuture<Integer> f, g;
1872 +        FailingCompletableFutureFunction r;
1873 +
1874 +        f = new CompletableFuture<Integer>();
1875 +        g = f.thenComposeAsync(r = new FailingCompletableFutureFunction());
1876 +        f.complete(one);
1877 +        checkCompletedWithWrappedCFException(g);
1878 +
1879 +        f = new CompletableFuture<Integer>();
1880 +        f.complete(one);
1881 +        g = f.thenComposeAsync(r = new FailingCompletableFutureFunction());
1882 +        checkCompletedWithWrappedCFException(g);
1883 +    }
1884 +
1885 +    /**
1886 +     * thenComposeAsync result completes exceptionally if source cancelled
1887 +     */
1888 +    public void testThenComposeAsync4() {
1889 +        CompletableFuture<Integer> f, g;
1890 +        CompletableFutureInc r;
1891 +
1892 +        f = new CompletableFuture<Integer>();
1893 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1894 +        assertTrue(f.cancel(true));
1895 +        checkCompletedWithWrappedCancellationException(g);
1896 +
1897 +        f = new CompletableFuture<Integer>();
1898 +        assertTrue(f.cancel(true));
1899 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
1900 +        checkCompletedWithWrappedCancellationException(g);
1901 +    }
1902 +
1903 +
1904 +    // async with explicit executors
1905 +
1906 +    /**
1907 +     * thenRunAsync result completes normally after normal completion of source
1908 +     */
1909 +    public void testThenRunAsyncE() {
1910 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1911 +        Noop r = new Noop();
1912 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
1913 +        f.complete(null);
1914 +        checkCompletedNormally(g, null);
1915 +
1916 +        // reordered version
1917 +        f = new CompletableFuture<Integer>();
1918 +        f.complete(null);
1919 +        r = new Noop();
1920 +        g = f.thenRunAsync(r, new ThreadExecutor());
1921 +        checkCompletedNormally(g, null);
1922 +    }
1923 +
1924 +    /**
1925 +     * thenRunAsync result completes exceptionally after exceptional
1926 +     * completion of source
1927 +     */
1928 +    public void testThenRunAsync2E() {
1929 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1930 +        Noop r = new Noop();
1931 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
1932 +        f.completeExceptionally(new CFException());
1933 +        try {
1934 +            g.join();
1935 +            shouldThrow();
1936 +        } catch (Exception ok) {
1937 +        }
1938 +        checkCompletedWithWrappedCFException(g);
1939 +    }
1940 +
1941 +    /**
1942 +     * thenRunAsync result completes exceptionally if action does
1943 +     */
1944 +    public void testThenRunAsync3E() {
1945 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1946 +        FailingNoop r = new FailingNoop();
1947 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
1948 +        f.complete(null);
1949 +        checkCompletedWithWrappedCFException(g);
1950 +    }
1951 +
1952 +    /**
1953 +     * thenRunAsync result completes exceptionally if source cancelled
1954 +     */
1955 +    public void testThenRunAsync4E() {
1956 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1957 +        Noop r = new Noop();
1958 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
1959 +        assertTrue(f.cancel(true));
1960 +        checkCompletedWithWrappedCancellationException(g);
1961 +    }
1962 +
1963 +    /**
1964 +     * thenApplyAsync result completes normally after normal completion of source
1965 +     */
1966 +    public void testThenApplyAsyncE() {
1967 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1968 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
1969 +        f.complete(one);
1970 +        checkCompletedNormally(g, two);
1971 +    }
1972 +
1973 +    /**
1974 +     * thenApplyAsync result completes exceptionally after exceptional
1975 +     * completion of source
1976 +     */
1977 +    public void testThenApplyAsync2E() {
1978 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1979 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
1980 +        f.completeExceptionally(new CFException());
1981 +        checkCompletedWithWrappedCFException(g);
1982 +    }
1983 +
1984 +    /**
1985 +     * thenApplyAsync result completes exceptionally if action does
1986 +     */
1987 +    public void testThenApplyAsync3E() {
1988 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
1989 +        FailingFunction r = new FailingFunction();
1990 +        CompletableFuture<Integer> g = f.thenApplyAsync(r, new ThreadExecutor());
1991 +        f.complete(null);
1992 +        checkCompletedWithWrappedCFException(g);
1993 +    }
1994 +
1995 +    /**
1996 +     * thenApplyAsync result completes exceptionally if source cancelled
1997 +     */
1998 +    public void testThenApplyAsync4E() {
1999 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2000 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
2001 +        assertTrue(f.cancel(true));
2002 +        checkCompletedWithWrappedCancellationException(g);
2003 +    }
2004 +
2005 +    /**
2006 +     * thenAcceptAsync result completes normally after normal
2007 +     * completion of source
2008 +     */
2009 +    public void testThenAcceptAsyncE() {
2010 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2011 +        IncAction r = new IncAction();
2012 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2013 +        f.complete(one);
2014 +        checkCompletedNormally(g, null);
2015 +        assertEquals(r.value, 2);
2016 +    }
2017 +
2018 +    /**
2019 +     * thenAcceptAsync result completes exceptionally after exceptional
2020 +     * completion of source
2021 +     */
2022 +    public void testThenAcceptAsync2E() {
2023 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2024 +        IncAction r = new IncAction();
2025 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2026 +        f.completeExceptionally(new CFException());
2027 +        checkCompletedWithWrappedCFException(g);
2028 +    }
2029 +
2030 +    /**
2031 +     * thenAcceptAsync result completes exceptionally if action does
2032 +     */
2033 +    public void testThenAcceptAsync3E() {
2034 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2035 +        FailingConsumer r = new FailingConsumer();
2036 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2037 +        f.complete(null);
2038 +        checkCompletedWithWrappedCFException(g);
2039 +    }
2040 +
2041 +    /**
2042 +     * thenAcceptAsync result completes exceptionally if source cancelled
2043 +     */
2044 +    public void testThenAcceptAsync4E() {
2045 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2046 +        IncAction r = new IncAction();
2047 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2048 +        assertTrue(f.cancel(true));
2049 +        checkCompletedWithWrappedCancellationException(g);
2050 +    }
2051 +
2052 +    /**
2053 +     * thenCombineAsync result completes normally after normal
2054 +     * completion of sources
2055 +     */
2056 +    public void testThenCombineAsyncE() {
2057 +        CompletableFuture<Integer> f, g, h;
2058 +        ThreadExecutor e = new ThreadExecutor();
2059 +        int count = 0;
2060 +
2061 +        f = new CompletableFuture<Integer>();
2062 +        g = new CompletableFuture<Integer>();
2063 +        h = f.thenCombineAsync(g, subtract, e);
2064 +        f.complete(3);
2065 +        checkIncomplete(h);
2066 +        g.complete(1);
2067 +        checkCompletedNormally(h, 2);
2068 +        assertEquals(++count, e.count.get());
2069 +
2070 +        f = new CompletableFuture<Integer>();
2071 +        g = new CompletableFuture<Integer>();
2072 +        h = f.thenCombineAsync(g, subtract, e);
2073 +        g.complete(1);
2074 +        checkIncomplete(h);
2075 +        f.complete(3);
2076 +        checkCompletedNormally(h, 2);
2077 +        assertEquals(++count, e.count.get());
2078 +
2079 +        f = new CompletableFuture<Integer>();
2080 +        g = new CompletableFuture<Integer>();
2081 +        g.complete(1);
2082 +        f.complete(3);
2083 +        h = f.thenCombineAsync(g, subtract, e);
2084 +        checkCompletedNormally(h, 2);
2085 +        assertEquals(++count, e.count.get());
2086 +    }
2087 +
2088 +    /**
2089 +     * thenCombineAsync result completes exceptionally after exceptional
2090 +     * completion of either source
2091 +     */
2092 +    public void testThenCombineAsync2E() {
2093 +        CompletableFuture<Integer> f, g, h;
2094 +        ThreadExecutor e = new ThreadExecutor();
2095 +        int count = 0;
2096 +
2097 +        f = new CompletableFuture<Integer>();
2098 +        g = new CompletableFuture<Integer>();
2099 +        h = f.thenCombineAsync(g, subtract, e);
2100 +        f.completeExceptionally(new CFException());
2101 +        checkIncomplete(h);
2102 +        g.complete(1);
2103 +        checkCompletedWithWrappedCFException(h);
2104 +
2105 +        f = new CompletableFuture<Integer>();
2106 +        g = new CompletableFuture<Integer>();
2107 +        h = f.thenCombineAsync(g, subtract, e);
2108 +        g.completeExceptionally(new CFException());
2109 +        checkIncomplete(h);
2110 +        f.complete(3);
2111 +        checkCompletedWithWrappedCFException(h);
2112 +
2113 +        f = new CompletableFuture<Integer>();
2114 +        g = new CompletableFuture<Integer>();
2115 +        g.completeExceptionally(new CFException());
2116 +        h = f.thenCombineAsync(g, subtract, e);
2117 +        checkIncomplete(h);
2118 +        f.complete(3);
2119 +        checkCompletedWithWrappedCFException(h);
2120 +
2121 +        assertEquals(0, e.count.get());
2122 +    }
2123 +
2124 +    /**
2125 +     * thenCombineAsync result completes exceptionally if action does
2126 +     */
2127 +    public void testThenCombineAsync3E() {
2128 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2129 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2130 +        FailingBiFunction r = new FailingBiFunction();
2131 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r, new ThreadExecutor());
2132 +        f.complete(one);
2133 +        checkIncomplete(g);
2134 +        assertFalse(r.ran);
2135 +        f2.complete(two);
2136 +        checkCompletedWithWrappedCFException(g);
2137 +        assertTrue(r.ran);
2138 +    }
2139 +
2140 +    /**
2141 +     * thenCombineAsync result completes exceptionally if either source cancelled
2142 +     */
2143 +    public void testThenCombineAsync4E() {
2144 +        CompletableFuture<Integer> f, g, h;
2145 +        ThreadExecutor e = new ThreadExecutor();
2146 +
2147 +        f = new CompletableFuture<Integer>();
2148 +        g = new CompletableFuture<Integer>();
2149 +        h = f.thenCombineAsync(g, subtract, e);
2150 +        assertTrue(f.cancel(true));
2151 +        checkIncomplete(h);
2152 +        g.complete(1);
2153 +        checkCompletedWithWrappedCancellationException(h);
2154 +
2155 +        f = new CompletableFuture<Integer>();
2156 +        g = new CompletableFuture<Integer>();
2157 +        h = f.thenCombineAsync(g, subtract, e);
2158 +        assertTrue(g.cancel(true));
2159 +        checkIncomplete(h);
2160 +        f.complete(3);
2161 +        checkCompletedWithWrappedCancellationException(h);
2162 +
2163 +        f = new CompletableFuture<Integer>();
2164 +        g = new CompletableFuture<Integer>();
2165 +        assertTrue(g.cancel(true));
2166 +        h = f.thenCombineAsync(g, subtract, e);
2167 +        checkIncomplete(h);
2168 +        f.complete(3);
2169 +        checkCompletedWithWrappedCancellationException(h);
2170 +
2171 +        f = new CompletableFuture<Integer>();
2172 +        g = new CompletableFuture<Integer>();
2173 +        assertTrue(f.cancel(true));
2174 +        assertTrue(g.cancel(true));
2175 +        h = f.thenCombineAsync(g, subtract, e);
2176 +        checkCompletedWithWrappedCancellationException(h);
2177 +
2178 +        assertEquals(0, e.count.get());
2179 +    }
2180 +
2181 +    /**
2182 +     * thenAcceptBothAsync result completes normally after normal
2183 +     * completion of sources
2184 +     */
2185 +    public void testThenAcceptBothAsyncE() {
2186 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2187 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2188 +        AddAction r = new AddAction();
2189 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
2190 +        f.complete(one);
2191 +        checkIncomplete(g);
2192 +        f2.complete(two);
2193 +        checkCompletedNormally(g, null);
2194 +        assertEquals(r.value, 3);
2195 +    }
2196 +
2197 +    /**
2198 +     * thenAcceptBothAsync result completes exceptionally after exceptional
2199 +     * completion of source
2200 +     */
2201 +    public void testThenAcceptBothAsync2E() {
2202 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2203 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2204 +        AddAction r = new AddAction();
2205 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
2206 +        f.completeExceptionally(new CFException());
2207 +        f2.complete(two);
2208 +        checkCompletedWithWrappedCFException(g);
2209 +
2210 +        r = new AddAction();
2211 +        f = new CompletableFuture<Integer>();
2212 +        f2 = new CompletableFuture<Integer>();
2213 +        g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
2214 +        f.complete(one);
2215 +        f2.completeExceptionally(new CFException());
2216 +        checkCompletedWithWrappedCFException(g);
2217 +    }
2218 +
2219 +    /**
2220 +     * thenAcceptBothAsync result completes exceptionally if action does
2221 +     */
2222 +    public void testThenAcceptBothAsync3E() {
2223 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2224 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2225 +        FailingBiConsumer r = new FailingBiConsumer();
2226 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
2227 +        f.complete(one);
2228 +        checkIncomplete(g);
2229 +        f2.complete(two);
2230 +        checkCompletedWithWrappedCFException(g);
2231 +    }
2232 +
2233 +    /**
2234 +     * thenAcceptBothAsync result completes exceptionally if either source cancelled
2235 +     */
2236 +    public void testThenAcceptBothAsync4E() {
2237 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2238 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2239 +        AddAction r = new AddAction();
2240 +        CompletableFuture<Void> g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
2241 +        assertTrue(f.cancel(true));
2242 +        f2.complete(two);
2243 +        checkCompletedWithWrappedCancellationException(g);
2244 +
2245 +        r = new AddAction();
2246 +        f = new CompletableFuture<Integer>();
2247 +        f2 = new CompletableFuture<Integer>();
2248 +        g = f.thenAcceptBothAsync(f2, r, new ThreadExecutor());
2249 +        f.complete(one);
2250 +        assertTrue(f2.cancel(true));
2251 +        checkCompletedWithWrappedCancellationException(g);
2252 +    }
2253 +
2254 +    /**
2255 +     * runAfterBothAsync result completes normally after normal
2256 +     * completion of sources
2257 +     */
2258 +    public void testRunAfterBothAsyncE() {
2259 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2260 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2261 +        Noop r = new Noop();
2262 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2263 +        f.complete(one);
2264 +        checkIncomplete(g);
2265 +        f2.complete(two);
2266 +        checkCompletedNormally(g, null);
2267 +        assertTrue(r.ran);
2268 +    }
2269 +
2270 +    /**
2271 +     * runAfterBothAsync result completes exceptionally after exceptional
2272 +     * completion of source
2273 +     */
2274 +    public void testRunAfterBothAsync2E() {
2275 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2276 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2277 +        Noop r = new Noop();
2278 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2279 +        f.completeExceptionally(new CFException());
2280 +        f2.complete(two);
2281 +        checkCompletedWithWrappedCFException(g);
2282 +
2283 +        r = new Noop();
2284 +        f = new CompletableFuture<Integer>();
2285 +        f2 = new CompletableFuture<Integer>();
2286 +        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2287 +        f.complete(one);
2288 +        f2.completeExceptionally(new CFException());
2289 +        checkCompletedWithWrappedCFException(g);
2290 +    }
2291 +
2292 +    /**
2293 +     * runAfterBothAsync result completes exceptionally if action does
2294 +     */
2295 +    public void testRunAfterBothAsync3E() {
2296 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2297 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2298 +        FailingNoop r = new FailingNoop();
2299 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2300 +        f.complete(one);
2301 +        checkIncomplete(g);
2302 +        f2.complete(two);
2303 +        checkCompletedWithWrappedCFException(g);
2304 +    }
2305 +
2306 +    /**
2307 +     * runAfterBothAsync result completes exceptionally if either source cancelled
2308 +     */
2309 +    public void testRunAfterBothAsync4E() {
2310 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2311 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2312 +        Noop r = new Noop();
2313 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2314 +        assertTrue(f.cancel(true));
2315 +        f2.complete(two);
2316 +        checkCompletedWithWrappedCancellationException(g);
2317 +
2318 +        r = new Noop();
2319 +        f = new CompletableFuture<Integer>();
2320 +        f2 = new CompletableFuture<Integer>();
2321 +        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2322 +        f.complete(one);
2323 +        assertTrue(f2.cancel(true));
2324 +        checkCompletedWithWrappedCancellationException(g);
2325 +    }
2326 +
2327 +    /**
2328 +     * applyToEitherAsync result completes normally after normal
2329 +     * completion of sources
2330 +     */
2331 +    public void testApplyToEitherAsyncE() {
2332 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2333 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2334 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2335 +        f.complete(one);
2336 +        checkCompletedNormally(g, two);
2337 +
2338 +        f = new CompletableFuture<Integer>();
2339 +        f.complete(one);
2340 +        f2 = new CompletableFuture<Integer>();
2341 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2342 +        checkCompletedNormally(g, two);
2343 +    }
2344 +
2345 +    /**
2346 +     * applyToEitherAsync result completes exceptionally after exceptional
2347 +     * completion of source
2348 +     */
2349 +    public void testApplyToEitherAsync2E() {
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 +        f.completeExceptionally(new CFException());
2354 +        checkCompletedWithWrappedCFException(g);
2355 +
2356 +        f = new CompletableFuture<Integer>();
2357 +        f2 = new CompletableFuture<Integer>();
2358 +        f2.completeExceptionally(new CFException());
2359 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2360 +        f.complete(one);
2361 +        checkCompletedWithWrappedCFException(g);
2362 +    }
2363 +
2364 +    /**
2365 +     * applyToEitherAsync result completes exceptionally if action does
2366 +     */
2367 +    public void testApplyToEitherAsync3E() {
2368 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2369 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2370 +        FailingFunction r = new FailingFunction();
2371 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r, new ThreadExecutor());
2372 +        f.complete(one);
2373 +        checkCompletedWithWrappedCFException(g);
2374 +    }
2375 +
2376 +    /**
2377 +     * applyToEitherAsync result completes exceptionally if either source cancelled
2378 +     */
2379 +    public void testApplyToEitherAsync4E() {
2380 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2381 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2382 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2383 +        assertTrue(f.cancel(true));
2384 +        checkCompletedWithWrappedCancellationException(g);
2385 +
2386 +        f = new CompletableFuture<Integer>();
2387 +        f2 = new CompletableFuture<Integer>();
2388 +        assertTrue(f2.cancel(true));
2389 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2390 +        checkCompletedWithWrappedCancellationException(g);
2391 +    }
2392 +
2393 +    /**
2394 +     * acceptEitherAsync result completes normally after normal
2395 +     * completion of sources
2396 +     */
2397 +    public void testAcceptEitherAsyncE() {
2398 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2399 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2400 +        IncAction r = new IncAction();
2401 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2402 +        f.complete(one);
2403 +        checkCompletedNormally(g, null);
2404 +        assertEquals(r.value, 2);
2405 +
2406 +        r = new IncAction();
2407 +        f = new CompletableFuture<Integer>();
2408 +        f.complete(one);
2409 +        f2 = new CompletableFuture<Integer>();
2410 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2411 +        checkCompletedNormally(g, null);
2412 +        assertEquals(r.value, 2);
2413 +    }
2414 +
2415 +    /**
2416 +     * acceptEitherAsync result completes exceptionally after exceptional
2417 +     * completion of source
2418 +     */
2419 +    public void testAcceptEitherAsync2E() {
2420 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2421 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2422 +        IncAction r = new IncAction();
2423 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2424 +        f.completeExceptionally(new CFException());
2425 +        checkCompletedWithWrappedCFException(g);
2426 +
2427 +        r = new IncAction();
2428 +        f = new CompletableFuture<Integer>();
2429 +        f2 = new CompletableFuture<Integer>();
2430 +        f2.completeExceptionally(new CFException());
2431 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2432 +        f.complete(one);
2433 +        checkCompletedWithWrappedCFException(g);
2434 +    }
2435 +
2436 +    /**
2437 +     * acceptEitherAsync result completes exceptionally if action does
2438 +     */
2439 +    public void testAcceptEitherAsync3E() {
2440 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2441 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2442 +        FailingConsumer r = new FailingConsumer();
2443 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2444 +        f.complete(one);
2445 +        checkCompletedWithWrappedCFException(g);
2446 +    }
2447 +
2448 +    /**
2449 +     * acceptEitherAsync result completes exceptionally if either
2450 +     * source cancelled
2451 +     */
2452 +    public void testAcceptEitherAsync4E() {
2453 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2454 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2455 +        IncAction r = new IncAction();
2456 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2457 +        assertTrue(f.cancel(true));
2458 +        checkCompletedWithWrappedCancellationException(g);
2459 +
2460 +        r = new IncAction();
2461 +        f = new CompletableFuture<Integer>();
2462 +        f2 = new CompletableFuture<Integer>();
2463 +        assertTrue(f2.cancel(true));
2464 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2465 +        checkCompletedWithWrappedCancellationException(g);
2466 +    }
2467 +
2468 +    /**
2469 +     * runAfterEitherAsync result completes normally after normal
2470 +     * completion of sources
2471 +     */
2472 +    public void testRunAfterEitherAsyncE() {
2473 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2474 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2475 +        Noop r = new Noop();
2476 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2477 +        f.complete(one);
2478 +        checkCompletedNormally(g, null);
2479 +        assertTrue(r.ran);
2480 +
2481 +        r = new Noop();
2482 +        f = new CompletableFuture<Integer>();
2483 +        f.complete(one);
2484 +        f2 = new CompletableFuture<Integer>();
2485 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2486 +        checkCompletedNormally(g, null);
2487 +        assertTrue(r.ran);
2488 +    }
2489 +
2490 +    /**
2491 +     * runAfterEitherAsync result completes exceptionally after exceptional
2492 +     * completion of source
2493 +     */
2494 +    public void testRunAfterEitherAsync2E() {
2495 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2496 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2497 +        Noop r = new Noop();
2498 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2499 +        f.completeExceptionally(new CFException());
2500 +        checkCompletedWithWrappedCFException(g);
2501 +
2502 +        r = new Noop();
2503 +        f = new CompletableFuture<Integer>();
2504 +        f2 = new CompletableFuture<Integer>();
2505 +        f2.completeExceptionally(new CFException());
2506 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2507 +        f.complete(one);
2508 +        checkCompletedWithWrappedCFException(g);
2509 +    }
2510 +
2511 +    /**
2512 +     * runAfterEitherAsync result completes exceptionally if action does
2513 +     */
2514 +    public void testRunAfterEitherAsync3E() {
2515 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2516 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2517 +        FailingNoop r = new FailingNoop();
2518 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2519 +        f.complete(one);
2520 +        checkCompletedWithWrappedCFException(g);
2521 +    }
2522 +
2523 +    /**
2524 +     * runAfterEitherAsync result completes exceptionally if either
2525 +     * source cancelled
2526 +     */
2527 +    public void testRunAfterEitherAsync4E() {
2528 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2529 +        CompletableFuture<Integer> f2 = new CompletableFuture<Integer>();
2530 +        Noop r = new Noop();
2531 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2532 +        assertTrue(f.cancel(true));
2533 +        checkCompletedWithWrappedCancellationException(g);
2534 +
2535 +        r = new Noop();
2536 +        f = new CompletableFuture<Integer>();
2537 +        f2 = new CompletableFuture<Integer>();
2538 +        assertTrue(f2.cancel(true));
2539 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2540 +        checkCompletedWithWrappedCancellationException(g);
2541 +    }
2542 +
2543 +    /**
2544 +     * thenComposeAsync result completes normally after normal
2545 +     * completion of source
2546 +     */
2547 +    public void testThenComposeAsyncE() {
2548 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2549 +        CompletableFutureInc r = new CompletableFutureInc();
2550 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2551 +        f.complete(one);
2552 +        checkCompletedNormally(g, two);
2553 +    }
2554 +
2555 +    /**
2556 +     * thenComposeAsync result completes exceptionally after
2557 +     * exceptional completion of source
2558 +     */
2559 +    public void testThenComposeAsync2E() {
2560 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2561 +        CompletableFutureInc r = new CompletableFutureInc();
2562 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2563 +        f.completeExceptionally(new CFException());
2564 +        checkCompletedWithWrappedCFException(g);
2565 +    }
2566 +
2567 +    /**
2568 +     * thenComposeAsync result completes exceptionally if action does
2569 +     */
2570 +    public void testThenComposeAsync3E() {
2571 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2572 +        FailingCompletableFutureFunction r = new FailingCompletableFutureFunction();
2573 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2574 +        f.complete(one);
2575 +        checkCompletedWithWrappedCFException(g);
2576 +    }
2577 +
2578 +    /**
2579 +     * thenComposeAsync result completes exceptionally if source cancelled
2580 +     */
2581 +    public void testThenComposeAsync4E() {
2582 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2583 +        CompletableFutureInc r = new CompletableFutureInc();
2584 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2585 +        assertTrue(f.cancel(true));
2586 +        checkCompletedWithWrappedCancellationException(g);
2587 +    }
2588 +
2589 +    // other static methods
2590 +
2591 +    /**
2592 +     * allOf(no component futures) returns a future completed normally
2593 +     * with the value null
2594 +     */
2595 +    public void testAllOf_empty() throws Exception {
2596 +        CompletableFuture<?> f = CompletableFuture.allOf();
2597 +        checkCompletedNormally(f, null);
2598 +    }
2599 +
2600 +    /**
2601 +     * allOf returns a future completed when all components complete
2602 +     */
2603 +    public void testAllOf() throws Exception {
2604 +        for (int k = 1; k < 20; ++k) {
2605 +            CompletableFuture[] fs = new CompletableFuture[k];
2606 +            for (int i = 0; i < k; ++i)
2607 +                fs[i] = new CompletableFuture<Integer>();
2608 +            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
2609 +            for (int i = 0; i < k; ++i) {
2610 +                checkIncomplete(f);
2611 +                fs[i].complete(one);
2612 +            }
2613 +            checkCompletedNormally(f, null);
2614 +        }
2615 +    }
2616 +
2617 +    /**
2618 +     * anyOf(no component futures) returns an incomplete future
2619 +     */
2620 +    public void testAnyOf_empty() throws Exception {
2621 +        CompletableFuture<?> f = CompletableFuture.anyOf();
2622 +        checkIncomplete(f);
2623 +    }
2624 +
2625 +    /**
2626 +     * anyOf returns a future completed when any components complete
2627 +     */
2628 +    public void testAnyOf() throws Exception {
2629 +        for (int k = 1; k < 20; ++k) {
2630 +            CompletableFuture[] fs = new CompletableFuture[k];
2631 +            for (int i = 0; i < k; ++i)
2632 +                fs[i] = new CompletableFuture<Integer>();
2633 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
2634 +            checkIncomplete(f);
2635 +            for (int i = 0; i < k; ++i) {
2636 +                fs[i].complete(one);
2637 +                checkCompletedNormally(f, one);
2638 +            }
2639 +        }
2640 +    }
2641 +
2642 +    /**
2643 +     * Completion methods throw NullPointerException with null arguments
2644 +     */
2645 +    public void testNPE() {
2646 +        CompletableFuture<Integer> f = new CompletableFuture<Integer>();
2647 +        CompletableFuture<Integer> g = new CompletableFuture<Integer>();
2648 +        CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
2649 +        CompletableFuture<?> h;
2650 +        ThreadExecutor exec = new ThreadExecutor();
2651 +
2652 +        Runnable[] throwingActions = {
2653 +            () -> { CompletableFuture.supplyAsync(null); },
2654 +            () -> { CompletableFuture.supplyAsync(null, exec); },
2655 +            () -> { CompletableFuture.supplyAsync(supplyOne, null); },
2656 +
2657 +            () -> { CompletableFuture.runAsync(null); },
2658 +            () -> { CompletableFuture.runAsync(null, exec); },
2659 +            () -> { CompletableFuture.runAsync(() -> {}, null); },
2660 +
2661 +            () -> { f.completeExceptionally(null); },
2662 +
2663 +            () -> { f.thenApply(null); },
2664 +            () -> { f.thenApplyAsync(null); },
2665 +            () -> { f.thenApplyAsync((x) -> x, null); },
2666 +            () -> { f.thenApplyAsync(null, exec); },
2667 +
2668 +            () -> { f.thenAccept(null); },
2669 +            () -> { f.thenAcceptAsync(null); },
2670 +            () -> { f.thenAcceptAsync((x) -> { ; }, null); },
2671 +            () -> { f.thenAcceptAsync(null, exec); },
2672 +
2673 +            () -> { f.thenRun(null); },
2674 +            () -> { f.thenRunAsync(null); },
2675 +            () -> { f.thenRunAsync(() -> { ; }, null); },
2676 +            () -> { f.thenRunAsync(null, exec); },
2677 +
2678 +            () -> { f.thenCombine(g, null); },
2679 +            () -> { f.thenCombineAsync(g, null); },
2680 +            () -> { f.thenCombineAsync(g, null, exec); },
2681 +            () -> { f.thenCombine(nullFuture, (x, y) -> x); },
2682 +            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x); },
2683 +            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x, exec); },
2684 +            () -> { f.thenCombineAsync(g, (x, y) -> x, null); },
2685 +
2686 +            () -> { f.thenAcceptBoth(g, null); },
2687 +            () -> { f.thenAcceptBothAsync(g, null); },
2688 +            () -> { f.thenAcceptBothAsync(g, null, exec); },
2689 +            () -> { f.thenAcceptBoth(nullFuture, (x, y) -> {}); },
2690 +            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}); },
2691 +            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec); },
2692 +            () -> { f.thenAcceptBothAsync(g, (x, y) -> {}, null); },
2693 +
2694 +            () -> { f.runAfterBoth(g, null); },
2695 +            () -> { f.runAfterBothAsync(g, null); },
2696 +            () -> { f.runAfterBothAsync(g, null, exec); },
2697 +            () -> { f.runAfterBoth(nullFuture, () -> {}); },
2698 +            () -> { f.runAfterBothAsync(nullFuture, () -> {}); },
2699 +            () -> { f.runAfterBothAsync(nullFuture, () -> {}, exec); },
2700 +            () -> { f.runAfterBothAsync(g, () -> {}, null); },
2701 +
2702 +            () -> { f.applyToEither(g, null); },
2703 +            () -> { f.applyToEitherAsync(g, null); },
2704 +            () -> { f.applyToEitherAsync(g, null, exec); },
2705 +            () -> { f.applyToEither(nullFuture, (x) -> x); },
2706 +            () -> { f.applyToEitherAsync(nullFuture, (x) -> x); },
2707 +            () -> { f.applyToEitherAsync(nullFuture, (x) -> x, exec); },
2708 +            () -> { f.applyToEitherAsync(g, (x) -> x, null); },
2709 +
2710 +            () -> { f.acceptEither(g, null); },
2711 +            () -> { f.acceptEitherAsync(g, null); },
2712 +            () -> { f.acceptEitherAsync(g, null, exec); },
2713 +            () -> { f.acceptEither(nullFuture, (x) -> {}); },
2714 +            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}); },
2715 +            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}, exec); },
2716 +            () -> { f.acceptEitherAsync(g, (x) -> {}, null); },
2717 +
2718 +            () -> { f.runAfterEither(g, null); },
2719 +            () -> { f.runAfterEitherAsync(g, null); },
2720 +            () -> { f.runAfterEitherAsync(g, null, exec); },
2721 +            () -> { f.runAfterEither(nullFuture, () -> {}); },
2722 +            () -> { f.runAfterEitherAsync(nullFuture, () -> {}); },
2723 +            () -> { f.runAfterEitherAsync(nullFuture, () -> {}, exec); },
2724 +            () -> { f.runAfterEitherAsync(g, () -> {}, null); },
2725 +
2726 +            () -> { f.thenCompose(null); },
2727 +            () -> { f.thenComposeAsync(null); },
2728 +            () -> { f.thenComposeAsync(new CompletableFutureInc(), null); },
2729 +            () -> { f.thenComposeAsync(null, exec); },
2730 +
2731 +            () -> { f.exceptionally(null); },
2732 +
2733 +            () -> { f.handle(null); },
2734 +
2735 +            () -> { CompletableFuture.allOf((CompletableFuture<?>)null); },
2736 +            () -> { CompletableFuture.allOf((CompletableFuture<?>[])null); },
2737 +            () -> { CompletableFuture.allOf(f, null); },
2738 +            () -> { CompletableFuture.allOf(null, f); },
2739 +
2740 +            () -> { CompletableFuture.anyOf((CompletableFuture<?>)null); },
2741 +            () -> { CompletableFuture.anyOf((CompletableFuture<?>[])null); },
2742 +            () -> { CompletableFuture.anyOf(f, null); },
2743 +            () -> { CompletableFuture.anyOf(null, f); },
2744 +        };
2745 +
2746 +        assertThrows(NullPointerException.class, throwingActions);
2747 +        assertEquals(0, exec.count.get());
2748 +    }
2749 +
2750   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines