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

Comparing jsr166/src/test/tck/CompletableFutureTest.java (file contents):
Revision 1.4 by jsr166, Sun Feb 10 21:18:25 2013 UTC vs.
Revision 1.12 by jsr166, Sun Mar 31 18:16:35 2013 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines