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.63 by jsr166, Fri Jun 6 16:54:16 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 808 | Line 851 | public class CompletableFutureTest exten
851          assertEquals(0, a.get());
852      }}
853  
811
854      /**
855       * exceptionally action completes with function value on source
856       * exception
# Line 852 | 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 909 | 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 965 | 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 990 | 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 1104 | 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 1171 | 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 1192 | 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 1249 | 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 1258 | Line 1443 | public class CompletableFutureTest exten
1443          }
1444  
1445          checkCompletedNormally(g, null);
1446 +        r.assertValue(v1);
1447          checkCompletedNormally(f, v1);
1262        r.assertInvoked();
1263        r.assertValue(inc(v1));
1448      }}
1449  
1450      /**
# Line 1273 | 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 1281 | 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 1295 | 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 1357 | 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 1384 | 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 1501 | 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 1618 | 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 1638 | Line 1822 | public class CompletableFutureTest exten
1822          final CompletableFuture<Integer> g = new CompletableFuture<>();
1823          final Noop r = new Noop(m);
1824  
1641
1825          (fFirst ? f : g).complete(v1);
1826          if (!createIncomplete)
1827              assertTrue((!fFirst ? f : g).cancel(mayInterruptIfRunning));
# Line 1753 | 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 1766 | 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 1822 | 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 1844 | Line 2084 | public class CompletableFutureTest exten
2084          for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
2085      }}
2086  
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 })
2092 +    {
2093 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
2094 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
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 +        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 +
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 +        checkCancelled(g);
2142 +    }}
2143 +
2144      /**
2145       * applyToEither result completes exceptionally if action does
2146       */
# Line 1896 | Line 2193 | public class CompletableFutureTest exten
2193      {
2194          final CompletableFuture<Integer> f = new CompletableFuture<>();
2195          final CompletableFuture<Integer> g = new CompletableFuture<>();
2196 <        final IncAction[] rs = new IncAction[6];
2197 <        for (int i = 0; i < rs.length; i++) rs[i] = 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]);
# Line 1908 | Line 2205 | public class CompletableFutureTest exten
2205          f.complete(v1);
2206          checkCompletedNormally(h0, null);
2207          checkCompletedNormally(h1, null);
2208 <        rs[0].assertValue(inc(v1));
2209 <        rs[1].assertValue(inc(v1));
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(inc(v1));
2215 <        rs[3].assertValue(inc(v1));
2214 >        rs[2].assertValue(v1);
2215 >        rs[3].assertValue(v1);
2216          g.complete(v2);
2217  
2218          // unspecified behavior - both source completions available
# Line 1923 | Line 2220 | public class CompletableFutureTest exten
2220          final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2221          checkCompletedNormally(h4, null);
2222          checkCompletedNormally(h5, null);
2223 <        assertTrue(Objects.equals(inc(v1), rs[4].value) ||
2224 <                   Objects.equals(inc(v2), rs[4].value));
2225 <        assertTrue(Objects.equals(inc(v1), rs[5].value) ||
2226 <                   Objects.equals(inc(v2), rs[5].value));
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);
# Line 1934 | Line 2231 | public class CompletableFutureTest exten
2231          checkCompletedNormally(h1, null);
2232          checkCompletedNormally(h2, null);
2233          checkCompletedNormally(h3, null);
2234 <        for (int i = 0; i < 4; i++) rs[i].assertValue(inc(v1));
2234 >        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
2235      }}
2236  
2237      /**
# Line 1948 | Line 2245 | public class CompletableFutureTest exten
2245          final CompletableFuture<Integer> f = new CompletableFuture<>();
2246          final CompletableFuture<Integer> g = new CompletableFuture<>();
2247          final CFException ex = new CFException();
2248 <        final IncAction[] rs = new IncAction[6];
2249 <        for (int i = 0; i < rs.length; i++) rs[i] = new IncAction(m);
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]);
# Line 1958 | Line 2255 | public class CompletableFutureTest exten
2255          rs[0].assertNotInvoked();
2256          rs[1].assertNotInvoked();
2257          f.completeExceptionally(ex);
2258 <        checkCompletedWithWrappedCFException(h0, ex);
2259 <        checkCompletedWithWrappedCFException(h1, 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 <        checkCompletedWithWrappedCFException(h2, ex);
2263 <        checkCompletedWithWrappedCFException(h3, ex);
2262 >        checkCompletedWithWrappedException(h2, ex);
2263 >        checkCompletedWithWrappedException(h3, ex);
2264  
2265          g.complete(v1);
2266  
# Line 1972 | Line 2269 | public class CompletableFutureTest exten
2269          final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2270          try {
2271              assertNull(h4.join());
2272 <            rs[4].assertValue(inc(v1));
2272 >            rs[4].assertValue(v1);
2273          } catch (CompletionException ok) {
2274 <            checkCompletedWithWrappedCFException(h4, ex);
2274 >            checkCompletedWithWrappedException(h4, ex);
2275              rs[4].assertNotInvoked();
2276          }
2277          try {
2278              assertNull(h5.join());
2279 <            rs[5].assertValue(inc(v1));
2279 >            rs[5].assertValue(v1);
2280          } catch (CompletionException ok) {
2281 <            checkCompletedWithWrappedCFException(h5, ex);
2281 >            checkCompletedWithWrappedException(h5, ex);
2282              rs[5].assertNotInvoked();
2283          }
2284  
2285 <        checkCompletedWithWrappedCFException(f, ex);
2285 >        checkCompletedExceptionally(f, ex);
2286          checkCompletedNormally(g, v1);
2287 <        checkCompletedWithWrappedCFException(h0, ex);
2288 <        checkCompletedWithWrappedCFException(h1, ex);
2289 <        checkCompletedWithWrappedCFException(h2, ex);
2290 <        checkCompletedWithWrappedCFException(h3, ex);
2291 <        checkCompletedWithWrappedCFException(h4, 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<>();
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 +        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 - both source completions available
2319 +        try {
2320 +            assertEquals(null, h0.join());
2321 +            rs[0].assertValue(v1);
2322 +        } catch (CompletionException ok) {
2323 +            checkCompletedWithWrappedException(h0, ex);
2324 +            rs[0].assertNotInvoked();
2325 +        }
2326 +        try {
2327 +            assertEquals(null, h1.join());
2328 +            rs[1].assertValue(v1);
2329 +        } catch (CompletionException ok) {
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 +
2348 +        checkCompletedNormally(f, v1);
2349 +        checkCompletedExceptionally(g, ex);
2350 +    }}
2351 +
2352      /**
2353       * acceptEither result completes exceptionally if either source cancelled
2354       */
# Line 2005 | Line 2359 | public class CompletableFutureTest exten
2359      {
2360          final CompletableFuture<Integer> f = new CompletableFuture<>();
2361          final CompletableFuture<Integer> g = new CompletableFuture<>();
2362 <        final IncAction[] rs = new IncAction[6];
2363 <        for (int i = 0; i < rs.length; i++) rs[i] = new IncAction(m);
2362 >        final NoopConsumer[] rs = new NoopConsumer[6];
2363 >        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
2364  
2365          final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
2366          final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
# Line 2029 | Line 2383 | public class CompletableFutureTest exten
2383          final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
2384          try {
2385              assertNull(h4.join());
2386 <            rs[4].assertValue(inc(v1));
2386 >            rs[4].assertValue(v1);
2387          } catch (CompletionException ok) {
2388              checkCompletedWithWrappedCancellationException(h4);
2389              rs[4].assertNotInvoked();
2390          }
2391          try {
2392              assertNull(h5.join());
2393 <            rs[5].assertValue(inc(v1));
2393 >            rs[5].assertValue(v1);
2394          } catch (CompletionException ok) {
2395              checkCompletedWithWrappedCancellationException(h5);
2396              rs[5].assertNotInvoked();
# Line 2096 | Line 2450 | public class CompletableFutureTest exten
2450       * runAfterEither result completes normally after normal completion
2451       * of either source
2452       */
2453 <    public void testRunAfterEither_normalCompletion1() {
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);
2461 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
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(h, null);
2471 <        r.assertInvoked();
2472 <        g.complete(v2);
2473 <
2474 <        checkCompletedNormally(f, v1);
2475 <        checkCompletedNormally(g, v2);
2476 <        checkCompletedNormally(h, null);
2477 <        r.assertInvoked();
2478 <    }}
2479 <
2120 <    public void testRunAfterEither_normalCompletion2() {
2121 <        for (ExecutionMode m : ExecutionMode.values())
2122 <        for (Integer v1 : new Integer[] { 1, null })
2123 <        for (Integer v2 : new Integer[] { 2, null })
2124 <    {
2125 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2126 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2127 <        final Noop r = new Noop(m);
2128 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
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);
2131        checkCompletedNormally(h, null);
2132        r.assertInvoked();
2133        f.complete(v1);
2482  
2483 <        checkCompletedNormally(f, v1);
2484 <        checkCompletedNormally(g, v2);
2137 <        checkCompletedNormally(h, null);
2138 <        r.assertInvoked();
2139 <        }}
2140 <
2141 <    public void testRunAfterEither_normalCompletion3() {
2142 <        for (ExecutionMode m : ExecutionMode.values())
2143 <        for (Integer v1 : new Integer[] { 1, null })
2144 <        for (Integer v2 : new Integer[] { 2, null })
2145 <    {
2146 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2147 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2148 <        final Noop r = new Noop(m);
2149 <
2150 <        f.complete(v1);
2151 <        g.complete(v2);
2152 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2483 >        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
2484 >        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
2485  
2154        checkCompletedNormally(h, null);
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<>();
2170        final Noop r = new Noop(m);
2171        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<>();
2190        final Noop r = new Noop(m);
2191        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2192        final CFException ex = new CFException();
2193
2194        g.completeExceptionally(ex);
2195        checkCompletedWithWrappedCFException(h, ex);
2196        f.complete(v1);
2197
2198        r.assertNotInvoked();
2199        checkCompletedNormally(f, v1);
2200        checkCompletedWithWrappedCFException(g, ex);
2201        checkCompletedWithWrappedCFException(h, ex);
2202    }}
2203
2204    public void testRunAfterEither_exceptionalCompletion3() {
2205        for (ExecutionMode m : ExecutionMode.values())
2206        for (Integer v1 : new Integer[] { 1, null })
2207    {
2208        final CompletableFuture<Integer> f = new CompletableFuture<>();
2209        final CompletableFuture<Integer> g = new CompletableFuture<>();
2210        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
2218 <        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  
2227        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  
2240        f.completeExceptionally(ex);
2639          g.complete(v1);
2242        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(h4.join());
2646 >            rs[4].assertInvoked();
2647 >        } catch (CompletionException ok) {
2648 >            checkCompletedWithWrappedCancellationException(h4);
2649 >            rs[4].assertNotInvoked();
2650 >        }
2651          try {
2652 <            assertNull(h.join());
2653 <            r.assertInvoked();
2652 >            assertNull(h5.join());
2653 >            rs[5].assertInvoked();
2654          } catch (CompletionException ok) {
2655 <            checkCompletedWithWrappedCFException(h, ex);
2656 <            r.assertNotInvoked();
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 <
2278 <    public void testRunAfterEither_actionFailed2() {
2279 <        for (ExecutionMode m : ExecutionMode.values())
2280 <        for (Integer v1 : new Integer[] { 1, null })
2281 <        for (Integer v2 : new Integer[] { 2, null })
2282 <    {
2283 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2284 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2285 <        final FailingRunnable r = new FailingRunnable(m);
2286 <        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  
2288        g.complete(v2);
2289        checkCompletedWithWrappedCFException(h);
2290        f.complete(v1);
2697          checkCompletedNormally(f, v1);
2698          checkCompletedNormally(g, v2);
2699 <    }}
2294 <
2295 <    /**
2296 <     * runAfterEither result completes exceptionally if either source cancelled
2297 <     */
2298 <    public void testRunAfterEither_sourceCancelled1() {
2299 <        for (ExecutionMode m : ExecutionMode.values())
2300 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2301 <        for (Integer v1 : new Integer[] { 1, null })
2302 <    {
2303 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2304 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2305 <        final Noop r = new Noop(m);
2306 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2307 <
2308 <        assertTrue(f.cancel(mayInterruptIfRunning));
2309 <        checkCompletedWithWrappedCancellationException(h);
2310 <        g.complete(v1);
2311 <
2312 <        checkCancelled(f);
2313 <        r.assertNotInvoked();
2314 <        checkCompletedNormally(g, v1);
2315 <        checkCompletedWithWrappedCancellationException(h);
2316 <    }}
2317 <
2318 <    public void testRunAfterEither_sourceCancelled2() {
2319 <        for (ExecutionMode m : ExecutionMode.values())
2320 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2321 <        for (Integer v1 : new Integer[] { 1, null })
2322 <    {
2323 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2324 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2325 <        final Noop r = new Noop(m);
2326 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2327 <
2328 <        assertTrue(g.cancel(mayInterruptIfRunning));
2329 <        checkCompletedWithWrappedCancellationException(h);
2330 <        f.complete(v1);
2331 <
2332 <        checkCancelled(g);
2333 <        r.assertNotInvoked();
2334 <        checkCompletedNormally(f, v1);
2335 <        checkCompletedWithWrappedCancellationException(h);
2336 <    }}
2337 <
2338 <    public void testRunAfterEither_sourceCancelled3() {
2339 <        for (ExecutionMode m : ExecutionMode.values())
2340 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2341 <        for (Integer v1 : new Integer[] { 1, null })
2342 <    {
2343 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2344 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2345 <        final Noop r = new Noop(m);
2346 <
2347 <        assertTrue(g.cancel(mayInterruptIfRunning));
2348 <        f.complete(v1);
2349 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2350 <
2351 <        // unspecified behavior
2352 <        Integer v;
2353 <        try {
2354 <            assertNull(h.join());
2355 <            r.assertInvoked();
2356 <        } catch (CompletionException ok) {
2357 <            checkCompletedWithWrappedCancellationException(h);
2358 <            r.assertNotInvoked();
2359 <        }
2360 <
2361 <        checkCancelled(g);
2362 <        checkCompletedNormally(f, v1);
2363 <    }}
2364 <
2365 <    public void testRunAfterEither_sourceCancelled4() {
2366 <        for (ExecutionMode m : ExecutionMode.values())
2367 <        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2368 <        for (Integer v1 : new Integer[] { 1, null })
2369 <    {
2370 <        final CompletableFuture<Integer> f = new CompletableFuture<>();
2371 <        final CompletableFuture<Integer> g = new CompletableFuture<>();
2372 <        final Noop r = new Noop(m);
2373 <
2374 <        assertTrue(f.cancel(mayInterruptIfRunning));
2375 <        g.complete(v1);
2376 <        final CompletableFuture<Void> h = m.runAfterEither(f, g, r);
2377 <
2378 <        // unspecified behavior
2379 <        Integer v;
2380 <        try {
2381 <            assertNull(h.join());
2382 <            r.assertInvoked();
2383 <        } catch (CompletionException ok) {
2384 <            checkCompletedWithWrappedCancellationException(h);
2385 <            r.assertNotInvoked();
2386 <        }
2387 <
2388 <        checkCancelled(f);
2389 <        checkCompletedNormally(g, v1);
2699 >        for (int i = 0; i < 6; i++) rs[i].assertInvoked();
2700      }}
2701  
2702      /**
# Line 2405 | 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 2423 | 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 2680 | Line 2990 | public class CompletableFutureTest exten
2990          assertSame(f, f.toCompletableFuture());
2991      }
2992  
2683    /**
2684     * whenComplete action executes on normal completion, propagating
2685     * source result.
2686     */
2687    public void testWhenComplete_normalCompletion1() {
2688        for (ExecutionMode m : ExecutionMode.values())
2689        for (boolean createIncomplete : new boolean[] { true, false })
2690        for (Integer v1 : new Integer[] { 1, null })
2691    {
2692        final AtomicInteger a = new AtomicInteger(0);
2693        final CompletableFuture<Integer> f = new CompletableFuture<>();
2694        if (!createIncomplete) f.complete(v1);
2695        final CompletableFuture<Integer> g = m.whenComplete
2696            (f,
2697             (Integer x, Throwable t) -> {
2698                threadAssertSame(x, v1);
2699                threadAssertNull(t);
2700                a.getAndIncrement();
2701            });
2702        if (createIncomplete) f.complete(v1);
2703
2704        checkCompletedNormally(g, v1);
2705        checkCompletedNormally(f, v1);
2706        assertEquals(1, a.get());
2707    }}
2708
2709    /**
2710     * whenComplete action executes on exceptional completion, propagating
2711     * source result.
2712     */
2713    public void testWhenComplete_exceptionalCompletion() {
2714        for (ExecutionMode m : ExecutionMode.values())
2715        for (boolean createIncomplete : new boolean[] { true, false })
2716        for (Integer v1 : new Integer[] { 1, null })
2717    {
2718        final AtomicInteger a = new AtomicInteger(0);
2719        final CFException ex = new CFException();
2720        final CompletableFuture<Integer> f = new CompletableFuture<>();
2721        if (!createIncomplete) f.completeExceptionally(ex);
2722        final CompletableFuture<Integer> g = m.whenComplete
2723            (f,
2724             (Integer x, Throwable t) -> {
2725                threadAssertNull(x);
2726                threadAssertSame(t, ex);
2727                a.getAndIncrement();
2728            });
2729        if (createIncomplete) f.completeExceptionally(ex);
2730        checkCompletedWithWrappedCFException(f, ex);
2731        checkCompletedWithWrappedCFException(g, ex);
2732        assertEquals(1, a.get());
2733    }}
2734
2735    /**
2736     * whenComplete action executes on cancelled source, propagating
2737     * CancellationException.
2738     */
2739    public void testWhenComplete_sourceCancelled() {
2740        for (ExecutionMode m : ExecutionMode.values())
2741        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
2742        for (boolean createIncomplete : new boolean[] { true, false })
2743    {
2744        final AtomicInteger a = new AtomicInteger(0);
2745        final CompletableFuture<Integer> f = new CompletableFuture<>();
2746        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
2747        final CompletableFuture<Integer> g = m.whenComplete
2748            (f,
2749             (Integer x, Throwable t) -> {
2750                threadAssertNull(x);
2751                threadAssertTrue(t instanceof CancellationException);
2752                a.getAndIncrement();
2753            });
2754        if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
2755
2756        //try { g.join(); } catch (Throwable t) { throw new Error(t); }
2757        checkCompletedWithWrappedCancellationException(g);
2758        checkCancelled(f);
2759        assertEquals(1, a.get());
2760    }}
2761
2762    /**
2763     * If a whenComplete action throws an exception when triggered by
2764     * a normal completion, it completes exceptionally
2765     */
2766    public void testWhenComplete_actionFailed() {
2767        for (boolean createIncomplete : new boolean[] { true, false })
2768        for (ExecutionMode m : ExecutionMode.values())
2769        for (Integer v1 : new Integer[] { 1, null })
2770    {
2771        final AtomicInteger a = new AtomicInteger(0);
2772        final CFException ex = new CFException();
2773        final CompletableFuture<Integer> f = new CompletableFuture<>();
2774        if (!createIncomplete) f.complete(v1);
2775        final CompletableFuture<Integer> g = m.whenComplete
2776            (f,
2777             (Integer x, Throwable t) -> {
2778                threadAssertSame(x, v1);
2779                threadAssertNull(t);
2780                a.getAndIncrement();
2781                throw ex;
2782            });
2783        if (createIncomplete) f.complete(v1);
2784        checkCompletedNormally(f, v1);
2785        checkCompletedWithWrappedCFException(g, ex);
2786        assertEquals(1, a.get());
2787    }}
2788
2789    /**
2790     * If a whenComplete action throws an exception when triggered by
2791     * a source completion that also throws an exception, the source
2792     * exception takes precedence.
2793     */
2794    public void testWhenComplete_actionFailedSourceFailed() {
2795        for (boolean createIncomplete : new boolean[] { true, false })
2796        for (ExecutionMode m : ExecutionMode.values())
2797        for (Integer v1 : new Integer[] { 1, null })
2798    {
2799        final AtomicInteger a = new AtomicInteger(0);
2800        final CFException ex1 = new CFException();
2801        final CFException ex2 = new CFException();
2802        final CompletableFuture<Integer> f = new CompletableFuture<>();
2803
2804        if (!createIncomplete) f.completeExceptionally(ex1);
2805        final CompletableFuture<Integer> g = m.whenComplete
2806            (f,
2807             (Integer x, Throwable t) -> {
2808                threadAssertSame(t, ex1);
2809                threadAssertNull(x);
2810                a.getAndIncrement();
2811                throw ex2;
2812            });
2813        if (createIncomplete) f.completeExceptionally(ex1);
2814
2815        checkCompletedWithWrappedCFException(f, ex1);
2816        checkCompletedWithWrappedCFException(g, ex1);
2817        assertEquals(1, a.get());
2818    }}
2819
2993   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines