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

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines