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

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines