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

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines