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

Comparing jsr166/src/test/tck/CompletableFutureTest.java (file contents):
Revision 1.1 by jsr166, Wed Feb 6 19:55:06 2013 UTC vs.
Revision 1.37 by jsr166, Sun Jun 1 23:20:19 2014 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines