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

Comparing jsr166/src/test/tck/CompletableFutureTest.java (file contents):
Revision 1.62 by jsr166, Fri Jun 6 01:19:22 2014 UTC vs.
Revision 1.75 by jsr166, Sat Jun 7 21:14:42 2014 UTC

# Line 105 | Line 105 | public class CompletableFutureTest exten
105          assertTrue(f.toString().contains("[Completed exceptionally]"));
106      }
107  
108 <    void checkCompletedWithWrappedCFException(CompletableFuture<?> f,
109 <                                              CFException ex) {
108 >    <U> void checkCompletedExceptionallyWithRootCause(CompletableFuture<U> f,
109 >                                                      Throwable ex) {
110          try {
111              f.get(LONG_DELAY_MS, MILLISECONDS);
112              shouldThrow();
# Line 131 | Line 131 | public class CompletableFutureTest exten
131          } catch (ExecutionException success) {
132              assertSame(ex, success.getCause());
133          } catch (Throwable fail) { threadUnexpectedException(fail); }
134 +
135          assertTrue(f.isDone());
136          assertFalse(f.isCancelled());
137          assertTrue(f.toString().contains("[Completed exceptionally]"));
138      }
139  
140 +    <U> void checkCompletedWithWrappedException(CompletableFuture<U> f,
141 +                                                Throwable ex) {
142 +        checkCompletedExceptionallyWithRootCause(f, ex);
143 +        try {
144 +            CompletableFuture<Throwable> spy = f.handle
145 +                ((U u, Throwable t) -> t);
146 +            assertTrue(spy.join() instanceof CompletionException);
147 +            assertSame(ex, spy.join().getCause());
148 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
149 +    }
150 +
151 +    <U> void checkCompletedExceptionally(CompletableFuture<U> f, Throwable ex) {
152 +        checkCompletedExceptionallyWithRootCause(f, ex);
153 +        try {
154 +            CompletableFuture<Throwable> spy = f.handle
155 +                ((U u, Throwable t) -> t);
156 +            assertSame(ex, spy.join());
157 +        } catch (Throwable fail) { threadUnexpectedException(fail); }
158 +    }
159 +
160      void checkCancelled(CompletableFuture<?> f) {
161          try {
162              f.get(LONG_DELAY_MS, MILLISECONDS);
# Line 218 | Line 239 | public class CompletableFutureTest exten
239       */
240      public void testCompleteExceptionally() {
241          CompletableFuture<Integer> f = new CompletableFuture<>();
242 +        CFException ex = new CFException();
243          checkIncomplete(f);
244 <        f.completeExceptionally(new CFException());
245 <        checkCompletedWithWrappedCFException(f);
244 >        f.completeExceptionally(ex);
245 >        checkCompletedExceptionally(f, ex);
246      }
247  
248      /**
# Line 261 | Line 283 | public class CompletableFutureTest exten
283       * obtrudeException forces completion with given exception
284       */
285      public void testObtrudeException() {
286 <        CompletableFuture<Integer> f = new CompletableFuture<>();
287 <        checkIncomplete(f);
288 <        f.complete(one);
289 <        checkCompletedNormally(f, one);
290 <        f.obtrudeException(new CFException());
269 <        checkCompletedWithWrappedCFException(f);
286 >        for (Integer v1 : new Integer[] { 1, null })
287 >    {
288 >        CFException ex;
289 >        CompletableFuture<Integer> f;
290 >
291          f = new CompletableFuture<>();
292 <        f.obtrudeException(new CFException());
293 <        checkCompletedWithWrappedCFException(f);
292 >        f.complete(v1);
293 >        for (int i = 0; i < 2; i++) {
294 >            f.obtrudeException(ex = new CFException());
295 >            checkCompletedExceptionally(f, ex);
296 >        }
297 >
298 >        f = new CompletableFuture<>();
299 >        for (int i = 0; i < 2; i++) {
300 >            f.obtrudeException(ex = new CFException());
301 >            checkCompletedExceptionally(f, ex);
302 >        }
303 >
304          f = new CompletableFuture<>();
305 +        f.completeExceptionally(ex = new CFException());
306 +        f.obtrudeValue(v1);
307 +        checkCompletedNormally(f, v1);
308 +        f.obtrudeException(ex = new CFException());
309 +        checkCompletedExceptionally(f, ex);
310          f.completeExceptionally(new CFException());
311 <        f.obtrudeValue(four);
312 <        checkCompletedNormally(f, four);
313 <        f.obtrudeException(new CFException());
314 <        checkCompletedWithWrappedCFException(f);
279 <    }
311 >        checkCompletedExceptionally(f, ex);
312 >        f.complete(v1);
313 >        checkCompletedExceptionally(f, ex);
314 >    }}
315  
316      /**
317       * getNumberOfDependents returns number of dependent tasks
# Line 310 | Line 345 | public class CompletableFutureTest exten
345          f = new CompletableFuture<String>();
346          f.completeExceptionally(new IndexOutOfBoundsException());
347          assertTrue(f.toString().contains("[Completed exceptionally]"));
348 +
349 +        f = new CompletableFuture<String>();
350 +        f.cancel(true);
351 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
352 +
353 +        f = new CompletableFuture<String>();
354 +        f.cancel(false);
355 +        assertTrue(f.toString().contains("[Completed exceptionally]"));
356      }
357  
358      /**
# Line 360 | Line 403 | public class CompletableFutureTest exten
403          return (x == null) ? null : x + 1;
404      }
405  
406 <    class IncAction extends CheckedIntegerAction
406 >    class NoopConsumer extends CheckedIntegerAction
407          implements Consumer<Integer>
408      {
409 <        IncAction(ExecutionMode m) { super(m); }
409 >        NoopConsumer(ExecutionMode m) { super(m); }
410          public void accept(Integer x) {
411              invoked();
412 <            value = inc(x);
412 >            value = x;
413          }
414      }
415  
# Line 415 | Line 458 | public class CompletableFutureTest exten
458          }
459      }
460  
461 <    class FailingSupplier extends CheckedAction implements Supplier<Integer>
461 >    class FailingSupplier extends CheckedAction
462 >        implements Supplier<Integer>
463      {
464          FailingSupplier(ExecutionMode m) { super(m); }
465          public Integer get() {
# Line 424 | Line 468 | public class CompletableFutureTest exten
468          }
469      }
470  
471 <    class FailingConsumer extends CheckedAction implements Consumer<Integer> {
471 >    class FailingConsumer extends CheckedIntegerAction
472 >        implements Consumer<Integer>
473 >    {
474          FailingConsumer(ExecutionMode m) { super(m); }
475          public void accept(Integer x) {
476              invoked();
477 +            value = x;
478              throw new CFException();
479          }
480      }
481  
482 <    class FailingBiConsumer extends CheckedAction
482 >    class FailingBiConsumer extends CheckedIntegerAction
483          implements BiConsumer<Integer, Integer>
484      {
485          FailingBiConsumer(ExecutionMode m) { super(m); }
486          public void accept(Integer x, Integer y) {
487              invoked();
488 +            value = subtract(x, y);
489              throw new CFException();
490          }
491      }
492  
493 <    class FailingFunction extends CheckedAction
493 >    class FailingFunction extends CheckedIntegerAction
494          implements Function<Integer, Integer>
495      {
496          FailingFunction(ExecutionMode m) { super(m); }
497          public Integer apply(Integer x) {
498              invoked();
499 +            value = x;
500              throw new CFException();
501          }
502      }
503  
504 <    class FailingBiFunction extends CheckedAction
504 >    class FailingBiFunction extends CheckedIntegerAction
505          implements BiFunction<Integer, Integer, Integer>
506      {
507          FailingBiFunction(ExecutionMode m) { super(m); }
508          public Integer apply(Integer x, Integer y) {
509              invoked();
510 +            value = subtract(x, y);
511              throw new CFException();
512          }
513      }
# Line 471 | Line 521 | public class CompletableFutureTest exten
521      }
522  
523  
524 <    class CompletableFutureInc extends CheckedAction
524 >    class CompletableFutureInc extends CheckedIntegerAction
525          implements Function<Integer, CompletableFuture<Integer>>
526      {
527          CompletableFutureInc(ExecutionMode m) { super(m); }
528          public CompletableFuture<Integer> apply(Integer x) {
529              invoked();
530 +            value = x;
531              CompletableFuture<Integer> f = new CompletableFuture<>();
532              f.complete(inc(x));
533              return f;
534          }
535      }
536  
537 <    class FailingCompletableFutureFunction extends CheckedAction
537 >    class FailingCompletableFutureFunction extends CheckedIntegerAction
538          implements Function<Integer, CompletableFuture<Integer>>
539      {
540          FailingCompletableFutureFunction(ExecutionMode m) { super(m); }
541          public CompletableFuture<Integer> apply(Integer x) {
542              invoked();
543 +            value = x;
544              throw new CFException();
545          }
546      }
# Line 799 | Line 851 | public class CompletableFutureTest exten
851          assertEquals(0, a.get());
852      }}
853  
802
854      /**
855       * exceptionally action completes with function value on source
856       * exception
# Line 843 | Line 894 | public class CompletableFutureTest exten
894              });
895          if (createIncomplete) f.completeExceptionally(ex1);
896  
897 <        checkCompletedWithWrappedCFException(g, ex2);
897 >        checkCompletedWithWrappedException(g, ex2);
898 >        assertEquals(1, a.get());
899 >    }}
900 >
901 >    /**
902 >     * whenComplete action executes on normal completion, propagating
903 >     * source result.
904 >     */
905 >    public void testWhenComplete_normalCompletion1() {
906 >        for (ExecutionMode m : ExecutionMode.values())
907 >        for (boolean createIncomplete : new boolean[] { true, false })
908 >        for (Integer v1 : new Integer[] { 1, null })
909 >    {
910 >        final AtomicInteger a = new AtomicInteger(0);
911 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
912 >        if (!createIncomplete) f.complete(v1);
913 >        final CompletableFuture<Integer> g = m.whenComplete
914 >            (f,
915 >             (Integer x, Throwable t) -> {
916 >                m.checkExecutionMode();
917 >                threadAssertSame(x, v1);
918 >                threadAssertNull(t);
919 >                a.getAndIncrement();
920 >            });
921 >        if (createIncomplete) f.complete(v1);
922 >
923 >        checkCompletedNormally(g, v1);
924 >        checkCompletedNormally(f, v1);
925 >        assertEquals(1, a.get());
926 >    }}
927 >
928 >    /**
929 >     * whenComplete action executes on exceptional completion, propagating
930 >     * source result.
931 >     */
932 >    public void testWhenComplete_exceptionalCompletion() {
933 >        for (ExecutionMode m : ExecutionMode.values())
934 >        for (boolean createIncomplete : new boolean[] { true, false })
935 >        for (Integer v1 : new Integer[] { 1, null })
936 >    {
937 >        final AtomicInteger a = new AtomicInteger(0);
938 >        final CFException ex = new CFException();
939 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
940 >        if (!createIncomplete) f.completeExceptionally(ex);
941 >        final CompletableFuture<Integer> g = m.whenComplete
942 >            (f,
943 >             (Integer x, Throwable t) -> {
944 >                m.checkExecutionMode();
945 >                threadAssertNull(x);
946 >                threadAssertSame(t, ex);
947 >                a.getAndIncrement();
948 >            });
949 >        if (createIncomplete) f.completeExceptionally(ex);
950 >
951 >        checkCompletedWithWrappedException(g, ex);
952 >        checkCompletedExceptionally(f, ex);
953 >        assertEquals(1, a.get());
954 >    }}
955 >
956 >    /**
957 >     * whenComplete action executes on cancelled source, propagating
958 >     * CancellationException.
959 >     */
960 >    public void testWhenComplete_sourceCancelled() {
961 >        for (ExecutionMode m : ExecutionMode.values())
962 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
963 >        for (boolean createIncomplete : new boolean[] { true, false })
964 >    {
965 >        final AtomicInteger a = new AtomicInteger(0);
966 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
967 >        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
968 >        final CompletableFuture<Integer> g = m.whenComplete
969 >            (f,
970 >             (Integer x, Throwable t) -> {
971 >                m.checkExecutionMode();
972 >                threadAssertNull(x);
973 >                threadAssertTrue(t instanceof CancellationException);
974 >                a.getAndIncrement();
975 >            });
976 >        if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
977 >
978 >        checkCompletedWithWrappedCancellationException(g);
979 >        checkCancelled(f);
980 >        assertEquals(1, a.get());
981 >    }}
982 >
983 >    /**
984 >     * If a whenComplete action throws an exception when triggered by
985 >     * a normal completion, it completes exceptionally
986 >     */
987 >    public void testWhenComplete_actionFailed() {
988 >        for (boolean createIncomplete : new boolean[] { true, false })
989 >        for (ExecutionMode m : ExecutionMode.values())
990 >        for (Integer v1 : new Integer[] { 1, null })
991 >    {
992 >        final AtomicInteger a = new AtomicInteger(0);
993 >        final CFException ex = new CFException();
994 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
995 >        if (!createIncomplete) f.complete(v1);
996 >        final CompletableFuture<Integer> g = m.whenComplete
997 >            (f,
998 >             (Integer x, Throwable t) -> {
999 >                m.checkExecutionMode();
1000 >                threadAssertSame(x, v1);
1001 >                threadAssertNull(t);
1002 >                a.getAndIncrement();
1003 >                throw ex;
1004 >            });
1005 >        if (createIncomplete) f.complete(v1);
1006 >
1007 >        checkCompletedWithWrappedException(g, ex);
1008 >        checkCompletedNormally(f, v1);
1009 >        assertEquals(1, a.get());
1010 >    }}
1011 >
1012 >    /**
1013 >     * If a whenComplete action throws an exception when triggered by
1014 >     * a source completion that also throws an exception, the source
1015 >     * exception takes precedence.
1016 >     */
1017 >    public void testWhenComplete_actionFailedSourceFailed() {
1018 >        for (boolean createIncomplete : new boolean[] { true, false })
1019 >        for (ExecutionMode m : ExecutionMode.values())
1020 >        for (Integer v1 : new Integer[] { 1, null })
1021 >    {
1022 >        final AtomicInteger a = new AtomicInteger(0);
1023 >        final CFException ex1 = new CFException();
1024 >        final CFException ex2 = new CFException();
1025 >        final CompletableFuture<Integer> f = new CompletableFuture<>();
1026 >
1027 >        if (!createIncomplete) f.completeExceptionally(ex1);
1028 >        final CompletableFuture<Integer> g = m.whenComplete
1029 >            (f,
1030 >             (Integer x, Throwable t) -> {
1031 >                m.checkExecutionMode();
1032 >                threadAssertSame(t, ex1);
1033 >                threadAssertNull(x);
1034 >                a.getAndIncrement();
1035 >                throw ex2;
1036 >            });
1037 >        if (createIncomplete) f.completeExceptionally(ex1);
1038 >
1039 >        checkCompletedWithWrappedException(g, ex1);
1040 >        checkCompletedExceptionally(f, ex1);
1041          assertEquals(1, a.get());
1042      }}
1043  
# Line 900 | Line 1094 | public class CompletableFutureTest exten
1094          if (createIncomplete) f.completeExceptionally(ex);
1095  
1096          checkCompletedNormally(g, v1);
1097 <        checkCompletedWithWrappedCFException(f, ex);
1097 >        checkCompletedExceptionally(f, ex);
1098          assertEquals(1, a.get());
1099      }}
1100  
# Line 956 | Line 1150 | public class CompletableFutureTest exten
1150              });
1151          if (createIncomplete) f.completeExceptionally(ex1);
1152  
1153 <        checkCompletedWithWrappedCFException(g, ex2);
1154 <        checkCompletedWithWrappedCFException(f, ex1);
1153 >        checkCompletedWithWrappedException(g, ex2);
1154 >        checkCompletedExceptionally(f, ex1);
1155          assertEquals(1, a.get());
1156      }}
1157  
# Line 981 | Line 1175 | public class CompletableFutureTest exten
1175              });
1176          if (createIncomplete) f.complete(v1);
1177  
1178 <        checkCompletedWithWrappedCFException(g, ex);
1178 >        checkCompletedWithWrappedException(g, ex);
1179          checkCompletedNormally(f, v1);
1180          assertEquals(1, a.get());
1181      }}
# Line 1095 | Line 1289 | public class CompletableFutureTest exten
1289              f.completeExceptionally(ex);
1290          }
1291  
1292 <        checkCompletedWithWrappedCFException(g, ex);
1293 <        checkCompletedWithWrappedCFException(f, ex);
1292 >        checkCompletedWithWrappedException(g, ex);
1293 >        checkCompletedExceptionally(f, ex);
1294          r.assertNotInvoked();
1295      }}
1296  
# Line 1162 | Line 1356 | public class CompletableFutureTest exten
1356  
1357          checkCompletedNormally(g, inc(v1));
1358          checkCompletedNormally(f, v1);
1359 <        r.assertInvoked();
1359 >        r.assertValue(inc(v1));
1360      }}
1361  
1362      /**
# Line 1183 | Line 1377 | public class CompletableFutureTest exten
1377              f.completeExceptionally(ex);
1378          }
1379  
1380 <        checkCompletedWithWrappedCFException(g, ex);
1381 <        checkCompletedWithWrappedCFException(f, ex);
1380 >        checkCompletedWithWrappedException(g, ex);
1381 >        checkCompletedExceptionally(f, ex);
1382          r.assertNotInvoked();
1383      }}
1384  
# Line 1240 | Line 1434 | public class CompletableFutureTest exten
1434          for (Integer v1 : new Integer[] { 1, null })
1435      {
1436          final CompletableFuture<Integer> f = new CompletableFuture<>();
1437 <        final IncAction r = new IncAction(m);
1437 >        final NoopConsumer r = new NoopConsumer(m);
1438          if (!createIncomplete) f.complete(v1);
1439          final CompletableFuture<Void> g = m.thenAccept(f, r);
1440          if (createIncomplete) {
# Line 1249 | Line 1443 | public class CompletableFutureTest exten
1443          }
1444  
1445          checkCompletedNormally(g, null);
1446 +        r.assertValue(v1);
1447          checkCompletedNormally(f, v1);
1253        r.assertInvoked();
1254        r.assertValue(inc(v1));
1448      }}
1449  
1450      /**
# Line 1264 | Line 1457 | public class CompletableFutureTest exten
1457      {
1458          final CFException ex = new CFException();
1459          final CompletableFuture<Integer> f = new CompletableFuture<>();
1460 <        final IncAction r = new IncAction(m);
1460 >        final NoopConsumer r = new NoopConsumer(m);
1461          if (!createIncomplete) f.completeExceptionally(ex);
1462          final CompletableFuture<Void> g = m.thenAccept(f, r);
1463          if (createIncomplete) {
# Line 1272 | Line 1465 | public class CompletableFutureTest exten
1465              f.completeExceptionally(ex);
1466          }
1467  
1468 <        checkCompletedWithWrappedCFException(g, ex);
1469 <        checkCompletedWithWrappedCFException(f, ex);
1468 >        checkCompletedWithWrappedException(g, ex);
1469 >        checkCompletedExceptionally(f, ex);
1470          r.assertNotInvoked();
1471      }}
1472  
# Line 1286 | Line 1479 | public class CompletableFutureTest exten
1479          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1480      {
1481          final CompletableFuture<Integer> f = new CompletableFuture<>();
1482 <        final IncAction r = new IncAction(m);
1482 >        final NoopConsumer r = new NoopConsumer(m);
1483          if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1484          final CompletableFuture<Void> g = m.thenAccept(f, r);
1485          if (createIncomplete) {
# Line 1348 | Line 1541 | public class CompletableFutureTest exten
1541          checkCompletedNormally(h, subtract(v1, v2));
1542          checkCompletedNormally(f, v1);
1543          checkCompletedNormally(g, v2);
1544 <        r.assertInvoked();
1544 >        r.assertValue(subtract(v1, v2));
1545      }}
1546  
1547      /**
# Line 1375 | Line 1568 | public class CompletableFutureTest exten
1568              (!fFirst ? f : g).completeExceptionally(ex);
1569          }
1570  
1571 <        checkCompletedWithWrappedCFException(h, ex);
1571 >        checkCompletedWithWrappedException(h, ex);
1572          r.assertNotInvoked();
1573          checkCompletedNormally(fFirst ? f : g, v1);
1574 <        checkCompletedWithWrappedCFException(!fFirst ? f : g, ex);
1574 >        checkCompletedExceptionally(!fFirst ? f : g, ex);
1575      }}
1576  
1577      /**
# Line 1492 | Line 1685 | public class CompletableFutureTest exten
1685              (!fFirst ? f : g).completeExceptionally(ex);
1686          }
1687  
1688 <        checkCompletedWithWrappedCFException(h, ex);
1688 >        checkCompletedWithWrappedException(h, ex);
1689          r.assertNotInvoked();
1690          checkCompletedNormally(fFirst ? f : g, v1);
1691 <        checkCompletedWithWrappedCFException(!fFirst ? f : g, ex);
1691 >        checkCompletedExceptionally(!fFirst ? f : g, ex);
1692      }}
1693  
1694      /**
# Line 1609 | Line 1802 | public class CompletableFutureTest exten
1802              (!fFirst ? f : g).completeExceptionally(ex);
1803          }
1804  
1805 <        checkCompletedWithWrappedCFException(h, ex);
1805 >        checkCompletedWithWrappedException(h, ex);
1806          r.assertNotInvoked();
1807          checkCompletedNormally(fFirst ? f : g, v1);
1808 <        checkCompletedWithWrappedCFException(!fFirst ? f : g, ex);
1808 >        checkCompletedExceptionally(!fFirst ? f : g, ex);
1809      }}
1810  
1811      /**
# Line 1629 | Line 1822 | public class CompletableFutureTest exten
1822          final CompletableFuture<Integer> g = new CompletableFuture<>();
1823          final Noop r = new Noop(m);
1824  
1632
1825          (fFirst ? f : g).complete(v1);
1826          if (!createIncomplete)
1827              assertTrue((!fFirst ? f : g).cancel(mayInterruptIfRunning));
# Line 1744 | Line 1936 | public class CompletableFutureTest exten
1936          rs[0].assertNotInvoked();
1937          rs[1].assertNotInvoked();
1938          f.completeExceptionally(ex);
1939 <        checkCompletedWithWrappedCFException(h0, ex);
1940 <        checkCompletedWithWrappedCFException(h1, ex);
1939 >        checkCompletedWithWrappedException(h0, ex);
1940 >        checkCompletedWithWrappedException(h1, ex);
1941          final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
1942          final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
1943 <        checkCompletedWithWrappedCFException(h2, ex);
1944 <        checkCompletedWithWrappedCFException(h3, ex);
1943 >        checkCompletedWithWrappedException(h2, ex);
1944 >        checkCompletedWithWrappedException(h3, ex);
1945          g.complete(v1);
1946  
1947          // unspecified behavior - both source completions available
# Line 1757 | Line 1949 | public class CompletableFutureTest exten
1949          final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
1950          try {
1951              assertEquals(inc(v1), h4.join());
1952 <            rs[4].assertInvoked();
1952 >            rs[4].assertValue(inc(v1));
1953          } catch (CompletionException ok) {
1954 <            checkCompletedWithWrappedCFException(h4, ex);
1954 >            checkCompletedWithWrappedException(h4, ex);
1955              rs[4].assertNotInvoked();
1956          }
1957          try {
1958              assertEquals(inc(v1), h5.join());
1959 <            rs[5].assertInvoked();
1959 >            rs[5].assertValue(inc(v1));
1960          } catch (CompletionException ok) {
1961 <            checkCompletedWithWrappedCFException(h5, ex);
1961 >            checkCompletedWithWrappedException(h5, ex);
1962              rs[5].assertNotInvoked();
1963          }
1964  
1965 <        checkCompletedWithWrappedCFException(f, ex);
1965 >        checkCompletedExceptionally(f, ex);
1966          checkCompletedNormally(g, v1);
1967 <        checkCompletedWithWrappedCFException(h0, ex);
1968 <        checkCompletedWithWrappedCFException(h1, ex);
1969 <        checkCompletedWithWrappedCFException(h2, ex);
1970 <        checkCompletedWithWrappedCFException(h3, ex);
1971 <        checkCompletedWithWrappedCFException(h4, ex);
1967 >        checkCompletedWithWrappedException(h0, ex);
1968 >        checkCompletedWithWrappedException(h1, ex);
1969 >        checkCompletedWithWrappedException(h2, ex);
1970 >        checkCompletedWithWrappedException(h3, ex);
1971 >        checkCompletedWithWrappedException(h4, ex);
1972          for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
1973      }}
1974  
1975 +    public void testApplyToEither_exceptionalCompletion2() {
1976 +        for (ExecutionMode m : ExecutionMode.values())
1977 +        for (boolean fFirst : new boolean[] { true, false })
1978 +        for (Integer v1 : new Integer[] { 1, null })
1979 +    {
1980 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
1981 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
1982 +        final CFException ex = new CFException();
1983 +        final IncFunction[] rs = new IncFunction[6];
1984 +        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1985 +
1986 +        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
1987 +        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
1988 +        if (fFirst) {
1989 +            f.complete(v1);
1990 +            g.completeExceptionally(ex);
1991 +        } else {
1992 +            g.completeExceptionally(ex);
1993 +            f.complete(v1);
1994 +        }
1995 +        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
1996 +        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
1997 +
1998 +        // unspecified behavior - both source completions available
1999 +        try {
2000 +            assertEquals(inc(v1), h0.join());
2001 +            rs[0].assertValue(inc(v1));
2002 +        } catch (CompletionException ok) {
2003 +            checkCompletedWithWrappedException(h0, ex);
2004 +            rs[0].assertNotInvoked();
2005 +        }
2006 +        try {
2007 +            assertEquals(inc(v1), h1.join());
2008 +            rs[1].assertValue(inc(v1));
2009 +        } catch (CompletionException ok) {
2010 +            checkCompletedWithWrappedException(h1, ex);
2011 +            rs[1].assertNotInvoked();
2012 +        }
2013 +        try {
2014 +            assertEquals(inc(v1), h2.join());
2015 +            rs[2].assertValue(inc(v1));
2016 +        } catch (CompletionException ok) {
2017 +            checkCompletedWithWrappedException(h2, ex);
2018 +            rs[2].assertNotInvoked();
2019 +        }
2020 +        try {
2021 +            assertEquals(inc(v1), h3.join());
2022 +            rs[3].assertValue(inc(v1));
2023 +        } catch (CompletionException ok) {
2024 +            checkCompletedWithWrappedException(h3, ex);
2025 +            rs[3].assertNotInvoked();
2026 +        }
2027 +
2028 +        checkCompletedNormally(f, v1);
2029 +        checkCompletedExceptionally(g, ex);
2030 +    }}
2031 +
2032      /**
2033       * applyToEither result completes exceptionally if either source cancelled
2034       */
# Line 1813 | Line 2062 | public class CompletableFutureTest exten
2062          final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2063          try {
2064              assertEquals(inc(v1), h4.join());
2065 <            rs[4].assertInvoked();
2065 >            rs[4].assertValue(inc(v1));
2066          } catch (CompletionException ok) {
2067              checkCompletedWithWrappedCancellationException(h4);
2068              rs[4].assertNotInvoked();
2069          }
2070          try {
2071              assertEquals(inc(v1), h5.join());
2072 <            rs[5].assertInvoked();
2072 >            rs[5].assertValue(inc(v1));
2073          } catch (CompletionException ok) {
2074              checkCompletedWithWrappedCancellationException(h5);
2075              rs[5].assertNotInvoked();
# Line 1835 | Line 2084 | public class CompletableFutureTest exten
2084          for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2085      }}
2086  
2087 <    /**
1839 <     * applyToEither result completes exceptionally if action does
1840 <     */
1841 <    public void testApplyToEither_actionFailed() {
2087 >    public void testApplyToEither_sourceCancelled2() {
2088          for (ExecutionMode m : ExecutionMode.values())
2089 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2090 +        for (boolean fFirst : new boolean[] { true, false })
2091          for (Integer v1 : new Integer[] { 1, null })
1844        for (Integer v2 : new Integer[] { 2, null })
2092      {
2093          final CompletableFuture<Integer> f = new CompletableFuture<>();
2094          final CompletableFuture<Integer> g = new CompletableFuture<>();
2095 <        final FailingFunction[] rs = new FailingFunction[6];
2096 <        for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
2095 >        final IncFunction[] rs = new IncFunction[6];
2096 >        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
2097  
2098          final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
2099          final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
2100 <        f.complete(v1);
2100 >        if (fFirst) {
2101 >            f.complete(v1);
2102 >            g.cancel(mayInterruptIfRunning);
2103 >        } else {
2104 >            g.cancel(mayInterruptIfRunning);
2105 >            f.complete(v1);
2106 >        }
2107          final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2108          final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2109 <        g.complete(v2);
2110 <        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2111 <        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2112 <        
2109 >
2110 >        // unspecified behavior - both source completions available
2111 >        try {
2112 >            assertEquals(inc(v1), h0.join());
2113 >            rs[0].assertValue(inc(v1));
2114 >        } catch (CompletionException ok) {
2115 >            checkCompletedWithWrappedCancellationException(h0);
2116 >            rs[0].assertNotInvoked();
2117 >        }
2118 >        try {
2119 >            assertEquals(inc(v1), h1.join());
2120 >            rs[1].assertValue(inc(v1));
2121 >        } catch (CompletionException ok) {
2122 >            checkCompletedWithWrappedCancellationException(h1);
2123 >            rs[1].assertNotInvoked();
2124 >        }
2125 >        try {
2126 >            assertEquals(inc(v1), h2.join());
2127 >            rs[2].assertValue(inc(v1));
2128 >        } catch (CompletionException ok) {
2129 >            checkCompletedWithWrappedCancellationException(h2);
2130 >            rs[2].assertNotInvoked();
2131 >        }
2132 >        try {
2133 >            assertEquals(inc(v1), h3.join());
2134 >            rs[3].assertValue(inc(v1));
2135 >        } catch (CompletionException ok) {
2136 >            checkCompletedWithWrappedCancellationException(h3);
2137 >            rs[3].assertNotInvoked();
2138 >        }
2139 >
2140          checkCompletedNormally(f, v1);
2141 <        checkCompletedNormally(g, v2);
1862 <        checkCompletedWithWrappedCFException(h0);
1863 <        checkCompletedWithWrappedCFException(h1);
1864 <        checkCompletedWithWrappedCFException(h2);
1865 <        checkCompletedWithWrappedCFException(h3);
1866 <        checkCompletedWithWrappedCFException(h4);
1867 <        checkCompletedWithWrappedCFException(h5);
1868 <        for (int i = 0; i < rs.length; i++) rs[i].assertInvoked();
2141 >        checkCancelled(g);
2142      }}
2143  
2144      /**
2145 <     * acceptEither result completes normally after normal completion
1873 <     * of either source
2145 >     * applyToEither result completes exceptionally if action does
2146       */
2147 <    public void testAcceptEither_normalCompletion1() {
2147 >    public void testApplyToEither_actionFailed() {
2148          for (ExecutionMode m : ExecutionMode.values())
2149          for (Integer v1 : new Integer[] { 1, null })
2150          for (Integer v2 : new Integer[] { 2, null })
2151      {
2152          final CompletableFuture<Integer> f = new CompletableFuture<>();
2153          final CompletableFuture<Integer> g = new CompletableFuture<>();
2154 <        final IncAction r = new IncAction(m);
2155 <        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2154 >        final FailingFunction[] rs = new FailingFunction[6];
2155 >        for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(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          f.complete(v1);
2160 <        checkCompletedNormally(h, null);
2161 <        assertEquals(inc(v1), r.value);
2162 <        g.complete(v2);
2160 >        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
2161 >        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
2162 >        checkCompletedWithWrappedCFException(h0);
2163 >        checkCompletedWithWrappedCFException(h1);
2164 >        checkCompletedWithWrappedCFException(h2);
2165 >        checkCompletedWithWrappedCFException(h3);
2166 >        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2167  
2168 <        checkCompletedNormally(f, v1);
1891 <        checkCompletedNormally(g, v2);
1892 <        checkCompletedNormally(h, null);
1893 <    }}
2168 >        g.complete(v2);
2169  
2170 <    public void testAcceptEither_normalCompletion2() {
2171 <        for (ExecutionMode m : ExecutionMode.values())
2172 <        for (Integer v1 : new Integer[] { 1, null })
1898 <        for (Integer v2 : new Integer[] { 2, null })
1899 <    {
1900 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
1901 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
1902 <        final IncAction r = new IncAction(m);
1903 <        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2170 >        // unspecified behavior - both source completions available
2171 >        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
2172 >        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
2173  
2174 <        g.complete(v2);
2175 <        checkCompletedNormally(h, null);
2176 <        assertEquals(inc(v2), r.value);
2177 <        f.complete(v1);
2174 >        checkCompletedWithWrappedCFException(h4);
2175 >        assertTrue(Objects.equals(v1, rs[4].value) ||
2176 >                   Objects.equals(v2, rs[4].value));
2177 >        checkCompletedWithWrappedCFException(h5);
2178 >        assertTrue(Objects.equals(v1, rs[5].value) ||
2179 >                   Objects.equals(v2, rs[5].value));
2180  
2181          checkCompletedNormally(f, v1);
2182          checkCompletedNormally(g, v2);
1912        checkCompletedNormally(h, null);
2183      }}
2184  
2185 <    public void testAcceptEither_normalCompletion3() {
2185 >    /**
2186 >     * acceptEither result completes normally after normal completion
2187 >     * of either source
2188 >     */
2189 >    public void testAcceptEither_normalCompletion() {
2190          for (ExecutionMode m : ExecutionMode.values())
2191          for (Integer v1 : new Integer[] { 1, null })
2192          for (Integer v2 : new Integer[] { 2, null })
2193      {
2194          final CompletableFuture<Integer> f = new CompletableFuture<>();
2195          final CompletableFuture<Integer> g = new CompletableFuture<>();
2196 <        final IncAction r = new IncAction(m);
2196 >        final NoopConsumer[] rs = new NoopConsumer[6];
2197 >        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2198  
2199 +        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2200 +        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2201 +        checkIncomplete(h0);
2202 +        checkIncomplete(h1);
2203 +        rs[0].assertNotInvoked();
2204 +        rs[1].assertNotInvoked();
2205          f.complete(v1);
2206 +        checkCompletedNormally(h0, null);
2207 +        checkCompletedNormally(h1, null);
2208 +        rs[0].assertValue(v1);
2209 +        rs[1].assertValue(v1);
2210 +        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2211 +        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2212 +        checkCompletedNormally(h2, null);
2213 +        checkCompletedNormally(h3, null);
2214 +        rs[2].assertValue(v1);
2215 +        rs[3].assertValue(v1);
2216          g.complete(v2);
1926        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2217  
2218 <        checkCompletedNormally(h, null);
2218 >        // unspecified behavior - both source completions available
2219 >        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2220 >        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2221 >        checkCompletedNormally(h4, null);
2222 >        checkCompletedNormally(h5, null);
2223 >        assertTrue(Objects.equals(v1, rs[4].value) ||
2224 >                   Objects.equals(v2, rs[4].value));
2225 >        assertTrue(Objects.equals(v1, rs[5].value) ||
2226 >                   Objects.equals(v2, rs[5].value));
2227 >
2228          checkCompletedNormally(f, v1);
2229          checkCompletedNormally(g, v2);
2230 <
2231 <        // unspecified behavior
2232 <        assertTrue(Objects.equals(r.value, inc(v1)) ||
2233 <                   Objects.equals(r.value, inc(v2)));
2230 >        checkCompletedNormally(h0, null);
2231 >        checkCompletedNormally(h1, null);
2232 >        checkCompletedNormally(h2, null);
2233 >        checkCompletedNormally(h3, null);
2234 >        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2235      }}
2236  
2237      /**
2238       * acceptEither result completes exceptionally after exceptional
2239       * completion of either source
2240       */
2241 <    public void testAcceptEither_exceptionalCompletion1() {
2241 >    public void testAcceptEither_exceptionalCompletion() {
2242          for (ExecutionMode m : ExecutionMode.values())
2243          for (Integer v1 : new Integer[] { 1, null })
2244      {
2245          final CompletableFuture<Integer> f = new CompletableFuture<>();
2246          final CompletableFuture<Integer> g = new CompletableFuture<>();
1947        final IncAction r = new IncAction(m);
1948        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2247          final CFException ex = new CFException();
2248 +        final NoopConsumer[] rs = new NoopConsumer[6];
2249 +        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2250  
2251 +        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2252 +        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2253 +        checkIncomplete(h0);
2254 +        checkIncomplete(h1);
2255 +        rs[0].assertNotInvoked();
2256 +        rs[1].assertNotInvoked();
2257          f.completeExceptionally(ex);
2258 <        checkCompletedWithWrappedCFException(h, ex);
2258 >        checkCompletedWithWrappedException(h0, ex);
2259 >        checkCompletedWithWrappedException(h1, ex);
2260 >        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2261 >        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2262 >        checkCompletedWithWrappedException(h2, ex);
2263 >        checkCompletedWithWrappedException(h3, ex);
2264 >
2265          g.complete(v1);
2266  
2267 <        r.assertNotInvoked();
2267 >        // unspecified behavior - both source completions available
2268 >        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2269 >        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2270 >        try {
2271 >            assertNull(h4.join());
2272 >            rs[4].assertValue(v1);
2273 >        } catch (CompletionException ok) {
2274 >            checkCompletedWithWrappedException(h4, ex);
2275 >            rs[4].assertNotInvoked();
2276 >        }
2277 >        try {
2278 >            assertNull(h5.join());
2279 >            rs[5].assertValue(v1);
2280 >        } catch (CompletionException ok) {
2281 >            checkCompletedWithWrappedException(h5, ex);
2282 >            rs[5].assertNotInvoked();
2283 >        }
2284 >
2285 >        checkCompletedExceptionally(f, ex);
2286          checkCompletedNormally(g, v1);
2287 <        checkCompletedWithWrappedCFException(f, ex);
2288 <        checkCompletedWithWrappedCFException(h, ex);
2287 >        checkCompletedWithWrappedException(h0, ex);
2288 >        checkCompletedWithWrappedException(h1, ex);
2289 >        checkCompletedWithWrappedException(h2, ex);
2290 >        checkCompletedWithWrappedException(h3, ex);
2291 >        checkCompletedWithWrappedException(h4, ex);
2292 >        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2293      }}
2294  
2295      public void testAcceptEither_exceptionalCompletion2() {
2296          for (ExecutionMode m : ExecutionMode.values())
2297 +        for (boolean fFirst : new boolean[] { true, false })
2298          for (Integer v1 : new Integer[] { 1, null })
2299      {
2300          final CompletableFuture<Integer> f = new CompletableFuture<>();
2301          final CompletableFuture<Integer> g = new CompletableFuture<>();
1967        final IncAction r = new IncAction(m);
1968        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
1969        final CFException ex = new CFException();
1970
1971        g.completeExceptionally(ex);
1972        checkCompletedWithWrappedCFException(h, ex);
1973        f.complete(v1);
1974
1975        r.assertNotInvoked();
1976        checkCompletedNormally(f, v1);
1977        checkCompletedWithWrappedCFException(g, ex);
1978        checkCompletedWithWrappedCFException(h, ex);
1979    }}
1980
1981    public void testAcceptEither_exceptionalCompletion3() {
1982        for (ExecutionMode m : ExecutionMode.values())
1983        for (Integer v1 : new Integer[] { 1, null })
1984    {
1985        final CompletableFuture<Integer> f = new CompletableFuture<>();
1986        final CompletableFuture<Integer> g = new CompletableFuture<>();
1987        final IncAction r = new IncAction(m);
2302          final CFException ex = new CFException();
2303 +        final NoopConsumer[] rs = new NoopConsumer[6];
2304 +        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2305  
2306 <        g.completeExceptionally(ex);
2307 <        f.complete(v1);
2308 <        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2306 >        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2307 >        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2308 >        if (fFirst) {
2309 >            f.complete(v1);
2310 >            g.completeExceptionally(ex);
2311 >        } else {
2312 >            g.completeExceptionally(ex);
2313 >            f.complete(v1);
2314 >        }
2315 >        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2316 >        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2317  
2318 <        // unspecified behavior
1995 <        Integer v;
2318 >        // unspecified behavior - both source completions available
2319          try {
2320 <            assertNull(h.join());
2321 <            r.assertInvoked();
1999 <            assertEquals(inc(v1), r.value);
2320 >            assertEquals(null, h0.join());
2321 >            rs[0].assertValue(v1);
2322          } catch (CompletionException ok) {
2323 <            checkCompletedWithWrappedCFException(h, ex);
2324 <            r.assertNotInvoked();
2323 >            checkCompletedWithWrappedException(h0, ex);
2324 >            rs[0].assertNotInvoked();
2325          }
2004
2005        checkCompletedWithWrappedCFException(g, ex);
2006        checkCompletedNormally(f, v1);
2007    }}
2008
2009    public void testAcceptEither_exceptionalCompletion4() {
2010        for (ExecutionMode m : ExecutionMode.values())
2011        for (Integer v1 : new Integer[] { 1, null })
2012    {
2013        final CompletableFuture<Integer> f = new CompletableFuture<>();
2014        final CompletableFuture<Integer> g = new CompletableFuture<>();
2015        final IncAction r = new IncAction(m);
2016        final CFException ex = new CFException();
2017
2018        f.completeExceptionally(ex);
2019        g.complete(v1);
2020        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2021
2022        // unspecified behavior
2023        Integer v;
2326          try {
2327 <            assertNull(h.join());
2328 <            r.assertInvoked();
2027 <            assertEquals(inc(v1), r.value);
2327 >            assertEquals(null, h1.join());
2328 >            rs[1].assertValue(v1);
2329          } catch (CompletionException ok) {
2330 <            checkCompletedWithWrappedCFException(h, ex);
2331 <            r.assertNotInvoked();
2330 >            checkCompletedWithWrappedException(h1, ex);
2331 >            rs[1].assertNotInvoked();
2332 >        }
2333 >        try {
2334 >            assertEquals(null, h2.join());
2335 >            rs[2].assertValue(v1);
2336 >        } catch (CompletionException ok) {
2337 >            checkCompletedWithWrappedException(h2, ex);
2338 >            rs[2].assertNotInvoked();
2339 >        }
2340 >        try {
2341 >            assertEquals(null, h3.join());
2342 >            rs[3].assertValue(v1);
2343 >        } catch (CompletionException ok) {
2344 >            checkCompletedWithWrappedException(h3, ex);
2345 >            rs[3].assertNotInvoked();
2346          }
2347  
2033        checkCompletedWithWrappedCFException(f, ex);
2034        checkCompletedNormally(g, v1);
2035    }}
2036
2037    /**
2038     * acceptEither result completes exceptionally if action does
2039     */
2040    public void testAcceptEither_actionFailed1() {
2041        for (ExecutionMode m : ExecutionMode.values())
2042        for (Integer v1 : new Integer[] { 1, null })
2043        for (Integer v2 : new Integer[] { 2, null })
2044    {
2045        final CompletableFuture<Integer> f = new CompletableFuture<>();
2046        final CompletableFuture<Integer> g = new CompletableFuture<>();
2047        final FailingConsumer r = new FailingConsumer(m);
2048        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2049
2050        f.complete(v1);
2051        checkCompletedWithWrappedCFException(h);
2052        g.complete(v2);
2053        checkCompletedNormally(f, v1);
2054        checkCompletedNormally(g, v2);
2055    }}
2056
2057    public void testAcceptEither_actionFailed2() {
2058        for (ExecutionMode m : ExecutionMode.values())
2059        for (Integer v1 : new Integer[] { 1, null })
2060        for (Integer v2 : new Integer[] { 2, null })
2061    {
2062        final CompletableFuture<Integer> f = new CompletableFuture<>();
2063        final CompletableFuture<Integer> g = new CompletableFuture<>();
2064        final FailingConsumer r = new FailingConsumer(m);
2065        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2066
2067        g.complete(v2);
2068        checkCompletedWithWrappedCFException(h);
2069        f.complete(v1);
2348          checkCompletedNormally(f, v1);
2349 <        checkCompletedNormally(g, v2);
2349 >        checkCompletedExceptionally(g, ex);
2350      }}
2351  
2352      /**
2353       * acceptEither result completes exceptionally if either source cancelled
2354       */
2355 <    public void testAcceptEither_sourceCancelled1() {
2078 <        for (ExecutionMode m : ExecutionMode.values())
2079 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2080 <        for (Integer v1 : new Integer[] { 1, null })
2081 <    {
2082 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2083 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2084 <        final IncAction r = new IncAction(m);
2085 <        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2086 <
2087 <        assertTrue(f.cancel(mayInterruptIfRunning));
2088 <        checkCompletedWithWrappedCancellationException(h);
2089 <        g.complete(v1);
2090 <
2091 <        checkCancelled(f);
2092 <        r.assertNotInvoked();
2093 <        checkCompletedNormally(g, v1);
2094 <        checkCompletedWithWrappedCancellationException(h);
2095 <    }}
2096 <
2097 <    public void testAcceptEither_sourceCancelled2() {
2355 >    public void testAcceptEither_sourceCancelled() {
2356          for (ExecutionMode m : ExecutionMode.values())
2357          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2358          for (Integer v1 : new Integer[] { 1, null })
2359      {
2360          final CompletableFuture<Integer> f = new CompletableFuture<>();
2361          final CompletableFuture<Integer> g = new CompletableFuture<>();
2362 <        final IncAction r = new IncAction(m);
2363 <        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2106 <
2107 <        assertTrue(g.cancel(mayInterruptIfRunning));
2108 <        checkCompletedWithWrappedCancellationException(h);
2109 <        f.complete(v1);
2362 >        final NoopConsumer[] rs = new NoopConsumer[6];
2363 >        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2364  
2365 <        checkCancelled(g);
2366 <        r.assertNotInvoked();
2367 <        checkCompletedNormally(f, v1);
2368 <        checkCompletedWithWrappedCancellationException(h);
2369 <    }}
2370 <
2371 <    public void testAcceptEither_sourceCancelled3() {
2372 <        for (ExecutionMode m : ExecutionMode.values())
2373 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2374 <        for (Integer v1 : new Integer[] { 1, null })
2375 <    {
2376 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2377 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2124 <        final IncAction r = new IncAction(m);
2365 >        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2366 >        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2367 >        checkIncomplete(h0);
2368 >        checkIncomplete(h1);
2369 >        rs[0].assertNotInvoked();
2370 >        rs[1].assertNotInvoked();
2371 >        f.cancel(mayInterruptIfRunning);
2372 >        checkCompletedWithWrappedCancellationException(h0);
2373 >        checkCompletedWithWrappedCancellationException(h1);
2374 >        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2375 >        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2376 >        checkCompletedWithWrappedCancellationException(h2);
2377 >        checkCompletedWithWrappedCancellationException(h3);
2378  
2379 <        assertTrue(g.cancel(mayInterruptIfRunning));
2127 <        f.complete(v1);
2128 <        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2379 >        g.complete(v1);
2380  
2381 <        // unspecified behavior
2382 <        Integer v;
2381 >        // unspecified behavior - both source completions available
2382 >        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2383 >        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2384          try {
2385 <            assertNull(h.join());
2386 <            r.assertInvoked();
2135 <            assertEquals(inc(v1), r.value);
2385 >            assertNull(h4.join());
2386 >            rs[4].assertValue(v1);
2387          } catch (CompletionException ok) {
2388 <            checkCompletedWithWrappedCancellationException(h);
2389 <            r.assertNotInvoked();
2388 >            checkCompletedWithWrappedCancellationException(h4);
2389 >            rs[4].assertNotInvoked();
2390          }
2140
2141        checkCancelled(g);
2142        checkCompletedNormally(f, v1);
2143    }}
2144
2145    public void testAcceptEither_sourceCancelled4() {
2146        for (ExecutionMode m : ExecutionMode.values())
2147        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2148        for (Integer v1 : new Integer[] { 1, null })
2149    {
2150        final CompletableFuture<Integer> f = new CompletableFuture<>();
2151        final CompletableFuture<Integer> g = new CompletableFuture<>();
2152        final IncAction r = new IncAction(m);
2153
2154        assertTrue(f.cancel(mayInterruptIfRunning));
2155        g.complete(v1);
2156        final CompletableFuture<Void> h = m.acceptEither(f, g, r);
2157
2158        // unspecified behavior
2159        Integer v;
2391          try {
2392 <            assertNull(h.join());
2393 <            r.assertInvoked();
2163 <            assertEquals(inc(v1), r.value);
2392 >            assertNull(h5.join());
2393 >            rs[5].assertValue(v1);
2394          } catch (CompletionException ok) {
2395 <            checkCompletedWithWrappedCancellationException(h);
2396 <            r.assertNotInvoked();
2395 >            checkCompletedWithWrappedCancellationException(h5);
2396 >            rs[5].assertNotInvoked();
2397          }
2398  
2399          checkCancelled(f);
2400          checkCompletedNormally(g, v1);
2401 +        checkCompletedWithWrappedCancellationException(h0);
2402 +        checkCompletedWithWrappedCancellationException(h1);
2403 +        checkCompletedWithWrappedCancellationException(h2);
2404 +        checkCompletedWithWrappedCancellationException(h3);
2405 +        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2406      }}
2407  
2408      /**
2409 <     * runAfterEither result completes normally after normal completion
2175 <     * of either source
2409 >     * acceptEither result completes exceptionally if action does
2410       */
2411 <    public void testRunAfterEither_normalCompletion1() {
2411 >    public void testAcceptEither_actionFailed() {
2412          for (ExecutionMode m : ExecutionMode.values())
2413          for (Integer v1 : new Integer[] { 1, null })
2414          for (Integer v2 : new Integer[] { 2, null })
2415      {
2416          final CompletableFuture<Integer> f = new CompletableFuture<>();
2417          final CompletableFuture<Integer> g = new CompletableFuture<>();
2418 <        final Noop r = new Noop(m);
2419 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2418 >        final FailingConsumer[] rs = new FailingConsumer[6];
2419 >        for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
2420  
2421 +        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2422 +        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
2423          f.complete(v1);
2424 <        checkCompletedNormally(h, null);
2425 <        r.assertInvoked();
2426 <        g.complete(v2);
2424 >        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
2425 >        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
2426 >        checkCompletedWithWrappedCFException(h0);
2427 >        checkCompletedWithWrappedCFException(h1);
2428 >        checkCompletedWithWrappedCFException(h2);
2429 >        checkCompletedWithWrappedCFException(h3);
2430 >        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2431  
2432 <        checkCompletedNormally(f, v1);
2193 <        checkCompletedNormally(g, v2);
2194 <        checkCompletedNormally(h, null);
2195 <        r.assertInvoked();
2196 <    }}
2432 >        g.complete(v2);
2433  
2434 <    public void testRunAfterEither_normalCompletion2() {
2435 <        for (ExecutionMode m : ExecutionMode.values())
2436 <        for (Integer v1 : new Integer[] { 1, null })
2201 <        for (Integer v2 : new Integer[] { 2, null })
2202 <    {
2203 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2204 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2205 <        final Noop r = new Noop(m);
2206 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2434 >        // unspecified behavior - both source completions available
2435 >        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
2436 >        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2437  
2438 <        g.complete(v2);
2439 <        checkCompletedNormally(h, null);
2440 <        r.assertInvoked();
2441 <        f.complete(v1);
2438 >        checkCompletedWithWrappedCFException(h4);
2439 >        assertTrue(Objects.equals(v1, rs[4].value) ||
2440 >                   Objects.equals(v2, rs[4].value));
2441 >        checkCompletedWithWrappedCFException(h5);
2442 >        assertTrue(Objects.equals(v1, rs[5].value) ||
2443 >                   Objects.equals(v2, rs[5].value));
2444  
2445          checkCompletedNormally(f, v1);
2446          checkCompletedNormally(g, v2);
2447 <        checkCompletedNormally(h, null);
2216 <        r.assertInvoked();
2217 <        }}
2447 >    }}
2448  
2449 <    public void testRunAfterEither_normalCompletion3() {
2449 >    /**
2450 >     * runAfterEither result completes normally after normal completion
2451 >     * of either source
2452 >     */
2453 >    public void testRunAfterEither_normalCompletion() {
2454          for (ExecutionMode m : ExecutionMode.values())
2455          for (Integer v1 : new Integer[] { 1, null })
2456          for (Integer v2 : new Integer[] { 2, null })
2457      {
2458          final CompletableFuture<Integer> f = new CompletableFuture<>();
2459          final CompletableFuture<Integer> g = new CompletableFuture<>();
2460 <        final Noop r = new Noop(m);
2460 >        final Noop[] rs = new Noop[6];
2461 >        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2462  
2463 +        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2464 +        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2465 +        checkIncomplete(h0);
2466 +        checkIncomplete(h1);
2467 +        rs[0].assertNotInvoked();
2468 +        rs[1].assertNotInvoked();
2469          f.complete(v1);
2470 +        checkCompletedNormally(h0, null);
2471 +        checkCompletedNormally(h1, null);
2472 +        rs[0].assertInvoked();
2473 +        rs[1].assertInvoked();
2474 +        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2475 +        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2476 +        checkCompletedNormally(h2, null);
2477 +        checkCompletedNormally(h3, null);
2478 +        rs[2].assertInvoked();
2479 +        rs[3].assertInvoked();
2480 +
2481          g.complete(v2);
2230        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2482  
2483 <        checkCompletedNormally(h, null);
2483 >        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2484 >        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2485 >
2486          checkCompletedNormally(f, v1);
2487          checkCompletedNormally(g, v2);
2488 <        r.assertInvoked();
2488 >        checkCompletedNormally(h0, null);
2489 >        checkCompletedNormally(h1, null);
2490 >        checkCompletedNormally(h2, null);
2491 >        checkCompletedNormally(h3, null);
2492 >        checkCompletedNormally(h4, null);
2493 >        checkCompletedNormally(h5, null);
2494 >        for (int i = 0; i < 6; i++) rs[i].assertInvoked();
2495      }}
2496  
2497      /**
2498       * runAfterEither result completes exceptionally after exceptional
2499       * completion of either source
2500       */
2501 <    public void testRunAfterEither_exceptionalCompletion1() {
2501 >    public void testRunAfterEither_exceptionalCompletion() {
2502          for (ExecutionMode m : ExecutionMode.values())
2503          for (Integer v1 : new Integer[] { 1, null })
2504      {
2505          final CompletableFuture<Integer> f = new CompletableFuture<>();
2506          final CompletableFuture<Integer> g = new CompletableFuture<>();
2248        final Noop r = new Noop(m);
2249        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2507          final CFException ex = new CFException();
2508 +        final Noop[] rs = new Noop[6];
2509 +        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2510  
2511 +        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2512 +        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2513 +        checkIncomplete(h0);
2514 +        checkIncomplete(h1);
2515 +        rs[0].assertNotInvoked();
2516 +        rs[1].assertNotInvoked();
2517          f.completeExceptionally(ex);
2518 <        checkCompletedWithWrappedCFException(h, ex);
2518 >        checkCompletedWithWrappedException(h0, ex);
2519 >        checkCompletedWithWrappedException(h1, ex);
2520 >        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2521 >        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2522 >        checkCompletedWithWrappedException(h2, ex);
2523 >        checkCompletedWithWrappedException(h3, ex);
2524 >
2525          g.complete(v1);
2526  
2527 <        r.assertNotInvoked();
2527 >        // unspecified behavior - both source completions available
2528 >        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2529 >        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2530 >        try {
2531 >            assertNull(h4.join());
2532 >            rs[4].assertInvoked();
2533 >        } catch (CompletionException ok) {
2534 >            checkCompletedWithWrappedException(h4, ex);
2535 >            rs[4].assertNotInvoked();
2536 >        }
2537 >        try {
2538 >            assertNull(h5.join());
2539 >            rs[5].assertInvoked();
2540 >        } catch (CompletionException ok) {
2541 >            checkCompletedWithWrappedException(h5, ex);
2542 >            rs[5].assertNotInvoked();
2543 >        }
2544 >
2545 >        checkCompletedExceptionally(f, ex);
2546          checkCompletedNormally(g, v1);
2547 <        checkCompletedWithWrappedCFException(f, ex);
2548 <        checkCompletedWithWrappedCFException(h, ex);
2547 >        checkCompletedWithWrappedException(h0, ex);
2548 >        checkCompletedWithWrappedException(h1, ex);
2549 >        checkCompletedWithWrappedException(h2, ex);
2550 >        checkCompletedWithWrappedException(h3, ex);
2551 >        checkCompletedWithWrappedException(h4, ex);
2552 >        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2553      }}
2554  
2555      public void testRunAfterEither_exceptionalCompletion2() {
2556          for (ExecutionMode m : ExecutionMode.values())
2557 +        for (boolean fFirst : new boolean[] { true, false })
2558          for (Integer v1 : new Integer[] { 1, null })
2559      {
2560          final CompletableFuture<Integer> f = new CompletableFuture<>();
2561          final CompletableFuture<Integer> g = new CompletableFuture<>();
2268        final Noop r = new Noop(m);
2269        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2270        final CFException ex = new CFException();
2271
2272        g.completeExceptionally(ex);
2273        checkCompletedWithWrappedCFException(h, ex);
2274        f.complete(v1);
2275
2276        r.assertNotInvoked();
2277        checkCompletedNormally(f, v1);
2278        checkCompletedWithWrappedCFException(g, ex);
2279        checkCompletedWithWrappedCFException(h, ex);
2280    }}
2281
2282    public void testRunAfterEither_exceptionalCompletion3() {
2283        for (ExecutionMode m : ExecutionMode.values())
2284        for (Integer v1 : new Integer[] { 1, null })
2285    {
2286        final CompletableFuture<Integer> f = new CompletableFuture<>();
2287        final CompletableFuture<Integer> g = new CompletableFuture<>();
2288        final Noop r = new Noop(m);
2562          final CFException ex = new CFException();
2563 +        final Noop[] rs = new Noop[6];
2564 +        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2565  
2566 <        g.completeExceptionally(ex);
2567 <        f.complete(v1);
2568 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2566 >        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2567 >        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2568 >        if (fFirst) {
2569 >            f.complete(v1);
2570 >            g.completeExceptionally(ex);
2571 >        } else {
2572 >            g.completeExceptionally(ex);
2573 >            f.complete(v1);
2574 >        }
2575 >        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2576 >        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2577  
2578 <        // unspecified behavior
2296 <        Integer v;
2578 >        // unspecified behavior - both source completions available
2579          try {
2580 <            assertNull(h.join());
2581 <            r.assertInvoked();
2580 >            assertEquals(null, h0.join());
2581 >            rs[0].assertInvoked();
2582          } catch (CompletionException ok) {
2583 <            checkCompletedWithWrappedCFException(h, ex);
2584 <            r.assertNotInvoked();
2583 >            checkCompletedWithWrappedException(h0, ex);
2584 >            rs[0].assertNotInvoked();
2585 >        }
2586 >        try {
2587 >            assertEquals(null, h1.join());
2588 >            rs[1].assertInvoked();
2589 >        } catch (CompletionException ok) {
2590 >            checkCompletedWithWrappedException(h1, ex);
2591 >            rs[1].assertNotInvoked();
2592 >        }
2593 >        try {
2594 >            assertEquals(null, h2.join());
2595 >            rs[2].assertInvoked();
2596 >        } catch (CompletionException ok) {
2597 >            checkCompletedWithWrappedException(h2, ex);
2598 >            rs[2].assertNotInvoked();
2599 >        }
2600 >        try {
2601 >            assertEquals(null, h3.join());
2602 >            rs[3].assertInvoked();
2603 >        } catch (CompletionException ok) {
2604 >            checkCompletedWithWrappedException(h3, ex);
2605 >            rs[3].assertNotInvoked();
2606          }
2607  
2305        checkCompletedWithWrappedCFException(g, ex);
2608          checkCompletedNormally(f, v1);
2609 +        checkCompletedExceptionally(g, ex);
2610      }}
2611  
2612 <    public void testRunAfterEither_exceptionalCompletion4() {
2612 >    /**
2613 >     * runAfterEither result completes exceptionally if either source cancelled
2614 >     */
2615 >    public void testRunAfterEither_sourceCancelled() {
2616          for (ExecutionMode m : ExecutionMode.values())
2617 +        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2618          for (Integer v1 : new Integer[] { 1, null })
2619      {
2620          final CompletableFuture<Integer> f = new CompletableFuture<>();
2621          final CompletableFuture<Integer> g = new CompletableFuture<>();
2622 <        final Noop r = new Noop(m);
2623 <        final CFException ex = new CFException();
2622 >        final Noop[] rs = new Noop[6];
2623 >        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
2624 >
2625 >        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2626 >        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2627 >        checkIncomplete(h0);
2628 >        checkIncomplete(h1);
2629 >        rs[0].assertNotInvoked();
2630 >        rs[1].assertNotInvoked();
2631 >        f.cancel(mayInterruptIfRunning);
2632 >        checkCompletedWithWrappedCancellationException(h0);
2633 >        checkCompletedWithWrappedCancellationException(h1);
2634 >        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2635 >        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2636 >        checkCompletedWithWrappedCancellationException(h2);
2637 >        checkCompletedWithWrappedCancellationException(h3);
2638  
2318        f.completeExceptionally(ex);
2639          g.complete(v1);
2320        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2640  
2641 <        // unspecified behavior
2642 <        Integer v;
2641 >        // unspecified behavior - both source completions available
2642 >        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2643 >        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2644          try {
2645 <            assertNull(h.join());
2646 <            r.assertInvoked();
2645 >            assertNull(h4.join());
2646 >            rs[4].assertInvoked();
2647          } catch (CompletionException ok) {
2648 <            checkCompletedWithWrappedCFException(h, ex);
2649 <            r.assertNotInvoked();
2648 >            checkCompletedWithWrappedCancellationException(h4);
2649 >            rs[4].assertNotInvoked();
2650 >        }
2651 >        try {
2652 >            assertNull(h5.join());
2653 >            rs[5].assertInvoked();
2654 >        } catch (CompletionException ok) {
2655 >            checkCompletedWithWrappedCancellationException(h5);
2656 >            rs[5].assertNotInvoked();
2657          }
2658  
2659 <        checkCompletedWithWrappedCFException(f, ex);
2659 >        checkCancelled(f);
2660          checkCompletedNormally(g, v1);
2661 +        checkCompletedWithWrappedCancellationException(h0);
2662 +        checkCompletedWithWrappedCancellationException(h1);
2663 +        checkCompletedWithWrappedCancellationException(h2);
2664 +        checkCompletedWithWrappedCancellationException(h3);
2665 +        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2666      }}
2667  
2668      /**
2669       * runAfterEither result completes exceptionally if action does
2670       */
2671 <    public void testRunAfterEither_actionFailed1() {
2671 >    public void testRunAfterEither_actionFailed() {
2672          for (ExecutionMode m : ExecutionMode.values())
2673          for (Integer v1 : new Integer[] { 1, null })
2674          for (Integer v2 : new Integer[] { 2, null })
2675      {
2676          final CompletableFuture<Integer> f = new CompletableFuture<>();
2677          final CompletableFuture<Integer> g = new CompletableFuture<>();
2678 <        final FailingRunnable r = new FailingRunnable(m);
2679 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2678 >        final FailingRunnable[] rs = new FailingRunnable[6];
2679 >        for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
2680  
2681 +        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
2682 +        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
2683          f.complete(v1);
2684 <        checkCompletedWithWrappedCFException(h);
2684 >        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
2685 >        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
2686 >        checkCompletedWithWrappedCFException(h0);
2687 >        checkCompletedWithWrappedCFException(h1);
2688 >        checkCompletedWithWrappedCFException(h2);
2689 >        checkCompletedWithWrappedCFException(h3);
2690 >        for (int i = 0; i < 4; i++) rs[i].assertInvoked();
2691          g.complete(v2);
2692 <        checkCompletedNormally(f, v1);
2693 <        checkCompletedNormally(g, v2);
2694 <    }}
2695 <
2356 <    public void testRunAfterEither_actionFailed2() {
2357 <        for (ExecutionMode m : ExecutionMode.values())
2358 <        for (Integer v1 : new Integer[] { 1, null })
2359 <        for (Integer v2 : new Integer[] { 2, null })
2360 <    {
2361 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2362 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2363 <        final FailingRunnable r = new FailingRunnable(m);
2364 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2692 >        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2693 >        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2694 >        checkCompletedWithWrappedCFException(h4);
2695 >        checkCompletedWithWrappedCFException(h5);
2696  
2366        g.complete(v2);
2367        checkCompletedWithWrappedCFException(h);
2368        f.complete(v1);
2697          checkCompletedNormally(f, v1);
2698          checkCompletedNormally(g, v2);
2699 <    }}
2372 <
2373 <    /**
2374 <     * runAfterEither result completes exceptionally if either source cancelled
2375 <     */
2376 <    public void testRunAfterEither_sourceCancelled1() {
2377 <        for (ExecutionMode m : ExecutionMode.values())
2378 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2379 <        for (Integer v1 : new Integer[] { 1, null })
2380 <    {
2381 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2382 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2383 <        final Noop r = new Noop(m);
2384 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2385 <
2386 <        assertTrue(f.cancel(mayInterruptIfRunning));
2387 <        checkCompletedWithWrappedCancellationException(h);
2388 <        g.complete(v1);
2389 <
2390 <        checkCancelled(f);
2391 <        r.assertNotInvoked();
2392 <        checkCompletedNormally(g, v1);
2393 <        checkCompletedWithWrappedCancellationException(h);
2394 <    }}
2395 <
2396 <    public void testRunAfterEither_sourceCancelled2() {
2397 <        for (ExecutionMode m : ExecutionMode.values())
2398 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2399 <        for (Integer v1 : new Integer[] { 1, null })
2400 <    {
2401 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2402 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2403 <        final Noop r = new Noop(m);
2404 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2405 <
2406 <        assertTrue(g.cancel(mayInterruptIfRunning));
2407 <        checkCompletedWithWrappedCancellationException(h);
2408 <        f.complete(v1);
2409 <
2410 <        checkCancelled(g);
2411 <        r.assertNotInvoked();
2412 <        checkCompletedNormally(f, v1);
2413 <        checkCompletedWithWrappedCancellationException(h);
2414 <    }}
2415 <
2416 <    public void testRunAfterEither_sourceCancelled3() {
2417 <        for (ExecutionMode m : ExecutionMode.values())
2418 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2419 <        for (Integer v1 : new Integer[] { 1, null })
2420 <    {
2421 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2422 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2423 <        final Noop r = new Noop(m);
2424 <
2425 <        assertTrue(g.cancel(mayInterruptIfRunning));
2426 <        f.complete(v1);
2427 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2428 <
2429 <        // unspecified behavior
2430 <        Integer v;
2431 <        try {
2432 <            assertNull(h.join());
2433 <            r.assertInvoked();
2434 <        } catch (CompletionException ok) {
2435 <            checkCompletedWithWrappedCancellationException(h);
2436 <            r.assertNotInvoked();
2437 <        }
2438 <
2439 <        checkCancelled(g);
2440 <        checkCompletedNormally(f, v1);
2441 <    }}
2442 <
2443 <    public void testRunAfterEither_sourceCancelled4() {
2444 <        for (ExecutionMode m : ExecutionMode.values())
2445 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2446 <        for (Integer v1 : new Integer[] { 1, null })
2447 <    {
2448 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2449 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2450 <        final Noop r = new Noop(m);
2451 <
2452 <        assertTrue(f.cancel(mayInterruptIfRunning));
2453 <        g.complete(v1);
2454 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2455 <
2456 <        // unspecified behavior
2457 <        Integer v;
2458 <        try {
2459 <            assertNull(h.join());
2460 <            r.assertInvoked();
2461 <        } catch (CompletionException ok) {
2462 <            checkCompletedWithWrappedCancellationException(h);
2463 <            r.assertNotInvoked();
2464 <        }
2465 <
2466 <        checkCancelled(f);
2467 <        checkCompletedNormally(g, v1);
2699 >        for (int i = 0; i < 6; i++) rs[i].assertInvoked();
2700      }}
2701  
2702      /**
# Line 2483 | Line 2715 | public class CompletableFutureTest exten
2715  
2716          checkCompletedNormally(g, inc(v1));
2717          checkCompletedNormally(f, v1);
2718 <        r.assertInvoked();
2718 >        r.assertValue(v1);
2719      }}
2720  
2721      /**
# Line 2501 | Line 2733 | public class CompletableFutureTest exten
2733          final CompletableFuture<Integer> g = m.thenCompose(f, r);
2734          if (createIncomplete) f.completeExceptionally(ex);
2735  
2736 <        checkCompletedWithWrappedCFException(g, ex);
2737 <        checkCompletedWithWrappedCFException(f, ex);
2736 >        checkCompletedWithWrappedException(g, ex);
2737 >        checkCompletedExceptionally(f, ex);
2738          r.assertNotInvoked();
2739      }}
2740  
# Line 2758 | Line 2990 | public class CompletableFutureTest exten
2990          assertSame(f, f.toCompletableFuture());
2991      }
2992  
2761    /**
2762     * whenComplete action executes on normal completion, propagating
2763     * source result.
2764     */
2765    public void testWhenComplete_normalCompletion1() {
2766        for (ExecutionMode m : ExecutionMode.values())
2767        for (boolean createIncomplete : new boolean[] { true, false })
2768        for (Integer v1 : new Integer[] { 1, null })
2769    {
2770        final AtomicInteger a = new AtomicInteger(0);
2771        final CompletableFuture<Integer> f = new CompletableFuture<>();
2772        if (!createIncomplete) f.complete(v1);
2773        final CompletableFuture<Integer> g = m.whenComplete
2774            (f,
2775             (Integer x, Throwable t) -> {
2776                threadAssertSame(x, v1);
2777                threadAssertNull(t);
2778                a.getAndIncrement();
2779            });
2780        if (createIncomplete) f.complete(v1);
2781
2782        checkCompletedNormally(g, v1);
2783        checkCompletedNormally(f, v1);
2784        assertEquals(1, a.get());
2785    }}
2786
2787    /**
2788     * whenComplete action executes on exceptional completion, propagating
2789     * source result.
2790     */
2791    public void testWhenComplete_exceptionalCompletion() {
2792        for (ExecutionMode m : ExecutionMode.values())
2793        for (boolean createIncomplete : new boolean[] { true, false })
2794        for (Integer v1 : new Integer[] { 1, null })
2795    {
2796        final AtomicInteger a = new AtomicInteger(0);
2797        final CFException ex = new CFException();
2798        final CompletableFuture<Integer> f = new CompletableFuture<>();
2799        if (!createIncomplete) f.completeExceptionally(ex);
2800        final CompletableFuture<Integer> g = m.whenComplete
2801            (f,
2802             (Integer x, Throwable t) -> {
2803                threadAssertNull(x);
2804                threadAssertSame(t, ex);
2805                a.getAndIncrement();
2806            });
2807        if (createIncomplete) f.completeExceptionally(ex);
2808        checkCompletedWithWrappedCFException(f, ex);
2809        checkCompletedWithWrappedCFException(g, ex);
2810        assertEquals(1, a.get());
2811    }}
2812
2813    /**
2814     * whenComplete action executes on cancelled source, propagating
2815     * CancellationException.
2816     */
2817    public void testWhenComplete_sourceCancelled() {
2818        for (ExecutionMode m : ExecutionMode.values())
2819        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2820        for (boolean createIncomplete : new boolean[] { true, false })
2821    {
2822        final AtomicInteger a = new AtomicInteger(0);
2823        final CompletableFuture<Integer> f = new CompletableFuture<>();
2824        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
2825        final CompletableFuture<Integer> g = m.whenComplete
2826            (f,
2827             (Integer x, Throwable t) -> {
2828                threadAssertNull(x);
2829                threadAssertTrue(t instanceof CancellationException);
2830                a.getAndIncrement();
2831            });
2832        if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
2833
2834        //try { g.join(); } catch (Throwable t) { throw new Error(t); }
2835        checkCompletedWithWrappedCancellationException(g);
2836        checkCancelled(f);
2837        assertEquals(1, a.get());
2838    }}
2839
2840    /**
2841     * If a whenComplete action throws an exception when triggered by
2842     * a normal completion, it completes exceptionally
2843     */
2844    public void testWhenComplete_actionFailed() {
2845        for (boolean createIncomplete : new boolean[] { true, false })
2846        for (ExecutionMode m : ExecutionMode.values())
2847        for (Integer v1 : new Integer[] { 1, null })
2848    {
2849        final AtomicInteger a = new AtomicInteger(0);
2850        final CFException ex = new CFException();
2851        final CompletableFuture<Integer> f = new CompletableFuture<>();
2852        if (!createIncomplete) f.complete(v1);
2853        final CompletableFuture<Integer> g = m.whenComplete
2854            (f,
2855             (Integer x, Throwable t) -> {
2856                threadAssertSame(x, v1);
2857                threadAssertNull(t);
2858                a.getAndIncrement();
2859                throw ex;
2860            });
2861        if (createIncomplete) f.complete(v1);
2862        checkCompletedNormally(f, v1);
2863        checkCompletedWithWrappedCFException(g, ex);
2864        assertEquals(1, a.get());
2865    }}
2866
2867    /**
2868     * If a whenComplete action throws an exception when triggered by
2869     * a source completion that also throws an exception, the source
2870     * exception takes precedence.
2871     */
2872    public void testWhenComplete_actionFailedSourceFailed() {
2873        for (boolean createIncomplete : new boolean[] { true, false })
2874        for (ExecutionMode m : ExecutionMode.values())
2875        for (Integer v1 : new Integer[] { 1, null })
2876    {
2877        final AtomicInteger a = new AtomicInteger(0);
2878        final CFException ex1 = new CFException();
2879        final CFException ex2 = new CFException();
2880        final CompletableFuture<Integer> f = new CompletableFuture<>();
2881
2882        if (!createIncomplete) f.completeExceptionally(ex1);
2883        final CompletableFuture<Integer> g = m.whenComplete
2884            (f,
2885             (Integer x, Throwable t) -> {
2886                threadAssertSame(t, ex1);
2887                threadAssertNull(x);
2888                a.getAndIncrement();
2889                throw ex2;
2890            });
2891        if (createIncomplete) f.completeExceptionally(ex1);
2892
2893        checkCompletedWithWrappedCFException(f, ex1);
2894        checkCompletedWithWrappedCFException(g, ex1);
2895        assertEquals(1, a.get());
2896    }}
2897
2993   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines