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.4 by jsr166, Sun Feb 10 21:18:25 2013 UTC vs.
Revision 1.19 by jsr166, Sun Apr 7 15:04:14 2013 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines