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

Comparing jsr166/src/test/tck/CompletableFutureTest.java (file contents):
Revision 1.2 by jsr166, Wed Feb 6 20:29:55 2013 UTC vs.
Revision 1.26 by dl, Fri Jul 5 15:47:52 2013 UTC

# Line 1 | Line 1
1   /*
2 < * Written by Doug Lea with assistance from members of JCP JSR-166
3 < * Expert Group and released to the public domain, as explained at
2 > * Written by Doug Lea and Martin Buchholz with assistance from
3 > * members of JCP JSR-166 Expert Group and released to the public
4 > * domain, as explained at
5   * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
6   */
7  
8   import junit.framework.*;
9   import java.util.concurrent.Callable;
10 + import java.util.concurrent.Executor;
11 + import java.util.concurrent.ExecutorService;
12 + import java.util.concurrent.Executors;
13   import java.util.concurrent.CancellationException;
14   import java.util.concurrent.CountDownLatch;
15   import java.util.concurrent.ExecutionException;
16   import java.util.concurrent.Future;
17   import java.util.concurrent.CompletableFuture;
18 + import java.util.concurrent.CompletionException;
19   import java.util.concurrent.TimeoutException;
20   import java.util.concurrent.atomic.AtomicInteger;
21   import static java.util.concurrent.TimeUnit.MILLISECONDS;
22   import static java.util.concurrent.TimeUnit.SECONDS;
23   import java.util.*;
24 + import java.util.function.Supplier;
25 + import java.util.function.Consumer;
26 + import java.util.function.BiConsumer;
27 + import java.util.function.Function;
28 + import java.util.function.BiFunction;
29  
30   public class CompletableFutureTest extends JSR166TestCase {
31  
# Line 28 | Line 36 | public class CompletableFutureTest exten
36          return new TestSuite(CompletableFutureTest.class);
37      }
38  
39 +    static class CFException extends RuntimeException {}
40 +
41 +    void checkIncomplete(CompletableFuture<?> f) {
42 +        assertFalse(f.isDone());
43 +        assertFalse(f.isCancelled());
44 +        assertTrue(f.toString().contains("[Not completed]"));
45 +        try {
46 +            assertNull(f.getNow(null));
47 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
48 +        try {
49 +            f.get(0L, SECONDS);
50 +            shouldThrow();
51 +        }
52 +        catch (TimeoutException success) {}
53 +        catch (Throwable fail) { threadUnexpectedException(fail); }
54 +    }
55 +
56 +    <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
57 +        try {
58 +            assertEquals(value, f.get(LONG_DELAY_MS, MILLISECONDS));
59 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
60 +        try {
61 +            assertEquals(value, f.join());
62 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
63 +        try {
64 +            assertEquals(value, f.getNow(null));
65 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
66 +        try {
67 +            assertEquals(value, f.get());
68 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
69 +        assertTrue(f.isDone());
70 +        assertFalse(f.isCancelled());
71 +        assertFalse(f.isCompletedExceptionally());
72 +        assertTrue(f.toString().contains("[Completed normally]"));
73 +    }
74 +
75 +    void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
76 +        try {
77 +            f.get(LONG_DELAY_MS, MILLISECONDS);
78 +            shouldThrow();
79 +        } catch (ExecutionException success) {
80 +            assertTrue(success.getCause() instanceof CFException);
81 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
82 +        try {
83 +            f.join();
84 +            shouldThrow();
85 +        } catch (CompletionException success) {
86 +            assertTrue(success.getCause() instanceof CFException);
87 +        }
88 +        try {
89 +            f.getNow(null);
90 +            shouldThrow();
91 +        } catch (CompletionException success) {
92 +            assertTrue(success.getCause() instanceof CFException);
93 +        }
94 +        try {
95 +            f.get();
96 +            shouldThrow();
97 +        } catch (ExecutionException success) {
98 +            assertTrue(success.getCause() instanceof CFException);
99 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
100 +        assertTrue(f.isDone());
101 +        assertFalse(f.isCancelled());
102 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
103 +    }
104 +
105 +    void checkCancelled(CompletableFuture<?> f) {
106 +        try {
107 +            f.get(LONG_DELAY_MS, MILLISECONDS);
108 +            shouldThrow();
109 +        } catch (CancellationException success) {
110 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
111 +        try {
112 +            f.join();
113 +            shouldThrow();
114 +        } catch (CancellationException success) {}
115 +        try {
116 +            f.getNow(null);
117 +            shouldThrow();
118 +        } catch (CancellationException success) {}
119 +        try {
120 +            f.get();
121 +            shouldThrow();
122 +        } catch (CancellationException success) {
123 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
124 +        assertTrue(f.isDone());
125 +        assertTrue(f.isCompletedExceptionally());
126 +        assertTrue(f.isCancelled());
127 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
128 +    }
129 +
130 +    void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
131 +        try {
132 +            f.get(LONG_DELAY_MS, MILLISECONDS);
133 +            shouldThrow();
134 +        } catch (ExecutionException success) {
135 +            assertTrue(success.getCause() instanceof CancellationException);
136 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
137 +        try {
138 +            f.join();
139 +            shouldThrow();
140 +        } catch (CompletionException success) {
141 +            assertTrue(success.getCause() instanceof CancellationException);
142 +        }
143 +        try {
144 +            f.getNow(null);
145 +            shouldThrow();
146 +        } catch (CompletionException success) {
147 +            assertTrue(success.getCause() instanceof CancellationException);
148 +        }
149 +        try {
150 +            f.get();
151 +            shouldThrow();
152 +        } catch (ExecutionException success) {
153 +            assertTrue(success.getCause() instanceof CancellationException);
154 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
155 +        assertTrue(f.isDone());
156 +        assertFalse(f.isCancelled());
157 +        assertTrue(f.isCompletedExceptionally());
158 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
159 +    }
160 +
161 +    /**
162 +     * A newly constructed CompletableFuture is incomplete, as indicated
163 +     * by methods isDone, isCancelled, and getNow
164 +     */
165 +    public void testConstructor() {
166 +        CompletableFuture<Integer> f = new CompletableFuture<>();
167 +        checkIncomplete(f);
168 +    }
169 +
170 +    /**
171 +     * complete completes normally, as indicated by methods isDone,
172 +     * isCancelled, join, get, and getNow
173 +     */
174 +    public void testComplete() {
175 +        CompletableFuture<Integer> f = new CompletableFuture<>();
176 +        checkIncomplete(f);
177 +        f.complete(one);
178 +        checkCompletedNormally(f, one);
179 +    }
180 +
181 +    /**
182 +     * completeExceptionally completes exceptionally, as indicated by
183 +     * methods isDone, isCancelled, join, get, and getNow
184 +     */
185 +    public void testCompleteExceptionally() {
186 +        CompletableFuture<Integer> f = new CompletableFuture<>();
187 +        checkIncomplete(f);
188 +        f.completeExceptionally(new CFException());
189 +        checkCompletedWithWrappedCFException(f);
190 +    }
191 +
192 +    /**
193 +     * cancel completes exceptionally and reports cancelled, as indicated by
194 +     * methods isDone, isCancelled, join, get, and getNow
195 +     */
196 +    public void testCancel() {
197 +        CompletableFuture<Integer> f = new CompletableFuture<>();
198 +        checkIncomplete(f);
199 +        assertTrue(f.cancel(true));
200 +        checkCancelled(f);
201 +    }
202 +
203 +    /**
204 +     * obtrudeValue forces completion with given value
205 +     */
206 +    public void testObtrudeValue() {
207 +        CompletableFuture<Integer> f = new CompletableFuture<>();
208 +        checkIncomplete(f);
209 +        f.complete(one);
210 +        checkCompletedNormally(f, one);
211 +        f.obtrudeValue(three);
212 +        checkCompletedNormally(f, three);
213 +        f.obtrudeValue(two);
214 +        checkCompletedNormally(f, two);
215 +        f = new CompletableFuture<>();
216 +        f.obtrudeValue(three);
217 +        checkCompletedNormally(f, three);
218 +        f = new CompletableFuture<>();
219 +        f.completeExceptionally(new CFException());
220 +        f.obtrudeValue(four);
221 +        checkCompletedNormally(f, four);
222 +    }
223 +
224 +    /**
225 +     * obtrudeException forces completion with given exception
226 +     */
227 +    public void testObtrudeException() {
228 +        CompletableFuture<Integer> f = new CompletableFuture<>();
229 +        checkIncomplete(f);
230 +        f.complete(one);
231 +        checkCompletedNormally(f, one);
232 +        f.obtrudeException(new CFException());
233 +        checkCompletedWithWrappedCFException(f);
234 +        f = new CompletableFuture<>();
235 +        f.obtrudeException(new CFException());
236 +        checkCompletedWithWrappedCFException(f);
237 +        f = new CompletableFuture<>();
238 +        f.completeExceptionally(new CFException());
239 +        f.obtrudeValue(four);
240 +        checkCompletedNormally(f, four);
241 +        f.obtrudeException(new CFException());
242 +        checkCompletedWithWrappedCFException(f);
243 +    }
244 +
245 +    /**
246 +     * getNumberOfDependents returns number of dependent tasks
247 +     */
248 +    public void testGetNumberOfDependents() {
249 +        CompletableFuture<Integer> f = new CompletableFuture<>();
250 +        assertEquals(f.getNumberOfDependents(), 0);
251 +        CompletableFuture g = f.thenRun(new Noop());
252 +        assertEquals(f.getNumberOfDependents(), 1);
253 +        assertEquals(g.getNumberOfDependents(), 0);
254 +        CompletableFuture h = f.thenRun(new Noop());
255 +        assertEquals(f.getNumberOfDependents(), 2);
256 +        f.complete(1);
257 +        checkCompletedNormally(g, null);
258 +        assertEquals(f.getNumberOfDependents(), 0);
259 +        assertEquals(g.getNumberOfDependents(), 0);
260 +    }
261 +
262 +
263 +    /**
264 +     * toString indicates current completion state
265 +     */
266      public void testToString() {
267          CompletableFuture<String> f;
268  
# Line 41 | Line 276 | public class CompletableFutureTest exten
276          f.completeExceptionally(new IndexOutOfBoundsException());
277          assertTrue(f.toString().contains("[Completed exceptionally]"));
278      }
279 +
280 +    /**
281 +     * completedFuture returns a completed CompletableFuture with given value
282 +     */
283 +    public void testCompletedFuture() {
284 +        CompletableFuture<String> f = CompletableFuture.completedFuture("test");
285 +        checkCompletedNormally(f, "test");
286 +    }
287 +
288 +    // Choose non-commutative actions for better coverage
289 +
290 +    static final Supplier<Integer> supplyOne =
291 +        () -> Integer.valueOf(1);
292 +    static final Function<Integer, Integer> inc =
293 +        (Integer x) -> Integer.valueOf(x.intValue() + 1);
294 +    static final BiFunction<Integer, Integer, Integer> subtract =
295 +        (Integer x, Integer y) -> Integer.valueOf(x.intValue() - y.intValue());
296 +    static final class IncAction implements Consumer<Integer> {
297 +        int value;
298 +        public void accept(Integer x) { value = x.intValue() + 1; }
299 +    }
300 +    static final class SubtractAction implements BiConsumer<Integer, Integer> {
301 +        int value;
302 +        public void accept(Integer x, Integer y) {
303 +            value = x.intValue() - y.intValue();
304 +        }
305 +    }
306 +    static final class Noop implements Runnable {
307 +        boolean ran;
308 +        public void run() { ran = true; }
309 +    }
310 +
311 +    static final class FailingSupplier implements Supplier<Integer> {
312 +        boolean ran;
313 +        public Integer get() { ran = true; throw new CFException(); }
314 +    }
315 +    static final class FailingConsumer implements Consumer<Integer> {
316 +        boolean ran;
317 +        public void accept(Integer x) { ran = true; throw new CFException(); }
318 +    }
319 +    static final class FailingBiConsumer implements BiConsumer<Integer, Integer> {
320 +        boolean ran;
321 +        public void accept(Integer x, Integer y) { ran = true; throw new CFException(); }
322 +    }
323 +    static final class FailingFunction implements Function<Integer, Integer> {
324 +        boolean ran;
325 +        public Integer apply(Integer x) { ran = true; throw new CFException(); }
326 +    }
327 +    static final class FailingBiFunction implements BiFunction<Integer, Integer, Integer> {
328 +        boolean ran;
329 +        public Integer apply(Integer x, Integer y) { ran = true; throw new CFException(); }
330 +    }
331 +    static final class FailingNoop implements Runnable {
332 +        boolean ran;
333 +        public void run() { ran = true; throw new CFException(); }
334 +    }
335 +
336 +    static final class CompletableFutureInc
337 +        implements Function<Integer, CompletableFuture<Integer>> {
338 +        boolean ran;
339 +        public CompletableFuture<Integer> apply(Integer x) {
340 +            ran = true;
341 +            CompletableFuture<Integer> f = new CompletableFuture<>();
342 +            f.complete(Integer.valueOf(x.intValue() + 1));
343 +            return f;
344 +        }
345 +    }
346 +
347 +    static final class FailingCompletableFutureFunction
348 +        implements Function<Integer, CompletableFuture<Integer>> {
349 +        boolean ran;
350 +        public CompletableFuture<Integer> apply(Integer x) {
351 +            ran = true; throw new CFException();
352 +        }
353 +    }
354 +
355 +    // Used for explicit executor tests
356 +    static final class ThreadExecutor implements Executor {
357 +        AtomicInteger count = new AtomicInteger(0);
358 +
359 +        public void execute(Runnable r) {
360 +            count.getAndIncrement();
361 +            new Thread(r).start();
362 +        }
363 +    }
364 +
365 +    static final class ExceptionToInteger implements Function<Throwable, Integer> {
366 +        public Integer apply(Throwable x) { return Integer.valueOf(3); }
367 +    }
368 +
369 +    static final class IntegerHandler implements BiFunction<Integer, Throwable, Integer> {
370 +        boolean ran;
371 +        public Integer apply(Integer x, Throwable t) {
372 +            ran = true;
373 +            return (t == null) ? two : three;
374 +        }
375 +    }
376 +
377 +
378 +    /**
379 +     * exceptionally action completes with function value on source
380 +     * exception;  otherwise with source value
381 +     */
382 +    public void testExceptionally() {
383 +        CompletableFuture<Integer> f = new CompletableFuture<>();
384 +        ExceptionToInteger r = new ExceptionToInteger();
385 +        CompletableFuture<Integer> g = f.exceptionally(r);
386 +        f.completeExceptionally(new CFException());
387 +        checkCompletedNormally(g, three);
388 +
389 +        f = new CompletableFuture<>();
390 +        r = new ExceptionToInteger();
391 +        g = f.exceptionally(r);
392 +        f.complete(one);
393 +        checkCompletedNormally(g, one);
394 +    }
395 +
396 +    /**
397 +     * handle action completes normally with function value on either
398 +     * normal or exceptional completion of source
399 +     */
400 +    public void testHandle() {
401 +        CompletableFuture<Integer> f, g;
402 +        IntegerHandler r;
403 +
404 +        f = new CompletableFuture<>();
405 +        f.completeExceptionally(new CFException());
406 +        g = f.handle(r = new IntegerHandler());
407 +        assertTrue(r.ran);
408 +        checkCompletedNormally(g, three);
409 +
410 +        f = new CompletableFuture<>();
411 +        g = f.handle(r = new IntegerHandler());
412 +        assertFalse(r.ran);
413 +        f.completeExceptionally(new CFException());
414 +        checkCompletedNormally(g, three);
415 +        assertTrue(r.ran);
416 +
417 +        f = new CompletableFuture<>();
418 +        f.complete(one);
419 +        g = f.handle(r = new IntegerHandler());
420 +        assertTrue(r.ran);
421 +        checkCompletedNormally(g, two);
422 +
423 +        f = new CompletableFuture<>();
424 +        g = f.handle(r = new IntegerHandler());
425 +        assertFalse(r.ran);
426 +        f.complete(one);
427 +        assertTrue(r.ran);
428 +        checkCompletedNormally(g, two);
429 +    }
430 +
431 +    /**
432 +     * runAsync completes after running Runnable
433 +     */
434 +    public void testRunAsync() {
435 +        Noop r = new Noop();
436 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r);
437 +        assertNull(f.join());
438 +        assertTrue(r.ran);
439 +        checkCompletedNormally(f, null);
440 +    }
441 +
442 +    /**
443 +     * runAsync with executor completes after running Runnable
444 +     */
445 +    public void testRunAsync2() {
446 +        Noop r = new Noop();
447 +        ThreadExecutor exec = new ThreadExecutor();
448 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r, exec);
449 +        assertNull(f.join());
450 +        assertTrue(r.ran);
451 +        checkCompletedNormally(f, null);
452 +        assertEquals(1, exec.count.get());
453 +    }
454 +
455 +    /**
456 +     * failing runAsync completes exceptionally after running Runnable
457 +     */
458 +    public void testRunAsync3() {
459 +        FailingNoop r = new FailingNoop();
460 +        CompletableFuture<Void> f = CompletableFuture.runAsync(r);
461 +        checkCompletedWithWrappedCFException(f);
462 +        assertTrue(r.ran);
463 +    }
464 +
465 +    /**
466 +     * supplyAsync completes with result of supplier
467 +     */
468 +    public void testSupplyAsync() {
469 +        CompletableFuture<Integer> f;
470 +        f = CompletableFuture.supplyAsync(supplyOne);
471 +        assertEquals(f.join(), one);
472 +        checkCompletedNormally(f, one);
473 +    }
474 +
475 +    /**
476 +     * supplyAsync with executor completes with result of supplier
477 +     */
478 +    public void testSupplyAsync2() {
479 +        CompletableFuture<Integer> f;
480 +        f = CompletableFuture.supplyAsync(supplyOne, new ThreadExecutor());
481 +        assertEquals(f.join(), one);
482 +        checkCompletedNormally(f, one);
483 +    }
484 +
485 +    /**
486 +     * Failing supplyAsync completes exceptionally
487 +     */
488 +    public void testSupplyAsync3() {
489 +        FailingSupplier r = new FailingSupplier();
490 +        CompletableFuture<Integer> f = CompletableFuture.supplyAsync(r);
491 +        checkCompletedWithWrappedCFException(f);
492 +        assertTrue(r.ran);
493 +    }
494 +
495 +    // seq completion methods
496 +
497 +    /**
498 +     * thenRun result completes normally after normal completion of source
499 +     */
500 +    public void testThenRun() {
501 +        CompletableFuture<Integer> f;
502 +        CompletableFuture<Void> g;
503 +        Noop r;
504 +
505 +        f = new CompletableFuture<>();
506 +        g = f.thenRun(r = new Noop());
507 +        f.complete(null);
508 +        checkCompletedNormally(g, null);
509 +        assertTrue(r.ran);
510 +
511 +        f = new CompletableFuture<>();
512 +        f.complete(null);
513 +        g = f.thenRun(r = new Noop());
514 +        checkCompletedNormally(g, null);
515 +        assertTrue(r.ran);
516 +    }
517 +
518 +    /**
519 +     * thenRun result completes exceptionally after exceptional
520 +     * completion of source
521 +     */
522 +    public void testThenRun2() {
523 +        CompletableFuture<Integer> f;
524 +        CompletableFuture<Void> g;
525 +        Noop r;
526 +
527 +        f = new CompletableFuture<>();
528 +        g = f.thenRun(r = new Noop());
529 +        f.completeExceptionally(new CFException());
530 +        checkCompletedWithWrappedCFException(g);
531 +        assertFalse(r.ran);
532 +
533 +        f = new CompletableFuture<>();
534 +        f.completeExceptionally(new CFException());
535 +        g = f.thenRun(r = new Noop());
536 +        checkCompletedWithWrappedCFException(g);
537 +        assertFalse(r.ran);
538 +    }
539 +
540 +    /**
541 +     * thenRun result completes exceptionally if action does
542 +     */
543 +    public void testThenRun3() {
544 +        CompletableFuture<Integer> f;
545 +        CompletableFuture<Void> g;
546 +        FailingNoop r;
547 +
548 +        f = new CompletableFuture<>();
549 +        g = f.thenRun(r = new FailingNoop());
550 +        f.complete(null);
551 +        checkCompletedWithWrappedCFException(g);
552 +
553 +        f = new CompletableFuture<>();
554 +        f.complete(null);
555 +        g = f.thenRun(r = new FailingNoop());
556 +        checkCompletedWithWrappedCFException(g);
557 +    }
558 +
559 +    /**
560 +     * thenRun result completes exceptionally if source cancelled
561 +     */
562 +    public void testThenRun4() {
563 +        CompletableFuture<Integer> f;
564 +        CompletableFuture<Void> g;
565 +        Noop r;
566 +
567 +        f = new CompletableFuture<>();
568 +        g = f.thenRun(r = new Noop());
569 +        assertTrue(f.cancel(true));
570 +        checkCompletedWithWrappedCancellationException(g);
571 +
572 +        f = new CompletableFuture<>();
573 +        assertTrue(f.cancel(true));
574 +        g = f.thenRun(r = new Noop());
575 +        checkCompletedWithWrappedCancellationException(g);
576 +    }
577 +
578 +    /**
579 +     * thenApply result completes normally after normal completion of source
580 +     */
581 +    public void testThenApply() {
582 +        CompletableFuture<Integer> f = new CompletableFuture<>();
583 +        CompletableFuture<Integer> g = f.thenApply(inc);
584 +        f.complete(one);
585 +        checkCompletedNormally(g, two);
586 +    }
587 +
588 +    /**
589 +     * thenApply result completes exceptionally after exceptional
590 +     * completion of source
591 +     */
592 +    public void testThenApply2() {
593 +        CompletableFuture<Integer> f = new CompletableFuture<>();
594 +        CompletableFuture<Integer> g = f.thenApply(inc);
595 +        f.completeExceptionally(new CFException());
596 +        checkCompletedWithWrappedCFException(g);
597 +    }
598 +
599 +    /**
600 +     * thenApply result completes exceptionally if action does
601 +     */
602 +    public void testThenApply3() {
603 +        CompletableFuture<Integer> f = new CompletableFuture<>();
604 +        CompletableFuture<Integer> g = f.thenApply(new FailingFunction());
605 +        f.complete(one);
606 +        checkCompletedWithWrappedCFException(g);
607 +    }
608 +
609 +    /**
610 +     * thenApply result completes exceptionally if source cancelled
611 +     */
612 +    public void testThenApply4() {
613 +        CompletableFuture<Integer> f = new CompletableFuture<>();
614 +        CompletableFuture<Integer> g = f.thenApply(inc);
615 +        assertTrue(f.cancel(true));
616 +        checkCompletedWithWrappedCancellationException(g);
617 +    }
618 +
619 +    /**
620 +     * thenAccept result completes normally after normal completion of source
621 +     */
622 +    public void testThenAccept() {
623 +        CompletableFuture<Integer> f = new CompletableFuture<>();
624 +        IncAction r = new IncAction();
625 +        CompletableFuture<Void> g = f.thenAccept(r);
626 +        f.complete(one);
627 +        checkCompletedNormally(g, null);
628 +        assertEquals(r.value, 2);
629 +    }
630 +
631 +    /**
632 +     * thenAccept result completes exceptionally after exceptional
633 +     * completion of source
634 +     */
635 +    public void testThenAccept2() {
636 +        CompletableFuture<Integer> f = new CompletableFuture<>();
637 +        IncAction r = new IncAction();
638 +        CompletableFuture<Void> g = f.thenAccept(r);
639 +        f.completeExceptionally(new CFException());
640 +        checkCompletedWithWrappedCFException(g);
641 +    }
642 +
643 +    /**
644 +     * thenAccept result completes exceptionally if action does
645 +     */
646 +    public void testThenAccept3() {
647 +        CompletableFuture<Integer> f = new CompletableFuture<>();
648 +        FailingConsumer r = new FailingConsumer();
649 +        CompletableFuture<Void> g = f.thenAccept(r);
650 +        f.complete(one);
651 +        checkCompletedWithWrappedCFException(g);
652 +        assertTrue(r.ran);
653 +    }
654 +
655 +    /**
656 +     * thenAccept result completes exceptionally if source cancelled
657 +     */
658 +    public void testThenAccept4() {
659 +        CompletableFuture<Integer> f = new CompletableFuture<>();
660 +        IncAction r = new IncAction();
661 +        CompletableFuture<Void> g = f.thenAccept(r);
662 +        assertTrue(f.cancel(true));
663 +        checkCompletedWithWrappedCancellationException(g);
664 +    }
665 +
666 +
667 +    /**
668 +     * thenCombine result completes normally after normal completion
669 +     * of sources
670 +     */
671 +    public void testThenCombine() {
672 +        CompletableFuture<Integer> f, g, h;
673 +
674 +        f = new CompletableFuture<>();
675 +        g = new CompletableFuture<>();
676 +        h = f.thenCombine(g, subtract);
677 +        f.complete(3);
678 +        checkIncomplete(h);
679 +        g.complete(1);
680 +        checkCompletedNormally(h, 2);
681 +
682 +        f = new CompletableFuture<>();
683 +        g = new CompletableFuture<>();
684 +        h = f.thenCombine(g, subtract);
685 +        g.complete(1);
686 +        checkIncomplete(h);
687 +        f.complete(3);
688 +        checkCompletedNormally(h, 2);
689 +
690 +        f = new CompletableFuture<>();
691 +        g = new CompletableFuture<>();
692 +        g.complete(1);
693 +        f.complete(3);
694 +        h = f.thenCombine(g, subtract);
695 +        checkCompletedNormally(h, 2);
696 +    }
697 +
698 +    /**
699 +     * thenCombine result completes exceptionally after exceptional
700 +     * completion of either source
701 +     */
702 +    public void testThenCombine2() {
703 +        CompletableFuture<Integer> f, g, h;
704 +
705 +        f = new CompletableFuture<>();
706 +        g = new CompletableFuture<>();
707 +        h = f.thenCombine(g, subtract);
708 +        f.completeExceptionally(new CFException());
709 +        checkIncomplete(h);
710 +        g.complete(1);
711 +        checkCompletedWithWrappedCFException(h);
712 +
713 +        f = new CompletableFuture<>();
714 +        g = new CompletableFuture<>();
715 +        h = f.thenCombine(g, subtract);
716 +        g.completeExceptionally(new CFException());
717 +        checkIncomplete(h);
718 +        f.complete(3);
719 +        checkCompletedWithWrappedCFException(h);
720 +
721 +        f = new CompletableFuture<>();
722 +        g = new CompletableFuture<>();
723 +        f.complete(3);
724 +        g.completeExceptionally(new CFException());
725 +        h = f.thenCombine(g, subtract);
726 +        checkCompletedWithWrappedCFException(h);
727 +
728 +        f = new CompletableFuture<>();
729 +        g = new CompletableFuture<>();
730 +        f.completeExceptionally(new CFException());
731 +        g.complete(3);
732 +        h = f.thenCombine(g, subtract);
733 +        checkCompletedWithWrappedCFException(h);
734 +    }
735 +
736 +    /**
737 +     * thenCombine result completes exceptionally if action does
738 +     */
739 +    public void testThenCombine3() {
740 +        CompletableFuture<Integer> f = new CompletableFuture<>();
741 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
742 +        FailingBiFunction r = new FailingBiFunction();
743 +        CompletableFuture<Integer> g = f.thenCombine(f2, r);
744 +        f.complete(one);
745 +        checkIncomplete(g);
746 +        assertFalse(r.ran);
747 +        f2.complete(two);
748 +        checkCompletedWithWrappedCFException(g);
749 +        assertTrue(r.ran);
750 +    }
751 +
752 +    /**
753 +     * thenCombine result completes exceptionally if either source cancelled
754 +     */
755 +    public void testThenCombine4() {
756 +        CompletableFuture<Integer> f, g, h;
757 +
758 +        f = new CompletableFuture<>();
759 +        g = new CompletableFuture<>();
760 +        h = f.thenCombine(g, subtract);
761 +        assertTrue(f.cancel(true));
762 +        checkIncomplete(h);
763 +        g.complete(1);
764 +        checkCompletedWithWrappedCancellationException(h);
765 +
766 +        f = new CompletableFuture<>();
767 +        g = new CompletableFuture<>();
768 +        h = f.thenCombine(g, subtract);
769 +        assertTrue(g.cancel(true));
770 +        checkIncomplete(h);
771 +        f.complete(3);
772 +        checkCompletedWithWrappedCancellationException(h);
773 +
774 +        f = new CompletableFuture<>();
775 +        g = new CompletableFuture<>();
776 +        assertTrue(f.cancel(true));
777 +        assertTrue(g.cancel(true));
778 +        h = f.thenCombine(g, subtract);
779 +        checkCompletedWithWrappedCancellationException(h);
780 +    }
781 +
782 +    /**
783 +     * thenAcceptBoth result completes normally after normal
784 +     * completion of sources
785 +     */
786 +    public void testThenAcceptBoth() {
787 +        CompletableFuture<Integer> f, g;
788 +        CompletableFuture<Void> h;
789 +        SubtractAction r;
790 +
791 +        f = new CompletableFuture<>();
792 +        g = new CompletableFuture<>();
793 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
794 +        f.complete(3);
795 +        checkIncomplete(h);
796 +        g.complete(1);
797 +        checkCompletedNormally(h, null);
798 +        assertEquals(r.value, 2);
799 +
800 +        f = new CompletableFuture<>();
801 +        g = new CompletableFuture<>();
802 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
803 +        g.complete(1);
804 +        checkIncomplete(h);
805 +        f.complete(3);
806 +        checkCompletedNormally(h, null);
807 +        assertEquals(r.value, 2);
808 +
809 +        f = new CompletableFuture<>();
810 +        g = new CompletableFuture<>();
811 +        g.complete(1);
812 +        f.complete(3);
813 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
814 +        checkCompletedNormally(h, null);
815 +        assertEquals(r.value, 2);
816 +    }
817 +
818 +    /**
819 +     * thenAcceptBoth result completes exceptionally after exceptional
820 +     * completion of either source
821 +     */
822 +    public void testThenAcceptBoth2() {
823 +        CompletableFuture<Integer> f, g;
824 +        CompletableFuture<Void> h;
825 +        SubtractAction r;
826 +
827 +        f = new CompletableFuture<>();
828 +        g = new CompletableFuture<>();
829 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
830 +        f.completeExceptionally(new CFException());
831 +        checkIncomplete(h);
832 +        g.complete(1);
833 +        checkCompletedWithWrappedCFException(h);
834 +
835 +        f = new CompletableFuture<>();
836 +        g = new CompletableFuture<>();
837 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
838 +        g.completeExceptionally(new CFException());
839 +        checkIncomplete(h);
840 +        f.complete(3);
841 +        checkCompletedWithWrappedCFException(h);
842 +
843 +        f = new CompletableFuture<>();
844 +        g = new CompletableFuture<>();
845 +        f.complete(3);
846 +        g.completeExceptionally(new CFException());
847 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
848 +        checkCompletedWithWrappedCFException(h);
849 +
850 +        f = new CompletableFuture<>();
851 +        g = new CompletableFuture<>();
852 +        f.completeExceptionally(new CFException());
853 +        g.complete(3);
854 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
855 +        checkCompletedWithWrappedCFException(h);
856 +    }
857 +
858 +    /**
859 +     * thenAcceptBoth result completes exceptionally if action does
860 +     */
861 +    public void testThenAcceptBoth3() {
862 +        CompletableFuture<Integer> f, g;
863 +        CompletableFuture<Void> h;
864 +        FailingBiConsumer r;
865 +
866 +        f = new CompletableFuture<>();
867 +        g = new CompletableFuture<>();
868 +        h = f.thenAcceptBoth(g, r = new FailingBiConsumer());
869 +        f.complete(3);
870 +        checkIncomplete(h);
871 +        g.complete(1);
872 +        checkCompletedWithWrappedCFException(h);
873 +
874 +        f = new CompletableFuture<>();
875 +        g = new CompletableFuture<>();
876 +        f.complete(3);
877 +        g.complete(1);
878 +        h = f.thenAcceptBoth(g, r = new FailingBiConsumer());
879 +        checkCompletedWithWrappedCFException(h);
880 +    }
881 +
882 +    /**
883 +     * thenAcceptBoth result completes exceptionally if either source cancelled
884 +     */
885 +    public void testThenAcceptBoth4() {
886 +        CompletableFuture<Integer> f, g;
887 +        CompletableFuture<Void> h;
888 +        SubtractAction r;
889 +
890 +        f = new CompletableFuture<>();
891 +        g = new CompletableFuture<>();
892 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
893 +        assertTrue(f.cancel(true));
894 +        checkIncomplete(h);
895 +        g.complete(1);
896 +        checkCompletedWithWrappedCancellationException(h);
897 +
898 +        f = new CompletableFuture<>();
899 +        g = new CompletableFuture<>();
900 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
901 +        assertTrue(g.cancel(true));
902 +        checkIncomplete(h);
903 +        f.complete(3);
904 +        checkCompletedWithWrappedCancellationException(h);
905 +
906 +        f = new CompletableFuture<>();
907 +        g = new CompletableFuture<>();
908 +        f.complete(3);
909 +        assertTrue(g.cancel(true));
910 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
911 +        checkCompletedWithWrappedCancellationException(h);
912 +
913 +        f = new CompletableFuture<>();
914 +        g = new CompletableFuture<>();
915 +        assertTrue(f.cancel(true));
916 +        g.complete(3);
917 +        h = f.thenAcceptBoth(g, r = new SubtractAction());
918 +        checkCompletedWithWrappedCancellationException(h);
919 +    }
920 +
921 +    /**
922 +     * runAfterBoth result completes normally after normal
923 +     * completion of sources
924 +     */
925 +    public void testRunAfterBoth() {
926 +        CompletableFuture<Integer> f, g;
927 +        CompletableFuture<Void> h;
928 +        Noop r;
929 +
930 +        f = new CompletableFuture<>();
931 +        g = new CompletableFuture<>();
932 +        h = f.runAfterBoth(g, r = new Noop());
933 +        f.complete(3);
934 +        checkIncomplete(h);
935 +        g.complete(1);
936 +        checkCompletedNormally(h, null);
937 +        assertTrue(r.ran);
938 +
939 +        f = new CompletableFuture<>();
940 +        g = new CompletableFuture<>();
941 +        h = f.runAfterBoth(g, r = new Noop());
942 +        g.complete(1);
943 +        checkIncomplete(h);
944 +        f.complete(3);
945 +        checkCompletedNormally(h, null);
946 +        assertTrue(r.ran);
947 +
948 +        f = new CompletableFuture<>();
949 +        g = new CompletableFuture<>();
950 +        g.complete(1);
951 +        f.complete(3);
952 +        h = f.runAfterBoth(g, r = new Noop());
953 +        checkCompletedNormally(h, null);
954 +        assertTrue(r.ran);
955 +    }
956 +
957 +    /**
958 +     * runAfterBoth result completes exceptionally after exceptional
959 +     * completion of either source
960 +     */
961 +    public void testRunAfterBoth2() {
962 +        CompletableFuture<Integer> f, g;
963 +        CompletableFuture<Void> h;
964 +        Noop r;
965 +
966 +        f = new CompletableFuture<>();
967 +        g = new CompletableFuture<>();
968 +        h = f.runAfterBoth(g, r = new Noop());
969 +        f.completeExceptionally(new CFException());
970 +        checkIncomplete(h);
971 +        g.complete(1);
972 +        checkCompletedWithWrappedCFException(h);
973 +        assertFalse(r.ran);
974 +
975 +        f = new CompletableFuture<>();
976 +        g = new CompletableFuture<>();
977 +        h = f.runAfterBoth(g, r = new Noop());
978 +        g.completeExceptionally(new CFException());
979 +        checkIncomplete(h);
980 +        f.complete(3);
981 +        checkCompletedWithWrappedCFException(h);
982 +        assertFalse(r.ran);
983 +
984 +        f = new CompletableFuture<>();
985 +        g = new CompletableFuture<>();
986 +        g.completeExceptionally(new CFException());
987 +        f.complete(3);
988 +        h = f.runAfterBoth(g, r = new Noop());
989 +        checkCompletedWithWrappedCFException(h);
990 +        assertFalse(r.ran);
991 +
992 +        f = new CompletableFuture<>();
993 +        g = new CompletableFuture<>();
994 +        f.completeExceptionally(new CFException());
995 +        g.complete(1);
996 +        h = f.runAfterBoth(g, r = new Noop());
997 +        checkCompletedWithWrappedCFException(h);
998 +        assertFalse(r.ran);
999 +    }
1000 +
1001 +    /**
1002 +     * runAfterBoth result completes exceptionally if action does
1003 +     */
1004 +    public void testRunAfterBoth3() {
1005 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1006 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1007 +        FailingNoop r = new FailingNoop();
1008 +        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
1009 +        f.complete(one);
1010 +        checkIncomplete(g);
1011 +        f2.complete(two);
1012 +        checkCompletedWithWrappedCFException(g);
1013 +    }
1014 +
1015 +    /**
1016 +     * runAfterBoth result completes exceptionally if either source cancelled
1017 +     */
1018 +    public void testRunAfterBoth4() {
1019 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1020 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1021 +        Noop r = new Noop();
1022 +        CompletableFuture<Void> g = f.runAfterBoth(f2, r);
1023 +        assertTrue(f.cancel(true));
1024 +        f2.complete(two);
1025 +        checkCompletedWithWrappedCancellationException(g);
1026 +        f = new CompletableFuture<>();
1027 +        f2 = new CompletableFuture<>();
1028 +        r = new Noop();
1029 +        g = f.runAfterBoth(f2, r);
1030 +        f.complete(one);
1031 +        assertTrue(f2.cancel(true));
1032 +        checkCompletedWithWrappedCancellationException(g);
1033 +    }
1034 +
1035 +    /**
1036 +     * applyToEither result completes normally after normal completion
1037 +     * of either source
1038 +     */
1039 +    public void testApplyToEither() {
1040 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1041 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1042 +        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
1043 +        f.complete(one);
1044 +        checkCompletedNormally(g, two);
1045 +        f2.complete(one);
1046 +        checkCompletedNormally(g, two);
1047 +
1048 +        f = new CompletableFuture<>();
1049 +        f.complete(one);
1050 +        f2 = new CompletableFuture<>();
1051 +        g = f.applyToEither(f2, inc);
1052 +        checkCompletedNormally(g, two);
1053 +    }
1054 +
1055 +    /**
1056 +     * applyToEither result completes exceptionally after exceptional
1057 +     * completion of either source
1058 +     */
1059 +    public void testApplyToEither2() {
1060 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1061 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1062 +        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
1063 +        f.completeExceptionally(new CFException());
1064 +        f2.complete(one);
1065 +        checkCompletedWithWrappedCFException(g);
1066 +
1067 +        f = new CompletableFuture<>();
1068 +        f2 = new CompletableFuture<>();
1069 +        f2.completeExceptionally(new CFException());
1070 +        g = f.applyToEither(f2, inc);
1071 +        checkCompletedWithWrappedCFException(g);
1072 +    }
1073 +
1074 +    /**
1075 +     * applyToEither result completes exceptionally if action does
1076 +     */
1077 +    public void testApplyToEither3() {
1078 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1079 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1080 +        FailingFunction r = new FailingFunction();
1081 +        CompletableFuture<Integer> g = f.applyToEither(f2, r);
1082 +        f2.complete(two);
1083 +        checkCompletedWithWrappedCFException(g);
1084 +    }
1085 +
1086 +    /**
1087 +     * applyToEither result completes exceptionally if either source cancelled
1088 +     */
1089 +    public void testApplyToEither4() {
1090 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1091 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1092 +        CompletableFuture<Integer> g = f.applyToEither(f2, inc);
1093 +        assertTrue(f.cancel(true));
1094 +        checkCompletedWithWrappedCancellationException(g);
1095 +        f = new CompletableFuture<>();
1096 +        f2 = new CompletableFuture<>();
1097 +        assertTrue(f2.cancel(true));
1098 +        checkCompletedWithWrappedCancellationException(g);
1099 +    }
1100 +
1101 +    /**
1102 +     * acceptEither result completes normally after normal completion
1103 +     * of either source
1104 +     */
1105 +    public void testAcceptEither() {
1106 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1107 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1108 +        IncAction r = new IncAction();
1109 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
1110 +        f.complete(one);
1111 +        checkCompletedNormally(g, null);
1112 +        f2.complete(one);
1113 +        checkCompletedNormally(g, null);
1114 +        assertEquals(r.value, 2);
1115 +
1116 +        r = new IncAction();
1117 +        f = new CompletableFuture<>();
1118 +        f.complete(one);
1119 +        f2 = new CompletableFuture<>();
1120 +        g = f.acceptEither(f2, r);
1121 +        checkCompletedNormally(g, null);
1122 +        assertEquals(r.value, 2);
1123 +    }
1124 +
1125 +    /**
1126 +     * acceptEither result completes exceptionally after exceptional
1127 +     * completion of either source
1128 +     */
1129 +    public void testAcceptEither2() {
1130 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1131 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1132 +        IncAction r = new IncAction();
1133 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
1134 +        f.completeExceptionally(new CFException());
1135 +        f2.complete(one);
1136 +        checkCompletedWithWrappedCFException(g);
1137 +
1138 +        r = new IncAction();
1139 +        f = new CompletableFuture<>();
1140 +        f2 = new CompletableFuture<>();
1141 +        f2.completeExceptionally(new CFException());
1142 +        g = f.acceptEither(f2, r);
1143 +        checkCompletedWithWrappedCFException(g);
1144 +    }
1145 +
1146 +    /**
1147 +     * acceptEither result completes exceptionally if action does
1148 +     */
1149 +    public void testAcceptEither3() {
1150 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1151 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1152 +        FailingConsumer r = new FailingConsumer();
1153 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
1154 +        f2.complete(two);
1155 +        checkCompletedWithWrappedCFException(g);
1156 +    }
1157 +
1158 +    /**
1159 +     * acceptEither result completes exceptionally if either source cancelled
1160 +     */
1161 +    public void testAcceptEither4() {
1162 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1163 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1164 +        IncAction r = new IncAction();
1165 +        CompletableFuture<Void> g = f.acceptEither(f2, r);
1166 +        assertTrue(f.cancel(true));
1167 +        checkCompletedWithWrappedCancellationException(g);
1168 +        f = new CompletableFuture<>();
1169 +        f2 = new CompletableFuture<>();
1170 +        assertTrue(f2.cancel(true));
1171 +        checkCompletedWithWrappedCancellationException(g);
1172 +    }
1173 +
1174 +
1175 +    /**
1176 +     * runAfterEither result completes normally after normal completion
1177 +     * of either source
1178 +     */
1179 +    public void testRunAfterEither() {
1180 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1181 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1182 +        Noop r = new Noop();
1183 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1184 +        f.complete(one);
1185 +        checkCompletedNormally(g, null);
1186 +        f2.complete(one);
1187 +        checkCompletedNormally(g, null);
1188 +        assertTrue(r.ran);
1189 +
1190 +        r = new Noop();
1191 +        f = new CompletableFuture<>();
1192 +        f.complete(one);
1193 +        f2 = new CompletableFuture<>();
1194 +        g = f.runAfterEither(f2, r);
1195 +        checkCompletedNormally(g, null);
1196 +        assertTrue(r.ran);
1197 +    }
1198 +
1199 +    /**
1200 +     * runAfterEither result completes exceptionally after exceptional
1201 +     * completion of either source
1202 +     */
1203 +    public void testRunAfterEither2() {
1204 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1205 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1206 +        Noop r = new Noop();
1207 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1208 +        f.completeExceptionally(new CFException());
1209 +        f2.complete(one);
1210 +        checkCompletedWithWrappedCFException(g);
1211 +
1212 +        r = new Noop();
1213 +        f = new CompletableFuture<>();
1214 +        f2 = new CompletableFuture<>();
1215 +        f2.completeExceptionally(new CFException());
1216 +        g = f.runAfterEither(f2, r);
1217 +        checkCompletedWithWrappedCFException(g);
1218 +    }
1219 +
1220 +    /**
1221 +     * runAfterEither result completes exceptionally if action does
1222 +     */
1223 +    public void testRunAfterEither3() {
1224 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1225 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1226 +        FailingNoop r = new FailingNoop();
1227 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1228 +        f2.complete(two);
1229 +        checkCompletedWithWrappedCFException(g);
1230 +    }
1231 +
1232 +    /**
1233 +     * runAfterEither result completes exceptionally if either source cancelled
1234 +     */
1235 +    public void testRunAfterEither4() {
1236 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1237 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1238 +        Noop r = new Noop();
1239 +        CompletableFuture<Void> g = f.runAfterEither(f2, r);
1240 +        assertTrue(f.cancel(true));
1241 +        checkCompletedWithWrappedCancellationException(g);
1242 +        f = new CompletableFuture<>();
1243 +        f2 = new CompletableFuture<>();
1244 +        assertTrue(f2.cancel(true));
1245 +        checkCompletedWithWrappedCancellationException(g);
1246 +    }
1247 +
1248 +    /**
1249 +     * thenCompose result completes normally after normal completion of source
1250 +     */
1251 +    public void testThenCompose() {
1252 +        CompletableFuture<Integer> f, g;
1253 +        CompletableFutureInc r;
1254 +
1255 +        f = new CompletableFuture<>();
1256 +        g = f.thenCompose(r = new CompletableFutureInc());
1257 +        f.complete(one);
1258 +        checkCompletedNormally(g, two);
1259 +        assertTrue(r.ran);
1260 +
1261 +        f = new CompletableFuture<>();
1262 +        f.complete(one);
1263 +        g = f.thenCompose(r = new CompletableFutureInc());
1264 +        checkCompletedNormally(g, two);
1265 +        assertTrue(r.ran);
1266 +    }
1267 +
1268 +    /**
1269 +     * thenCompose result completes exceptionally after exceptional
1270 +     * completion of source
1271 +     */
1272 +    public void testThenCompose2() {
1273 +        CompletableFuture<Integer> f, g;
1274 +        CompletableFutureInc r;
1275 +
1276 +        f = new CompletableFuture<>();
1277 +        g = f.thenCompose(r = new CompletableFutureInc());
1278 +        f.completeExceptionally(new CFException());
1279 +        checkCompletedWithWrappedCFException(g);
1280 +
1281 +        f = new CompletableFuture<>();
1282 +        f.completeExceptionally(new CFException());
1283 +        g = f.thenCompose(r = new CompletableFutureInc());
1284 +        checkCompletedWithWrappedCFException(g);
1285 +    }
1286 +
1287 +    /**
1288 +     * thenCompose result completes exceptionally if action does
1289 +     */
1290 +    public void testThenCompose3() {
1291 +        CompletableFuture<Integer> f, g;
1292 +        FailingCompletableFutureFunction r;
1293 +
1294 +        f = new CompletableFuture<>();
1295 +        g = f.thenCompose(r = new FailingCompletableFutureFunction());
1296 +        f.complete(one);
1297 +        checkCompletedWithWrappedCFException(g);
1298 +
1299 +        f = new CompletableFuture<>();
1300 +        f.complete(one);
1301 +        g = f.thenCompose(r = new FailingCompletableFutureFunction());
1302 +        checkCompletedWithWrappedCFException(g);
1303 +    }
1304 +
1305 +    /**
1306 +     * thenCompose result completes exceptionally if source cancelled
1307 +     */
1308 +    public void testThenCompose4() {
1309 +        CompletableFuture<Integer> f, g;
1310 +        CompletableFutureInc r;
1311 +
1312 +        f = new CompletableFuture<>();
1313 +        g = f.thenCompose(r = new CompletableFutureInc());
1314 +        assertTrue(f.cancel(true));
1315 +        checkCompletedWithWrappedCancellationException(g);
1316 +
1317 +        f = new CompletableFuture<>();
1318 +        assertTrue(f.cancel(true));
1319 +        g = f.thenCompose(r = new CompletableFutureInc());
1320 +        checkCompletedWithWrappedCancellationException(g);
1321 +    }
1322 +
1323 +
1324 +    // asyncs
1325 +
1326 +    /**
1327 +     * thenRunAsync result completes normally after normal completion of source
1328 +     */
1329 +    public void testThenRunAsync() {
1330 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1331 +        Noop r = new Noop();
1332 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1333 +        f.complete(null);
1334 +        checkCompletedNormally(g, null);
1335 +
1336 +        // reordered version
1337 +        f = new CompletableFuture<>();
1338 +        f.complete(null);
1339 +        r = new Noop();
1340 +        g = f.thenRunAsync(r);
1341 +        checkCompletedNormally(g, null);
1342 +    }
1343 +
1344 +    /**
1345 +     * thenRunAsync result completes exceptionally after exceptional
1346 +     * completion of source
1347 +     */
1348 +    public void testThenRunAsync2() {
1349 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1350 +        Noop r = new Noop();
1351 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1352 +        f.completeExceptionally(new CFException());
1353 +        try {
1354 +            g.join();
1355 +            shouldThrow();
1356 +        } catch (Exception ok) {
1357 +        }
1358 +        checkCompletedWithWrappedCFException(g);
1359 +    }
1360 +
1361 +    /**
1362 +     * thenRunAsync result completes exceptionally if action does
1363 +     */
1364 +    public void testThenRunAsync3() {
1365 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1366 +        FailingNoop r = new FailingNoop();
1367 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1368 +        f.complete(null);
1369 +        checkCompletedWithWrappedCFException(g);
1370 +    }
1371 +
1372 +    /**
1373 +     * thenRunAsync result completes exceptionally if source cancelled
1374 +     */
1375 +    public void testThenRunAsync4() {
1376 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1377 +        Noop r = new Noop();
1378 +        CompletableFuture<Void> g = f.thenRunAsync(r);
1379 +        assertTrue(f.cancel(true));
1380 +        checkCompletedWithWrappedCancellationException(g);
1381 +    }
1382 +
1383 +    /**
1384 +     * thenApplyAsync result completes normally after normal completion of source
1385 +     */
1386 +    public void testThenApplyAsync() {
1387 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1388 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1389 +        f.complete(one);
1390 +        checkCompletedNormally(g, two);
1391 +    }
1392 +
1393 +    /**
1394 +     * thenApplyAsync result completes exceptionally after exceptional
1395 +     * completion of source
1396 +     */
1397 +    public void testThenApplyAsync2() {
1398 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1399 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1400 +        f.completeExceptionally(new CFException());
1401 +        checkCompletedWithWrappedCFException(g);
1402 +    }
1403 +
1404 +    /**
1405 +     * thenApplyAsync result completes exceptionally if action does
1406 +     */
1407 +    public void testThenApplyAsync3() {
1408 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1409 +        FailingFunction r = new FailingFunction();
1410 +        CompletableFuture<Integer> g = f.thenApplyAsync(r);
1411 +        f.complete(null);
1412 +        checkCompletedWithWrappedCFException(g);
1413 +    }
1414 +
1415 +    /**
1416 +     * thenApplyAsync result completes exceptionally if source cancelled
1417 +     */
1418 +    public void testThenApplyAsync4() {
1419 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1420 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc);
1421 +        assertTrue(f.cancel(true));
1422 +        checkCompletedWithWrappedCancellationException(g);
1423 +    }
1424 +
1425 +    /**
1426 +     * thenAcceptAsync result completes normally after normal
1427 +     * completion of source
1428 +     */
1429 +    public void testThenAcceptAsync() {
1430 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1431 +        IncAction r = new IncAction();
1432 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1433 +        f.complete(one);
1434 +        checkCompletedNormally(g, null);
1435 +        assertEquals(r.value, 2);
1436 +    }
1437 +
1438 +    /**
1439 +     * thenAcceptAsync result completes exceptionally after exceptional
1440 +     * completion of source
1441 +     */
1442 +    public void testThenAcceptAsync2() {
1443 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1444 +        IncAction r = new IncAction();
1445 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1446 +        f.completeExceptionally(new CFException());
1447 +        checkCompletedWithWrappedCFException(g);
1448 +    }
1449 +
1450 +    /**
1451 +     * thenAcceptAsync result completes exceptionally if action does
1452 +     */
1453 +    public void testThenAcceptAsync3() {
1454 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1455 +        FailingConsumer r = new FailingConsumer();
1456 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1457 +        f.complete(null);
1458 +        checkCompletedWithWrappedCFException(g);
1459 +    }
1460 +
1461 +    /**
1462 +     * thenAcceptAsync result completes exceptionally if source cancelled
1463 +     */
1464 +    public void testThenAcceptAsync4() {
1465 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1466 +        IncAction r = new IncAction();
1467 +        CompletableFuture<Void> g = f.thenAcceptAsync(r);
1468 +        assertTrue(f.cancel(true));
1469 +        checkCompletedWithWrappedCancellationException(g);
1470 +    }
1471 +
1472 +    /**
1473 +     * thenCombineAsync result completes normally after normal
1474 +     * completion of sources
1475 +     */
1476 +    public void testThenCombineAsync() {
1477 +        CompletableFuture<Integer> f, g, h;
1478 +
1479 +        f = new CompletableFuture<>();
1480 +        g = new CompletableFuture<>();
1481 +        h = f.thenCombineAsync(g, subtract);
1482 +        f.complete(3);
1483 +        checkIncomplete(h);
1484 +        g.complete(1);
1485 +        checkCompletedNormally(h, 2);
1486 +
1487 +        f = new CompletableFuture<>();
1488 +        g = new CompletableFuture<>();
1489 +        h = f.thenCombineAsync(g, subtract);
1490 +        g.complete(1);
1491 +        checkIncomplete(h);
1492 +        f.complete(3);
1493 +        checkCompletedNormally(h, 2);
1494 +
1495 +        f = new CompletableFuture<>();
1496 +        g = new CompletableFuture<>();
1497 +        g.complete(1);
1498 +        f.complete(3);
1499 +        h = f.thenCombineAsync(g, subtract);
1500 +        checkCompletedNormally(h, 2);
1501 +    }
1502 +
1503 +    /**
1504 +     * thenCombineAsync result completes exceptionally after exceptional
1505 +     * completion of either source
1506 +     */
1507 +    public void testThenCombineAsync2() {
1508 +        CompletableFuture<Integer> f, g, h;
1509 +
1510 +        f = new CompletableFuture<>();
1511 +        g = new CompletableFuture<>();
1512 +        h = f.thenCombineAsync(g, subtract);
1513 +        f.completeExceptionally(new CFException());
1514 +        checkIncomplete(h);
1515 +        g.complete(1);
1516 +        checkCompletedWithWrappedCFException(h);
1517 +
1518 +        f = new CompletableFuture<>();
1519 +        g = new CompletableFuture<>();
1520 +        h = f.thenCombineAsync(g, subtract);
1521 +        g.completeExceptionally(new CFException());
1522 +        checkIncomplete(h);
1523 +        f.complete(3);
1524 +        checkCompletedWithWrappedCFException(h);
1525 +
1526 +        f = new CompletableFuture<>();
1527 +        g = new CompletableFuture<>();
1528 +        g.completeExceptionally(new CFException());
1529 +        f.complete(3);
1530 +        h = f.thenCombineAsync(g, subtract);
1531 +        checkCompletedWithWrappedCFException(h);
1532 +    }
1533 +
1534 +    /**
1535 +     * thenCombineAsync result completes exceptionally if action does
1536 +     */
1537 +    public void testThenCombineAsync3() {
1538 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1539 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1540 +        FailingBiFunction r = new FailingBiFunction();
1541 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r);
1542 +        f.complete(one);
1543 +        checkIncomplete(g);
1544 +        assertFalse(r.ran);
1545 +        f2.complete(two);
1546 +        checkCompletedWithWrappedCFException(g);
1547 +        assertTrue(r.ran);
1548 +    }
1549 +
1550 +    /**
1551 +     * thenCombineAsync result completes exceptionally if either source cancelled
1552 +     */
1553 +    public void testThenCombineAsync4() {
1554 +        CompletableFuture<Integer> f, g, h;
1555 +
1556 +        f = new CompletableFuture<>();
1557 +        g = new CompletableFuture<>();
1558 +        h = f.thenCombineAsync(g, subtract);
1559 +        assertTrue(f.cancel(true));
1560 +        checkIncomplete(h);
1561 +        g.complete(1);
1562 +        checkCompletedWithWrappedCancellationException(h);
1563 +
1564 +        f = new CompletableFuture<>();
1565 +        g = new CompletableFuture<>();
1566 +        h = f.thenCombineAsync(g, subtract);
1567 +        assertTrue(g.cancel(true));
1568 +        checkIncomplete(h);
1569 +        f.complete(3);
1570 +        checkCompletedWithWrappedCancellationException(h);
1571 +
1572 +        f = new CompletableFuture<>();
1573 +        g = new CompletableFuture<>();
1574 +        g.complete(3);
1575 +        assertTrue(f.cancel(true));
1576 +        h = f.thenCombineAsync(g, subtract);
1577 +        checkCompletedWithWrappedCancellationException(h);
1578 +
1579 +        f = new CompletableFuture<>();
1580 +        g = new CompletableFuture<>();
1581 +        f.complete(3);
1582 +        assertTrue(g.cancel(true));
1583 +        h = f.thenCombineAsync(g, subtract);
1584 +        checkCompletedWithWrappedCancellationException(h);
1585 +    }
1586 +
1587 +    /**
1588 +     * thenAcceptBothAsync result completes normally after normal
1589 +     * completion of sources
1590 +     */
1591 +    public void testThenAcceptBothAsync() {
1592 +        CompletableFuture<Integer> f, g;
1593 +        CompletableFuture<Void> h;
1594 +        SubtractAction r;
1595 +
1596 +        f = new CompletableFuture<>();
1597 +        g = new CompletableFuture<>();
1598 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1599 +        f.complete(3);
1600 +        checkIncomplete(h);
1601 +        g.complete(1);
1602 +        checkCompletedNormally(h, null);
1603 +        assertEquals(r.value, 2);
1604 +
1605 +        f = new CompletableFuture<>();
1606 +        g = new CompletableFuture<>();
1607 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1608 +        g.complete(1);
1609 +        checkIncomplete(h);
1610 +        f.complete(3);
1611 +        checkCompletedNormally(h, null);
1612 +        assertEquals(r.value, 2);
1613 +
1614 +        f = new CompletableFuture<>();
1615 +        g = new CompletableFuture<>();
1616 +        g.complete(1);
1617 +        f.complete(3);
1618 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1619 +        checkCompletedNormally(h, null);
1620 +        assertEquals(r.value, 2);
1621 +    }
1622 +
1623 +    /**
1624 +     * thenAcceptBothAsync result completes exceptionally after exceptional
1625 +     * completion of source
1626 +     */
1627 +    public void testThenAcceptBothAsync2() {
1628 +        CompletableFuture<Integer> f, g;
1629 +        CompletableFuture<Void> h;
1630 +        SubtractAction r;
1631 +
1632 +        f = new CompletableFuture<>();
1633 +        g = new CompletableFuture<>();
1634 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1635 +        f.completeExceptionally(new CFException());
1636 +        checkIncomplete(h);
1637 +        g.complete(1);
1638 +        checkCompletedWithWrappedCFException(h);
1639 +
1640 +        f = new CompletableFuture<>();
1641 +        g = new CompletableFuture<>();
1642 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1643 +        g.completeExceptionally(new CFException());
1644 +        checkIncomplete(h);
1645 +        f.complete(3);
1646 +        checkCompletedWithWrappedCFException(h);
1647 +
1648 +        f = new CompletableFuture<>();
1649 +        g = new CompletableFuture<>();
1650 +        f.complete(3);
1651 +        g.completeExceptionally(new CFException());
1652 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1653 +        checkCompletedWithWrappedCFException(h);
1654 +
1655 +        f = new CompletableFuture<>();
1656 +        g = new CompletableFuture<>();
1657 +        f.completeExceptionally(new CFException());
1658 +        g.complete(3);
1659 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1660 +        checkCompletedWithWrappedCFException(h);
1661 +    }
1662 +
1663 +    /**
1664 +     * thenAcceptBothAsync result completes exceptionally if action does
1665 +     */
1666 +    public void testThenAcceptBothAsync3() {
1667 +        CompletableFuture<Integer> f, g;
1668 +        CompletableFuture<Void> h;
1669 +        FailingBiConsumer r;
1670 +
1671 +        f = new CompletableFuture<>();
1672 +        g = new CompletableFuture<>();
1673 +        h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer());
1674 +        f.complete(3);
1675 +        checkIncomplete(h);
1676 +        g.complete(1);
1677 +        checkCompletedWithWrappedCFException(h);
1678 +
1679 +        f = new CompletableFuture<>();
1680 +        g = new CompletableFuture<>();
1681 +        f.complete(3);
1682 +        g.complete(1);
1683 +        h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer());
1684 +        checkCompletedWithWrappedCFException(h);
1685 +    }
1686 +
1687 +    /**
1688 +     * thenAcceptBothAsync result completes exceptionally if either source cancelled
1689 +     */
1690 +    public void testThenAcceptBothAsync4() {
1691 +        CompletableFuture<Integer> f, g;
1692 +        CompletableFuture<Void> h;
1693 +        SubtractAction r;
1694 +
1695 +        f = new CompletableFuture<>();
1696 +        g = new CompletableFuture<>();
1697 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1698 +        assertTrue(f.cancel(true));
1699 +        checkIncomplete(h);
1700 +        g.complete(1);
1701 +        checkCompletedWithWrappedCancellationException(h);
1702 +
1703 +        f = new CompletableFuture<>();
1704 +        g = new CompletableFuture<>();
1705 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1706 +        assertTrue(g.cancel(true));
1707 +        checkIncomplete(h);
1708 +        f.complete(3);
1709 +        checkCompletedWithWrappedCancellationException(h);
1710 +
1711 +        f = new CompletableFuture<>();
1712 +        g = new CompletableFuture<>();
1713 +        f.complete(3);
1714 +        assertTrue(g.cancel(true));
1715 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1716 +        checkCompletedWithWrappedCancellationException(h);
1717 +
1718 +        f = new CompletableFuture<>();
1719 +        g = new CompletableFuture<>();
1720 +        assertTrue(f.cancel(true));
1721 +        g.complete(3);
1722 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction());
1723 +        checkCompletedWithWrappedCancellationException(h);
1724 +    }
1725 +
1726 +    /**
1727 +     * runAfterBothAsync result completes normally after normal
1728 +     * completion of sources
1729 +     */
1730 +    public void testRunAfterBothAsync() {
1731 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1732 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1733 +        Noop r = new Noop();
1734 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1735 +        f.complete(one);
1736 +        checkIncomplete(g);
1737 +        f2.complete(two);
1738 +        checkCompletedNormally(g, null);
1739 +        assertTrue(r.ran);
1740 +    }
1741 +
1742 +    /**
1743 +     * runAfterBothAsync result completes exceptionally after exceptional
1744 +     * completion of source
1745 +     */
1746 +    public void testRunAfterBothAsync2() {
1747 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1748 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1749 +        Noop r = new Noop();
1750 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1751 +        f.completeExceptionally(new CFException());
1752 +        f2.complete(two);
1753 +        checkCompletedWithWrappedCFException(g);
1754 +
1755 +        r = new Noop();
1756 +        f = new CompletableFuture<>();
1757 +        f2 = new CompletableFuture<>();
1758 +        g = f.runAfterBothAsync(f2, r);
1759 +        f.complete(one);
1760 +        f2.completeExceptionally(new CFException());
1761 +        checkCompletedWithWrappedCFException(g);
1762 +    }
1763 +
1764 +    /**
1765 +     * runAfterBothAsync result completes exceptionally if action does
1766 +     */
1767 +    public void testRunAfterBothAsync3() {
1768 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1769 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1770 +        FailingNoop r = new FailingNoop();
1771 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1772 +        f.complete(one);
1773 +        checkIncomplete(g);
1774 +        f2.complete(two);
1775 +        checkCompletedWithWrappedCFException(g);
1776 +    }
1777 +
1778 +    /**
1779 +     * runAfterBothAsync result completes exceptionally if either source cancelled
1780 +     */
1781 +    public void testRunAfterBothAsync4() {
1782 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1783 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1784 +        Noop r = new Noop();
1785 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r);
1786 +        assertTrue(f.cancel(true));
1787 +        f2.complete(two);
1788 +        checkCompletedWithWrappedCancellationException(g);
1789 +
1790 +        r = new Noop();
1791 +        f = new CompletableFuture<>();
1792 +        f2 = new CompletableFuture<>();
1793 +        g = f.runAfterBothAsync(f2, r);
1794 +        f.complete(one);
1795 +        assertTrue(f2.cancel(true));
1796 +        checkCompletedWithWrappedCancellationException(g);
1797 +    }
1798 +
1799 +    /**
1800 +     * applyToEitherAsync result completes normally after normal
1801 +     * completion of sources
1802 +     */
1803 +    public void testApplyToEitherAsync() {
1804 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1805 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1806 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1807 +        f.complete(one);
1808 +        checkCompletedNormally(g, two);
1809 +
1810 +        f = new CompletableFuture<>();
1811 +        f.complete(one);
1812 +        f2 = new CompletableFuture<>();
1813 +        g = f.applyToEitherAsync(f2, inc);
1814 +        checkCompletedNormally(g, two);
1815 +    }
1816 +
1817 +    /**
1818 +     * applyToEitherAsync result completes exceptionally after exceptional
1819 +     * completion of source
1820 +     */
1821 +    public void testApplyToEitherAsync2() {
1822 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1823 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1824 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1825 +        f.completeExceptionally(new CFException());
1826 +        checkCompletedWithWrappedCFException(g);
1827 +
1828 +        f = new CompletableFuture<>();
1829 +        f2 = new CompletableFuture<>();
1830 +        f2.completeExceptionally(new CFException());
1831 +        g = f.applyToEitherAsync(f2, inc);
1832 +        f.complete(one);
1833 +        checkCompletedWithWrappedCFException(g);
1834 +    }
1835 +
1836 +    /**
1837 +     * applyToEitherAsync result completes exceptionally if action does
1838 +     */
1839 +    public void testApplyToEitherAsync3() {
1840 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1841 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1842 +        FailingFunction r = new FailingFunction();
1843 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r);
1844 +        f.complete(one);
1845 +        checkCompletedWithWrappedCFException(g);
1846 +    }
1847 +
1848 +    /**
1849 +     * applyToEitherAsync result completes exceptionally if either source cancelled
1850 +     */
1851 +    public void testApplyToEitherAsync4() {
1852 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1853 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1854 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc);
1855 +        assertTrue(f.cancel(true));
1856 +        checkCompletedWithWrappedCancellationException(g);
1857 +
1858 +        f = new CompletableFuture<>();
1859 +        f2 = new CompletableFuture<>();
1860 +        assertTrue(f2.cancel(true));
1861 +        g = f.applyToEitherAsync(f2, inc);
1862 +        checkCompletedWithWrappedCancellationException(g);
1863 +    }
1864 +
1865 +    /**
1866 +     * acceptEitherAsync result completes normally after normal
1867 +     * completion of sources
1868 +     */
1869 +    public void testAcceptEitherAsync() {
1870 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1871 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1872 +        IncAction r = new IncAction();
1873 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1874 +        f.complete(one);
1875 +        checkCompletedNormally(g, null);
1876 +        assertEquals(r.value, 2);
1877 +
1878 +        r = new IncAction();
1879 +        f = new CompletableFuture<>();
1880 +        f.complete(one);
1881 +        f2 = new CompletableFuture<>();
1882 +        g = f.acceptEitherAsync(f2, r);
1883 +        checkCompletedNormally(g, null);
1884 +        assertEquals(r.value, 2);
1885 +    }
1886 +
1887 +    /**
1888 +     * acceptEitherAsync result completes exceptionally after exceptional
1889 +     * completion of source
1890 +     */
1891 +    public void testAcceptEitherAsync2() {
1892 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1893 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1894 +        IncAction r = new IncAction();
1895 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1896 +        f.completeExceptionally(new CFException());
1897 +        checkCompletedWithWrappedCFException(g);
1898 +
1899 +        r = new IncAction();
1900 +        f = new CompletableFuture<>();
1901 +        f2 = new CompletableFuture<>();
1902 +        f2.completeExceptionally(new CFException());
1903 +        g = f.acceptEitherAsync(f2, r);
1904 +        f.complete(one);
1905 +        checkCompletedWithWrappedCFException(g);
1906 +    }
1907 +
1908 +    /**
1909 +     * acceptEitherAsync result completes exceptionally if action does
1910 +     */
1911 +    public void testAcceptEitherAsync3() {
1912 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1913 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1914 +        FailingConsumer r = new FailingConsumer();
1915 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1916 +        f.complete(one);
1917 +        checkCompletedWithWrappedCFException(g);
1918 +    }
1919 +
1920 +    /**
1921 +     * acceptEitherAsync result completes exceptionally if either
1922 +     * source cancelled
1923 +     */
1924 +    public void testAcceptEitherAsync4() {
1925 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1926 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1927 +        IncAction r = new IncAction();
1928 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r);
1929 +        assertTrue(f.cancel(true));
1930 +        checkCompletedWithWrappedCancellationException(g);
1931 +
1932 +        r = new IncAction();
1933 +        f = new CompletableFuture<>();
1934 +        f2 = new CompletableFuture<>();
1935 +        assertTrue(f2.cancel(true));
1936 +        g = f.acceptEitherAsync(f2, r);
1937 +        checkCompletedWithWrappedCancellationException(g);
1938 +    }
1939 +
1940 +    /**
1941 +     * runAfterEitherAsync result completes normally after normal
1942 +     * completion of sources
1943 +     */
1944 +    public void testRunAfterEitherAsync() {
1945 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1946 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1947 +        Noop r = new Noop();
1948 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1949 +        f.complete(one);
1950 +        checkCompletedNormally(g, null);
1951 +        assertTrue(r.ran);
1952 +
1953 +        r = new Noop();
1954 +        f = new CompletableFuture<>();
1955 +        f.complete(one);
1956 +        f2 = new CompletableFuture<>();
1957 +        g = f.runAfterEitherAsync(f2, r);
1958 +        checkCompletedNormally(g, null);
1959 +        assertTrue(r.ran);
1960 +    }
1961 +
1962 +    /**
1963 +     * runAfterEitherAsync result completes exceptionally after exceptional
1964 +     * completion of source
1965 +     */
1966 +    public void testRunAfterEitherAsync2() {
1967 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1968 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1969 +        Noop r = new Noop();
1970 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1971 +        f.completeExceptionally(new CFException());
1972 +        checkCompletedWithWrappedCFException(g);
1973 +
1974 +        r = new Noop();
1975 +        f = new CompletableFuture<>();
1976 +        f2 = new CompletableFuture<>();
1977 +        f2.completeExceptionally(new CFException());
1978 +        g = f.runAfterEitherAsync(f2, r);
1979 +        f.complete(one);
1980 +        checkCompletedWithWrappedCFException(g);
1981 +    }
1982 +
1983 +    /**
1984 +     * runAfterEitherAsync result completes exceptionally if action does
1985 +     */
1986 +    public void testRunAfterEitherAsync3() {
1987 +        CompletableFuture<Integer> f = new CompletableFuture<>();
1988 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
1989 +        FailingNoop r = new FailingNoop();
1990 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
1991 +        f.complete(one);
1992 +        checkCompletedWithWrappedCFException(g);
1993 +    }
1994 +
1995 +    /**
1996 +     * runAfterEitherAsync result completes exceptionally if either
1997 +     * source cancelled
1998 +     */
1999 +    public void testRunAfterEitherAsync4() {
2000 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2001 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2002 +        Noop r = new Noop();
2003 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r);
2004 +        assertTrue(f.cancel(true));
2005 +        checkCompletedWithWrappedCancellationException(g);
2006 +
2007 +        r = new Noop();
2008 +        f = new CompletableFuture<>();
2009 +        f2 = new CompletableFuture<>();
2010 +        assertTrue(f2.cancel(true));
2011 +        g = f.runAfterEitherAsync(f2, r);
2012 +        checkCompletedWithWrappedCancellationException(g);
2013 +    }
2014 +
2015 +    /**
2016 +     * thenComposeAsync result completes normally after normal
2017 +     * completion of source
2018 +     */
2019 +    public void testThenComposeAsync() {
2020 +        CompletableFuture<Integer> f, g;
2021 +        CompletableFutureInc r;
2022 +
2023 +        f = new CompletableFuture<>();
2024 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2025 +        f.complete(one);
2026 +        checkCompletedNormally(g, two);
2027 +
2028 +        f = new CompletableFuture<>();
2029 +        f.complete(one);
2030 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2031 +        checkCompletedNormally(g, two);
2032 +    }
2033 +
2034 +    /**
2035 +     * thenComposeAsync result completes exceptionally after
2036 +     * exceptional completion of source
2037 +     */
2038 +    public void testThenComposeAsync2() {
2039 +        CompletableFuture<Integer> f, g;
2040 +        CompletableFutureInc r;
2041 +
2042 +        f = new CompletableFuture<>();
2043 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2044 +        f.completeExceptionally(new CFException());
2045 +        checkCompletedWithWrappedCFException(g);
2046 +        assertFalse(r.ran);
2047 +
2048 +        f = new CompletableFuture<>();
2049 +        f.completeExceptionally(new CFException());
2050 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2051 +        checkCompletedWithWrappedCFException(g);
2052 +        assertFalse(r.ran);
2053 +    }
2054 +
2055 +    /**
2056 +     * thenComposeAsync result completes exceptionally if action does
2057 +     */
2058 +    public void testThenComposeAsync3() {
2059 +        CompletableFuture<Integer> f, g;
2060 +        FailingCompletableFutureFunction r;
2061 +
2062 +        f = new CompletableFuture<>();
2063 +        g = f.thenComposeAsync(r = new FailingCompletableFutureFunction());
2064 +        f.complete(one);
2065 +        checkCompletedWithWrappedCFException(g);
2066 +
2067 +        f = new CompletableFuture<>();
2068 +        f.complete(one);
2069 +        g = f.thenComposeAsync(r = new FailingCompletableFutureFunction());
2070 +        checkCompletedWithWrappedCFException(g);
2071 +    }
2072 +
2073 +    /**
2074 +     * thenComposeAsync result completes exceptionally if source cancelled
2075 +     */
2076 +    public void testThenComposeAsync4() {
2077 +        CompletableFuture<Integer> f, g;
2078 +        CompletableFutureInc r;
2079 +
2080 +        f = new CompletableFuture<>();
2081 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2082 +        assertTrue(f.cancel(true));
2083 +        checkCompletedWithWrappedCancellationException(g);
2084 +
2085 +        f = new CompletableFuture<>();
2086 +        assertTrue(f.cancel(true));
2087 +        g = f.thenComposeAsync(r = new CompletableFutureInc());
2088 +        checkCompletedWithWrappedCancellationException(g);
2089 +    }
2090 +
2091 +
2092 +    // async with explicit executors
2093 +
2094 +    /**
2095 +     * thenRunAsync result completes normally after normal completion of source
2096 +     */
2097 +    public void testThenRunAsyncE() {
2098 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2099 +        Noop r = new Noop();
2100 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
2101 +        f.complete(null);
2102 +        checkCompletedNormally(g, null);
2103 +
2104 +        // reordered version
2105 +        f = new CompletableFuture<>();
2106 +        f.complete(null);
2107 +        r = new Noop();
2108 +        g = f.thenRunAsync(r, new ThreadExecutor());
2109 +        checkCompletedNormally(g, null);
2110 +    }
2111 +
2112 +    /**
2113 +     * thenRunAsync result completes exceptionally after exceptional
2114 +     * completion of source
2115 +     */
2116 +    public void testThenRunAsync2E() {
2117 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2118 +        Noop r = new Noop();
2119 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
2120 +        f.completeExceptionally(new CFException());
2121 +        try {
2122 +            g.join();
2123 +            shouldThrow();
2124 +        } catch (Exception ok) {
2125 +        }
2126 +        checkCompletedWithWrappedCFException(g);
2127 +    }
2128 +
2129 +    /**
2130 +     * thenRunAsync result completes exceptionally if action does
2131 +     */
2132 +    public void testThenRunAsync3E() {
2133 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2134 +        FailingNoop r = new FailingNoop();
2135 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
2136 +        f.complete(null);
2137 +        checkCompletedWithWrappedCFException(g);
2138 +    }
2139 +
2140 +    /**
2141 +     * thenRunAsync result completes exceptionally if source cancelled
2142 +     */
2143 +    public void testThenRunAsync4E() {
2144 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2145 +        Noop r = new Noop();
2146 +        CompletableFuture<Void> g = f.thenRunAsync(r, new ThreadExecutor());
2147 +        assertTrue(f.cancel(true));
2148 +        checkCompletedWithWrappedCancellationException(g);
2149 +    }
2150 +
2151 +    /**
2152 +     * thenApplyAsync result completes normally after normal completion of source
2153 +     */
2154 +    public void testThenApplyAsyncE() {
2155 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2156 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
2157 +        f.complete(one);
2158 +        checkCompletedNormally(g, two);
2159 +    }
2160 +
2161 +    /**
2162 +     * thenApplyAsync result completes exceptionally after exceptional
2163 +     * completion of source
2164 +     */
2165 +    public void testThenApplyAsync2E() {
2166 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2167 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
2168 +        f.completeExceptionally(new CFException());
2169 +        checkCompletedWithWrappedCFException(g);
2170 +    }
2171 +
2172 +    /**
2173 +     * thenApplyAsync result completes exceptionally if action does
2174 +     */
2175 +    public void testThenApplyAsync3E() {
2176 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2177 +        FailingFunction r = new FailingFunction();
2178 +        CompletableFuture<Integer> g = f.thenApplyAsync(r, new ThreadExecutor());
2179 +        f.complete(null);
2180 +        checkCompletedWithWrappedCFException(g);
2181 +    }
2182 +
2183 +    /**
2184 +     * thenApplyAsync result completes exceptionally if source cancelled
2185 +     */
2186 +    public void testThenApplyAsync4E() {
2187 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2188 +        CompletableFuture<Integer> g = f.thenApplyAsync(inc, new ThreadExecutor());
2189 +        assertTrue(f.cancel(true));
2190 +        checkCompletedWithWrappedCancellationException(g);
2191 +    }
2192 +
2193 +    /**
2194 +     * thenAcceptAsync result completes normally after normal
2195 +     * completion of source
2196 +     */
2197 +    public void testThenAcceptAsyncE() {
2198 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2199 +        IncAction r = new IncAction();
2200 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2201 +        f.complete(one);
2202 +        checkCompletedNormally(g, null);
2203 +        assertEquals(r.value, 2);
2204 +    }
2205 +
2206 +    /**
2207 +     * thenAcceptAsync result completes exceptionally after exceptional
2208 +     * completion of source
2209 +     */
2210 +    public void testThenAcceptAsync2E() {
2211 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2212 +        IncAction r = new IncAction();
2213 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2214 +        f.completeExceptionally(new CFException());
2215 +        checkCompletedWithWrappedCFException(g);
2216 +    }
2217 +
2218 +    /**
2219 +     * thenAcceptAsync result completes exceptionally if action does
2220 +     */
2221 +    public void testThenAcceptAsync3E() {
2222 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2223 +        FailingConsumer r = new FailingConsumer();
2224 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2225 +        f.complete(null);
2226 +        checkCompletedWithWrappedCFException(g);
2227 +    }
2228 +
2229 +    /**
2230 +     * thenAcceptAsync result completes exceptionally if source cancelled
2231 +     */
2232 +    public void testThenAcceptAsync4E() {
2233 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2234 +        IncAction r = new IncAction();
2235 +        CompletableFuture<Void> g = f.thenAcceptAsync(r, new ThreadExecutor());
2236 +        assertTrue(f.cancel(true));
2237 +        checkCompletedWithWrappedCancellationException(g);
2238 +    }
2239 +
2240 +    /**
2241 +     * thenCombineAsync result completes normally after normal
2242 +     * completion of sources
2243 +     */
2244 +    public void testThenCombineAsyncE() {
2245 +        CompletableFuture<Integer> f, g, h;
2246 +        ThreadExecutor e = new ThreadExecutor();
2247 +        int count = 0;
2248 +
2249 +        f = new CompletableFuture<>();
2250 +        g = new CompletableFuture<>();
2251 +        h = f.thenCombineAsync(g, subtract, e);
2252 +        f.complete(3);
2253 +        checkIncomplete(h);
2254 +        g.complete(1);
2255 +        checkCompletedNormally(h, 2);
2256 +        assertEquals(++count, e.count.get());
2257 +
2258 +        f = new CompletableFuture<>();
2259 +        g = new CompletableFuture<>();
2260 +        h = f.thenCombineAsync(g, subtract, e);
2261 +        g.complete(1);
2262 +        checkIncomplete(h);
2263 +        f.complete(3);
2264 +        checkCompletedNormally(h, 2);
2265 +        assertEquals(++count, e.count.get());
2266 +
2267 +        f = new CompletableFuture<>();
2268 +        g = new CompletableFuture<>();
2269 +        g.complete(1);
2270 +        f.complete(3);
2271 +        h = f.thenCombineAsync(g, subtract, e);
2272 +        checkCompletedNormally(h, 2);
2273 +        assertEquals(++count, e.count.get());
2274 +    }
2275 +
2276 +    /**
2277 +     * thenCombineAsync result completes exceptionally after exceptional
2278 +     * completion of either source
2279 +     */
2280 +    public void testThenCombineAsync2E() {
2281 +        CompletableFuture<Integer> f, g, h;
2282 +        ThreadExecutor e = new ThreadExecutor();
2283 +        int count = 0;
2284 +
2285 +        f = new CompletableFuture<>();
2286 +        g = new CompletableFuture<>();
2287 +        h = f.thenCombineAsync(g, subtract, e);
2288 +        f.completeExceptionally(new CFException());
2289 +        checkIncomplete(h);
2290 +        g.complete(1);
2291 +        checkCompletedWithWrappedCFException(h);
2292 +
2293 +        f = new CompletableFuture<>();
2294 +        g = new CompletableFuture<>();
2295 +        h = f.thenCombineAsync(g, subtract, e);
2296 +        g.completeExceptionally(new CFException());
2297 +        checkIncomplete(h);
2298 +        f.complete(3);
2299 +        checkCompletedWithWrappedCFException(h);
2300 +
2301 +        f = new CompletableFuture<>();
2302 +        g = new CompletableFuture<>();
2303 +        g.completeExceptionally(new CFException());
2304 +        h = f.thenCombineAsync(g, subtract, e);
2305 +        checkIncomplete(h);
2306 +        f.complete(3);
2307 +        checkCompletedWithWrappedCFException(h);
2308 +
2309 +        assertEquals(0, e.count.get());
2310 +    }
2311 +
2312 +    /**
2313 +     * thenCombineAsync result completes exceptionally if action does
2314 +     */
2315 +    public void testThenCombineAsync3E() {
2316 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2317 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2318 +        FailingBiFunction r = new FailingBiFunction();
2319 +        CompletableFuture<Integer> g = f.thenCombineAsync(f2, r, new ThreadExecutor());
2320 +        f.complete(one);
2321 +        checkIncomplete(g);
2322 +        assertFalse(r.ran);
2323 +        f2.complete(two);
2324 +        checkCompletedWithWrappedCFException(g);
2325 +        assertTrue(r.ran);
2326 +    }
2327 +
2328 +    /**
2329 +     * thenCombineAsync result completes exceptionally if either source cancelled
2330 +     */
2331 +    public void testThenCombineAsync4E() {
2332 +        CompletableFuture<Integer> f, g, h;
2333 +        ThreadExecutor e = new ThreadExecutor();
2334 +
2335 +        f = new CompletableFuture<>();
2336 +        g = new CompletableFuture<>();
2337 +        h = f.thenCombineAsync(g, subtract, e);
2338 +        assertTrue(f.cancel(true));
2339 +        checkIncomplete(h);
2340 +        g.complete(1);
2341 +        checkCompletedWithWrappedCancellationException(h);
2342 +
2343 +        f = new CompletableFuture<>();
2344 +        g = new CompletableFuture<>();
2345 +        h = f.thenCombineAsync(g, subtract, e);
2346 +        assertTrue(g.cancel(true));
2347 +        checkIncomplete(h);
2348 +        f.complete(3);
2349 +        checkCompletedWithWrappedCancellationException(h);
2350 +
2351 +        f = new CompletableFuture<>();
2352 +        g = new CompletableFuture<>();
2353 +        assertTrue(g.cancel(true));
2354 +        h = f.thenCombineAsync(g, subtract, e);
2355 +        checkIncomplete(h);
2356 +        f.complete(3);
2357 +        checkCompletedWithWrappedCancellationException(h);
2358 +
2359 +        f = new CompletableFuture<>();
2360 +        g = new CompletableFuture<>();
2361 +        assertTrue(f.cancel(true));
2362 +        assertTrue(g.cancel(true));
2363 +        h = f.thenCombineAsync(g, subtract, e);
2364 +        checkCompletedWithWrappedCancellationException(h);
2365 +
2366 +        assertEquals(0, e.count.get());
2367 +    }
2368 +
2369 +    /**
2370 +     * thenAcceptBothAsync result completes normally after normal
2371 +     * completion of sources
2372 +     */
2373 +    public void testThenAcceptBothAsyncE() {
2374 +        CompletableFuture<Integer> f, g;
2375 +        CompletableFuture<Void> h;
2376 +        SubtractAction r;
2377 +        ThreadExecutor e = new ThreadExecutor();
2378 +
2379 +        f = new CompletableFuture<>();
2380 +        g = new CompletableFuture<>();
2381 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2382 +        f.complete(3);
2383 +        checkIncomplete(h);
2384 +        g.complete(1);
2385 +        checkCompletedNormally(h, null);
2386 +        assertEquals(r.value, 2);
2387 +
2388 +        f = new CompletableFuture<>();
2389 +        g = new CompletableFuture<>();
2390 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2391 +        g.complete(1);
2392 +        checkIncomplete(h);
2393 +        f.complete(3);
2394 +        checkCompletedNormally(h, null);
2395 +        assertEquals(r.value, 2);
2396 +
2397 +        f = new CompletableFuture<>();
2398 +        g = new CompletableFuture<>();
2399 +        g.complete(1);
2400 +        f.complete(3);
2401 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2402 +        checkCompletedNormally(h, null);
2403 +        assertEquals(r.value, 2);
2404 +
2405 +        assertEquals(3, e.count.get());
2406 +    }
2407 +
2408 +    /**
2409 +     * thenAcceptBothAsync result completes exceptionally after exceptional
2410 +     * completion of source
2411 +     */
2412 +    public void testThenAcceptBothAsync2E() {
2413 +        CompletableFuture<Integer> f, g;
2414 +        CompletableFuture<Void> h;
2415 +        SubtractAction r;
2416 +        ThreadExecutor e = new ThreadExecutor();
2417 +
2418 +        f = new CompletableFuture<>();
2419 +        g = new CompletableFuture<>();
2420 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2421 +        f.completeExceptionally(new CFException());
2422 +        checkIncomplete(h);
2423 +        g.complete(1);
2424 +        checkCompletedWithWrappedCFException(h);
2425 +
2426 +        f = new CompletableFuture<>();
2427 +        g = new CompletableFuture<>();
2428 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2429 +        g.completeExceptionally(new CFException());
2430 +        checkIncomplete(h);
2431 +        f.complete(3);
2432 +        checkCompletedWithWrappedCFException(h);
2433 +
2434 +        f = new CompletableFuture<>();
2435 +        g = new CompletableFuture<>();
2436 +        f.complete(3);
2437 +        g.completeExceptionally(new CFException());
2438 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2439 +        checkCompletedWithWrappedCFException(h);
2440 +
2441 +        f = new CompletableFuture<>();
2442 +        g = new CompletableFuture<>();
2443 +        f.completeExceptionally(new CFException());
2444 +        g.complete(3);
2445 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2446 +        checkCompletedWithWrappedCFException(h);
2447 +
2448 +        assertEquals(0, e.count.get());
2449 +    }
2450 +
2451 +    /**
2452 +     * thenAcceptBothAsync result completes exceptionally if action does
2453 +     */
2454 +    public void testThenAcceptBothAsync3E() {
2455 +        CompletableFuture<Integer> f, g;
2456 +        CompletableFuture<Void> h;
2457 +        FailingBiConsumer r;
2458 +        ThreadExecutor e = new ThreadExecutor();
2459 +
2460 +        f = new CompletableFuture<>();
2461 +        g = new CompletableFuture<>();
2462 +        h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer(), e);
2463 +        f.complete(3);
2464 +        checkIncomplete(h);
2465 +        g.complete(1);
2466 +        checkCompletedWithWrappedCFException(h);
2467 +
2468 +        f = new CompletableFuture<>();
2469 +        g = new CompletableFuture<>();
2470 +        f.complete(3);
2471 +        g.complete(1);
2472 +        h = f.thenAcceptBothAsync(g, r = new FailingBiConsumer(), e);
2473 +        checkCompletedWithWrappedCFException(h);
2474 +
2475 +        assertEquals(2, e.count.get());
2476 +    }
2477 +
2478 +    /**
2479 +     * thenAcceptBothAsync result completes exceptionally if either source cancelled
2480 +     */
2481 +    public void testThenAcceptBothAsync4E() {
2482 +        CompletableFuture<Integer> f, g;
2483 +        CompletableFuture<Void> h;
2484 +        SubtractAction r;
2485 +        ThreadExecutor e = new ThreadExecutor();
2486 +
2487 +        f = new CompletableFuture<>();
2488 +        g = new CompletableFuture<>();
2489 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2490 +        assertTrue(f.cancel(true));
2491 +        checkIncomplete(h);
2492 +        g.complete(1);
2493 +        checkCompletedWithWrappedCancellationException(h);
2494 +
2495 +        f = new CompletableFuture<>();
2496 +        g = new CompletableFuture<>();
2497 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2498 +        assertTrue(g.cancel(true));
2499 +        checkIncomplete(h);
2500 +        f.complete(3);
2501 +        checkCompletedWithWrappedCancellationException(h);
2502 +
2503 +        f = new CompletableFuture<>();
2504 +        g = new CompletableFuture<>();
2505 +        f.complete(3);
2506 +        assertTrue(g.cancel(true));
2507 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2508 +        checkCompletedWithWrappedCancellationException(h);
2509 +
2510 +        f = new CompletableFuture<>();
2511 +        g = new CompletableFuture<>();
2512 +        assertTrue(f.cancel(true));
2513 +        g.complete(3);
2514 +        h = f.thenAcceptBothAsync(g, r = new SubtractAction(), e);
2515 +        checkCompletedWithWrappedCancellationException(h);
2516 +
2517 +        assertEquals(0, e.count.get());
2518 +    }
2519 +
2520 +    /**
2521 +     * runAfterBothAsync result completes normally after normal
2522 +     * completion of sources
2523 +     */
2524 +    public void testRunAfterBothAsyncE() {
2525 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2526 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2527 +        Noop r = new Noop();
2528 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2529 +        f.complete(one);
2530 +        checkIncomplete(g);
2531 +        f2.complete(two);
2532 +        checkCompletedNormally(g, null);
2533 +        assertTrue(r.ran);
2534 +    }
2535 +
2536 +    /**
2537 +     * runAfterBothAsync result completes exceptionally after exceptional
2538 +     * completion of source
2539 +     */
2540 +    public void testRunAfterBothAsync2E() {
2541 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2542 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2543 +        Noop r = new Noop();
2544 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2545 +        f.completeExceptionally(new CFException());
2546 +        f2.complete(two);
2547 +        checkCompletedWithWrappedCFException(g);
2548 +
2549 +        r = new Noop();
2550 +        f = new CompletableFuture<>();
2551 +        f2 = new CompletableFuture<>();
2552 +        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2553 +        f.complete(one);
2554 +        f2.completeExceptionally(new CFException());
2555 +        checkCompletedWithWrappedCFException(g);
2556 +    }
2557 +
2558 +    /**
2559 +     * runAfterBothAsync result completes exceptionally if action does
2560 +     */
2561 +    public void testRunAfterBothAsync3E() {
2562 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2563 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2564 +        FailingNoop r = new FailingNoop();
2565 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2566 +        f.complete(one);
2567 +        checkIncomplete(g);
2568 +        f2.complete(two);
2569 +        checkCompletedWithWrappedCFException(g);
2570 +    }
2571 +
2572 +    /**
2573 +     * runAfterBothAsync result completes exceptionally if either source cancelled
2574 +     */
2575 +    public void testRunAfterBothAsync4E() {
2576 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2577 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2578 +        Noop r = new Noop();
2579 +        CompletableFuture<Void> g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2580 +        assertTrue(f.cancel(true));
2581 +        f2.complete(two);
2582 +        checkCompletedWithWrappedCancellationException(g);
2583 +
2584 +        r = new Noop();
2585 +        f = new CompletableFuture<>();
2586 +        f2 = new CompletableFuture<>();
2587 +        g = f.runAfterBothAsync(f2, r, new ThreadExecutor());
2588 +        f.complete(one);
2589 +        assertTrue(f2.cancel(true));
2590 +        checkCompletedWithWrappedCancellationException(g);
2591 +    }
2592 +
2593 +    /**
2594 +     * applyToEitherAsync result completes normally after normal
2595 +     * completion of sources
2596 +     */
2597 +    public void testApplyToEitherAsyncE() {
2598 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2599 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2600 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2601 +        f.complete(one);
2602 +        checkCompletedNormally(g, two);
2603 +
2604 +        f = new CompletableFuture<>();
2605 +        f.complete(one);
2606 +        f2 = new CompletableFuture<>();
2607 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2608 +        checkCompletedNormally(g, two);
2609 +    }
2610 +
2611 +    /**
2612 +     * applyToEitherAsync result completes exceptionally after exceptional
2613 +     * completion of source
2614 +     */
2615 +    public void testApplyToEitherAsync2E() {
2616 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2617 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2618 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2619 +        f.completeExceptionally(new CFException());
2620 +        checkCompletedWithWrappedCFException(g);
2621 +
2622 +        f = new CompletableFuture<>();
2623 +        f2 = new CompletableFuture<>();
2624 +        f2.completeExceptionally(new CFException());
2625 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2626 +        f.complete(one);
2627 +        checkCompletedWithWrappedCFException(g);
2628 +    }
2629 +
2630 +    /**
2631 +     * applyToEitherAsync result completes exceptionally if action does
2632 +     */
2633 +    public void testApplyToEitherAsync3E() {
2634 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2635 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2636 +        FailingFunction r = new FailingFunction();
2637 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, r, new ThreadExecutor());
2638 +        f.complete(one);
2639 +        checkCompletedWithWrappedCFException(g);
2640 +    }
2641 +
2642 +    /**
2643 +     * applyToEitherAsync result completes exceptionally if either source cancelled
2644 +     */
2645 +    public void testApplyToEitherAsync4E() {
2646 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2647 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2648 +        CompletableFuture<Integer> g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2649 +        assertTrue(f.cancel(true));
2650 +        checkCompletedWithWrappedCancellationException(g);
2651 +
2652 +        f = new CompletableFuture<>();
2653 +        f2 = new CompletableFuture<>();
2654 +        assertTrue(f2.cancel(true));
2655 +        g = f.applyToEitherAsync(f2, inc, new ThreadExecutor());
2656 +        checkCompletedWithWrappedCancellationException(g);
2657 +    }
2658 +
2659 +    /**
2660 +     * acceptEitherAsync result completes normally after normal
2661 +     * completion of sources
2662 +     */
2663 +    public void testAcceptEitherAsyncE() {
2664 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2665 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2666 +        IncAction r = new IncAction();
2667 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2668 +        f.complete(one);
2669 +        checkCompletedNormally(g, null);
2670 +        assertEquals(r.value, 2);
2671 +
2672 +        r = new IncAction();
2673 +        f = new CompletableFuture<>();
2674 +        f.complete(one);
2675 +        f2 = new CompletableFuture<>();
2676 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2677 +        checkCompletedNormally(g, null);
2678 +        assertEquals(r.value, 2);
2679 +    }
2680 +
2681 +    /**
2682 +     * acceptEitherAsync result completes exceptionally after exceptional
2683 +     * completion of source
2684 +     */
2685 +    public void testAcceptEitherAsync2E() {
2686 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2687 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2688 +        IncAction r = new IncAction();
2689 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2690 +        f.completeExceptionally(new CFException());
2691 +        checkCompletedWithWrappedCFException(g);
2692 +
2693 +        r = new IncAction();
2694 +        f = new CompletableFuture<>();
2695 +        f2 = new CompletableFuture<>();
2696 +        f2.completeExceptionally(new CFException());
2697 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2698 +        f.complete(one);
2699 +        checkCompletedWithWrappedCFException(g);
2700 +    }
2701 +
2702 +    /**
2703 +     * acceptEitherAsync result completes exceptionally if action does
2704 +     */
2705 +    public void testAcceptEitherAsync3E() {
2706 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2707 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2708 +        FailingConsumer r = new FailingConsumer();
2709 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2710 +        f.complete(one);
2711 +        checkCompletedWithWrappedCFException(g);
2712 +    }
2713 +
2714 +    /**
2715 +     * acceptEitherAsync result completes exceptionally if either
2716 +     * source cancelled
2717 +     */
2718 +    public void testAcceptEitherAsync4E() {
2719 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2720 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2721 +        IncAction r = new IncAction();
2722 +        CompletableFuture<Void> g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2723 +        assertTrue(f.cancel(true));
2724 +        checkCompletedWithWrappedCancellationException(g);
2725 +
2726 +        r = new IncAction();
2727 +        f = new CompletableFuture<>();
2728 +        f2 = new CompletableFuture<>();
2729 +        assertTrue(f2.cancel(true));
2730 +        g = f.acceptEitherAsync(f2, r, new ThreadExecutor());
2731 +        checkCompletedWithWrappedCancellationException(g);
2732 +    }
2733 +
2734 +    /**
2735 +     * runAfterEitherAsync result completes normally after normal
2736 +     * completion of sources
2737 +     */
2738 +    public void testRunAfterEitherAsyncE() {
2739 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2740 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2741 +        Noop r = new Noop();
2742 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2743 +        f.complete(one);
2744 +        checkCompletedNormally(g, null);
2745 +        assertTrue(r.ran);
2746 +
2747 +        r = new Noop();
2748 +        f = new CompletableFuture<>();
2749 +        f.complete(one);
2750 +        f2 = new CompletableFuture<>();
2751 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2752 +        checkCompletedNormally(g, null);
2753 +        assertTrue(r.ran);
2754 +    }
2755 +
2756 +    /**
2757 +     * runAfterEitherAsync result completes exceptionally after exceptional
2758 +     * completion of source
2759 +     */
2760 +    public void testRunAfterEitherAsync2E() {
2761 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2762 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2763 +        Noop r = new Noop();
2764 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2765 +        f.completeExceptionally(new CFException());
2766 +        checkCompletedWithWrappedCFException(g);
2767 +
2768 +        r = new Noop();
2769 +        f = new CompletableFuture<>();
2770 +        f2 = new CompletableFuture<>();
2771 +        f2.completeExceptionally(new CFException());
2772 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2773 +        f.complete(one);
2774 +        checkCompletedWithWrappedCFException(g);
2775 +    }
2776 +
2777 +    /**
2778 +     * runAfterEitherAsync result completes exceptionally if action does
2779 +     */
2780 +    public void testRunAfterEitherAsync3E() {
2781 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2782 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2783 +        FailingNoop r = new FailingNoop();
2784 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2785 +        f.complete(one);
2786 +        checkCompletedWithWrappedCFException(g);
2787 +    }
2788 +
2789 +    /**
2790 +     * runAfterEitherAsync result completes exceptionally if either
2791 +     * source cancelled
2792 +     */
2793 +    public void testRunAfterEitherAsync4E() {
2794 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2795 +        CompletableFuture<Integer> f2 = new CompletableFuture<>();
2796 +        Noop r = new Noop();
2797 +        CompletableFuture<Void> g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2798 +        assertTrue(f.cancel(true));
2799 +        checkCompletedWithWrappedCancellationException(g);
2800 +
2801 +        r = new Noop();
2802 +        f = new CompletableFuture<>();
2803 +        f2 = new CompletableFuture<>();
2804 +        assertTrue(f2.cancel(true));
2805 +        g = f.runAfterEitherAsync(f2, r, new ThreadExecutor());
2806 +        checkCompletedWithWrappedCancellationException(g);
2807 +    }
2808 +
2809 +    /**
2810 +     * thenComposeAsync result completes normally after normal
2811 +     * completion of source
2812 +     */
2813 +    public void testThenComposeAsyncE() {
2814 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2815 +        CompletableFutureInc r = new CompletableFutureInc();
2816 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2817 +        f.complete(one);
2818 +        checkCompletedNormally(g, two);
2819 +    }
2820 +
2821 +    /**
2822 +     * thenComposeAsync result completes exceptionally after
2823 +     * exceptional completion of source
2824 +     */
2825 +    public void testThenComposeAsync2E() {
2826 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2827 +        CompletableFutureInc r = new CompletableFutureInc();
2828 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2829 +        f.completeExceptionally(new CFException());
2830 +        checkCompletedWithWrappedCFException(g);
2831 +    }
2832 +
2833 +    /**
2834 +     * thenComposeAsync result completes exceptionally if action does
2835 +     */
2836 +    public void testThenComposeAsync3E() {
2837 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2838 +        FailingCompletableFutureFunction r = new FailingCompletableFutureFunction();
2839 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2840 +        f.complete(one);
2841 +        checkCompletedWithWrappedCFException(g);
2842 +    }
2843 +
2844 +    /**
2845 +     * thenComposeAsync result completes exceptionally if source cancelled
2846 +     */
2847 +    public void testThenComposeAsync4E() {
2848 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2849 +        CompletableFutureInc r = new CompletableFutureInc();
2850 +        CompletableFuture<Integer> g = f.thenComposeAsync(r, new ThreadExecutor());
2851 +        assertTrue(f.cancel(true));
2852 +        checkCompletedWithWrappedCancellationException(g);
2853 +    }
2854 +
2855 +    // other static methods
2856 +
2857 +    /**
2858 +     * allOf(no component futures) returns a future completed normally
2859 +     * with the value null
2860 +     */
2861 +    public void testAllOf_empty() throws Exception {
2862 +        CompletableFuture<Void> f = CompletableFuture.allOf();
2863 +        checkCompletedNormally(f, null);
2864 +    }
2865 +
2866 +    /**
2867 +     * allOf returns a future completed normally with the value null
2868 +     * when all components complete normally
2869 +     */
2870 +    public void testAllOf_normal() throws Exception {
2871 +        for (int k = 1; k < 20; ++k) {
2872 +            CompletableFuture<Integer>[] fs = (CompletableFuture<Integer>[]) new CompletableFuture[k];
2873 +            for (int i = 0; i < k; ++i)
2874 +                fs[i] = new CompletableFuture<>();
2875 +            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
2876 +            for (int i = 0; i < k; ++i) {
2877 +                checkIncomplete(f);
2878 +                checkIncomplete(CompletableFuture.allOf(fs));
2879 +                fs[i].complete(one);
2880 +            }
2881 +            checkCompletedNormally(f, null);
2882 +            checkCompletedNormally(CompletableFuture.allOf(fs), null);
2883 +        }
2884 +    }
2885 +
2886 +    /**
2887 +     * anyOf(no component futures) returns an incomplete future
2888 +     */
2889 +    public void testAnyOf_empty() throws Exception {
2890 +        CompletableFuture<Object> f = CompletableFuture.anyOf();
2891 +        checkIncomplete(f);
2892 +    }
2893 +
2894 +    /**
2895 +     * anyOf returns a future completed normally with a value when
2896 +     * a component future does
2897 +     */
2898 +    public void testAnyOf_normal() throws Exception {
2899 +        for (int k = 0; k < 10; ++k) {
2900 +            CompletableFuture[] fs = new CompletableFuture[k];
2901 +            for (int i = 0; i < k; ++i)
2902 +                fs[i] = new CompletableFuture<>();
2903 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
2904 +            checkIncomplete(f);
2905 +            for (int i = 0; i < k; ++i) {
2906 +                fs[i].complete(one);
2907 +                checkCompletedNormally(f, one);
2908 +                checkCompletedNormally(CompletableFuture.anyOf(fs), one);
2909 +            }
2910 +        }
2911 +    }
2912 +
2913 +    /**
2914 +     * anyOf result completes exceptionally when any component does.
2915 +     */
2916 +    public void testAnyOf_exceptional() throws Exception {
2917 +        for (int k = 0; k < 10; ++k) {
2918 +            CompletableFuture[] fs = new CompletableFuture[k];
2919 +            for (int i = 0; i < k; ++i)
2920 +                fs[i] = new CompletableFuture<>();
2921 +            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
2922 +            checkIncomplete(f);
2923 +            for (int i = 0; i < k; ++i) {
2924 +                fs[i].completeExceptionally(new CFException());
2925 +                checkCompletedWithWrappedCFException(f);
2926 +                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
2927 +            }
2928 +        }
2929 +    }
2930 +
2931 +    /**
2932 +     * Completion methods throw NullPointerException with null arguments
2933 +     */
2934 +    public void testNPE() {
2935 +        CompletableFuture<Integer> f = new CompletableFuture<>();
2936 +        CompletableFuture<Integer> g = new CompletableFuture<>();
2937 +        CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
2938 +        CompletableFuture<?> h;
2939 +        ThreadExecutor exec = new ThreadExecutor();
2940 +
2941 +        Runnable[] throwingActions = {
2942 +            () -> { CompletableFuture.supplyAsync(null); },
2943 +            () -> { CompletableFuture.supplyAsync(null, exec); },
2944 +            () -> { CompletableFuture.supplyAsync(supplyOne, null); },
2945 +
2946 +            () -> { CompletableFuture.runAsync(null); },
2947 +            () -> { CompletableFuture.runAsync(null, exec); },
2948 +            () -> { CompletableFuture.runAsync(() -> {}, null); },
2949 +
2950 +            () -> { f.completeExceptionally(null); },
2951 +
2952 +            () -> { f.thenApply(null); },
2953 +            () -> { f.thenApplyAsync(null); },
2954 +            () -> { f.thenApplyAsync((x) -> x, null); },
2955 +            () -> { f.thenApplyAsync(null, exec); },
2956 +
2957 +            () -> { f.thenAccept(null); },
2958 +            () -> { f.thenAcceptAsync(null); },
2959 +            () -> { f.thenAcceptAsync((x) -> { ; }, null); },
2960 +            () -> { f.thenAcceptAsync(null, exec); },
2961 +
2962 +            () -> { f.thenRun(null); },
2963 +            () -> { f.thenRunAsync(null); },
2964 +            () -> { f.thenRunAsync(() -> { ; }, null); },
2965 +            () -> { f.thenRunAsync(null, exec); },
2966 +
2967 +            () -> { f.thenCombine(g, null); },
2968 +            () -> { f.thenCombineAsync(g, null); },
2969 +            () -> { f.thenCombineAsync(g, null, exec); },
2970 +            () -> { f.thenCombine(nullFuture, (x, y) -> x); },
2971 +            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x); },
2972 +            () -> { f.thenCombineAsync(nullFuture, (x, y) -> x, exec); },
2973 +            () -> { f.thenCombineAsync(g, (x, y) -> x, null); },
2974 +
2975 +            () -> { f.thenAcceptBoth(g, null); },
2976 +            () -> { f.thenAcceptBothAsync(g, null); },
2977 +            () -> { f.thenAcceptBothAsync(g, null, exec); },
2978 +            () -> { f.thenAcceptBoth(nullFuture, (x, y) -> {}); },
2979 +            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}); },
2980 +            () -> { f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec); },
2981 +            () -> { f.thenAcceptBothAsync(g, (x, y) -> {}, null); },
2982 +
2983 +            () -> { f.runAfterBoth(g, null); },
2984 +            () -> { f.runAfterBothAsync(g, null); },
2985 +            () -> { f.runAfterBothAsync(g, null, exec); },
2986 +            () -> { f.runAfterBoth(nullFuture, () -> {}); },
2987 +            () -> { f.runAfterBothAsync(nullFuture, () -> {}); },
2988 +            () -> { f.runAfterBothAsync(nullFuture, () -> {}, exec); },
2989 +            () -> { f.runAfterBothAsync(g, () -> {}, null); },
2990 +
2991 +            () -> { f.applyToEither(g, null); },
2992 +            () -> { f.applyToEitherAsync(g, null); },
2993 +            () -> { f.applyToEitherAsync(g, null, exec); },
2994 +            () -> { f.applyToEither(nullFuture, (x) -> x); },
2995 +            () -> { f.applyToEitherAsync(nullFuture, (x) -> x); },
2996 +            () -> { f.applyToEitherAsync(nullFuture, (x) -> x, exec); },
2997 +            () -> { f.applyToEitherAsync(g, (x) -> x, null); },
2998 +
2999 +            () -> { f.acceptEither(g, null); },
3000 +            () -> { f.acceptEitherAsync(g, null); },
3001 +            () -> { f.acceptEitherAsync(g, null, exec); },
3002 +            () -> { f.acceptEither(nullFuture, (x) -> {}); },
3003 +            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}); },
3004 +            () -> { f.acceptEitherAsync(nullFuture, (x) -> {}, exec); },
3005 +            () -> { f.acceptEitherAsync(g, (x) -> {}, null); },
3006 +
3007 +            () -> { f.runAfterEither(g, null); },
3008 +            () -> { f.runAfterEitherAsync(g, null); },
3009 +            () -> { f.runAfterEitherAsync(g, null, exec); },
3010 +            () -> { f.runAfterEither(nullFuture, () -> {}); },
3011 +            () -> { f.runAfterEitherAsync(nullFuture, () -> {}); },
3012 +            () -> { f.runAfterEitherAsync(nullFuture, () -> {}, exec); },
3013 +            () -> { f.runAfterEitherAsync(g, () -> {}, null); },
3014 +
3015 +            () -> { f.thenCompose(null); },
3016 +            () -> { f.thenComposeAsync(null); },
3017 +            () -> { f.thenComposeAsync(new CompletableFutureInc(), null); },
3018 +            () -> { f.thenComposeAsync(null, exec); },
3019 +
3020 +            () -> { f.exceptionally(null); },
3021 +
3022 +            () -> { f.handle(null); },
3023 +
3024 +            () -> { CompletableFuture.allOf((CompletableFuture<?>)null); },
3025 +            () -> { CompletableFuture.allOf((CompletableFuture<?>[])null); },
3026 +            () -> { CompletableFuture.allOf(f, null); },
3027 +            () -> { CompletableFuture.allOf(null, f); },
3028 +
3029 +            () -> { CompletableFuture.anyOf((CompletableFuture<?>)null); },
3030 +            () -> { CompletableFuture.anyOf((CompletableFuture<?>[])null); },
3031 +            () -> { CompletableFuture.anyOf(f, null); },
3032 +            () -> { CompletableFuture.anyOf(null, f); },
3033 +        };
3034 +
3035 +        assertThrows(NullPointerException.class, throwingActions);
3036 +        assertEquals(0, exec.count.get());
3037 +    }
3038 +
3039 +    /**
3040 +     * toCompletableFuture returns this CompletableFuture.
3041 +     */
3042 +    public void testToCompletableFuture() {
3043 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3044 +        assertSame(f, f.toCompletableFuture());
3045 +    }
3046 +
3047 +    /**
3048 +     * whenComplete action executes on normal completion, propagating
3049 +     * source result.
3050 +     */
3051 +    public void testWhenComplete1() {
3052 +        final AtomicInteger a = new AtomicInteger();
3053 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3054 +        CompletableFuture<Integer> g =
3055 +            f.whenComplete((Integer x, Throwable t) -> a.getAndIncrement());
3056 +        f.complete(three);
3057 +        checkCompletedNormally(f, three);
3058 +        checkCompletedNormally(g, three);
3059 +        assertEquals(a.get(), 1);
3060 +    }
3061 +
3062 +    /**
3063 +     * whenComplete action executes on exceptional completion, propagating
3064 +     * source result.
3065 +     */
3066 +    public void testWhenComplete2() {
3067 +        final AtomicInteger a = new AtomicInteger();
3068 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3069 +        CompletableFuture<Integer> g =
3070 +            f.whenComplete((Integer x, Throwable t) -> a.getAndIncrement());
3071 +        f.completeExceptionally(new CFException());
3072 +        assertTrue(f.isCompletedExceptionally());
3073 +        assertTrue(g.isCompletedExceptionally());
3074 +        assertEquals(a.get(), 1);
3075 +    }
3076 +
3077 +    /**
3078 +     * If a whenComplete action throws an exception when triggered by
3079 +     * a normal completion, it completes exceptionally
3080 +     */
3081 +    public void testWhenComplete3() {
3082 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3083 +        CompletableFuture<Integer> g =
3084 +            f.whenComplete((Integer x, Throwable t) ->
3085 +                           { throw new CFException(); } );
3086 +        f.complete(three);
3087 +        checkCompletedNormally(f, three);
3088 +        assertTrue(g.isCompletedExceptionally());
3089 +        checkCompletedWithWrappedCFException(g);
3090 +    }
3091 +
3092 +    /**
3093 +     * whenCompleteAsync action executes on normal completion, propagating
3094 +     * source result.
3095 +     */
3096 +    public void testWhenCompleteAsync1() {
3097 +        final AtomicInteger a = new AtomicInteger();
3098 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3099 +        CompletableFuture<Integer> g =
3100 +            f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement());
3101 +        f.complete(three);
3102 +        checkCompletedNormally(f, three);
3103 +        checkCompletedNormally(g, three);
3104 +        assertEquals(a.get(), 1);
3105 +    }
3106 +
3107 +    /**
3108 +     * whenCompleteAsync action executes on exceptional completion, propagating
3109 +     * source result.
3110 +     */
3111 +    public void testWhenCompleteAsync2() {
3112 +        final AtomicInteger a = new AtomicInteger();
3113 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3114 +        CompletableFuture<Integer> g =
3115 +            f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement());
3116 +        f.completeExceptionally(new CFException());
3117 +        checkCompletedWithWrappedCFException(f);
3118 +        checkCompletedWithWrappedCFException(g);
3119 +    }
3120 +
3121 +    /**
3122 +     * If a whenCompleteAsync action throws an exception when
3123 +     * triggered by a normal completion, it completes exceptionally
3124 +     */
3125 +    public void testWhenCompleteAsync3() {
3126 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3127 +        CompletableFuture<Integer> g =
3128 +            f.whenCompleteAsync((Integer x, Throwable t) ->
3129 +                           { throw new CFException(); } );
3130 +        f.complete(three);
3131 +        checkCompletedNormally(f, three);
3132 +        checkCompletedWithWrappedCFException(g);
3133 +    }
3134 +
3135 +    /**
3136 +     * whenCompleteAsync action executes on normal completion, propagating
3137 +     * source result.
3138 +     */
3139 +    public void testWhenCompleteAsync1e() {
3140 +        final AtomicInteger a = new AtomicInteger();
3141 +        ThreadExecutor exec = new ThreadExecutor();
3142 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3143 +        CompletableFuture<Integer> g =
3144 +            f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement(),
3145 +                                exec);
3146 +        f.complete(three);
3147 +        checkCompletedNormally(f, three);
3148 +        checkCompletedNormally(g, three);
3149 +        assertEquals(a.get(), 1);
3150 +    }
3151 +
3152 +    /**
3153 +     * whenCompleteAsync action executes on exceptional completion, propagating
3154 +     * source result.
3155 +     */
3156 +    public void testWhenCompleteAsync2e() {
3157 +        final AtomicInteger a = new AtomicInteger();
3158 +        ThreadExecutor exec = new ThreadExecutor();
3159 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3160 +        CompletableFuture<Integer> g =
3161 +            f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement(),
3162 +                                exec);
3163 +        f.completeExceptionally(new CFException());
3164 +        checkCompletedWithWrappedCFException(f);
3165 +        checkCompletedWithWrappedCFException(g);
3166 +    }
3167 +
3168 +    /**
3169 +     * If a whenCompleteAsync action throws an exception when triggered
3170 +     * by a normal completion, it completes exceptionally
3171 +     */
3172 +    public void testWhenCompleteAsync3e() {
3173 +        ThreadExecutor exec = new ThreadExecutor();
3174 +        CompletableFuture<Integer> f = new CompletableFuture<>();
3175 +        CompletableFuture<Integer> g =
3176 +            f.whenCompleteAsync((Integer x, Throwable t) ->
3177 +                                { throw new CFException(); },
3178 +                                exec);
3179 +        f.complete(three);
3180 +        checkCompletedNormally(f, three);
3181 +        checkCompletedWithWrappedCFException(g);
3182 +    }
3183 +
3184 +
3185 +    /**
3186 +     * handleAsync action action completes normally with function
3187 +     * value on either normal or exceptional completion of source
3188 +     */
3189 +    public void testHandleAsync() {
3190 +        CompletableFuture<Integer> f, g;
3191 +        IntegerHandler r;
3192 +
3193 +        f = new CompletableFuture<>();
3194 +        g = f.handleAsync(r = new IntegerHandler());
3195 +        assertFalse(r.ran);
3196 +        f.completeExceptionally(new CFException());
3197 +        checkCompletedWithWrappedCFException(f);
3198 +        checkCompletedNormally(g, three);
3199 +        assertTrue(r.ran);
3200 +
3201 +        f = new CompletableFuture<>();
3202 +        g = f.handleAsync(r = new IntegerHandler());
3203 +        assertFalse(r.ran);
3204 +        f.completeExceptionally(new CFException());
3205 +        checkCompletedWithWrappedCFException(f);
3206 +        checkCompletedNormally(g, three);
3207 +        assertTrue(r.ran);
3208 +
3209 +        f = new CompletableFuture<>();
3210 +        g = f.handleAsync(r = new IntegerHandler());
3211 +        assertFalse(r.ran);
3212 +        f.complete(one);
3213 +        checkCompletedNormally(f, one);
3214 +        checkCompletedNormally(g, two);
3215 +        assertTrue(r.ran);
3216 +
3217 +        f = new CompletableFuture<>();
3218 +        g = f.handleAsync(r = new IntegerHandler());
3219 +        assertFalse(r.ran);
3220 +        f.complete(one);
3221 +        checkCompletedNormally(f, one);
3222 +        checkCompletedNormally(g, two);
3223 +        assertTrue(r.ran);
3224 +    }
3225 +
3226 +    /**
3227 +     * handleAsync action with Executor completes normally with
3228 +     * function value on either normal or exceptional completion of
3229 +     * source
3230 +     */
3231 +    public void testHandleAsync2() {
3232 +        CompletableFuture<Integer> f, g;
3233 +        ThreadExecutor exec = new ThreadExecutor();
3234 +        IntegerHandler r;
3235 +
3236 +        f = new CompletableFuture<>();
3237 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3238 +        assertFalse(r.ran);
3239 +        f.completeExceptionally(new CFException());
3240 +        checkCompletedWithWrappedCFException(f);
3241 +        checkCompletedNormally(g, three);
3242 +        assertTrue(r.ran);
3243 +
3244 +        f = new CompletableFuture<>();
3245 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3246 +        assertFalse(r.ran);
3247 +        f.completeExceptionally(new CFException());
3248 +        checkCompletedWithWrappedCFException(f);
3249 +        checkCompletedNormally(g, three);
3250 +        assertTrue(r.ran);
3251 +
3252 +        f = new CompletableFuture<>();
3253 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3254 +        assertFalse(r.ran);
3255 +        f.complete(one);
3256 +        checkCompletedNormally(f, one);
3257 +        checkCompletedNormally(g, two);
3258 +        assertTrue(r.ran);
3259 +
3260 +        f = new CompletableFuture<>();
3261 +        g = f.handleAsync(r = new IntegerHandler(), exec);
3262 +        assertFalse(r.ran);
3263 +        f.complete(one);
3264 +        checkCompletedNormally(f, one);
3265 +        checkCompletedNormally(g, two);
3266 +        assertTrue(r.ran);
3267 +    }
3268 +
3269   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines