• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
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/
6   */
7  
8  package jsr166;
9  
10  import static java.util.concurrent.TimeUnit.MILLISECONDS;
11  import static java.util.concurrent.TimeUnit.SECONDS;
12  import static java.util.concurrent.CompletableFuture.completedFuture;
13  import static java.util.concurrent.CompletableFuture.failedFuture;
14  
15  import java.lang.reflect.Method;
16  import java.lang.reflect.Modifier;
17  
18  import java.util.stream.Collectors;
19  import java.util.stream.Stream;
20  
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.List;
24  import java.util.Objects;
25  import java.util.Set;
26  import java.util.concurrent.Callable;
27  import java.util.concurrent.CancellationException;
28  import java.util.concurrent.CompletableFuture;
29  import java.util.concurrent.CompletionException;
30  import java.util.concurrent.CompletionStage;
31  import java.util.concurrent.ExecutionException;
32  import java.util.concurrent.Executor;
33  import java.util.concurrent.ForkJoinPool;
34  import java.util.concurrent.ForkJoinTask;
35  import java.util.concurrent.TimeoutException;
36  import java.util.concurrent.TimeUnit;
37  import java.util.concurrent.atomic.AtomicInteger;
38  import java.util.concurrent.atomic.AtomicReference;
39  import java.util.function.BiConsumer;
40  import java.util.function.BiFunction;
41  import java.util.function.Consumer;
42  import java.util.function.Function;
43  import java.util.function.Predicate;
44  import java.util.function.Supplier;
45  
46  import junit.framework.AssertionFailedError;
47  import junit.framework.Test;
48  import junit.framework.TestSuite;
49  
50  public class CompletableFutureTest extends JSR166TestCase {
51  
52      // android-note: Removed because the CTS runner does a bad job of
53      // retrying tests that have suite() declarations.
54      //
55      // public static void main(String[] args) {
56      //     main(suite(), args);
57      // }
58      // public static Test suite() {
59      //     return new TestSuite(CompletableFutureTest.class);
60      // }
61  
62      static class CFException extends RuntimeException {}
63  
checkIncomplete(CompletableFuture<?> f)64      void checkIncomplete(CompletableFuture<?> f) {
65          assertFalse(f.isDone());
66          assertFalse(f.isCancelled());
67          assertTrue(f.toString().contains("Not completed"));
68          try {
69              assertNull(f.getNow(null));
70          } catch (Throwable fail) { threadUnexpectedException(fail); }
71          try {
72              f.get(0L, SECONDS);
73              shouldThrow();
74          }
75          catch (TimeoutException success) {}
76          catch (Throwable fail) { threadUnexpectedException(fail); }
77      }
78  
checkCompletedNormally(CompletableFuture<T> f, T value)79      <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
80          checkTimedGet(f, value);
81  
82          try {
83              assertEquals(value, f.join());
84          } catch (Throwable fail) { threadUnexpectedException(fail); }
85          try {
86              assertEquals(value, f.getNow(null));
87          } catch (Throwable fail) { threadUnexpectedException(fail); }
88          try {
89              assertEquals(value, f.get());
90          } catch (Throwable fail) { threadUnexpectedException(fail); }
91          assertTrue(f.isDone());
92          assertFalse(f.isCancelled());
93          assertFalse(f.isCompletedExceptionally());
94          assertTrue(f.toString().contains("[Completed normally]"));
95      }
96  
97      /**
98       * Returns the "raw" internal exceptional completion of f,
99       * without any additional wrapping with CompletionException.
100       */
exceptionalCompletion(CompletableFuture<U> f)101      <U> Throwable exceptionalCompletion(CompletableFuture<U> f) {
102          // handle (and whenComplete) can distinguish between "direct"
103          // and "wrapped" exceptional completion
104          return f.handle((U u, Throwable t) -> t).join();
105      }
106  
checkCompletedExceptionally(CompletableFuture<?> f, boolean wrapped, Consumer<Throwable> checker)107      void checkCompletedExceptionally(CompletableFuture<?> f,
108                                       boolean wrapped,
109                                       Consumer<Throwable> checker) {
110          Throwable cause = exceptionalCompletion(f);
111          if (wrapped) {
112              assertTrue(cause instanceof CompletionException);
113              cause = cause.getCause();
114          }
115          checker.accept(cause);
116  
117          long startTime = System.nanoTime();
118          try {
119              f.get(LONG_DELAY_MS, MILLISECONDS);
120              shouldThrow();
121          } catch (ExecutionException success) {
122              assertSame(cause, success.getCause());
123          } catch (Throwable fail) { threadUnexpectedException(fail); }
124          assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
125  
126          try {
127              f.join();
128              shouldThrow();
129          } catch (CompletionException success) {
130              assertSame(cause, success.getCause());
131          } catch (Throwable fail) { threadUnexpectedException(fail); }
132  
133          try {
134              f.getNow(null);
135              shouldThrow();
136          } catch (CompletionException success) {
137              assertSame(cause, success.getCause());
138          } catch (Throwable fail) { threadUnexpectedException(fail); }
139  
140          try {
141              f.get();
142              shouldThrow();
143          } catch (ExecutionException success) {
144              assertSame(cause, success.getCause());
145          } catch (Throwable fail) { threadUnexpectedException(fail); }
146  
147          assertFalse(f.isCancelled());
148          assertTrue(f.isDone());
149          assertTrue(f.isCompletedExceptionally());
150          assertTrue(f.toString().contains("[Completed exceptionally:"));
151      }
152  
153      void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
154          checkCompletedExceptionally(f, true,
155              (t) -> assertTrue(t instanceof CFException));
156      }
157  
checkCompletedWithWrappedCancellationException(CompletableFuture<?> f)158      void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
159          checkCompletedExceptionally(f, true,
160              (t) -> assertTrue(t instanceof CancellationException));
161      }
162  
checkCompletedWithTimeoutException(CompletableFuture<?> f)163      void checkCompletedWithTimeoutException(CompletableFuture<?> f) {
164          checkCompletedExceptionally(f, false,
165              (t) -> assertTrue(t instanceof TimeoutException));
166      }
167  
checkCompletedWithWrappedException(CompletableFuture<?> f, Throwable ex)168      void checkCompletedWithWrappedException(CompletableFuture<?> f,
169                                              Throwable ex) {
170          checkCompletedExceptionally(f, true, (t) -> assertSame(t, ex));
171      }
172  
checkCompletedExceptionally(CompletableFuture<?> f, Throwable ex)173      void checkCompletedExceptionally(CompletableFuture<?> f, Throwable ex) {
174          checkCompletedExceptionally(f, false, (t) -> assertSame(t, ex));
175      }
176  
checkCancelled(CompletableFuture<?> f)177      void checkCancelled(CompletableFuture<?> f) {
178          long startTime = System.nanoTime();
179          try {
180              f.get(LONG_DELAY_MS, MILLISECONDS);
181              shouldThrow();
182          } catch (CancellationException success) {
183          } catch (Throwable fail) { threadUnexpectedException(fail); }
184          assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
185  
186          try {
187              f.join();
188              shouldThrow();
189          } catch (CancellationException success) {}
190          try {
191              f.getNow(null);
192              shouldThrow();
193          } catch (CancellationException success) {}
194          try {
195              f.get();
196              shouldThrow();
197          } catch (CancellationException success) {
198          } catch (Throwable fail) { threadUnexpectedException(fail); }
199  
200          assertTrue(exceptionalCompletion(f) instanceof CancellationException);
201  
202          assertTrue(f.isDone());
203          assertTrue(f.isCompletedExceptionally());
204          assertTrue(f.isCancelled());
205          assertTrue(f.toString().contains("[Completed exceptionally:"));
206      }
207  
208      /**
209       * A newly constructed CompletableFuture is incomplete, as indicated
210       * by methods isDone, isCancelled, and getNow
211       */
212      public void testConstructor() {
213          CompletableFuture<Integer> f = new CompletableFuture<>();
214          checkIncomplete(f);
215      }
216  
217      /**
218       * complete completes normally, as indicated by methods isDone,
219       * isCancelled, join, get, and getNow
220       */
221      public void testComplete() {
222          for (Integer v1 : new Integer[] { 1, null })
223      {
224          CompletableFuture<Integer> f = new CompletableFuture<>();
225          checkIncomplete(f);
226          assertTrue(f.complete(v1));
227          assertFalse(f.complete(v1));
228          checkCompletedNormally(f, v1);
229      }}
230  
231      /**
232       * completeExceptionally completes exceptionally, as indicated by
233       * methods isDone, isCancelled, join, get, and getNow
234       */
235      public void testCompleteExceptionally() {
236          CompletableFuture<Integer> f = new CompletableFuture<>();
237          CFException ex = new CFException();
238          checkIncomplete(f);
239          f.completeExceptionally(ex);
240          checkCompletedExceptionally(f, ex);
241      }
242  
243      /**
244       * cancel completes exceptionally and reports cancelled, as indicated by
245       * methods isDone, isCancelled, join, get, and getNow
246       */
247      public void testCancel() {
248          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
249      {
250          CompletableFuture<Integer> f = new CompletableFuture<>();
251          checkIncomplete(f);
252          assertTrue(f.cancel(mayInterruptIfRunning));
253          assertTrue(f.cancel(mayInterruptIfRunning));
254          assertTrue(f.cancel(!mayInterruptIfRunning));
255          checkCancelled(f);
256      }}
257  
258      /**
259       * obtrudeValue forces completion with given value
260       */
261      public void testObtrudeValue() {
262          CompletableFuture<Integer> f = new CompletableFuture<>();
263          checkIncomplete(f);
264          assertTrue(f.complete(one));
265          checkCompletedNormally(f, one);
266          f.obtrudeValue(three);
267          checkCompletedNormally(f, three);
268          f.obtrudeValue(two);
269          checkCompletedNormally(f, two);
270          f = new CompletableFuture<>();
271          f.obtrudeValue(three);
272          checkCompletedNormally(f, three);
273          f.obtrudeValue(null);
274          checkCompletedNormally(f, null);
275          f = new CompletableFuture<>();
276          f.completeExceptionally(new CFException());
277          f.obtrudeValue(four);
278          checkCompletedNormally(f, four);
279      }
280  
281      /**
282       * obtrudeException forces completion with given exception
283       */
284      public void testObtrudeException() {
285          for (Integer v1 : new Integer[] { 1, null })
286      {
287          CFException ex;
288          CompletableFuture<Integer> f;
289  
290          f = new CompletableFuture<>();
291          assertTrue(f.complete(v1));
292          for (int i = 0; i < 2; i++) {
293              f.obtrudeException(ex = new CFException());
294              checkCompletedExceptionally(f, ex);
295          }
296  
297          f = new CompletableFuture<>();
298          for (int i = 0; i < 2; i++) {
299              f.obtrudeException(ex = new CFException());
300              checkCompletedExceptionally(f, ex);
301          }
302  
303          f = new CompletableFuture<>();
304          f.completeExceptionally(ex = new CFException());
305          f.obtrudeValue(v1);
306          checkCompletedNormally(f, v1);
307          f.obtrudeException(ex = new CFException());
308          checkCompletedExceptionally(f, ex);
309          f.completeExceptionally(new CFException());
310          checkCompletedExceptionally(f, ex);
311          assertFalse(f.complete(v1));
312          checkCompletedExceptionally(f, ex);
313      }}
314  
315      /**
316       * getNumberOfDependents returns number of dependent tasks
317       */
318      public void testGetNumberOfDependents() {
319          for (ExecutionMode m : ExecutionMode.values())
320          for (Integer v1 : new Integer[] { 1, null })
321      {
322          CompletableFuture<Integer> f = new CompletableFuture<>();
323          assertEquals(0, f.getNumberOfDependents());
324          final CompletableFuture<Void> g = m.thenRun(f, new Noop(m));
325          assertEquals(1, f.getNumberOfDependents());
326          assertEquals(0, g.getNumberOfDependents());
327          final CompletableFuture<Void> h = m.thenRun(f, new Noop(m));
328          assertEquals(2, f.getNumberOfDependents());
329          assertEquals(0, h.getNumberOfDependents());
330          assertTrue(f.complete(v1));
331          checkCompletedNormally(g, null);
332          checkCompletedNormally(h, null);
333          assertEquals(0, f.getNumberOfDependents());
334          assertEquals(0, g.getNumberOfDependents());
335          assertEquals(0, h.getNumberOfDependents());
336      }}
337  
338      /**
339       * toString indicates current completion state
340       */
341      public void testToString() {
342          CompletableFuture<String> f;
343  
344          f = new CompletableFuture<String>();
345          assertTrue(f.toString().contains("[Not completed]"));
346  
347          assertTrue(f.complete("foo"));
348          assertTrue(f.toString().contains("[Completed normally]"));
349  
350          f = new CompletableFuture<String>();
351          assertTrue(f.completeExceptionally(new IndexOutOfBoundsException()));
352          assertTrue(f.toString().contains("[Completed exceptionally:"));
353  
354          for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
355              f = new CompletableFuture<String>();
356              assertTrue(f.cancel(mayInterruptIfRunning));
357              assertTrue(f.toString().contains("[Completed exceptionally:"));
358          }
359      }
360  
361      /**
362       * completedFuture returns a completed CompletableFuture with given value
363       */
364      public void testCompletedFuture() {
365          CompletableFuture<String> f = CompletableFuture.completedFuture("test");
366          checkCompletedNormally(f, "test");
367      }
368  
369      abstract class CheckedAction {
370          int invocationCount = 0;
371          final ExecutionMode m;
372          CheckedAction(ExecutionMode m) { this.m = m; }
373          void invoked() {
374              m.checkExecutionMode();
375              assertEquals(0, invocationCount++);
376          }
377          void assertNotInvoked() { assertEquals(0, invocationCount); }
378          void assertInvoked() { assertEquals(1, invocationCount); }
379      }
380  
381      abstract class CheckedIntegerAction extends CheckedAction {
382          Integer value;
383          CheckedIntegerAction(ExecutionMode m) { super(m); }
384          void assertValue(Integer expected) {
385              assertInvoked();
386              assertEquals(expected, value);
387          }
388      }
389  
390      class IntegerSupplier extends CheckedAction
391          implements Supplier<Integer>
392      {
393          final Integer value;
394          IntegerSupplier(ExecutionMode m, Integer value) {
395              super(m);
396              this.value = value;
397          }
398          public Integer get() {
399              invoked();
400              return value;
401          }
402      }
403  
404      // A function that handles and produces null values as well.
405      static Integer inc(Integer x) {
406          return (x == null) ? null : x + 1;
407      }
408  
409      class NoopConsumer extends CheckedIntegerAction
410          implements Consumer<Integer>
411      {
412          NoopConsumer(ExecutionMode m) { super(m); }
413          public void accept(Integer x) {
414              invoked();
415              value = x;
416          }
417      }
418  
419      class IncFunction extends CheckedIntegerAction
420          implements Function<Integer,Integer>
421      {
422          IncFunction(ExecutionMode m) { super(m); }
423          public Integer apply(Integer x) {
424              invoked();
425              return value = inc(x);
426          }
427      }
428  
429      // Choose non-commutative actions for better coverage
430      // A non-commutative function that handles and produces null values as well.
431      static Integer subtract(Integer x, Integer y) {
432          return (x == null && y == null) ? null :
433              ((x == null) ? 42 : x.intValue())
434              - ((y == null) ? 99 : y.intValue());
435      }
436  
437      class SubtractAction extends CheckedIntegerAction
438          implements BiConsumer<Integer, Integer>
439      {
440          SubtractAction(ExecutionMode m) { super(m); }
441          public void accept(Integer x, Integer y) {
442              invoked();
443              value = subtract(x, y);
444          }
445      }
446  
447      class SubtractFunction extends CheckedIntegerAction
448          implements BiFunction<Integer, Integer, Integer>
449      {
450          SubtractFunction(ExecutionMode m) { super(m); }
451          public Integer apply(Integer x, Integer y) {
452              invoked();
453              return value = subtract(x, y);
454          }
455      }
456  
457      class Noop extends CheckedAction implements Runnable {
458          Noop(ExecutionMode m) { super(m); }
459          public void run() {
460              invoked();
461          }
462      }
463  
464      class FailingSupplier extends CheckedAction
465          implements Supplier<Integer>
466      {
467          FailingSupplier(ExecutionMode m) { super(m); }
468          public Integer get() {
469              invoked();
470              throw new CFException();
471          }
472      }
473  
474      class FailingConsumer extends CheckedIntegerAction
475          implements Consumer<Integer>
476      {
477          FailingConsumer(ExecutionMode m) { super(m); }
478          public void accept(Integer x) {
479              invoked();
480              value = x;
481              throw new CFException();
482          }
483      }
484  
485      class FailingBiConsumer extends CheckedIntegerAction
486          implements BiConsumer<Integer, Integer>
487      {
488          FailingBiConsumer(ExecutionMode m) { super(m); }
489          public void accept(Integer x, Integer y) {
490              invoked();
491              value = subtract(x, y);
492              throw new CFException();
493          }
494      }
495  
496      class FailingFunction extends CheckedIntegerAction
497          implements Function<Integer, Integer>
498      {
499          FailingFunction(ExecutionMode m) { super(m); }
500          public Integer apply(Integer x) {
501              invoked();
502              value = x;
503              throw new CFException();
504          }
505      }
506  
507      class FailingBiFunction extends CheckedIntegerAction
508          implements BiFunction<Integer, Integer, Integer>
509      {
510          FailingBiFunction(ExecutionMode m) { super(m); }
511          public Integer apply(Integer x, Integer y) {
512              invoked();
513              value = subtract(x, y);
514              throw new CFException();
515          }
516      }
517  
518      class FailingRunnable extends CheckedAction implements Runnable {
519          FailingRunnable(ExecutionMode m) { super(m); }
520          public void run() {
521              invoked();
522              throw new CFException();
523          }
524      }
525  
526      class CompletableFutureInc extends CheckedIntegerAction
527          implements Function<Integer, CompletableFuture<Integer>>
528      {
529          CompletableFutureInc(ExecutionMode m) { super(m); }
530          public CompletableFuture<Integer> apply(Integer x) {
531              invoked();
532              value = x;
533              CompletableFuture<Integer> f = new CompletableFuture<>();
534              assertTrue(f.complete(inc(x)));
535              return f;
536          }
537      }
538  
539      class FailingCompletableFutureFunction extends CheckedIntegerAction
540          implements Function<Integer, CompletableFuture<Integer>>
541      {
542          FailingCompletableFutureFunction(ExecutionMode m) { super(m); }
543          public CompletableFuture<Integer> apply(Integer x) {
544              invoked();
545              value = x;
546              throw new CFException();
547          }
548      }
549  
550      // Used for explicit executor tests
551      static final class ThreadExecutor implements Executor {
552          final AtomicInteger count = new AtomicInteger(0);
553          static final ThreadGroup tg = new ThreadGroup("ThreadExecutor");
554          static boolean startedCurrentThread() {
555              return Thread.currentThread().getThreadGroup() == tg;
556          }
557  
558          public void execute(Runnable r) {
559              count.getAndIncrement();
560              new Thread(tg, r).start();
561          }
562      }
563  
564      static final boolean defaultExecutorIsCommonPool
565          = ForkJoinPool.getCommonPoolParallelism() > 1;
566  
567      /**
568       * Permits the testing of parallel code for the 3 different
569       * execution modes without copy/pasting all the test methods.
570       */
571      enum ExecutionMode {
572          SYNC {
573              public void checkExecutionMode() {
574                  assertFalse(ThreadExecutor.startedCurrentThread());
575                  assertNull(ForkJoinTask.getPool());
576              }
577              public CompletableFuture<Void> runAsync(Runnable a) {
578                  throw new UnsupportedOperationException();
579              }
580              public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
581                  throw new UnsupportedOperationException();
582              }
583              public <T> CompletableFuture<Void> thenRun
584                  (CompletableFuture<T> f, Runnable a) {
585                  return f.thenRun(a);
586              }
587              public <T> CompletableFuture<Void> thenAccept
588                  (CompletableFuture<T> f, Consumer<? super T> a) {
589                  return f.thenAccept(a);
590              }
591              public <T,U> CompletableFuture<U> thenApply
592                  (CompletableFuture<T> f, Function<? super T,U> a) {
593                  return f.thenApply(a);
594              }
595              public <T,U> CompletableFuture<U> thenCompose
596                  (CompletableFuture<T> f,
597                   Function<? super T,? extends CompletionStage<U>> a) {
598                  return f.thenCompose(a);
599              }
600              public <T,U> CompletableFuture<U> handle
601                  (CompletableFuture<T> f,
602                   BiFunction<? super T,Throwable,? extends U> a) {
603                  return f.handle(a);
604              }
605              public <T> CompletableFuture<T> whenComplete
606                  (CompletableFuture<T> f,
607                   BiConsumer<? super T,? super Throwable> a) {
608                  return f.whenComplete(a);
609              }
610              public <T,U> CompletableFuture<Void> runAfterBoth
611                  (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
612                  return f.runAfterBoth(g, a);
613              }
614              public <T,U> CompletableFuture<Void> thenAcceptBoth
615                  (CompletableFuture<T> f,
616                   CompletionStage<? extends U> g,
617                   BiConsumer<? super T,? super U> a) {
618                  return f.thenAcceptBoth(g, a);
619              }
620              public <T,U,V> CompletableFuture<V> thenCombine
621                  (CompletableFuture<T> f,
622                   CompletionStage<? extends U> g,
623                   BiFunction<? super T,? super U,? extends V> a) {
624                  return f.thenCombine(g, a);
625              }
626              public <T> CompletableFuture<Void> runAfterEither
627                  (CompletableFuture<T> f,
628                   CompletionStage<?> g,
629                   java.lang.Runnable a) {
630                  return f.runAfterEither(g, a);
631              }
632              public <T> CompletableFuture<Void> acceptEither
633                  (CompletableFuture<T> f,
634                   CompletionStage<? extends T> g,
635                   Consumer<? super T> a) {
636                  return f.acceptEither(g, a);
637              }
638              public <T,U> CompletableFuture<U> applyToEither
639                  (CompletableFuture<T> f,
640                   CompletionStage<? extends T> g,
641                   Function<? super T,U> a) {
642                  return f.applyToEither(g, a);
643              }
644          },
645  
646          ASYNC {
647              public void checkExecutionMode() {
648                  assertEquals(defaultExecutorIsCommonPool,
649                               (ForkJoinPool.commonPool() == ForkJoinTask.getPool()));
650              }
651              public CompletableFuture<Void> runAsync(Runnable a) {
652                  return CompletableFuture.runAsync(a);
653              }
654              public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
655                  return CompletableFuture.supplyAsync(a);
656              }
657              public <T> CompletableFuture<Void> thenRun
658                  (CompletableFuture<T> f, Runnable a) {
659                  return f.thenRunAsync(a);
660              }
661              public <T> CompletableFuture<Void> thenAccept
662                  (CompletableFuture<T> f, Consumer<? super T> a) {
663                  return f.thenAcceptAsync(a);
664              }
665              public <T,U> CompletableFuture<U> thenApply
666                  (CompletableFuture<T> f, Function<? super T,U> a) {
667                  return f.thenApplyAsync(a);
668              }
669              public <T,U> CompletableFuture<U> thenCompose
670                  (CompletableFuture<T> f,
671                   Function<? super T,? extends CompletionStage<U>> a) {
672                  return f.thenComposeAsync(a);
673              }
674              public <T,U> CompletableFuture<U> handle
675                  (CompletableFuture<T> f,
676                   BiFunction<? super T,Throwable,? extends U> a) {
677                  return f.handleAsync(a);
678              }
679              public <T> CompletableFuture<T> whenComplete
680                  (CompletableFuture<T> f,
681                   BiConsumer<? super T,? super Throwable> a) {
682                  return f.whenCompleteAsync(a);
683              }
684              public <T,U> CompletableFuture<Void> runAfterBoth
685                  (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
686                  return f.runAfterBothAsync(g, a);
687              }
688              public <T,U> CompletableFuture<Void> thenAcceptBoth
689                  (CompletableFuture<T> f,
690                   CompletionStage<? extends U> g,
691                   BiConsumer<? super T,? super U> a) {
692                  return f.thenAcceptBothAsync(g, a);
693              }
694              public <T,U,V> CompletableFuture<V> thenCombine
695                  (CompletableFuture<T> f,
696                   CompletionStage<? extends U> g,
697                   BiFunction<? super T,? super U,? extends V> a) {
698                  return f.thenCombineAsync(g, a);
699              }
700              public <T> CompletableFuture<Void> runAfterEither
701                  (CompletableFuture<T> f,
702                   CompletionStage<?> g,
703                   java.lang.Runnable a) {
704                  return f.runAfterEitherAsync(g, a);
705              }
706              public <T> CompletableFuture<Void> acceptEither
707                  (CompletableFuture<T> f,
708                   CompletionStage<? extends T> g,
709                   Consumer<? super T> a) {
710                  return f.acceptEitherAsync(g, a);
711              }
712              public <T,U> CompletableFuture<U> applyToEither
713                  (CompletableFuture<T> f,
714                   CompletionStage<? extends T> g,
715                   Function<? super T,U> a) {
716                  return f.applyToEitherAsync(g, a);
717              }
718          },
719  
720          EXECUTOR {
721              public void checkExecutionMode() {
722                  assertTrue(ThreadExecutor.startedCurrentThread());
723              }
724              public CompletableFuture<Void> runAsync(Runnable a) {
725                  return CompletableFuture.runAsync(a, new ThreadExecutor());
726              }
727              public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
728                  return CompletableFuture.supplyAsync(a, new ThreadExecutor());
729              }
730              public <T> CompletableFuture<Void> thenRun
731                  (CompletableFuture<T> f, Runnable a) {
732                  return f.thenRunAsync(a, new ThreadExecutor());
733              }
734              public <T> CompletableFuture<Void> thenAccept
735                  (CompletableFuture<T> f, Consumer<? super T> a) {
736                  return f.thenAcceptAsync(a, new ThreadExecutor());
737              }
738              public <T,U> CompletableFuture<U> thenApply
739                  (CompletableFuture<T> f, Function<? super T,U> a) {
740                  return f.thenApplyAsync(a, new ThreadExecutor());
741              }
742              public <T,U> CompletableFuture<U> thenCompose
743                  (CompletableFuture<T> f,
744                   Function<? super T,? extends CompletionStage<U>> a) {
745                  return f.thenComposeAsync(a, new ThreadExecutor());
746              }
747              public <T,U> CompletableFuture<U> handle
748                  (CompletableFuture<T> f,
749                   BiFunction<? super T,Throwable,? extends U> a) {
750                  return f.handleAsync(a, new ThreadExecutor());
751              }
752              public <T> CompletableFuture<T> whenComplete
753                  (CompletableFuture<T> f,
754                   BiConsumer<? super T,? super Throwable> a) {
755                  return f.whenCompleteAsync(a, new ThreadExecutor());
756              }
757              public <T,U> CompletableFuture<Void> runAfterBoth
758                  (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
759                  return f.runAfterBothAsync(g, a, new ThreadExecutor());
760              }
761              public <T,U> CompletableFuture<Void> thenAcceptBoth
762                  (CompletableFuture<T> f,
763                   CompletionStage<? extends U> g,
764                   BiConsumer<? super T,? super U> a) {
765                  return f.thenAcceptBothAsync(g, a, new ThreadExecutor());
766              }
767              public <T,U,V> CompletableFuture<V> thenCombine
768                  (CompletableFuture<T> f,
769                   CompletionStage<? extends U> g,
770                   BiFunction<? super T,? super U,? extends V> a) {
771                  return f.thenCombineAsync(g, a, new ThreadExecutor());
772              }
773              public <T> CompletableFuture<Void> runAfterEither
774                  (CompletableFuture<T> f,
775                   CompletionStage<?> g,
776                   java.lang.Runnable a) {
777                  return f.runAfterEitherAsync(g, a, new ThreadExecutor());
778              }
779              public <T> CompletableFuture<Void> acceptEither
780                  (CompletableFuture<T> f,
781                   CompletionStage<? extends T> g,
782                   Consumer<? super T> a) {
783                  return f.acceptEitherAsync(g, a, new ThreadExecutor());
784              }
785              public <T,U> CompletableFuture<U> applyToEither
786                  (CompletableFuture<T> f,
787                   CompletionStage<? extends T> g,
788                   Function<? super T,U> a) {
789                  return f.applyToEitherAsync(g, a, new ThreadExecutor());
790              }
791          };
792  
793          public abstract void checkExecutionMode();
794          public abstract CompletableFuture<Void> runAsync(Runnable a);
795          public abstract <U> CompletableFuture<U> supplyAsync(Supplier<U> a);
796          public abstract <T> CompletableFuture<Void> thenRun
797              (CompletableFuture<T> f, Runnable a);
798          public abstract <T> CompletableFuture<Void> thenAccept
799              (CompletableFuture<T> f, Consumer<? super T> a);
800          public abstract <T,U> CompletableFuture<U> thenApply
801              (CompletableFuture<T> f, Function<? super T,U> a);
802          public abstract <T,U> CompletableFuture<U> thenCompose
803              (CompletableFuture<T> f,
804               Function<? super T,? extends CompletionStage<U>> a);
805          public abstract <T,U> CompletableFuture<U> handle
806              (CompletableFuture<T> f,
807               BiFunction<? super T,Throwable,? extends U> a);
808          public abstract <T> CompletableFuture<T> whenComplete
809              (CompletableFuture<T> f,
810               BiConsumer<? super T,? super Throwable> a);
811          public abstract <T,U> CompletableFuture<Void> runAfterBoth
812              (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a);
813          public abstract <T,U> CompletableFuture<Void> thenAcceptBoth
814              (CompletableFuture<T> f,
815               CompletionStage<? extends U> g,
816               BiConsumer<? super T,? super U> a);
817          public abstract <T,U,V> CompletableFuture<V> thenCombine
818              (CompletableFuture<T> f,
819               CompletionStage<? extends U> g,
820               BiFunction<? super T,? super U,? extends V> a);
821          public abstract <T> CompletableFuture<Void> runAfterEither
822              (CompletableFuture<T> f,
823               CompletionStage<?> g,
824               java.lang.Runnable a);
825          public abstract <T> CompletableFuture<Void> acceptEither
826              (CompletableFuture<T> f,
827               CompletionStage<? extends T> g,
828               Consumer<? super T> a);
829          public abstract <T,U> CompletableFuture<U> applyToEither
830              (CompletableFuture<T> f,
831               CompletionStage<? extends T> g,
832               Function<? super T,U> a);
833      }
834  
835      /**
836       * exceptionally action is not invoked when source completes
837       * normally, and source result is propagated
838       */
839      public void testExceptionally_normalCompletion() {
840          for (boolean createIncomplete : new boolean[] { true, false })
841          for (Integer v1 : new Integer[] { 1, null })
842      {
843          final AtomicInteger a = new AtomicInteger(0);
844          final CompletableFuture<Integer> f = new CompletableFuture<>();
845          if (!createIncomplete) assertTrue(f.complete(v1));
846          final CompletableFuture<Integer> g = f.exceptionally
847              ((Throwable t) -> {
848                  a.getAndIncrement();
849                  threadFail("should not be called");
850                  return null;            // unreached
851              });
852          if (createIncomplete) assertTrue(f.complete(v1));
853  
854          checkCompletedNormally(g, v1);
855          checkCompletedNormally(f, v1);
856          assertEquals(0, a.get());
857      }}
858  
859      /**
860       * exceptionally action completes with function value on source
861       * exception
862       */
863      public void testExceptionally_exceptionalCompletion() {
864          for (boolean createIncomplete : new boolean[] { true, false })
865          for (Integer v1 : new Integer[] { 1, null })
866      {
867          final AtomicInteger a = new AtomicInteger(0);
868          final CFException ex = new CFException();
869          final CompletableFuture<Integer> f = new CompletableFuture<>();
870          if (!createIncomplete) f.completeExceptionally(ex);
871          final CompletableFuture<Integer> g = f.exceptionally
872              ((Throwable t) -> {
873                  ExecutionMode.SYNC.checkExecutionMode();
874                  threadAssertSame(t, ex);
875                  a.getAndIncrement();
876                  return v1;
877              });
878          if (createIncomplete) f.completeExceptionally(ex);
879  
880          checkCompletedNormally(g, v1);
881          assertEquals(1, a.get());
882      }}
883  
884      /**
885       * If an "exceptionally action" throws an exception, it completes
886       * exceptionally with that exception
887       */
testExceptionally_exceptionalCompletionActionFailed()888      public void testExceptionally_exceptionalCompletionActionFailed() {
889          for (boolean createIncomplete : new boolean[] { true, false })
890      {
891          final AtomicInteger a = new AtomicInteger(0);
892          final CFException ex1 = new CFException();
893          final CFException ex2 = new CFException();
894          final CompletableFuture<Integer> f = new CompletableFuture<>();
895          if (!createIncomplete) f.completeExceptionally(ex1);
896          final CompletableFuture<Integer> g = f.exceptionally
897              ((Throwable t) -> {
898                  ExecutionMode.SYNC.checkExecutionMode();
899                  threadAssertSame(t, ex1);
900                  a.getAndIncrement();
901                  throw ex2;
902              });
903          if (createIncomplete) f.completeExceptionally(ex1);
904  
905          checkCompletedWithWrappedException(g, ex2);
906          checkCompletedExceptionally(f, ex1);
907          assertEquals(1, a.get());
908      }}
909  
910      /**
911       * whenComplete action executes on normal completion, propagating
912       * source result.
913       */
testWhenComplete_normalCompletion()914      public void testWhenComplete_normalCompletion() {
915          for (ExecutionMode m : ExecutionMode.values())
916          for (boolean createIncomplete : new boolean[] { true, false })
917          for (Integer v1 : new Integer[] { 1, null })
918      {
919          final AtomicInteger a = new AtomicInteger(0);
920          final CompletableFuture<Integer> f = new CompletableFuture<>();
921          if (!createIncomplete) assertTrue(f.complete(v1));
922          final CompletableFuture<Integer> g = m.whenComplete
923              (f,
924               (Integer result, Throwable t) -> {
925                  m.checkExecutionMode();
926                  threadAssertSame(result, v1);
927                  threadAssertNull(t);
928                  a.getAndIncrement();
929              });
930          if (createIncomplete) assertTrue(f.complete(v1));
931  
932          checkCompletedNormally(g, v1);
933          checkCompletedNormally(f, v1);
934          assertEquals(1, a.get());
935      }}
936  
937      /**
938       * whenComplete action executes on exceptional completion, propagating
939       * source result.
940       */
testWhenComplete_exceptionalCompletion()941      public void testWhenComplete_exceptionalCompletion() {
942          for (ExecutionMode m : ExecutionMode.values())
943          for (boolean createIncomplete : new boolean[] { true, false })
944      {
945          final AtomicInteger a = new AtomicInteger(0);
946          final CFException ex = new CFException();
947          final CompletableFuture<Integer> f = new CompletableFuture<>();
948          if (!createIncomplete) f.completeExceptionally(ex);
949          final CompletableFuture<Integer> g = m.whenComplete
950              (f,
951               (Integer result, Throwable t) -> {
952                  m.checkExecutionMode();
953                  threadAssertNull(result);
954                  threadAssertSame(t, ex);
955                  a.getAndIncrement();
956              });
957          if (createIncomplete) f.completeExceptionally(ex);
958  
959          checkCompletedWithWrappedException(g, ex);
960          checkCompletedExceptionally(f, ex);
961          assertEquals(1, a.get());
962      }}
963  
964      /**
965       * whenComplete action executes on cancelled source, propagating
966       * CancellationException.
967       */
testWhenComplete_sourceCancelled()968      public void testWhenComplete_sourceCancelled() {
969          for (ExecutionMode m : ExecutionMode.values())
970          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
971          for (boolean createIncomplete : new boolean[] { true, false })
972      {
973          final AtomicInteger a = new AtomicInteger(0);
974          final CompletableFuture<Integer> f = new CompletableFuture<>();
975          if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
976          final CompletableFuture<Integer> g = m.whenComplete
977              (f,
978               (Integer result, Throwable t) -> {
979                  m.checkExecutionMode();
980                  threadAssertNull(result);
981                  threadAssertTrue(t instanceof CancellationException);
982                  a.getAndIncrement();
983              });
984          if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
985  
986          checkCompletedWithWrappedCancellationException(g);
987          checkCancelled(f);
988          assertEquals(1, a.get());
989      }}
990  
991      /**
992       * If a whenComplete action throws an exception when triggered by
993       * a normal completion, it completes exceptionally
994       */
testWhenComplete_sourceCompletedNormallyActionFailed()995      public void testWhenComplete_sourceCompletedNormallyActionFailed() {
996          for (boolean createIncomplete : new boolean[] { true, false })
997          for (ExecutionMode m : ExecutionMode.values())
998          for (Integer v1 : new Integer[] { 1, null })
999      {
1000          final AtomicInteger a = new AtomicInteger(0);
1001          final CFException ex = new CFException();
1002          final CompletableFuture<Integer> f = new CompletableFuture<>();
1003          if (!createIncomplete) assertTrue(f.complete(v1));
1004          final CompletableFuture<Integer> g = m.whenComplete
1005              (f,
1006               (Integer result, Throwable t) -> {
1007                  m.checkExecutionMode();
1008                  threadAssertSame(result, v1);
1009                  threadAssertNull(t);
1010                  a.getAndIncrement();
1011                  throw ex;
1012              });
1013          if (createIncomplete) assertTrue(f.complete(v1));
1014  
1015          checkCompletedWithWrappedException(g, ex);
1016          checkCompletedNormally(f, v1);
1017          assertEquals(1, a.get());
1018      }}
1019  
1020      /**
1021       * If a whenComplete action throws an exception when triggered by
1022       * a source completion that also throws an exception, the source
1023       * exception takes precedence (unlike handle)
1024       */
testWhenComplete_sourceFailedActionFailed()1025      public void testWhenComplete_sourceFailedActionFailed() {
1026          for (boolean createIncomplete : new boolean[] { true, false })
1027          for (ExecutionMode m : ExecutionMode.values())
1028      {
1029          final AtomicInteger a = new AtomicInteger(0);
1030          final CFException ex1 = new CFException();
1031          final CFException ex2 = new CFException();
1032          final CompletableFuture<Integer> f = new CompletableFuture<>();
1033  
1034          if (!createIncomplete) f.completeExceptionally(ex1);
1035          final CompletableFuture<Integer> g = m.whenComplete
1036              (f,
1037               (Integer result, Throwable t) -> {
1038                  m.checkExecutionMode();
1039                  threadAssertSame(t, ex1);
1040                  threadAssertNull(result);
1041                  a.getAndIncrement();
1042                  throw ex2;
1043              });
1044          if (createIncomplete) f.completeExceptionally(ex1);
1045  
1046          checkCompletedWithWrappedException(g, ex1);
1047          checkCompletedExceptionally(f, ex1);
1048          if (testImplementationDetails) {
1049              assertEquals(1, ex1.getSuppressed().length);
1050              assertSame(ex2, ex1.getSuppressed()[0]);
1051          }
1052          assertEquals(1, a.get());
1053      }}
1054  
1055      /**
1056       * handle action completes normally with function value on normal
1057       * completion of source
1058       */
testHandle_normalCompletion()1059      public void testHandle_normalCompletion() {
1060          for (ExecutionMode m : ExecutionMode.values())
1061          for (boolean createIncomplete : new boolean[] { true, false })
1062          for (Integer v1 : new Integer[] { 1, null })
1063      {
1064          final CompletableFuture<Integer> f = new CompletableFuture<>();
1065          final AtomicInteger a = new AtomicInteger(0);
1066          if (!createIncomplete) assertTrue(f.complete(v1));
1067          final CompletableFuture<Integer> g = m.handle
1068              (f,
1069               (Integer result, Throwable t) -> {
1070                  m.checkExecutionMode();
1071                  threadAssertSame(result, v1);
1072                  threadAssertNull(t);
1073                  a.getAndIncrement();
1074                  return inc(v1);
1075              });
1076          if (createIncomplete) assertTrue(f.complete(v1));
1077  
1078          checkCompletedNormally(g, inc(v1));
1079          checkCompletedNormally(f, v1);
1080          assertEquals(1, a.get());
1081      }}
1082  
1083      /**
1084       * handle action completes normally with function value on
1085       * exceptional completion of source
1086       */
testHandle_exceptionalCompletion()1087      public void testHandle_exceptionalCompletion() {
1088          for (ExecutionMode m : ExecutionMode.values())
1089          for (boolean createIncomplete : new boolean[] { true, false })
1090          for (Integer v1 : new Integer[] { 1, null })
1091      {
1092          final CompletableFuture<Integer> f = new CompletableFuture<>();
1093          final AtomicInteger a = new AtomicInteger(0);
1094          final CFException ex = new CFException();
1095          if (!createIncomplete) f.completeExceptionally(ex);
1096          final CompletableFuture<Integer> g = m.handle
1097              (f,
1098               (Integer result, Throwable t) -> {
1099                  m.checkExecutionMode();
1100                  threadAssertNull(result);
1101                  threadAssertSame(t, ex);
1102                  a.getAndIncrement();
1103                  return v1;
1104              });
1105          if (createIncomplete) f.completeExceptionally(ex);
1106  
1107          checkCompletedNormally(g, v1);
1108          checkCompletedExceptionally(f, ex);
1109          assertEquals(1, a.get());
1110      }}
1111  
1112      /**
1113       * handle action completes normally with function value on
1114       * cancelled source
1115       */
testHandle_sourceCancelled()1116      public void testHandle_sourceCancelled() {
1117          for (ExecutionMode m : ExecutionMode.values())
1118          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1119          for (boolean createIncomplete : new boolean[] { true, false })
1120          for (Integer v1 : new Integer[] { 1, null })
1121      {
1122          final CompletableFuture<Integer> f = new CompletableFuture<>();
1123          final AtomicInteger a = new AtomicInteger(0);
1124          if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1125          final CompletableFuture<Integer> g = m.handle
1126              (f,
1127               (Integer result, Throwable t) -> {
1128                  m.checkExecutionMode();
1129                  threadAssertNull(result);
1130                  threadAssertTrue(t instanceof CancellationException);
1131                  a.getAndIncrement();
1132                  return v1;
1133              });
1134          if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1135  
1136          checkCompletedNormally(g, v1);
1137          checkCancelled(f);
1138          assertEquals(1, a.get());
1139      }}
1140  
1141      /**
1142       * If a "handle action" throws an exception when triggered by
1143       * a normal completion, it completes exceptionally
1144       */
testHandle_sourceCompletedNormallyActionFailed()1145      public void testHandle_sourceCompletedNormallyActionFailed() {
1146          for (ExecutionMode m : ExecutionMode.values())
1147          for (boolean createIncomplete : new boolean[] { true, false })
1148          for (Integer v1 : new Integer[] { 1, null })
1149      {
1150          final CompletableFuture<Integer> f = new CompletableFuture<>();
1151          final AtomicInteger a = new AtomicInteger(0);
1152          final CFException ex = new CFException();
1153          if (!createIncomplete) assertTrue(f.complete(v1));
1154          final CompletableFuture<Integer> g = m.handle
1155              (f,
1156               (Integer result, Throwable t) -> {
1157                  m.checkExecutionMode();
1158                  threadAssertSame(result, v1);
1159                  threadAssertNull(t);
1160                  a.getAndIncrement();
1161                  throw ex;
1162              });
1163          if (createIncomplete) assertTrue(f.complete(v1));
1164  
1165          checkCompletedWithWrappedException(g, ex);
1166          checkCompletedNormally(f, v1);
1167          assertEquals(1, a.get());
1168      }}
1169  
1170      /**
1171       * If a "handle action" throws an exception when triggered by
1172       * a source completion that also throws an exception, the action
1173       * exception takes precedence (unlike whenComplete)
1174       */
testHandle_sourceFailedActionFailed()1175      public void testHandle_sourceFailedActionFailed() {
1176          for (boolean createIncomplete : new boolean[] { true, false })
1177          for (ExecutionMode m : ExecutionMode.values())
1178      {
1179          final AtomicInteger a = new AtomicInteger(0);
1180          final CFException ex1 = new CFException();
1181          final CFException ex2 = new CFException();
1182          final CompletableFuture<Integer> f = new CompletableFuture<>();
1183  
1184          if (!createIncomplete) f.completeExceptionally(ex1);
1185          final CompletableFuture<Integer> g = m.handle
1186              (f,
1187               (Integer result, Throwable t) -> {
1188                  m.checkExecutionMode();
1189                  threadAssertNull(result);
1190                  threadAssertSame(ex1, t);
1191                  a.getAndIncrement();
1192                  throw ex2;
1193              });
1194          if (createIncomplete) f.completeExceptionally(ex1);
1195  
1196          checkCompletedWithWrappedException(g, ex2);
1197          checkCompletedExceptionally(f, ex1);
1198          assertEquals(1, a.get());
1199      }}
1200  
1201      /**
1202       * runAsync completes after running Runnable
1203       */
testRunAsync_normalCompletion()1204      public void testRunAsync_normalCompletion() {
1205          ExecutionMode[] executionModes = {
1206              ExecutionMode.ASYNC,
1207              ExecutionMode.EXECUTOR,
1208          };
1209          for (ExecutionMode m : executionModes)
1210      {
1211          final Noop r = new Noop(m);
1212          final CompletableFuture<Void> f = m.runAsync(r);
1213          assertNull(f.join());
1214          checkCompletedNormally(f, null);
1215          r.assertInvoked();
1216      }}
1217  
1218      /**
1219       * failing runAsync completes exceptionally after running Runnable
1220       */
testRunAsync_exceptionalCompletion()1221      public void testRunAsync_exceptionalCompletion() {
1222          ExecutionMode[] executionModes = {
1223              ExecutionMode.ASYNC,
1224              ExecutionMode.EXECUTOR,
1225          };
1226          for (ExecutionMode m : executionModes)
1227      {
1228          final FailingRunnable r = new FailingRunnable(m);
1229          final CompletableFuture<Void> f = m.runAsync(r);
1230          checkCompletedWithWrappedCFException(f);
1231          r.assertInvoked();
1232      }}
1233  
1234      /**
1235       * supplyAsync completes with result of supplier
1236       */
testSupplyAsync_normalCompletion()1237      public void testSupplyAsync_normalCompletion() {
1238          ExecutionMode[] executionModes = {
1239              ExecutionMode.ASYNC,
1240              ExecutionMode.EXECUTOR,
1241          };
1242          for (ExecutionMode m : executionModes)
1243          for (Integer v1 : new Integer[] { 1, null })
1244      {
1245          final IntegerSupplier r = new IntegerSupplier(m, v1);
1246          final CompletableFuture<Integer> f = m.supplyAsync(r);
1247          assertSame(v1, f.join());
1248          checkCompletedNormally(f, v1);
1249          r.assertInvoked();
1250      }}
1251  
1252      /**
1253       * Failing supplyAsync completes exceptionally
1254       */
testSupplyAsync_exceptionalCompletion()1255      public void testSupplyAsync_exceptionalCompletion() {
1256          ExecutionMode[] executionModes = {
1257              ExecutionMode.ASYNC,
1258              ExecutionMode.EXECUTOR,
1259          };
1260          for (ExecutionMode m : executionModes)
1261      {
1262          FailingSupplier r = new FailingSupplier(m);
1263          CompletableFuture<Integer> f = m.supplyAsync(r);
1264          checkCompletedWithWrappedCFException(f);
1265          r.assertInvoked();
1266      }}
1267  
1268      // seq completion methods
1269  
1270      /**
1271       * thenRun result completes normally after normal completion of source
1272       */
testThenRun_normalCompletion()1273      public void testThenRun_normalCompletion() {
1274          for (ExecutionMode m : ExecutionMode.values())
1275          for (Integer v1 : new Integer[] { 1, null })
1276      {
1277          final CompletableFuture<Integer> f = new CompletableFuture<>();
1278          final Noop[] rs = new Noop[6];
1279          for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1280  
1281          final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1282          final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1283          final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1284          checkIncomplete(h0);
1285          checkIncomplete(h1);
1286          checkIncomplete(h2);
1287          assertTrue(f.complete(v1));
1288          final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1289          final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1290          final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1291  
1292          checkCompletedNormally(h0, null);
1293          checkCompletedNormally(h1, null);
1294          checkCompletedNormally(h2, null);
1295          checkCompletedNormally(h3, null);
1296          checkCompletedNormally(h4, null);
1297          checkCompletedNormally(h5, null);
1298          checkCompletedNormally(f, v1);
1299          for (Noop r : rs) r.assertInvoked();
1300      }}
1301  
1302      /**
1303       * thenRun result completes exceptionally after exceptional
1304       * completion of source
1305       */
testThenRun_exceptionalCompletion()1306      public void testThenRun_exceptionalCompletion() {
1307          for (ExecutionMode m : ExecutionMode.values())
1308      {
1309          final CFException ex = new CFException();
1310          final CompletableFuture<Integer> f = new CompletableFuture<>();
1311          final Noop[] rs = new Noop[6];
1312          for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1313  
1314          final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1315          final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1316          final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1317          checkIncomplete(h0);
1318          checkIncomplete(h1);
1319          checkIncomplete(h2);
1320          assertTrue(f.completeExceptionally(ex));
1321          final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1322          final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1323          final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1324  
1325          checkCompletedWithWrappedException(h0, ex);
1326          checkCompletedWithWrappedException(h1, ex);
1327          checkCompletedWithWrappedException(h2, ex);
1328          checkCompletedWithWrappedException(h3, ex);
1329          checkCompletedWithWrappedException(h4, ex);
1330          checkCompletedWithWrappedException(h5, ex);
1331          checkCompletedExceptionally(f, ex);
1332          for (Noop r : rs) r.assertNotInvoked();
1333      }}
1334  
1335      /**
1336       * thenRun result completes exceptionally if source cancelled
1337       */
testThenRun_sourceCancelled()1338      public void testThenRun_sourceCancelled() {
1339          for (ExecutionMode m : ExecutionMode.values())
1340          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1341      {
1342          final CompletableFuture<Integer> f = new CompletableFuture<>();
1343          final Noop[] rs = new Noop[6];
1344          for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1345  
1346          final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1347          final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1348          final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1349          checkIncomplete(h0);
1350          checkIncomplete(h1);
1351          checkIncomplete(h2);
1352          assertTrue(f.cancel(mayInterruptIfRunning));
1353          final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1354          final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1355          final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1356  
1357          checkCompletedWithWrappedCancellationException(h0);
1358          checkCompletedWithWrappedCancellationException(h1);
1359          checkCompletedWithWrappedCancellationException(h2);
1360          checkCompletedWithWrappedCancellationException(h3);
1361          checkCompletedWithWrappedCancellationException(h4);
1362          checkCompletedWithWrappedCancellationException(h5);
1363          checkCancelled(f);
1364          for (Noop r : rs) r.assertNotInvoked();
1365      }}
1366  
1367      /**
1368       * thenRun result completes exceptionally if action does
1369       */
testThenRun_actionFailed()1370      public void testThenRun_actionFailed() {
1371          for (ExecutionMode m : ExecutionMode.values())
1372          for (Integer v1 : new Integer[] { 1, null })
1373      {
1374          final CompletableFuture<Integer> f = new CompletableFuture<>();
1375          final FailingRunnable[] rs = new FailingRunnable[6];
1376          for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
1377  
1378          final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1379          final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1380          final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1381          assertTrue(f.complete(v1));
1382          final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1383          final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1384          final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1385  
1386          checkCompletedWithWrappedCFException(h0);
1387          checkCompletedWithWrappedCFException(h1);
1388          checkCompletedWithWrappedCFException(h2);
1389          checkCompletedWithWrappedCFException(h3);
1390          checkCompletedWithWrappedCFException(h4);
1391          checkCompletedWithWrappedCFException(h5);
1392          checkCompletedNormally(f, v1);
1393      }}
1394  
1395      /**
1396       * thenApply result completes normally after normal completion of source
1397       */
testThenApply_normalCompletion()1398      public void testThenApply_normalCompletion() {
1399          for (ExecutionMode m : ExecutionMode.values())
1400          for (Integer v1 : new Integer[] { 1, null })
1401      {
1402          final CompletableFuture<Integer> f = new CompletableFuture<>();
1403          final IncFunction[] rs = new IncFunction[4];
1404          for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1405  
1406          final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1407          final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1408          checkIncomplete(h0);
1409          checkIncomplete(h1);
1410          assertTrue(f.complete(v1));
1411          final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1412          final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1413  
1414          checkCompletedNormally(h0, inc(v1));
1415          checkCompletedNormally(h1, inc(v1));
1416          checkCompletedNormally(h2, inc(v1));
1417          checkCompletedNormally(h3, inc(v1));
1418          checkCompletedNormally(f, v1);
1419          for (IncFunction r : rs) r.assertValue(inc(v1));
1420      }}
1421  
1422      /**
1423       * thenApply result completes exceptionally after exceptional
1424       * completion of source
1425       */
testThenApply_exceptionalCompletion()1426      public void testThenApply_exceptionalCompletion() {
1427          for (ExecutionMode m : ExecutionMode.values())
1428      {
1429          final CFException ex = new CFException();
1430          final CompletableFuture<Integer> f = new CompletableFuture<>();
1431          final IncFunction[] rs = new IncFunction[4];
1432          for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1433  
1434          final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1435          final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1436          assertTrue(f.completeExceptionally(ex));
1437          final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1438          final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1439  
1440          checkCompletedWithWrappedException(h0, ex);
1441          checkCompletedWithWrappedException(h1, ex);
1442          checkCompletedWithWrappedException(h2, ex);
1443          checkCompletedWithWrappedException(h3, ex);
1444          checkCompletedExceptionally(f, ex);
1445          for (IncFunction r : rs) r.assertNotInvoked();
1446      }}
1447  
1448      /**
1449       * thenApply result completes exceptionally if source cancelled
1450       */
testThenApply_sourceCancelled()1451      public void testThenApply_sourceCancelled() {
1452          for (ExecutionMode m : ExecutionMode.values())
1453          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1454      {
1455          final CompletableFuture<Integer> f = new CompletableFuture<>();
1456          final IncFunction[] rs = new IncFunction[4];
1457          for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1458  
1459          final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1460          final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1461          assertTrue(f.cancel(mayInterruptIfRunning));
1462          final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1463          final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1464  
1465          checkCompletedWithWrappedCancellationException(h0);
1466          checkCompletedWithWrappedCancellationException(h1);
1467          checkCompletedWithWrappedCancellationException(h2);
1468          checkCompletedWithWrappedCancellationException(h3);
1469          checkCancelled(f);
1470          for (IncFunction r : rs) r.assertNotInvoked();
1471      }}
1472  
1473      /**
1474       * thenApply result completes exceptionally if action does
1475       */
testThenApply_actionFailed()1476      public void testThenApply_actionFailed() {
1477          for (ExecutionMode m : ExecutionMode.values())
1478          for (Integer v1 : new Integer[] { 1, null })
1479      {
1480          final CompletableFuture<Integer> f = new CompletableFuture<>();
1481          final FailingFunction[] rs = new FailingFunction[4];
1482          for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
1483  
1484          final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1485          final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1486          assertTrue(f.complete(v1));
1487          final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1488          final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1489  
1490          checkCompletedWithWrappedCFException(h0);
1491          checkCompletedWithWrappedCFException(h1);
1492          checkCompletedWithWrappedCFException(h2);
1493          checkCompletedWithWrappedCFException(h3);
1494          checkCompletedNormally(f, v1);
1495      }}
1496  
1497      /**
1498       * thenAccept result completes normally after normal completion of source
1499       */
testThenAccept_normalCompletion()1500      public void testThenAccept_normalCompletion() {
1501          for (ExecutionMode m : ExecutionMode.values())
1502          for (Integer v1 : new Integer[] { 1, null })
1503      {
1504          final CompletableFuture<Integer> f = new CompletableFuture<>();
1505          final NoopConsumer[] rs = new NoopConsumer[4];
1506          for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1507  
1508          final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1509          final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1510          checkIncomplete(h0);
1511          checkIncomplete(h1);
1512          assertTrue(f.complete(v1));
1513          final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1514          final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1515  
1516          checkCompletedNormally(h0, null);
1517          checkCompletedNormally(h1, null);
1518          checkCompletedNormally(h2, null);
1519          checkCompletedNormally(h3, null);
1520          checkCompletedNormally(f, v1);
1521          for (NoopConsumer r : rs) r.assertValue(v1);
1522      }}
1523  
1524      /**
1525       * thenAccept result completes exceptionally after exceptional
1526       * completion of source
1527       */
testThenAccept_exceptionalCompletion()1528      public void testThenAccept_exceptionalCompletion() {
1529          for (ExecutionMode m : ExecutionMode.values())
1530      {
1531          final CFException ex = new CFException();
1532          final CompletableFuture<Integer> f = new CompletableFuture<>();
1533          final NoopConsumer[] rs = new NoopConsumer[4];
1534          for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1535  
1536          final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1537          final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1538          assertTrue(f.completeExceptionally(ex));
1539          final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1540          final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1541  
1542          checkCompletedWithWrappedException(h0, ex);
1543          checkCompletedWithWrappedException(h1, ex);
1544          checkCompletedWithWrappedException(h2, ex);
1545          checkCompletedWithWrappedException(h3, ex);
1546          checkCompletedExceptionally(f, ex);
1547          for (NoopConsumer r : rs) r.assertNotInvoked();
1548      }}
1549  
1550      /**
1551       * thenAccept result completes exceptionally if source cancelled
1552       */
testThenAccept_sourceCancelled()1553      public void testThenAccept_sourceCancelled() {
1554          for (ExecutionMode m : ExecutionMode.values())
1555          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1556      {
1557          final CompletableFuture<Integer> f = new CompletableFuture<>();
1558          final NoopConsumer[] rs = new NoopConsumer[4];
1559          for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1560  
1561          final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1562          final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1563          assertTrue(f.cancel(mayInterruptIfRunning));
1564          final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1565          final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1566  
1567          checkCompletedWithWrappedCancellationException(h0);
1568          checkCompletedWithWrappedCancellationException(h1);
1569          checkCompletedWithWrappedCancellationException(h2);
1570          checkCompletedWithWrappedCancellationException(h3);
1571          checkCancelled(f);
1572          for (NoopConsumer r : rs) r.assertNotInvoked();
1573      }}
1574  
1575      /**
1576       * thenAccept result completes exceptionally if action does
1577       */
testThenAccept_actionFailed()1578      public void testThenAccept_actionFailed() {
1579          for (ExecutionMode m : ExecutionMode.values())
1580          for (Integer v1 : new Integer[] { 1, null })
1581      {
1582          final CompletableFuture<Integer> f = new CompletableFuture<>();
1583          final FailingConsumer[] rs = new FailingConsumer[4];
1584          for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
1585  
1586          final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1587          final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1588          assertTrue(f.complete(v1));
1589          final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1590          final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1591  
1592          checkCompletedWithWrappedCFException(h0);
1593          checkCompletedWithWrappedCFException(h1);
1594          checkCompletedWithWrappedCFException(h2);
1595          checkCompletedWithWrappedCFException(h3);
1596          checkCompletedNormally(f, v1);
1597      }}
1598  
1599      /**
1600       * thenCombine result completes normally after normal completion
1601       * of sources
1602       */
testThenCombine_normalCompletion()1603      public void testThenCombine_normalCompletion() {
1604          for (ExecutionMode m : ExecutionMode.values())
1605          for (boolean fFirst : new boolean[] { true, false })
1606          for (Integer v1 : new Integer[] { 1, null })
1607          for (Integer v2 : new Integer[] { 2, null })
1608      {
1609          final CompletableFuture<Integer> f = new CompletableFuture<>();
1610          final CompletableFuture<Integer> g = new CompletableFuture<>();
1611          final SubtractFunction[] rs = new SubtractFunction[6];
1612          for (int i = 0; i < rs.length; i++) rs[i] = new SubtractFunction(m);
1613  
1614          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1615          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1616          final Integer w1 =  fFirst ? v1 : v2;
1617          final Integer w2 = !fFirst ? v1 : v2;
1618  
1619          final CompletableFuture<Integer> h0 = m.thenCombine(f, g, rs[0]);
1620          final CompletableFuture<Integer> h1 = m.thenCombine(fst, fst, rs[1]);
1621          assertTrue(fst.complete(w1));
1622          final CompletableFuture<Integer> h2 = m.thenCombine(f, g, rs[2]);
1623          final CompletableFuture<Integer> h3 = m.thenCombine(fst, fst, rs[3]);
1624          checkIncomplete(h0); rs[0].assertNotInvoked();
1625          checkIncomplete(h2); rs[2].assertNotInvoked();
1626          checkCompletedNormally(h1, subtract(w1, w1));
1627          checkCompletedNormally(h3, subtract(w1, w1));
1628          rs[1].assertValue(subtract(w1, w1));
1629          rs[3].assertValue(subtract(w1, w1));
1630          assertTrue(snd.complete(w2));
1631          final CompletableFuture<Integer> h4 = m.thenCombine(f, g, rs[4]);
1632  
1633          checkCompletedNormally(h0, subtract(v1, v2));
1634          checkCompletedNormally(h2, subtract(v1, v2));
1635          checkCompletedNormally(h4, subtract(v1, v2));
1636          rs[0].assertValue(subtract(v1, v2));
1637          rs[2].assertValue(subtract(v1, v2));
1638          rs[4].assertValue(subtract(v1, v2));
1639  
1640          checkCompletedNormally(f, v1);
1641          checkCompletedNormally(g, v2);
1642      }}
1643  
1644      /**
1645       * thenCombine result completes exceptionally after exceptional
1646       * completion of either source
1647       */
testThenCombine_exceptionalCompletion()1648      public void testThenCombine_exceptionalCompletion() throws Throwable {
1649          for (ExecutionMode m : ExecutionMode.values())
1650          for (boolean fFirst : new boolean[] { true, false })
1651          for (boolean failFirst : new boolean[] { true, false })
1652          for (Integer v1 : new Integer[] { 1, null })
1653      {
1654          final CompletableFuture<Integer> f = new CompletableFuture<>();
1655          final CompletableFuture<Integer> g = new CompletableFuture<>();
1656          final CFException ex = new CFException();
1657          final SubtractFunction r1 = new SubtractFunction(m);
1658          final SubtractFunction r2 = new SubtractFunction(m);
1659          final SubtractFunction r3 = new SubtractFunction(m);
1660  
1661          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1662          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1663          final Callable<Boolean> complete1 = failFirst ?
1664              () -> fst.completeExceptionally(ex) :
1665              () -> fst.complete(v1);
1666          final Callable<Boolean> complete2 = failFirst ?
1667              () -> snd.complete(v1) :
1668              () -> snd.completeExceptionally(ex);
1669  
1670          final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1671          assertTrue(complete1.call());
1672          final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1673          checkIncomplete(h1);
1674          checkIncomplete(h2);
1675          assertTrue(complete2.call());
1676          final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1677  
1678          checkCompletedWithWrappedException(h1, ex);
1679          checkCompletedWithWrappedException(h2, ex);
1680          checkCompletedWithWrappedException(h3, ex);
1681          r1.assertNotInvoked();
1682          r2.assertNotInvoked();
1683          r3.assertNotInvoked();
1684          checkCompletedNormally(failFirst ? snd : fst, v1);
1685          checkCompletedExceptionally(failFirst ? fst : snd, ex);
1686      }}
1687  
1688      /**
1689       * thenCombine result completes exceptionally if either source cancelled
1690       */
testThenCombine_sourceCancelled()1691      public void testThenCombine_sourceCancelled() throws Throwable {
1692          for (ExecutionMode m : ExecutionMode.values())
1693          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1694          for (boolean fFirst : new boolean[] { true, false })
1695          for (boolean failFirst : new boolean[] { true, false })
1696          for (Integer v1 : new Integer[] { 1, null })
1697      {
1698          final CompletableFuture<Integer> f = new CompletableFuture<>();
1699          final CompletableFuture<Integer> g = new CompletableFuture<>();
1700          final SubtractFunction r1 = new SubtractFunction(m);
1701          final SubtractFunction r2 = new SubtractFunction(m);
1702          final SubtractFunction r3 = new SubtractFunction(m);
1703  
1704          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1705          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1706          final Callable<Boolean> complete1 = failFirst ?
1707              () -> fst.cancel(mayInterruptIfRunning) :
1708              () -> fst.complete(v1);
1709          final Callable<Boolean> complete2 = failFirst ?
1710              () -> snd.complete(v1) :
1711              () -> snd.cancel(mayInterruptIfRunning);
1712  
1713          final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1714          assertTrue(complete1.call());
1715          final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1716          checkIncomplete(h1);
1717          checkIncomplete(h2);
1718          assertTrue(complete2.call());
1719          final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1720  
1721          checkCompletedWithWrappedCancellationException(h1);
1722          checkCompletedWithWrappedCancellationException(h2);
1723          checkCompletedWithWrappedCancellationException(h3);
1724          r1.assertNotInvoked();
1725          r2.assertNotInvoked();
1726          r3.assertNotInvoked();
1727          checkCompletedNormally(failFirst ? snd : fst, v1);
1728          checkCancelled(failFirst ? fst : snd);
1729      }}
1730  
1731      /**
1732       * thenCombine result completes exceptionally if action does
1733       */
testThenCombine_actionFailed()1734      public void testThenCombine_actionFailed() {
1735          for (ExecutionMode m : ExecutionMode.values())
1736          for (boolean fFirst : new boolean[] { true, false })
1737          for (Integer v1 : new Integer[] { 1, null })
1738          for (Integer v2 : new Integer[] { 2, null })
1739      {
1740          final CompletableFuture<Integer> f = new CompletableFuture<>();
1741          final CompletableFuture<Integer> g = new CompletableFuture<>();
1742          final FailingBiFunction r1 = new FailingBiFunction(m);
1743          final FailingBiFunction r2 = new FailingBiFunction(m);
1744          final FailingBiFunction r3 = new FailingBiFunction(m);
1745  
1746          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1747          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1748          final Integer w1 =  fFirst ? v1 : v2;
1749          final Integer w2 = !fFirst ? v1 : v2;
1750  
1751          final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1752          assertTrue(fst.complete(w1));
1753          final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1754          assertTrue(snd.complete(w2));
1755          final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1756  
1757          checkCompletedWithWrappedCFException(h1);
1758          checkCompletedWithWrappedCFException(h2);
1759          checkCompletedWithWrappedCFException(h3);
1760          r1.assertInvoked();
1761          r2.assertInvoked();
1762          r3.assertInvoked();
1763          checkCompletedNormally(f, v1);
1764          checkCompletedNormally(g, v2);
1765      }}
1766  
1767      /**
1768       * thenAcceptBoth result completes normally after normal
1769       * completion of sources
1770       */
testThenAcceptBoth_normalCompletion()1771      public void testThenAcceptBoth_normalCompletion() {
1772          for (ExecutionMode m : ExecutionMode.values())
1773          for (boolean fFirst : new boolean[] { true, false })
1774          for (Integer v1 : new Integer[] { 1, null })
1775          for (Integer v2 : new Integer[] { 2, null })
1776      {
1777          final CompletableFuture<Integer> f = new CompletableFuture<>();
1778          final CompletableFuture<Integer> g = new CompletableFuture<>();
1779          final SubtractAction r1 = new SubtractAction(m);
1780          final SubtractAction r2 = new SubtractAction(m);
1781          final SubtractAction r3 = new SubtractAction(m);
1782  
1783          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1784          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1785          final Integer w1 =  fFirst ? v1 : v2;
1786          final Integer w2 = !fFirst ? v1 : v2;
1787  
1788          final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1789          assertTrue(fst.complete(w1));
1790          final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1791          checkIncomplete(h1);
1792          checkIncomplete(h2);
1793          r1.assertNotInvoked();
1794          r2.assertNotInvoked();
1795          assertTrue(snd.complete(w2));
1796          final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1797  
1798          checkCompletedNormally(h1, null);
1799          checkCompletedNormally(h2, null);
1800          checkCompletedNormally(h3, null);
1801          r1.assertValue(subtract(v1, v2));
1802          r2.assertValue(subtract(v1, v2));
1803          r3.assertValue(subtract(v1, v2));
1804          checkCompletedNormally(f, v1);
1805          checkCompletedNormally(g, v2);
1806      }}
1807  
1808      /**
1809       * thenAcceptBoth result completes exceptionally after exceptional
1810       * completion of either source
1811       */
testThenAcceptBoth_exceptionalCompletion()1812      public void testThenAcceptBoth_exceptionalCompletion() throws Throwable {
1813          for (ExecutionMode m : ExecutionMode.values())
1814          for (boolean fFirst : new boolean[] { true, false })
1815          for (boolean failFirst : new boolean[] { true, false })
1816          for (Integer v1 : new Integer[] { 1, null })
1817      {
1818          final CompletableFuture<Integer> f = new CompletableFuture<>();
1819          final CompletableFuture<Integer> g = new CompletableFuture<>();
1820          final CFException ex = new CFException();
1821          final SubtractAction r1 = new SubtractAction(m);
1822          final SubtractAction r2 = new SubtractAction(m);
1823          final SubtractAction r3 = new SubtractAction(m);
1824  
1825          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1826          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1827          final Callable<Boolean> complete1 = failFirst ?
1828              () -> fst.completeExceptionally(ex) :
1829              () -> fst.complete(v1);
1830          final Callable<Boolean> complete2 = failFirst ?
1831              () -> snd.complete(v1) :
1832              () -> snd.completeExceptionally(ex);
1833  
1834          final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1835          assertTrue(complete1.call());
1836          final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1837          checkIncomplete(h1);
1838          checkIncomplete(h2);
1839          assertTrue(complete2.call());
1840          final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1841  
1842          checkCompletedWithWrappedException(h1, ex);
1843          checkCompletedWithWrappedException(h2, ex);
1844          checkCompletedWithWrappedException(h3, ex);
1845          r1.assertNotInvoked();
1846          r2.assertNotInvoked();
1847          r3.assertNotInvoked();
1848          checkCompletedNormally(failFirst ? snd : fst, v1);
1849          checkCompletedExceptionally(failFirst ? fst : snd, ex);
1850      }}
1851  
1852      /**
1853       * thenAcceptBoth result completes exceptionally if either source cancelled
1854       */
testThenAcceptBoth_sourceCancelled()1855      public void testThenAcceptBoth_sourceCancelled() throws Throwable {
1856          for (ExecutionMode m : ExecutionMode.values())
1857          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1858          for (boolean fFirst : new boolean[] { true, false })
1859          for (boolean failFirst : new boolean[] { true, false })
1860          for (Integer v1 : new Integer[] { 1, null })
1861      {
1862          final CompletableFuture<Integer> f = new CompletableFuture<>();
1863          final CompletableFuture<Integer> g = new CompletableFuture<>();
1864          final SubtractAction r1 = new SubtractAction(m);
1865          final SubtractAction r2 = new SubtractAction(m);
1866          final SubtractAction r3 = new SubtractAction(m);
1867  
1868          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1869          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1870          final Callable<Boolean> complete1 = failFirst ?
1871              () -> fst.cancel(mayInterruptIfRunning) :
1872              () -> fst.complete(v1);
1873          final Callable<Boolean> complete2 = failFirst ?
1874              () -> snd.complete(v1) :
1875              () -> snd.cancel(mayInterruptIfRunning);
1876  
1877          final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1878          assertTrue(complete1.call());
1879          final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1880          checkIncomplete(h1);
1881          checkIncomplete(h2);
1882          assertTrue(complete2.call());
1883          final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1884  
1885          checkCompletedWithWrappedCancellationException(h1);
1886          checkCompletedWithWrappedCancellationException(h2);
1887          checkCompletedWithWrappedCancellationException(h3);
1888          r1.assertNotInvoked();
1889          r2.assertNotInvoked();
1890          r3.assertNotInvoked();
1891          checkCompletedNormally(failFirst ? snd : fst, v1);
1892          checkCancelled(failFirst ? fst : snd);
1893      }}
1894  
1895      /**
1896       * thenAcceptBoth result completes exceptionally if action does
1897       */
testThenAcceptBoth_actionFailed()1898      public void testThenAcceptBoth_actionFailed() {
1899          for (ExecutionMode m : ExecutionMode.values())
1900          for (boolean fFirst : new boolean[] { true, false })
1901          for (Integer v1 : new Integer[] { 1, null })
1902          for (Integer v2 : new Integer[] { 2, null })
1903      {
1904          final CompletableFuture<Integer> f = new CompletableFuture<>();
1905          final CompletableFuture<Integer> g = new CompletableFuture<>();
1906          final FailingBiConsumer r1 = new FailingBiConsumer(m);
1907          final FailingBiConsumer r2 = new FailingBiConsumer(m);
1908          final FailingBiConsumer r3 = new FailingBiConsumer(m);
1909  
1910          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1911          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1912          final Integer w1 =  fFirst ? v1 : v2;
1913          final Integer w2 = !fFirst ? v1 : v2;
1914  
1915          final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
1916          assertTrue(fst.complete(w1));
1917          final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
1918          assertTrue(snd.complete(w2));
1919          final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
1920  
1921          checkCompletedWithWrappedCFException(h1);
1922          checkCompletedWithWrappedCFException(h2);
1923          checkCompletedWithWrappedCFException(h3);
1924          r1.assertInvoked();
1925          r2.assertInvoked();
1926          r3.assertInvoked();
1927          checkCompletedNormally(f, v1);
1928          checkCompletedNormally(g, v2);
1929      }}
1930  
1931      /**
1932       * runAfterBoth result completes normally after normal
1933       * completion of sources
1934       */
testRunAfterBoth_normalCompletion()1935      public void testRunAfterBoth_normalCompletion() {
1936          for (ExecutionMode m : ExecutionMode.values())
1937          for (boolean fFirst : new boolean[] { true, false })
1938          for (Integer v1 : new Integer[] { 1, null })
1939          for (Integer v2 : new Integer[] { 2, null })
1940      {
1941          final CompletableFuture<Integer> f = new CompletableFuture<>();
1942          final CompletableFuture<Integer> g = new CompletableFuture<>();
1943          final Noop r1 = new Noop(m);
1944          final Noop r2 = new Noop(m);
1945          final Noop r3 = new Noop(m);
1946  
1947          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1948          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1949          final Integer w1 =  fFirst ? v1 : v2;
1950          final Integer w2 = !fFirst ? v1 : v2;
1951  
1952          final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
1953          assertTrue(fst.complete(w1));
1954          final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
1955          checkIncomplete(h1);
1956          checkIncomplete(h2);
1957          r1.assertNotInvoked();
1958          r2.assertNotInvoked();
1959          assertTrue(snd.complete(w2));
1960          final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
1961  
1962          checkCompletedNormally(h1, null);
1963          checkCompletedNormally(h2, null);
1964          checkCompletedNormally(h3, null);
1965          r1.assertInvoked();
1966          r2.assertInvoked();
1967          r3.assertInvoked();
1968          checkCompletedNormally(f, v1);
1969          checkCompletedNormally(g, v2);
1970      }}
1971  
1972      /**
1973       * runAfterBoth result completes exceptionally after exceptional
1974       * completion of either source
1975       */
testRunAfterBoth_exceptionalCompletion()1976      public void testRunAfterBoth_exceptionalCompletion() throws Throwable {
1977          for (ExecutionMode m : ExecutionMode.values())
1978          for (boolean fFirst : new boolean[] { true, false })
1979          for (boolean failFirst : new boolean[] { true, false })
1980          for (Integer v1 : new Integer[] { 1, null })
1981      {
1982          final CompletableFuture<Integer> f = new CompletableFuture<>();
1983          final CompletableFuture<Integer> g = new CompletableFuture<>();
1984          final CFException ex = new CFException();
1985          final Noop r1 = new Noop(m);
1986          final Noop r2 = new Noop(m);
1987          final Noop r3 = new Noop(m);
1988  
1989          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1990          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1991          final Callable<Boolean> complete1 = failFirst ?
1992              () -> fst.completeExceptionally(ex) :
1993              () -> fst.complete(v1);
1994          final Callable<Boolean> complete2 = failFirst ?
1995              () -> snd.complete(v1) :
1996              () -> snd.completeExceptionally(ex);
1997  
1998          final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
1999          assertTrue(complete1.call());
2000          final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2001          checkIncomplete(h1);
2002          checkIncomplete(h2);
2003          assertTrue(complete2.call());
2004          final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2005  
2006          checkCompletedWithWrappedException(h1, ex);
2007          checkCompletedWithWrappedException(h2, ex);
2008          checkCompletedWithWrappedException(h3, ex);
2009          r1.assertNotInvoked();
2010          r2.assertNotInvoked();
2011          r3.assertNotInvoked();
2012          checkCompletedNormally(failFirst ? snd : fst, v1);
2013          checkCompletedExceptionally(failFirst ? fst : snd, ex);
2014      }}
2015  
2016      /**
2017       * runAfterBoth result completes exceptionally if either source cancelled
2018       */
testRunAfterBoth_sourceCancelled()2019      public void testRunAfterBoth_sourceCancelled() throws Throwable {
2020          for (ExecutionMode m : ExecutionMode.values())
2021          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2022          for (boolean fFirst : new boolean[] { true, false })
2023          for (boolean failFirst : new boolean[] { true, false })
2024          for (Integer v1 : new Integer[] { 1, null })
2025      {
2026          final CompletableFuture<Integer> f = new CompletableFuture<>();
2027          final CompletableFuture<Integer> g = new CompletableFuture<>();
2028          final Noop r1 = new Noop(m);
2029          final Noop r2 = new Noop(m);
2030          final Noop r3 = new Noop(m);
2031  
2032          final CompletableFuture<Integer> fst =  fFirst ? f : g;
2033          final CompletableFuture<Integer> snd = !fFirst ? f : g;
2034          final Callable<Boolean> complete1 = failFirst ?
2035              () -> fst.cancel(mayInterruptIfRunning) :
2036              () -> fst.complete(v1);
2037          final Callable<Boolean> complete2 = failFirst ?
2038              () -> snd.complete(v1) :
2039              () -> snd.cancel(mayInterruptIfRunning);
2040  
2041          final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2042          assertTrue(complete1.call());
2043          final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2044          checkIncomplete(h1);
2045          checkIncomplete(h2);
2046          assertTrue(complete2.call());
2047          final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2048  
2049          checkCompletedWithWrappedCancellationException(h1);
2050          checkCompletedWithWrappedCancellationException(h2);
2051          checkCompletedWithWrappedCancellationException(h3);
2052          r1.assertNotInvoked();
2053          r2.assertNotInvoked();
2054          r3.assertNotInvoked();
2055          checkCompletedNormally(failFirst ? snd : fst, v1);
2056          checkCancelled(failFirst ? fst : snd);
2057      }}
2058  
2059      /**
2060       * runAfterBoth result completes exceptionally if action does
2061       */
testRunAfterBoth_actionFailed()2062      public void testRunAfterBoth_actionFailed() {
2063          for (ExecutionMode m : ExecutionMode.values())
2064          for (boolean fFirst : new boolean[] { true, false })
2065          for (Integer v1 : new Integer[] { 1, null })
2066          for (Integer v2 : new Integer[] { 2, null })
2067      {
2068          final CompletableFuture<Integer> f = new CompletableFuture<>();
2069          final CompletableFuture<Integer> g = new CompletableFuture<>();
2070          final FailingRunnable r1 = new FailingRunnable(m);
2071          final FailingRunnable r2 = new FailingRunnable(m);
2072          final FailingRunnable r3 = new FailingRunnable(m);
2073  
2074          final CompletableFuture<Integer> fst =  fFirst ? f : g;
2075          final CompletableFuture<Integer> snd = !fFirst ? f : g;
2076          final Integer w1 =  fFirst ? v1 : v2;
2077          final Integer w2 = !fFirst ? v1 : v2;
2078  
2079          final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2080          assertTrue(fst.complete(w1));
2081          final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2082          assertTrue(snd.complete(w2));
2083          final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2084  
2085          checkCompletedWithWrappedCFException(h1);
2086          checkCompletedWithWrappedCFException(h2);
2087          checkCompletedWithWrappedCFException(h3);
2088          r1.assertInvoked();
2089          r2.assertInvoked();
2090          r3.assertInvoked();
2091          checkCompletedNormally(f, v1);
2092          checkCompletedNormally(g, v2);
2093      }}
2094  
2095      /**
2096       * applyToEither result completes normally after normal completion
2097       * of either source
2098       */
testApplyToEither_normalCompletion()2099      public void testApplyToEither_normalCompletion() {
2100          for (ExecutionMode m : ExecutionMode.values())
2101          for (Integer v1 : new Integer[] { 1, null })
2102          for (Integer v2 : new Integer[] { 2, null })
2103      {
2104          final CompletableFuture<Integer> f = new CompletableFuture<>();
2105          final CompletableFuture<Integer> g = new CompletableFuture<>();
2106          final IncFunction[] rs = new IncFunction[6];
2107          for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2108  
2109          final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2110          final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2111          checkIncomplete(h0);
2112          checkIncomplete(h1);
2113          rs[0].assertNotInvoked();
2114          rs[1].assertNotInvoked();
2115          f.complete(v1);
2116          checkCompletedNormally(h0, inc(v1));
2117          checkCompletedNormally(h1, inc(v1));
2118          final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2119          final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2120          checkCompletedNormally(h2, inc(v1));
2121          checkCompletedNormally(h3, inc(v1));
2122          g.complete(v2);
2123  
2124          // unspecified behavior - both source completions available
2125          final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2126          final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2127          rs[4].assertValue(h4.join());
2128          rs[5].assertValue(h5.join());
2129          assertTrue(Objects.equals(inc(v1), h4.join()) ||
2130                     Objects.equals(inc(v2), h4.join()));
2131          assertTrue(Objects.equals(inc(v1), h5.join()) ||
2132                     Objects.equals(inc(v2), h5.join()));
2133  
2134          checkCompletedNormally(f, v1);
2135          checkCompletedNormally(g, v2);
2136          checkCompletedNormally(h0, inc(v1));
2137          checkCompletedNormally(h1, inc(v1));
2138          checkCompletedNormally(h2, inc(v1));
2139          checkCompletedNormally(h3, inc(v1));
2140          for (int i = 0; i < 4; i++) rs[i].assertValue(inc(v1));
2141      }}
2142  
2143      /**
2144       * applyToEither result completes exceptionally after exceptional
2145       * completion of either source
2146       */
testApplyToEither_exceptionalCompletion()2147      public void testApplyToEither_exceptionalCompletion() {
2148          for (ExecutionMode m : ExecutionMode.values())
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 IncFunction[] rs = new IncFunction[6];
2155          for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2156  
2157          final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2158          final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2159          checkIncomplete(h0);
2160          checkIncomplete(h1);
2161          rs[0].assertNotInvoked();
2162          rs[1].assertNotInvoked();
2163          f.completeExceptionally(ex);
2164          checkCompletedWithWrappedException(h0, ex);
2165          checkCompletedWithWrappedException(h1, ex);
2166          final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2167          final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2168          checkCompletedWithWrappedException(h2, ex);
2169          checkCompletedWithWrappedException(h3, ex);
2170          g.complete(v1);
2171  
2172          // unspecified behavior - both source completions available
2173          final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2174          final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2175          try {
2176              assertEquals(inc(v1), h4.join());
2177              rs[4].assertValue(inc(v1));
2178          } catch (CompletionException ok) {
2179              checkCompletedWithWrappedException(h4, ex);
2180              rs[4].assertNotInvoked();
2181          }
2182          try {
2183              assertEquals(inc(v1), h5.join());
2184              rs[5].assertValue(inc(v1));
2185          } catch (CompletionException ok) {
2186              checkCompletedWithWrappedException(h5, ex);
2187              rs[5].assertNotInvoked();
2188          }
2189  
2190          checkCompletedExceptionally(f, ex);
2191          checkCompletedNormally(g, v1);
2192          checkCompletedWithWrappedException(h0, ex);
2193          checkCompletedWithWrappedException(h1, ex);
2194          checkCompletedWithWrappedException(h2, ex);
2195          checkCompletedWithWrappedException(h3, ex);
2196          checkCompletedWithWrappedException(h4, ex);
2197          for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2198      }}
2199  
testApplyToEither_exceptionalCompletion2()2200      public void testApplyToEither_exceptionalCompletion2() {
2201          for (ExecutionMode m : ExecutionMode.values())
2202          for (boolean fFirst : new boolean[] { true, false })
2203          for (Integer v1 : new Integer[] { 1, null })
2204      {
2205          final CompletableFuture<Integer> f = new CompletableFuture<>();
2206          final CompletableFuture<Integer> g = new CompletableFuture<>();
2207          final CFException ex = new CFException();
2208          final IncFunction[] rs = new IncFunction[6];
2209          for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2210  
2211          final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2212          final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2213          assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2214          assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2215          final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2216          final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2217  
2218          // unspecified behavior - both source completions available
2219          try {
2220              assertEquals(inc(v1), h0.join());
2221              rs[0].assertValue(inc(v1));
2222          } catch (CompletionException ok) {
2223              checkCompletedWithWrappedException(h0, ex);
2224              rs[0].assertNotInvoked();
2225          }
2226          try {
2227              assertEquals(inc(v1), h1.join());
2228              rs[1].assertValue(inc(v1));
2229          } catch (CompletionException ok) {
2230              checkCompletedWithWrappedException(h1, ex);
2231              rs[1].assertNotInvoked();
2232          }
2233          try {
2234              assertEquals(inc(v1), h2.join());
2235              rs[2].assertValue(inc(v1));
2236          } catch (CompletionException ok) {
2237              checkCompletedWithWrappedException(h2, ex);
2238              rs[2].assertNotInvoked();
2239          }
2240          try {
2241              assertEquals(inc(v1), h3.join());
2242              rs[3].assertValue(inc(v1));
2243          } catch (CompletionException ok) {
2244              checkCompletedWithWrappedException(h3, ex);
2245              rs[3].assertNotInvoked();
2246          }
2247  
2248          checkCompletedNormally(f, v1);
2249          checkCompletedExceptionally(g, ex);
2250      }}
2251  
2252      /**
2253       * applyToEither result completes exceptionally if either source cancelled
2254       */
testApplyToEither_sourceCancelled()2255      public void testApplyToEither_sourceCancelled() {
2256          for (ExecutionMode m : ExecutionMode.values())
2257          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2258          for (Integer v1 : new Integer[] { 1, null })
2259      {
2260          final CompletableFuture<Integer> f = new CompletableFuture<>();
2261          final CompletableFuture<Integer> g = new CompletableFuture<>();
2262          final IncFunction[] rs = new IncFunction[6];
2263          for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2264  
2265          final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2266          final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2267          checkIncomplete(h0);
2268          checkIncomplete(h1);
2269          rs[0].assertNotInvoked();
2270          rs[1].assertNotInvoked();
2271          f.cancel(mayInterruptIfRunning);
2272          checkCompletedWithWrappedCancellationException(h0);
2273          checkCompletedWithWrappedCancellationException(h1);
2274          final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2275          final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2276          checkCompletedWithWrappedCancellationException(h2);
2277          checkCompletedWithWrappedCancellationException(h3);
2278          g.complete(v1);
2279  
2280          // unspecified behavior - both source completions available
2281          final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2282          final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2283          try {
2284              assertEquals(inc(v1), h4.join());
2285              rs[4].assertValue(inc(v1));
2286          } catch (CompletionException ok) {
2287              checkCompletedWithWrappedCancellationException(h4);
2288              rs[4].assertNotInvoked();
2289          }
2290          try {
2291              assertEquals(inc(v1), h5.join());
2292              rs[5].assertValue(inc(v1));
2293          } catch (CompletionException ok) {
2294              checkCompletedWithWrappedCancellationException(h5);
2295              rs[5].assertNotInvoked();
2296          }
2297  
2298          checkCancelled(f);
2299          checkCompletedNormally(g, v1);
2300          checkCompletedWithWrappedCancellationException(h0);
2301          checkCompletedWithWrappedCancellationException(h1);
2302          checkCompletedWithWrappedCancellationException(h2);
2303          checkCompletedWithWrappedCancellationException(h3);
2304          for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2305      }}
2306  
testApplyToEither_sourceCancelled2()2307      public void testApplyToEither_sourceCancelled2() {
2308          for (ExecutionMode m : ExecutionMode.values())
2309          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2310          for (boolean fFirst : new boolean[] { true, false })
2311          for (Integer v1 : new Integer[] { 1, null })
2312      {
2313          final CompletableFuture<Integer> f = new CompletableFuture<>();
2314          final CompletableFuture<Integer> g = new CompletableFuture<>();
2315          final IncFunction[] rs = new IncFunction[6];
2316          for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2317  
2318          final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2319          final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2320          assertTrue(fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
2321          assertTrue(!fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
2322          final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2323          final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2324  
2325          // unspecified behavior - both source completions available
2326          try {
2327              assertEquals(inc(v1), h0.join());
2328              rs[0].assertValue(inc(v1));
2329          } catch (CompletionException ok) {
2330              checkCompletedWithWrappedCancellationException(h0);
2331              rs[0].assertNotInvoked();
2332          }
2333          try {
2334              assertEquals(inc(v1), h1.join());
2335              rs[1].assertValue(inc(v1));
2336          } catch (CompletionException ok) {
2337              checkCompletedWithWrappedCancellationException(h1);
2338              rs[1].assertNotInvoked();
2339          }
2340          try {
2341              assertEquals(inc(v1), h2.join());
2342              rs[2].assertValue(inc(v1));
2343          } catch (CompletionException ok) {
2344              checkCompletedWithWrappedCancellationException(h2);
2345              rs[2].assertNotInvoked();
2346          }
2347          try {
2348              assertEquals(inc(v1), h3.join());
2349              rs[3].assertValue(inc(v1));
2350          } catch (CompletionException ok) {
2351              checkCompletedWithWrappedCancellationException(h3);
2352              rs[3].assertNotInvoked();
2353          }
2354  
2355          checkCompletedNormally(f, v1);
2356          checkCancelled(g);
2357      }}
2358  
2359      /**
2360       * applyToEither result completes exceptionally if action does
2361       */
testApplyToEither_actionFailed()2362      public void testApplyToEither_actionFailed() {
2363          for (ExecutionMode m : ExecutionMode.values())
2364          for (Integer v1 : new Integer[] { 1, null })
2365          for (Integer v2 : new Integer[] { 2, null })
2366      {
2367          final CompletableFuture<Integer> f = new CompletableFuture<>();
2368          final CompletableFuture<Integer> g = new CompletableFuture<>();
2369          final FailingFunction[] rs = new FailingFunction[6];
2370          for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
2371  
2372          final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2373          final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2374          f.complete(v1);
2375          final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2376          final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2377          checkCompletedWithWrappedCFException(h0);
2378          checkCompletedWithWrappedCFException(h1);
2379          checkCompletedWithWrappedCFException(h2);
2380          checkCompletedWithWrappedCFException(h3);
2381          for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2382  
2383          g.complete(v2);
2384  
2385          // unspecified behavior - both source completions available
2386          final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2387          final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2388  
2389          checkCompletedWithWrappedCFException(h4);
2390          assertTrue(Objects.equals(v1, rs[4].value) ||
2391                     Objects.equals(v2, rs[4].value));
2392          checkCompletedWithWrappedCFException(h5);
2393          assertTrue(Objects.equals(v1, rs[5].value) ||
2394                     Objects.equals(v2, rs[5].value));
2395  
2396          checkCompletedNormally(f, v1);
2397          checkCompletedNormally(g, v2);
2398      }}
2399  
2400      /**
2401       * acceptEither result completes normally after normal completion
2402       * of either source
2403       */
testAcceptEither_normalCompletion()2404      public void testAcceptEither_normalCompletion() {
2405          for (ExecutionMode m : ExecutionMode.values())
2406          for (Integer v1 : new Integer[] { 1, null })
2407          for (Integer v2 : new Integer[] { 2, null })
2408      {
2409          final CompletableFuture<Integer> f = new CompletableFuture<>();
2410          final CompletableFuture<Integer> g = new CompletableFuture<>();
2411          final NoopConsumer[] rs = new NoopConsumer[6];
2412          for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2413  
2414          final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2415          final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2416          checkIncomplete(h0);
2417          checkIncomplete(h1);
2418          rs[0].assertNotInvoked();
2419          rs[1].assertNotInvoked();
2420          f.complete(v1);
2421          checkCompletedNormally(h0, null);
2422          checkCompletedNormally(h1, null);
2423          rs[0].assertValue(v1);
2424          rs[1].assertValue(v1);
2425          final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2426          final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2427          checkCompletedNormally(h2, null);
2428          checkCompletedNormally(h3, null);
2429          rs[2].assertValue(v1);
2430          rs[3].assertValue(v1);
2431          g.complete(v2);
2432  
2433          // unspecified behavior - both source completions available
2434          final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2435          final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2436          checkCompletedNormally(h4, null);
2437          checkCompletedNormally(h5, null);
2438          assertTrue(Objects.equals(v1, rs[4].value) ||
2439                     Objects.equals(v2, rs[4].value));
2440          assertTrue(Objects.equals(v1, rs[5].value) ||
2441                     Objects.equals(v2, rs[5].value));
2442  
2443          checkCompletedNormally(f, v1);
2444          checkCompletedNormally(g, v2);
2445          checkCompletedNormally(h0, null);
2446          checkCompletedNormally(h1, null);
2447          checkCompletedNormally(h2, null);
2448          checkCompletedNormally(h3, null);
2449          for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2450      }}
2451  
2452      /**
2453       * acceptEither result completes exceptionally after exceptional
2454       * completion of either source
2455       */
testAcceptEither_exceptionalCompletion()2456      public void testAcceptEither_exceptionalCompletion() {
2457          for (ExecutionMode m : ExecutionMode.values())
2458          for (Integer v1 : new Integer[] { 1, null })
2459      {
2460          final CompletableFuture<Integer> f = new CompletableFuture<>();
2461          final CompletableFuture<Integer> g = new CompletableFuture<>();
2462          final CFException ex = new CFException();
2463          final NoopConsumer[] rs = new NoopConsumer[6];
2464          for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2465  
2466          final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2467          final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2468          checkIncomplete(h0);
2469          checkIncomplete(h1);
2470          rs[0].assertNotInvoked();
2471          rs[1].assertNotInvoked();
2472          f.completeExceptionally(ex);
2473          checkCompletedWithWrappedException(h0, ex);
2474          checkCompletedWithWrappedException(h1, ex);
2475          final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2476          final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2477          checkCompletedWithWrappedException(h2, ex);
2478          checkCompletedWithWrappedException(h3, ex);
2479  
2480          g.complete(v1);
2481  
2482          // unspecified behavior - both source completions available
2483          final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2484          final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2485          try {
2486              assertNull(h4.join());
2487              rs[4].assertValue(v1);
2488          } catch (CompletionException ok) {
2489              checkCompletedWithWrappedException(h4, ex);
2490              rs[4].assertNotInvoked();
2491          }
2492          try {
2493              assertNull(h5.join());
2494              rs[5].assertValue(v1);
2495          } catch (CompletionException ok) {
2496              checkCompletedWithWrappedException(h5, ex);
2497              rs[5].assertNotInvoked();
2498          }
2499  
2500          checkCompletedExceptionally(f, ex);
2501          checkCompletedNormally(g, v1);
2502          checkCompletedWithWrappedException(h0, ex);
2503          checkCompletedWithWrappedException(h1, ex);
2504          checkCompletedWithWrappedException(h2, ex);
2505          checkCompletedWithWrappedException(h3, ex);
2506          checkCompletedWithWrappedException(h4, ex);
2507          for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2508      }}
2509  
testAcceptEither_exceptionalCompletion2()2510      public void testAcceptEither_exceptionalCompletion2() {
2511          for (ExecutionMode m : ExecutionMode.values())
2512          for (boolean fFirst : new boolean[] { true, false })
2513          for (Integer v1 : new Integer[] { 1, null })
2514      {
2515          final CompletableFuture<Integer> f = new CompletableFuture<>();
2516          final CompletableFuture<Integer> g = new CompletableFuture<>();
2517          final CFException ex = new CFException();
2518          final NoopConsumer[] rs = new NoopConsumer[6];
2519          for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2520  
2521          final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2522          final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2523          assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2524          assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2525          final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2526          final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2527  
2528          // unspecified behavior - both source completions available
2529          try {
2530              assertEquals(null, h0.join());
2531              rs[0].assertValue(v1);
2532          } catch (CompletionException ok) {
2533              checkCompletedWithWrappedException(h0, ex);
2534              rs[0].assertNotInvoked();
2535          }
2536          try {
2537              assertEquals(null, h1.join());
2538              rs[1].assertValue(v1);
2539          } catch (CompletionException ok) {
2540              checkCompletedWithWrappedException(h1, ex);
2541              rs[1].assertNotInvoked();
2542          }
2543          try {
2544              assertEquals(null, h2.join());
2545              rs[2].assertValue(v1);
2546          } catch (CompletionException ok) {
2547              checkCompletedWithWrappedException(h2, ex);
2548              rs[2].assertNotInvoked();
2549          }
2550          try {
2551              assertEquals(null, h3.join());
2552              rs[3].assertValue(v1);
2553          } catch (CompletionException ok) {
2554              checkCompletedWithWrappedException(h3, ex);
2555              rs[3].assertNotInvoked();
2556          }
2557  
2558          checkCompletedNormally(f, v1);
2559          checkCompletedExceptionally(g, ex);
2560      }}
2561  
2562      /**
2563       * acceptEither result completes exceptionally if either source cancelled
2564       */
testAcceptEither_sourceCancelled()2565      public void testAcceptEither_sourceCancelled() {
2566          for (ExecutionMode m : ExecutionMode.values())
2567          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2568          for (Integer v1 : new Integer[] { 1, null })
2569      {
2570          final CompletableFuture<Integer> f = new CompletableFuture<>();
2571          final CompletableFuture<Integer> g = new CompletableFuture<>();
2572          final NoopConsumer[] rs = new NoopConsumer[6];
2573          for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2574  
2575          final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2576          final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2577          checkIncomplete(h0);
2578          checkIncomplete(h1);
2579          rs[0].assertNotInvoked();
2580          rs[1].assertNotInvoked();
2581          f.cancel(mayInterruptIfRunning);
2582          checkCompletedWithWrappedCancellationException(h0);
2583          checkCompletedWithWrappedCancellationException(h1);
2584          final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2585          final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2586          checkCompletedWithWrappedCancellationException(h2);
2587          checkCompletedWithWrappedCancellationException(h3);
2588  
2589          g.complete(v1);
2590  
2591          // unspecified behavior - both source completions available
2592          final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2593          final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2594          try {
2595              assertNull(h4.join());
2596              rs[4].assertValue(v1);
2597          } catch (CompletionException ok) {
2598              checkCompletedWithWrappedCancellationException(h4);
2599              rs[4].assertNotInvoked();
2600          }
2601          try {
2602              assertNull(h5.join());
2603              rs[5].assertValue(v1);
2604          } catch (CompletionException ok) {
2605              checkCompletedWithWrappedCancellationException(h5);
2606              rs[5].assertNotInvoked();
2607          }
2608  
2609          checkCancelled(f);
2610          checkCompletedNormally(g, v1);
2611          checkCompletedWithWrappedCancellationException(h0);
2612          checkCompletedWithWrappedCancellationException(h1);
2613          checkCompletedWithWrappedCancellationException(h2);
2614          checkCompletedWithWrappedCancellationException(h3);
2615          for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2616      }}
2617  
2618      /**
2619       * acceptEither result completes exceptionally if action does
2620       */
testAcceptEither_actionFailed()2621      public void testAcceptEither_actionFailed() {
2622          for (ExecutionMode m : ExecutionMode.values())
2623          for (Integer v1 : new Integer[] { 1, null })
2624          for (Integer v2 : new Integer[] { 2, null })
2625      {
2626          final CompletableFuture<Integer> f = new CompletableFuture<>();
2627          final CompletableFuture<Integer> g = new CompletableFuture<>();
2628          final FailingConsumer[] rs = new FailingConsumer[6];
2629          for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
2630  
2631          final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2632          final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2633          f.complete(v1);
2634          final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2635          final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2636          checkCompletedWithWrappedCFException(h0);
2637          checkCompletedWithWrappedCFException(h1);
2638          checkCompletedWithWrappedCFException(h2);
2639          checkCompletedWithWrappedCFException(h3);
2640          for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2641  
2642          g.complete(v2);
2643  
2644          // unspecified behavior - both source completions available
2645          final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2646          final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2647  
2648          checkCompletedWithWrappedCFException(h4);
2649          assertTrue(Objects.equals(v1, rs[4].value) ||
2650                     Objects.equals(v2, rs[4].value));
2651          checkCompletedWithWrappedCFException(h5);
2652          assertTrue(Objects.equals(v1, rs[5].value) ||
2653                     Objects.equals(v2, rs[5].value));
2654  
2655          checkCompletedNormally(f, v1);
2656          checkCompletedNormally(g, v2);
2657      }}
2658  
2659      /**
2660       * runAfterEither result completes normally after normal completion
2661       * of either source
2662       */
testRunAfterEither_normalCompletion()2663      public void testRunAfterEither_normalCompletion() {
2664          for (ExecutionMode m : ExecutionMode.values())
2665          for (Integer v1 : new Integer[] { 1, null })
2666          for (Integer v2 : new Integer[] { 2, null })
2667      {
2668          final CompletableFuture<Integer> f = new CompletableFuture<>();
2669          final CompletableFuture<Integer> g = new CompletableFuture<>();
2670          final Noop[] rs = new Noop[6];
2671          for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2672  
2673          final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2674          final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2675          checkIncomplete(h0);
2676          checkIncomplete(h1);
2677          rs[0].assertNotInvoked();
2678          rs[1].assertNotInvoked();
2679          f.complete(v1);
2680          checkCompletedNormally(h0, null);
2681          checkCompletedNormally(h1, null);
2682          rs[0].assertInvoked();
2683          rs[1].assertInvoked();
2684          final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2685          final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2686          checkCompletedNormally(h2, null);
2687          checkCompletedNormally(h3, null);
2688          rs[2].assertInvoked();
2689          rs[3].assertInvoked();
2690  
2691          g.complete(v2);
2692  
2693          final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2694          final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2695  
2696          checkCompletedNormally(f, v1);
2697          checkCompletedNormally(g, v2);
2698          checkCompletedNormally(h0, null);
2699          checkCompletedNormally(h1, null);
2700          checkCompletedNormally(h2, null);
2701          checkCompletedNormally(h3, null);
2702          checkCompletedNormally(h4, null);
2703          checkCompletedNormally(h5, null);
2704          for (int i = 0; i < 6; i++) rs[i].assertInvoked();
2705      }}
2706  
2707      /**
2708       * runAfterEither result completes exceptionally after exceptional
2709       * completion of either source
2710       */
testRunAfterEither_exceptionalCompletion()2711      public void testRunAfterEither_exceptionalCompletion() {
2712          for (ExecutionMode m : ExecutionMode.values())
2713          for (Integer v1 : new Integer[] { 1, null })
2714      {
2715          final CompletableFuture<Integer> f = new CompletableFuture<>();
2716          final CompletableFuture<Integer> g = new CompletableFuture<>();
2717          final CFException ex = new CFException();
2718          final Noop[] rs = new Noop[6];
2719          for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2720  
2721          final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2722          final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2723          checkIncomplete(h0);
2724          checkIncomplete(h1);
2725          rs[0].assertNotInvoked();
2726          rs[1].assertNotInvoked();
2727          assertTrue(f.completeExceptionally(ex));
2728          checkCompletedWithWrappedException(h0, ex);
2729          checkCompletedWithWrappedException(h1, ex);
2730          final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2731          final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2732          checkCompletedWithWrappedException(h2, ex);
2733          checkCompletedWithWrappedException(h3, ex);
2734  
2735          assertTrue(g.complete(v1));
2736  
2737          // unspecified behavior - both source completions available
2738          final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2739          final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2740          try {
2741              assertNull(h4.join());
2742              rs[4].assertInvoked();
2743          } catch (CompletionException ok) {
2744              checkCompletedWithWrappedException(h4, ex);
2745              rs[4].assertNotInvoked();
2746          }
2747          try {
2748              assertNull(h5.join());
2749              rs[5].assertInvoked();
2750          } catch (CompletionException ok) {
2751              checkCompletedWithWrappedException(h5, ex);
2752              rs[5].assertNotInvoked();
2753          }
2754  
2755          checkCompletedExceptionally(f, ex);
2756          checkCompletedNormally(g, v1);
2757          checkCompletedWithWrappedException(h0, ex);
2758          checkCompletedWithWrappedException(h1, ex);
2759          checkCompletedWithWrappedException(h2, ex);
2760          checkCompletedWithWrappedException(h3, ex);
2761          checkCompletedWithWrappedException(h4, ex);
2762          for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2763      }}
2764  
testRunAfterEither_exceptionalCompletion2()2765      public void testRunAfterEither_exceptionalCompletion2() {
2766          for (ExecutionMode m : ExecutionMode.values())
2767          for (boolean fFirst : new boolean[] { true, false })
2768          for (Integer v1 : new Integer[] { 1, null })
2769      {
2770          final CompletableFuture<Integer> f = new CompletableFuture<>();
2771          final CompletableFuture<Integer> g = new CompletableFuture<>();
2772          final CFException ex = new CFException();
2773          final Noop[] rs = new Noop[6];
2774          for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2775  
2776          final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2777          final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2778          assertTrue( fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2779          assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
2780          final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2781          final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2782  
2783          // unspecified behavior - both source completions available
2784          try {
2785              assertEquals(null, h0.join());
2786              rs[0].assertInvoked();
2787          } catch (CompletionException ok) {
2788              checkCompletedWithWrappedException(h0, ex);
2789              rs[0].assertNotInvoked();
2790          }
2791          try {
2792              assertEquals(null, h1.join());
2793              rs[1].assertInvoked();
2794          } catch (CompletionException ok) {
2795              checkCompletedWithWrappedException(h1, ex);
2796              rs[1].assertNotInvoked();
2797          }
2798          try {
2799              assertEquals(null, h2.join());
2800              rs[2].assertInvoked();
2801          } catch (CompletionException ok) {
2802              checkCompletedWithWrappedException(h2, ex);
2803              rs[2].assertNotInvoked();
2804          }
2805          try {
2806              assertEquals(null, h3.join());
2807              rs[3].assertInvoked();
2808          } catch (CompletionException ok) {
2809              checkCompletedWithWrappedException(h3, ex);
2810              rs[3].assertNotInvoked();
2811          }
2812  
2813          checkCompletedNormally(f, v1);
2814          checkCompletedExceptionally(g, ex);
2815      }}
2816  
2817      /**
2818       * runAfterEither result completes exceptionally if either source cancelled
2819       */
testRunAfterEither_sourceCancelled()2820      public void testRunAfterEither_sourceCancelled() {
2821          for (ExecutionMode m : ExecutionMode.values())
2822          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2823          for (Integer v1 : new Integer[] { 1, null })
2824      {
2825          final CompletableFuture<Integer> f = new CompletableFuture<>();
2826          final CompletableFuture<Integer> g = new CompletableFuture<>();
2827          final Noop[] rs = new Noop[6];
2828          for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2829  
2830          final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2831          final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2832          checkIncomplete(h0);
2833          checkIncomplete(h1);
2834          rs[0].assertNotInvoked();
2835          rs[1].assertNotInvoked();
2836          f.cancel(mayInterruptIfRunning);
2837          checkCompletedWithWrappedCancellationException(h0);
2838          checkCompletedWithWrappedCancellationException(h1);
2839          final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2840          final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2841          checkCompletedWithWrappedCancellationException(h2);
2842          checkCompletedWithWrappedCancellationException(h3);
2843  
2844          assertTrue(g.complete(v1));
2845  
2846          // unspecified behavior - both source completions available
2847          final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2848          final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2849          try {
2850              assertNull(h4.join());
2851              rs[4].assertInvoked();
2852          } catch (CompletionException ok) {
2853              checkCompletedWithWrappedCancellationException(h4);
2854              rs[4].assertNotInvoked();
2855          }
2856          try {
2857              assertNull(h5.join());
2858              rs[5].assertInvoked();
2859          } catch (CompletionException ok) {
2860              checkCompletedWithWrappedCancellationException(h5);
2861              rs[5].assertNotInvoked();
2862          }
2863  
2864          checkCancelled(f);
2865          checkCompletedNormally(g, v1);
2866          checkCompletedWithWrappedCancellationException(h0);
2867          checkCompletedWithWrappedCancellationException(h1);
2868          checkCompletedWithWrappedCancellationException(h2);
2869          checkCompletedWithWrappedCancellationException(h3);
2870          for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2871      }}
2872  
2873      /**
2874       * runAfterEither result completes exceptionally if action does
2875       */
testRunAfterEither_actionFailed()2876      public void testRunAfterEither_actionFailed() {
2877          for (ExecutionMode m : ExecutionMode.values())
2878          for (Integer v1 : new Integer[] { 1, null })
2879          for (Integer v2 : new Integer[] { 2, null })
2880      {
2881          final CompletableFuture<Integer> f = new CompletableFuture<>();
2882          final CompletableFuture<Integer> g = new CompletableFuture<>();
2883          final FailingRunnable[] rs = new FailingRunnable[6];
2884          for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
2885  
2886          final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2887          final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2888          assertTrue(f.complete(v1));
2889          final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2890          final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2891          checkCompletedWithWrappedCFException(h0);
2892          checkCompletedWithWrappedCFException(h1);
2893          checkCompletedWithWrappedCFException(h2);
2894          checkCompletedWithWrappedCFException(h3);
2895          for (int i = 0; i < 4; i++) rs[i].assertInvoked();
2896          assertTrue(g.complete(v2));
2897          final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2898          final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2899          checkCompletedWithWrappedCFException(h4);
2900          checkCompletedWithWrappedCFException(h5);
2901  
2902          checkCompletedNormally(f, v1);
2903          checkCompletedNormally(g, v2);
2904          for (int i = 0; i < 6; i++) rs[i].assertInvoked();
2905      }}
2906  
2907      /**
2908       * thenCompose result completes normally after normal completion of source
2909       */
testThenCompose_normalCompletion()2910      public void testThenCompose_normalCompletion() {
2911          for (ExecutionMode m : ExecutionMode.values())
2912          for (boolean createIncomplete : new boolean[] { true, false })
2913          for (Integer v1 : new Integer[] { 1, null })
2914      {
2915          final CompletableFuture<Integer> f = new CompletableFuture<>();
2916          final CompletableFutureInc r = new CompletableFutureInc(m);
2917          if (!createIncomplete) assertTrue(f.complete(v1));
2918          final CompletableFuture<Integer> g = m.thenCompose(f, r);
2919          if (createIncomplete) assertTrue(f.complete(v1));
2920  
2921          checkCompletedNormally(g, inc(v1));
2922          checkCompletedNormally(f, v1);
2923          r.assertValue(v1);
2924      }}
2925  
2926      /**
2927       * thenCompose result completes exceptionally after exceptional
2928       * completion of source
2929       */
testThenCompose_exceptionalCompletion()2930      public void testThenCompose_exceptionalCompletion() {
2931          for (ExecutionMode m : ExecutionMode.values())
2932          for (boolean createIncomplete : new boolean[] { true, false })
2933      {
2934          final CFException ex = new CFException();
2935          final CompletableFutureInc r = new CompletableFutureInc(m);
2936          final CompletableFuture<Integer> f = new CompletableFuture<>();
2937          if (!createIncomplete) f.completeExceptionally(ex);
2938          final CompletableFuture<Integer> g = m.thenCompose(f, r);
2939          if (createIncomplete) f.completeExceptionally(ex);
2940  
2941          checkCompletedWithWrappedException(g, ex);
2942          checkCompletedExceptionally(f, ex);
2943          r.assertNotInvoked();
2944      }}
2945  
2946      /**
2947       * thenCompose result completes exceptionally if action does
2948       */
testThenCompose_actionFailed()2949      public void testThenCompose_actionFailed() {
2950          for (ExecutionMode m : ExecutionMode.values())
2951          for (boolean createIncomplete : new boolean[] { true, false })
2952          for (Integer v1 : new Integer[] { 1, null })
2953      {
2954          final CompletableFuture<Integer> f = new CompletableFuture<>();
2955          final FailingCompletableFutureFunction r
2956              = new FailingCompletableFutureFunction(m);
2957          if (!createIncomplete) assertTrue(f.complete(v1));
2958          final CompletableFuture<Integer> g = m.thenCompose(f, r);
2959          if (createIncomplete) assertTrue(f.complete(v1));
2960  
2961          checkCompletedWithWrappedCFException(g);
2962          checkCompletedNormally(f, v1);
2963      }}
2964  
2965      /**
2966       * thenCompose result completes exceptionally if source cancelled
2967       */
testThenCompose_sourceCancelled()2968      public void testThenCompose_sourceCancelled() {
2969          for (ExecutionMode m : ExecutionMode.values())
2970          for (boolean createIncomplete : new boolean[] { true, false })
2971          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2972      {
2973          final CompletableFuture<Integer> f = new CompletableFuture<>();
2974          final CompletableFutureInc r = new CompletableFutureInc(m);
2975          if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
2976          final CompletableFuture<Integer> g = m.thenCompose(f, r);
2977          if (createIncomplete) {
2978              checkIncomplete(g);
2979              assertTrue(f.cancel(mayInterruptIfRunning));
2980          }
2981  
2982          checkCompletedWithWrappedCancellationException(g);
2983          checkCancelled(f);
2984      }}
2985  
2986      /**
2987       * thenCompose result completes exceptionally if the result of the action does
2988       */
testThenCompose_actionReturnsFailingFuture()2989      public void testThenCompose_actionReturnsFailingFuture() {
2990          for (ExecutionMode m : ExecutionMode.values())
2991          for (int order = 0; order < 6; order++)
2992          for (Integer v1 : new Integer[] { 1, null })
2993      {
2994          final CFException ex = new CFException();
2995          final CompletableFuture<Integer> f = new CompletableFuture<>();
2996          final CompletableFuture<Integer> g = new CompletableFuture<>();
2997          final CompletableFuture<Integer> h;
2998          // Test all permutations of orders
2999          switch (order) {
3000          case 0:
3001              assertTrue(f.complete(v1));
3002              assertTrue(g.completeExceptionally(ex));
3003              h = m.thenCompose(f, (x -> g));
3004              break;
3005          case 1:
3006              assertTrue(f.complete(v1));
3007              h = m.thenCompose(f, (x -> g));
3008              assertTrue(g.completeExceptionally(ex));
3009              break;
3010          case 2:
3011              assertTrue(g.completeExceptionally(ex));
3012              assertTrue(f.complete(v1));
3013              h = m.thenCompose(f, (x -> g));
3014              break;
3015          case 3:
3016              assertTrue(g.completeExceptionally(ex));
3017              h = m.thenCompose(f, (x -> g));
3018              assertTrue(f.complete(v1));
3019              break;
3020          case 4:
3021              h = m.thenCompose(f, (x -> g));
3022              assertTrue(f.complete(v1));
3023              assertTrue(g.completeExceptionally(ex));
3024              break;
3025          case 5:
3026              h = m.thenCompose(f, (x -> g));
3027              assertTrue(f.complete(v1));
3028              assertTrue(g.completeExceptionally(ex));
3029              break;
3030          default: throw new AssertionError();
3031          }
3032  
3033          checkCompletedExceptionally(g, ex);
3034          checkCompletedWithWrappedException(h, ex);
3035          checkCompletedNormally(f, v1);
3036      }}
3037  
3038      // other static methods
3039  
3040      /**
3041       * allOf(no component futures) returns a future completed normally
3042       * with the value null
3043       */
testAllOf_empty()3044      public void testAllOf_empty() throws Exception {
3045          CompletableFuture<Void> f = CompletableFuture.allOf();
3046          checkCompletedNormally(f, null);
3047      }
3048  
3049      /**
3050       * allOf returns a future completed normally with the value null
3051       * when all components complete normally
3052       */
testAllOf_normal()3053      public void testAllOf_normal() throws Exception {
3054          for (int k = 1; k < 10; k++) {
3055              CompletableFuture<Integer>[] fs
3056                  = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3057              for (int i = 0; i < k; i++)
3058                  fs[i] = new CompletableFuture<>();
3059              CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3060              for (int i = 0; i < k; i++) {
3061                  checkIncomplete(f);
3062                  checkIncomplete(CompletableFuture.allOf(fs));
3063                  fs[i].complete(one);
3064              }
3065              checkCompletedNormally(f, null);
3066              checkCompletedNormally(CompletableFuture.allOf(fs), null);
3067          }
3068      }
3069  
testAllOf_backwards()3070      public void testAllOf_backwards() throws Exception {
3071          for (int k = 1; k < 10; k++) {
3072              CompletableFuture<Integer>[] fs
3073                  = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3074              for (int i = 0; i < k; i++)
3075                  fs[i] = new CompletableFuture<>();
3076              CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3077              for (int i = k - 1; i >= 0; i--) {
3078                  checkIncomplete(f);
3079                  checkIncomplete(CompletableFuture.allOf(fs));
3080                  fs[i].complete(one);
3081              }
3082              checkCompletedNormally(f, null);
3083              checkCompletedNormally(CompletableFuture.allOf(fs), null);
3084          }
3085      }
3086  
testAllOf_exceptional()3087      public void testAllOf_exceptional() throws Exception {
3088          for (int k = 1; k < 10; k++) {
3089              CompletableFuture<Integer>[] fs
3090                  = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3091              CFException ex = new CFException();
3092              for (int i = 0; i < k; i++)
3093                  fs[i] = new CompletableFuture<>();
3094              CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3095              for (int i = 0; i < k; i++) {
3096                  checkIncomplete(f);
3097                  checkIncomplete(CompletableFuture.allOf(fs));
3098                  if (i != k / 2) {
3099                      fs[i].complete(i);
3100                      checkCompletedNormally(fs[i], i);
3101                  } else {
3102                      fs[i].completeExceptionally(ex);
3103                      checkCompletedExceptionally(fs[i], ex);
3104                  }
3105              }
3106              checkCompletedWithWrappedException(f, ex);
3107              checkCompletedWithWrappedException(CompletableFuture.allOf(fs), ex);
3108          }
3109      }
3110  
3111      /**
3112       * anyOf(no component futures) returns an incomplete future
3113       */
testAnyOf_empty()3114      public void testAnyOf_empty() throws Exception {
3115          for (Integer v1 : new Integer[] { 1, null })
3116      {
3117          CompletableFuture<Object> f = CompletableFuture.anyOf();
3118          checkIncomplete(f);
3119  
3120          f.complete(v1);
3121          checkCompletedNormally(f, v1);
3122      }}
3123  
3124      /**
3125       * anyOf returns a future completed normally with a value when
3126       * a component future does
3127       */
testAnyOf_normal()3128      public void testAnyOf_normal() throws Exception {
3129          for (int k = 0; k < 10; k++) {
3130              CompletableFuture[] fs = new CompletableFuture[k];
3131              for (int i = 0; i < k; i++)
3132                  fs[i] = new CompletableFuture<>();
3133              CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3134              checkIncomplete(f);
3135              for (int i = 0; i < k; i++) {
3136                  fs[i].complete(i);
3137                  checkCompletedNormally(f, 0);
3138                  int x = (int) CompletableFuture.anyOf(fs).join();
3139                  assertTrue(0 <= x && x <= i);
3140              }
3141          }
3142      }
testAnyOf_normal_backwards()3143      public void testAnyOf_normal_backwards() throws Exception {
3144          for (int k = 0; k < 10; k++) {
3145              CompletableFuture[] fs = new CompletableFuture[k];
3146              for (int i = 0; i < k; i++)
3147                  fs[i] = new CompletableFuture<>();
3148              CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3149              checkIncomplete(f);
3150              for (int i = k - 1; i >= 0; i--) {
3151                  fs[i].complete(i);
3152                  checkCompletedNormally(f, k - 1);
3153                  int x = (int) CompletableFuture.anyOf(fs).join();
3154                  assertTrue(i <= x && x <= k - 1);
3155              }
3156          }
3157      }
3158  
3159      /**
3160       * anyOf result completes exceptionally when any component does.
3161       */
testAnyOf_exceptional()3162      public void testAnyOf_exceptional() throws Exception {
3163          for (int k = 0; k < 10; k++) {
3164              CompletableFuture[] fs = new CompletableFuture[k];
3165              CFException[] exs = new CFException[k];
3166              for (int i = 0; i < k; i++) {
3167                  fs[i] = new CompletableFuture<>();
3168                  exs[i] = new CFException();
3169              }
3170              CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3171              checkIncomplete(f);
3172              for (int i = 0; i < k; i++) {
3173                  fs[i].completeExceptionally(exs[i]);
3174                  checkCompletedWithWrappedException(f, exs[0]);
3175                  checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3176              }
3177          }
3178      }
3179  
testAnyOf_exceptional_backwards()3180      public void testAnyOf_exceptional_backwards() throws Exception {
3181          for (int k = 0; k < 10; k++) {
3182              CompletableFuture[] fs = new CompletableFuture[k];
3183              CFException[] exs = new CFException[k];
3184              for (int i = 0; i < k; i++) {
3185                  fs[i] = new CompletableFuture<>();
3186                  exs[i] = new CFException();
3187              }
3188              CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3189              checkIncomplete(f);
3190              for (int i = k - 1; i >= 0; i--) {
3191                  fs[i].completeExceptionally(exs[i]);
3192                  checkCompletedWithWrappedException(f, exs[k - 1]);
3193                  checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3194              }
3195          }
3196      }
3197  
3198      /**
3199       * Completion methods throw NullPointerException with null arguments
3200       */
testNPE()3201      public void testNPE() {
3202          CompletableFuture<Integer> f = new CompletableFuture<>();
3203          CompletableFuture<Integer> g = new CompletableFuture<>();
3204          CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
3205          ThreadExecutor exec = new ThreadExecutor();
3206  
3207          Runnable[] throwingActions = {
3208              () -> CompletableFuture.supplyAsync(null),
3209              () -> CompletableFuture.supplyAsync(null, exec),
3210              () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.SYNC, 42), null),
3211  
3212              () -> CompletableFuture.runAsync(null),
3213              () -> CompletableFuture.runAsync(null, exec),
3214              () -> CompletableFuture.runAsync(() -> {}, null),
3215  
3216              () -> f.completeExceptionally(null),
3217  
3218              () -> f.thenApply(null),
3219              () -> f.thenApplyAsync(null),
3220              () -> f.thenApplyAsync((x) -> x, null),
3221              () -> f.thenApplyAsync(null, exec),
3222  
3223              () -> f.thenAccept(null),
3224              () -> f.thenAcceptAsync(null),
3225              () -> f.thenAcceptAsync((x) -> {} , null),
3226              () -> f.thenAcceptAsync(null, exec),
3227  
3228              () -> f.thenRun(null),
3229              () -> f.thenRunAsync(null),
3230              () -> f.thenRunAsync(() -> {} , null),
3231              () -> f.thenRunAsync(null, exec),
3232  
3233              () -> f.thenCombine(g, null),
3234              () -> f.thenCombineAsync(g, null),
3235              () -> f.thenCombineAsync(g, null, exec),
3236              () -> f.thenCombine(nullFuture, (x, y) -> x),
3237              () -> f.thenCombineAsync(nullFuture, (x, y) -> x),
3238              () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec),
3239              () -> f.thenCombineAsync(g, (x, y) -> x, null),
3240  
3241              () -> f.thenAcceptBoth(g, null),
3242              () -> f.thenAcceptBothAsync(g, null),
3243              () -> f.thenAcceptBothAsync(g, null, exec),
3244              () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}),
3245              () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}),
3246              () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec),
3247              () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null),
3248  
3249              () -> f.runAfterBoth(g, null),
3250              () -> f.runAfterBothAsync(g, null),
3251              () -> f.runAfterBothAsync(g, null, exec),
3252              () -> f.runAfterBoth(nullFuture, () -> {}),
3253              () -> f.runAfterBothAsync(nullFuture, () -> {}),
3254              () -> f.runAfterBothAsync(nullFuture, () -> {}, exec),
3255              () -> f.runAfterBothAsync(g, () -> {}, null),
3256  
3257              () -> f.applyToEither(g, null),
3258              () -> f.applyToEitherAsync(g, null),
3259              () -> f.applyToEitherAsync(g, null, exec),
3260              () -> f.applyToEither(nullFuture, (x) -> x),
3261              () -> f.applyToEitherAsync(nullFuture, (x) -> x),
3262              () -> f.applyToEitherAsync(nullFuture, (x) -> x, exec),
3263              () -> f.applyToEitherAsync(g, (x) -> x, null),
3264  
3265              () -> f.acceptEither(g, null),
3266              () -> f.acceptEitherAsync(g, null),
3267              () -> f.acceptEitherAsync(g, null, exec),
3268              () -> f.acceptEither(nullFuture, (x) -> {}),
3269              () -> f.acceptEitherAsync(nullFuture, (x) -> {}),
3270              () -> f.acceptEitherAsync(nullFuture, (x) -> {}, exec),
3271              () -> f.acceptEitherAsync(g, (x) -> {}, null),
3272  
3273              () -> f.runAfterEither(g, null),
3274              () -> f.runAfterEitherAsync(g, null),
3275              () -> f.runAfterEitherAsync(g, null, exec),
3276              () -> f.runAfterEither(nullFuture, () -> {}),
3277              () -> f.runAfterEitherAsync(nullFuture, () -> {}),
3278              () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec),
3279              () -> f.runAfterEitherAsync(g, () -> {}, null),
3280  
3281              () -> f.thenCompose(null),
3282              () -> f.thenComposeAsync(null),
3283              () -> f.thenComposeAsync(new CompletableFutureInc(ExecutionMode.EXECUTOR), null),
3284              () -> f.thenComposeAsync(null, exec),
3285  
3286              () -> f.exceptionally(null),
3287  
3288              () -> f.handle(null),
3289  
3290              () -> CompletableFuture.allOf((CompletableFuture<?>)null),
3291              () -> CompletableFuture.allOf((CompletableFuture<?>[])null),
3292              () -> CompletableFuture.allOf(f, null),
3293              () -> CompletableFuture.allOf(null, f),
3294  
3295              () -> CompletableFuture.anyOf((CompletableFuture<?>)null),
3296              () -> CompletableFuture.anyOf((CompletableFuture<?>[])null),
3297              () -> CompletableFuture.anyOf(f, null),
3298              () -> CompletableFuture.anyOf(null, f),
3299  
3300              () -> f.obtrudeException(null),
3301  
3302              () -> CompletableFuture.delayedExecutor(1L, SECONDS, null),
3303              () -> CompletableFuture.delayedExecutor(1L, null, new ThreadExecutor()),
3304              () -> CompletableFuture.delayedExecutor(1L, null),
3305  
3306              () -> f.orTimeout(1L, null),
3307              () -> f.completeOnTimeout(42, 1L, null),
3308  
3309              () -> CompletableFuture.failedFuture(null),
3310              () -> CompletableFuture.failedStage(null),
3311          };
3312  
3313          assertThrows(NullPointerException.class, throwingActions);
3314          assertEquals(0, exec.count.get());
3315      }
3316  
3317      /**
3318       * toCompletableFuture returns this CompletableFuture.
3319       */
testToCompletableFuture()3320      public void testToCompletableFuture() {
3321          CompletableFuture<Integer> f = new CompletableFuture<>();
3322          assertSame(f, f.toCompletableFuture());
3323      }
3324  
3325      // jdk9
3326  
3327      /**
3328       * newIncompleteFuture returns an incomplete CompletableFuture
3329       */
testNewIncompleteFuture()3330      public void testNewIncompleteFuture() {
3331          for (Integer v1 : new Integer[] { 1, null })
3332      {
3333          CompletableFuture<Integer> f = new CompletableFuture<>();
3334          CompletableFuture<Integer> g = f.newIncompleteFuture();
3335          checkIncomplete(f);
3336          checkIncomplete(g);
3337          f.complete(v1);
3338          checkCompletedNormally(f, v1);
3339          checkIncomplete(g);
3340          g.complete(v1);
3341          checkCompletedNormally(g, v1);
3342          assertSame(g.getClass(), CompletableFuture.class);
3343      }}
3344  
3345      /**
3346       * completedStage returns a completed CompletionStage
3347       */
testCompletedStage()3348      public void testCompletedStage() {
3349          AtomicInteger x = new AtomicInteger(0);
3350          AtomicReference<Throwable> r = new AtomicReference<Throwable>();
3351          CompletionStage<Integer> f = CompletableFuture.completedStage(1);
3352          f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
3353          assertEquals(x.get(), 1);
3354          assertNull(r.get());
3355      }
3356  
3357      /**
3358       * defaultExecutor by default returns the commonPool if
3359       * it supports more than one thread.
3360       */
testDefaultExecutor()3361      public void testDefaultExecutor() {
3362          CompletableFuture<Integer> f = new CompletableFuture<>();
3363          Executor e = f.defaultExecutor();
3364          Executor c = ForkJoinPool.commonPool();
3365          if (ForkJoinPool.getCommonPoolParallelism() > 1)
3366              assertSame(e, c);
3367          else
3368              assertNotSame(e, c);
3369      }
3370  
3371      /**
3372       * failedFuture returns a CompletableFuture completed
3373       * exceptionally with the given Exception
3374       */
testFailedFuture()3375      public void testFailedFuture() {
3376          CFException ex = new CFException();
3377          CompletableFuture<Integer> f = CompletableFuture.failedFuture(ex);
3378          checkCompletedExceptionally(f, ex);
3379      }
3380  
3381      /**
3382       * failedFuture(null) throws NPE
3383       */
testFailedFuture_null()3384      public void testFailedFuture_null() {
3385          try {
3386              CompletableFuture<Integer> f = CompletableFuture.failedFuture(null);
3387              shouldThrow();
3388          } catch (NullPointerException success) {}
3389      }
3390  
3391      /**
3392       * copy returns a CompletableFuture that is completed normally,
3393       * with the same value, when source is.
3394       */
testCopy()3395      public void testCopy() {
3396          CompletableFuture<Integer> f = new CompletableFuture<>();
3397          CompletableFuture<Integer> g = f.copy();
3398          checkIncomplete(f);
3399          checkIncomplete(g);
3400          f.complete(1);
3401          checkCompletedNormally(f, 1);
3402          checkCompletedNormally(g, 1);
3403      }
3404  
3405      /**
3406       * copy returns a CompletableFuture that is completed exceptionally
3407       * when source is.
3408       */
testCopy2()3409      public void testCopy2() {
3410          CompletableFuture<Integer> f = new CompletableFuture<>();
3411          CompletableFuture<Integer> g = f.copy();
3412          checkIncomplete(f);
3413          checkIncomplete(g);
3414          CFException ex = new CFException();
3415          f.completeExceptionally(ex);
3416          checkCompletedExceptionally(f, ex);
3417          checkCompletedWithWrappedException(g, ex);
3418      }
3419  
3420      /**
3421       * minimalCompletionStage returns a CompletableFuture that is
3422       * completed normally, with the same value, when source is.
3423       */
testMinimalCompletionStage()3424      public void testMinimalCompletionStage() {
3425          CompletableFuture<Integer> f = new CompletableFuture<>();
3426          CompletionStage<Integer> g = f.minimalCompletionStage();
3427          AtomicInteger x = new AtomicInteger(0);
3428          AtomicReference<Throwable> r = new AtomicReference<Throwable>();
3429          checkIncomplete(f);
3430          g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
3431          f.complete(1);
3432          checkCompletedNormally(f, 1);
3433          assertEquals(x.get(), 1);
3434          assertNull(r.get());
3435      }
3436  
3437      /**
3438       * minimalCompletionStage returns a CompletableFuture that is
3439       * completed exceptionally when source is.
3440       */
testMinimalCompletionStage2()3441      public void testMinimalCompletionStage2() {
3442          CompletableFuture<Integer> f = new CompletableFuture<>();
3443          CompletionStage<Integer> g = f.minimalCompletionStage();
3444          AtomicInteger x = new AtomicInteger(0);
3445          AtomicReference<Throwable> r = new AtomicReference<Throwable>();
3446          g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
3447          checkIncomplete(f);
3448          CFException ex = new CFException();
3449          f.completeExceptionally(ex);
3450          checkCompletedExceptionally(f, ex);
3451          assertEquals(x.get(), 0);
3452          assertEquals(r.get().getCause(), ex);
3453      }
3454  
3455      /**
3456       * failedStage returns a CompletionStage completed
3457       * exceptionally with the given Exception
3458       */
testFailedStage()3459      public void testFailedStage() {
3460          CFException ex = new CFException();
3461          CompletionStage<Integer> f = CompletableFuture.failedStage(ex);
3462          AtomicInteger x = new AtomicInteger(0);
3463          AtomicReference<Throwable> r = new AtomicReference<Throwable>();
3464          f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
3465          assertEquals(x.get(), 0);
3466          assertEquals(r.get(), ex);
3467      }
3468  
3469      /**
3470       * completeAsync completes with value of given supplier
3471       */
testCompleteAsync()3472      public void testCompleteAsync() {
3473          for (Integer v1 : new Integer[] { 1, null })
3474      {
3475          CompletableFuture<Integer> f = new CompletableFuture<>();
3476          f.completeAsync(() -> v1);
3477          f.join();
3478          checkCompletedNormally(f, v1);
3479      }}
3480  
3481      /**
3482       * completeAsync completes exceptionally if given supplier throws
3483       */
testCompleteAsync2()3484      public void testCompleteAsync2() {
3485          CompletableFuture<Integer> f = new CompletableFuture<>();
3486          CFException ex = new CFException();
3487          f.completeAsync(() -> {if (true) throw ex; return 1;});
3488          try {
3489              f.join();
3490              shouldThrow();
3491          } catch (CompletionException success) {}
3492          checkCompletedWithWrappedException(f, ex);
3493      }
3494  
3495      /**
3496       * completeAsync with given executor completes with value of given supplier
3497       */
testCompleteAsync3()3498      public void testCompleteAsync3() {
3499          for (Integer v1 : new Integer[] { 1, null })
3500      {
3501          CompletableFuture<Integer> f = new CompletableFuture<>();
3502          ThreadExecutor executor = new ThreadExecutor();
3503          f.completeAsync(() -> v1, executor);
3504          assertSame(v1, f.join());
3505          checkCompletedNormally(f, v1);
3506          assertEquals(1, executor.count.get());
3507      }}
3508  
3509      /**
3510       * completeAsync with given executor completes exceptionally if
3511       * given supplier throws
3512       */
testCompleteAsync4()3513      public void testCompleteAsync4() {
3514          CompletableFuture<Integer> f = new CompletableFuture<>();
3515          CFException ex = new CFException();
3516          ThreadExecutor executor = new ThreadExecutor();
3517          f.completeAsync(() -> {if (true) throw ex; return 1;}, executor);
3518          try {
3519              f.join();
3520              shouldThrow();
3521          } catch (CompletionException success) {}
3522          checkCompletedWithWrappedException(f, ex);
3523          assertEquals(1, executor.count.get());
3524      }
3525  
3526      /**
3527       * orTimeout completes with TimeoutException if not complete
3528       */
testOrTimeout_timesOut()3529      public void testOrTimeout_timesOut() {
3530          long timeoutMillis = timeoutMillis();
3531          CompletableFuture<Integer> f = new CompletableFuture<>();
3532          long startTime = System.nanoTime();
3533          f.orTimeout(timeoutMillis, MILLISECONDS);
3534          checkCompletedWithTimeoutException(f);
3535          assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
3536      }
3537  
3538      /**
3539       * orTimeout completes normally if completed before timeout
3540       */
testOrTimeout_completed()3541      public void testOrTimeout_completed() {
3542          for (Integer v1 : new Integer[] { 1, null })
3543      {
3544          CompletableFuture<Integer> f = new CompletableFuture<>();
3545          CompletableFuture<Integer> g = new CompletableFuture<>();
3546          long startTime = System.nanoTime();
3547          f.complete(v1);
3548          f.orTimeout(LONG_DELAY_MS, MILLISECONDS);
3549          g.orTimeout(LONG_DELAY_MS, MILLISECONDS);
3550          g.complete(v1);
3551          checkCompletedNormally(f, v1);
3552          checkCompletedNormally(g, v1);
3553          assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
3554      }}
3555  
3556      /**
3557       * completeOnTimeout completes with given value if not complete
3558       */
3559      public void testCompleteOnTimeout_timesOut() {
3560          testInParallel(() -> testCompleteOnTimeout_timesOut(42),
3561                         () -> testCompleteOnTimeout_timesOut(null));
3562      }
3563  
testCompleteOnTimeout_timesOut(Integer v)3564      public void testCompleteOnTimeout_timesOut(Integer v) {
3565          long timeoutMillis = timeoutMillis();
3566          CompletableFuture<Integer> f = new CompletableFuture<>();
3567          long startTime = System.nanoTime();
3568          f.completeOnTimeout(v, timeoutMillis, MILLISECONDS);
3569          assertSame(v, f.join());
3570          assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
3571          f.complete(99);         // should have no effect
3572          checkCompletedNormally(f, v);
3573      }
3574  
3575      /**
3576       * completeOnTimeout has no effect if completed within timeout
3577       */
testCompleteOnTimeout_completed()3578      public void testCompleteOnTimeout_completed() {
3579          for (Integer v1 : new Integer[] { 1, null })
3580      {
3581          CompletableFuture<Integer> f = new CompletableFuture<>();
3582          CompletableFuture<Integer> g = new CompletableFuture<>();
3583          long startTime = System.nanoTime();
3584          f.complete(v1);
3585          f.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS);
3586          g.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS);
3587          g.complete(v1);
3588          checkCompletedNormally(f, v1);
3589          checkCompletedNormally(g, v1);
3590          assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
3591      }}
3592  
3593      /**
3594       * delayedExecutor returns an executor that delays submission
3595       */
3596      public void testDelayedExecutor() {
3597          testInParallel(() -> testDelayedExecutor(null, null),
3598                         () -> testDelayedExecutor(null, 1),
3599                         () -> testDelayedExecutor(new ThreadExecutor(), 1),
3600                         () -> testDelayedExecutor(new ThreadExecutor(), 1));
3601      }
3602  
testDelayedExecutor(Executor executor, Integer v)3603      public void testDelayedExecutor(Executor executor, Integer v) throws Exception {
3604          long timeoutMillis = timeoutMillis();
3605          // Use an "unreasonably long" long timeout to catch lingering threads
3606          long longTimeoutMillis = 1000 * 60 * 60 * 24;
3607          final Executor delayer, longDelayer;
3608          if (executor == null) {
3609              delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS);
3610              longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS);
3611          } else {
3612              delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS, executor);
3613              longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS, executor);
3614          }
3615          long startTime = System.nanoTime();
3616          CompletableFuture<Integer> f =
3617              CompletableFuture.supplyAsync(() -> v, delayer);
3618          CompletableFuture<Integer> g =
3619              CompletableFuture.supplyAsync(() -> v, longDelayer);
3620  
3621          assertNull(g.getNow(null));
3622  
3623          assertSame(v, f.get(LONG_DELAY_MS, MILLISECONDS));
3624          long millisElapsed = millisElapsedSince(startTime);
3625          assertTrue(millisElapsed >= timeoutMillis);
3626          assertTrue(millisElapsed < LONG_DELAY_MS / 2);
3627  
3628          checkCompletedNormally(f, v);
3629  
3630          checkIncomplete(g);
3631          assertTrue(g.cancel(true));
3632      }
3633  
3634      //--- tests of implementation details; not part of official tck ---
3635  
3636      Object resultOf(CompletableFuture<?> f) {
3637          try {
3638              java.lang.reflect.Field resultField
3639                  = CompletableFuture.class.getDeclaredField("result");
3640              resultField.setAccessible(true);
3641              return resultField.get(f);
3642          } catch (Throwable t) { throw new AssertionError(t); }
3643      }
3644  
3645      public void testExceptionPropagationReusesResultObject() {
3646          if (!testImplementationDetails) return;
3647          for (ExecutionMode m : ExecutionMode.values())
3648      {
3649          final CFException ex = new CFException();
3650          final CompletableFuture<Integer> v42 = CompletableFuture.completedFuture(42);
3651          final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
3652  
3653          List<Function<CompletableFuture<Integer>, CompletableFuture<?>>> funs
3654              = new ArrayList<>();
3655  
3656          funs.add((y) -> m.thenRun(y, new Noop(m)));
3657          funs.add((y) -> m.thenAccept(y, new NoopConsumer(m)));
3658          funs.add((y) -> m.thenApply(y, new IncFunction(m)));
3659  
3660          funs.add((y) -> m.runAfterEither(y, incomplete, new Noop(m)));
3661          funs.add((y) -> m.acceptEither(y, incomplete, new NoopConsumer(m)));
3662          funs.add((y) -> m.applyToEither(y, incomplete, new IncFunction(m)));
3663  
3664          funs.add((y) -> m.runAfterBoth(y, v42, new Noop(m)));
3665          funs.add((y) -> m.thenAcceptBoth(y, v42, new SubtractAction(m)));
3666          funs.add((y) -> m.thenCombine(y, v42, new SubtractFunction(m)));
3667  
3668          funs.add((y) -> m.whenComplete(y, (Integer r, Throwable t) -> {}));
3669  
3670          funs.add((y) -> m.thenCompose(y, new CompletableFutureInc(m)));
3671  
3672          funs.add((y) -> CompletableFuture.allOf(new CompletableFuture<?>[] {y, v42}));
3673          funs.add((y) -> CompletableFuture.anyOf(new CompletableFuture<?>[] {y, incomplete}));
3674  
3675          for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3676                   fun : funs) {
3677              CompletableFuture<Integer> f = new CompletableFuture<>();
3678              f.completeExceptionally(ex);
3679              CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3680              checkCompletedWithWrappedException(src, ex);
3681              CompletableFuture<?> dep = fun.apply(src);
3682              checkCompletedWithWrappedException(dep, ex);
3683              assertSame(resultOf(src), resultOf(dep));
3684          }
3685  
3686          for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3687                   fun : funs) {
3688              CompletableFuture<Integer> f = new CompletableFuture<>();
3689              CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3690              CompletableFuture<?> dep = fun.apply(src);
3691              f.completeExceptionally(ex);
3692              checkCompletedWithWrappedException(src, ex);
3693              checkCompletedWithWrappedException(dep, ex);
3694              assertSame(resultOf(src), resultOf(dep));
3695          }
3696  
3697          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
3698          for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3699                   fun : funs) {
3700              CompletableFuture<Integer> f = new CompletableFuture<>();
3701              f.cancel(mayInterruptIfRunning);
3702              checkCancelled(f);
3703              CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3704              checkCompletedWithWrappedCancellationException(src);
3705              CompletableFuture<?> dep = fun.apply(src);
3706              checkCompletedWithWrappedCancellationException(dep);
3707              assertSame(resultOf(src), resultOf(dep));
3708          }
3709  
3710          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
3711          for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3712                   fun : funs) {
3713              CompletableFuture<Integer> f = new CompletableFuture<>();
3714              CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3715              CompletableFuture<?> dep = fun.apply(src);
3716              f.cancel(mayInterruptIfRunning);
3717              checkCancelled(f);
3718              checkCompletedWithWrappedCancellationException(src);
3719              checkCompletedWithWrappedCancellationException(dep);
3720              assertSame(resultOf(src), resultOf(dep));
3721          }
3722      }}
3723  
3724      /**
3725       * Minimal completion stages throw UOE for all non-CompletionStage methods
3726       */
testMinimalCompletionStage_minimality()3727      public void testMinimalCompletionStage_minimality() {
3728          if (!testImplementationDetails) return;
3729          Function<Method, String> toSignature =
3730              (method) -> method.getName() + Arrays.toString(method.getParameterTypes());
3731          Predicate<Method> isNotStatic =
3732              (method) -> (method.getModifiers() & Modifier.STATIC) == 0;
3733          // Android-changed: Added a cast to workaround an ECJ bug. http://b/33371837
3734          List<Method> minimalMethods =
3735              Stream.of(Object.class, CompletionStage.class)
3736              .flatMap((klazz) -> (Stream<Method>) Stream.of(klazz.getMethods()))
3737              .filter(isNotStatic)
3738              .collect(Collectors.toList());
3739          // Methods from CompletableFuture permitted NOT to throw UOE
3740          String[] signatureWhitelist = {
3741              "newIncompleteFuture[]",
3742              "defaultExecutor[]",
3743              "minimalCompletionStage[]",
3744              "copy[]",
3745          };
3746          Set<String> permittedMethodSignatures =
3747              Stream.concat(minimalMethods.stream().map(toSignature),
3748                            Stream.of(signatureWhitelist))
3749              .collect(Collectors.toSet());
3750          List<Method> allMethods = Stream.of(CompletableFuture.class.getMethods())
3751              .filter(isNotStatic)
3752              .filter((method) -> !permittedMethodSignatures.contains(toSignature.apply(method)))
3753              .collect(Collectors.toList());
3754  
3755          CompletionStage<Integer> minimalStage =
3756              new CompletableFuture<Integer>().minimalCompletionStage();
3757  
3758          List<Method> bugs = new ArrayList<>();
3759          for (Method method : allMethods) {
3760              Class<?>[] parameterTypes = method.getParameterTypes();
3761              Object[] args = new Object[parameterTypes.length];
3762              // Manufacture boxed primitives for primitive params
3763              for (int i = 0; i < args.length; i++) {
3764                  Class<?> type = parameterTypes[i];
3765                  if (parameterTypes[i] == boolean.class)
3766                      args[i] = false;
3767                  else if (parameterTypes[i] == int.class)
3768                      args[i] = 0;
3769                  else if (parameterTypes[i] == long.class)
3770                      args[i] = 0L;
3771              }
3772              try {
3773                  method.invoke(minimalStage, args);
3774                  bugs.add(method);
3775              }
3776              catch (java.lang.reflect.InvocationTargetException expected) {
3777                  if (! (expected.getCause() instanceof UnsupportedOperationException)) {
3778                      bugs.add(method);
3779                      // expected.getCause().printStackTrace();
3780                  }
3781              }
3782              catch (ReflectiveOperationException bad) { throw new Error(bad); }
3783          }
3784          if (!bugs.isEmpty())
3785              throw new Error("Methods did not throw UOE: " + bugs.toString());
3786      }
3787  
3788      static class Monad {
3789          static class ZeroException extends RuntimeException {
ZeroException()3790              public ZeroException() { super("monadic zero"); }
3791          }
3792          // "return", "unit"
unit(T value)3793          static <T> CompletableFuture<T> unit(T value) {
3794              return completedFuture(value);
3795          }
3796          // monadic zero ?
zero()3797          static <T> CompletableFuture<T> zero() {
3798              return failedFuture(new ZeroException());
3799          }
3800          // >=>
compose(Function<T, CompletableFuture<U>> f, Function<U, CompletableFuture<V>> g)3801          static <T,U,V> Function<T, CompletableFuture<V>> compose
3802              (Function<T, CompletableFuture<U>> f,
3803               Function<U, CompletableFuture<V>> g) {
3804              return (x) -> f.apply(x).thenCompose(g);
3805          }
3806  
assertZero(CompletableFuture<?> f)3807          static void assertZero(CompletableFuture<?> f) {
3808              try {
3809                  f.getNow(null);
3810                  throw new AssertionFailedError("should throw");
3811              } catch (CompletionException success) {
3812                  assertTrue(success.getCause() instanceof ZeroException);
3813              }
3814          }
3815  
assertFutureEquals(CompletableFuture<T> f, CompletableFuture<T> g)3816          static <T> void assertFutureEquals(CompletableFuture<T> f,
3817                                             CompletableFuture<T> g) {
3818              T fval = null, gval = null;
3819              Throwable fex = null, gex = null;
3820  
3821              try { fval = f.get(); }
3822              catch (ExecutionException ex) { fex = ex.getCause(); }
3823              catch (Throwable ex) { fex = ex; }
3824  
3825              try { gval = g.get(); }
3826              catch (ExecutionException ex) { gex = ex.getCause(); }
3827              catch (Throwable ex) { gex = ex; }
3828  
3829              if (fex != null || gex != null)
3830                  assertSame(fex.getClass(), gex.getClass());
3831              else
3832                  assertEquals(fval, gval);
3833          }
3834  
3835          static class PlusFuture<T> extends CompletableFuture<T> {
3836              AtomicReference<Throwable> firstFailure = new AtomicReference<>(null);
3837          }
3838  
3839          /** Implements "monadic plus". */
plus(CompletableFuture<? extends T> f, CompletableFuture<? extends T> g)3840          static <T> CompletableFuture<T> plus(CompletableFuture<? extends T> f,
3841                                               CompletableFuture<? extends T> g) {
3842              PlusFuture<T> plus = new PlusFuture<T>();
3843              BiConsumer<T, Throwable> action = (T result, Throwable ex) -> {
3844                  try {
3845                      if (ex == null) {
3846                          if (plus.complete(result))
3847                              if (plus.firstFailure.get() != null)
3848                                  plus.firstFailure.set(null);
3849                      }
3850                      else if (plus.firstFailure.compareAndSet(null, ex)) {
3851                          if (plus.isDone())
3852                              plus.firstFailure.set(null);
3853                      }
3854                      else {
3855                          // first failure has precedence
3856                          Throwable first = plus.firstFailure.getAndSet(null);
3857  
3858                          // may fail with "Self-suppression not permitted"
3859                          try { first.addSuppressed(ex); }
3860                          catch (Exception ignored) {}
3861  
3862                          plus.completeExceptionally(first);
3863                      }
3864                  } catch (Throwable unexpected) {
3865                      plus.completeExceptionally(unexpected);
3866                  }
3867              };
3868              f.whenComplete(action);
3869              g.whenComplete(action);
3870              return plus;
3871          }
3872      }
3873  
3874      /**
3875       * CompletableFuture is an additive monad - sort of.
3876       * https://en.wikipedia.org/wiki/Monad_(functional_programming)#Additive_monads
3877       */
testAdditiveMonad()3878      public void testAdditiveMonad() throws Throwable {
3879          Function<Long, CompletableFuture<Long>> unit = Monad::unit;
3880          CompletableFuture<Long> zero = Monad.zero();
3881  
3882          // Some mutually non-commutative functions
3883          Function<Long, CompletableFuture<Long>> triple
3884              = (x) -> Monad.unit(3 * x);
3885          Function<Long, CompletableFuture<Long>> inc
3886              = (x) -> Monad.unit(x + 1);
3887  
3888          // unit is a right identity: m >>= unit === m
3889          Monad.assertFutureEquals(inc.apply(5L).thenCompose(unit),
3890                                   inc.apply(5L));
3891          // unit is a left identity: (unit x) >>= f === f x
3892          Monad.assertFutureEquals(unit.apply(5L).thenCompose(inc),
3893                                   inc.apply(5L));
3894  
3895          // associativity: (m >>= f) >>= g === m >>= ( \x -> (f x >>= g) )
3896          Monad.assertFutureEquals(
3897              unit.apply(5L).thenCompose(inc).thenCompose(triple),
3898              unit.apply(5L).thenCompose((x) -> inc.apply(x).thenCompose(triple)));
3899  
3900          // The case for CompletableFuture as an additive monad is weaker...
3901  
3902          // zero is a monadic zero
3903          Monad.assertZero(zero);
3904  
3905          // left zero: zero >>= f === zero
3906          Monad.assertZero(zero.thenCompose(inc));
3907          // right zero: f >>= (\x -> zero) === zero
3908          Monad.assertZero(inc.apply(5L).thenCompose((x) -> zero));
3909  
3910          // f plus zero === f
3911          Monad.assertFutureEquals(Monad.unit(5L),
3912                                   Monad.plus(Monad.unit(5L), zero));
3913          // zero plus f === f
3914          Monad.assertFutureEquals(Monad.unit(5L),
3915                                   Monad.plus(zero, Monad.unit(5L)));
3916          // zero plus zero === zero
3917          Monad.assertZero(Monad.plus(zero, zero));
3918          {
3919              CompletableFuture<Long> f = Monad.plus(Monad.unit(5L),
3920                                                     Monad.unit(8L));
3921              // non-determinism
3922              assertTrue(f.get() == 5L || f.get() == 8L);
3923          }
3924  
3925          CompletableFuture<Long> godot = new CompletableFuture<>();
3926          // f plus godot === f (doesn't wait for godot)
3927          Monad.assertFutureEquals(Monad.unit(5L),
3928                                   Monad.plus(Monad.unit(5L), godot));
3929          // godot plus f === f (doesn't wait for godot)
3930          Monad.assertFutureEquals(Monad.unit(5L),
3931                                   Monad.plus(godot, Monad.unit(5L)));
3932      }
3933  
3934  //     static <U> U join(CompletionStage<U> stage) {
3935  //         CompletableFuture<U> f = new CompletableFuture<>();
3936  //         stage.whenComplete((v, ex) -> {
3937  //             if (ex != null) f.completeExceptionally(ex); else f.complete(v);
3938  //         });
3939  //         return f.join();
3940  //     }
3941  
3942  //     static <U> boolean isDone(CompletionStage<U> stage) {
3943  //         CompletableFuture<U> f = new CompletableFuture<>();
3944  //         stage.whenComplete((v, ex) -> {
3945  //             if (ex != null) f.completeExceptionally(ex); else f.complete(v);
3946  //         });
3947  //         return f.isDone();
3948  //     }
3949  
3950  //     static <U> U join2(CompletionStage<U> stage) {
3951  //         return stage.toCompletableFuture().copy().join();
3952  //     }
3953  
3954  //     static <U> boolean isDone2(CompletionStage<U> stage) {
3955  //         return stage.toCompletableFuture().copy().isDone();
3956  //     }
3957  
3958  }
3959