--- jsr166/src/test/tck/CompletableFutureTest.java 2014/06/01 23:51:44 1.38 +++ jsr166/src/test/tck/CompletableFutureTest.java 2014/06/02 02:19:23 1.42 @@ -375,8 +375,12 @@ public class CompletableFutureTest exten } } static final class Noop implements Runnable { + int invocationCount = 0; boolean ran; - public void run() { ran = true; } + public void run() { + invocationCount++; + ran = true; + } } static final class FailingSupplier implements Supplier { @@ -954,12 +958,13 @@ public class CompletableFutureTest exten f.complete(v1); checkIncomplete(h); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); g.complete(v2); checkCompletedNormally(h, subtract(v1, v2)); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); + assertEquals(r.invocationCount, 1); } } @@ -975,12 +980,13 @@ public class CompletableFutureTest exten g.complete(v2); checkIncomplete(h); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); f.complete(v1); checkCompletedNormally(h, subtract(v1, v2)); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); + assertEquals(r.invocationCount, 1); } } @@ -1000,6 +1006,7 @@ public class CompletableFutureTest exten checkCompletedNormally(h, subtract(v1, v2)); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); + assertEquals(r.invocationCount, 1); } } @@ -1019,6 +1026,7 @@ public class CompletableFutureTest exten checkCompletedNormally(h, subtract(v1, v2)); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); + assertEquals(r.invocationCount, 1); } } @@ -1042,7 +1050,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1063,7 +1071,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1083,7 +1091,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1103,7 +1111,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1170,7 +1178,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1191,7 +1199,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1211,7 +1219,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1231,7 +1239,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1344,7 +1352,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1365,7 +1373,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1385,7 +1393,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1472,7 +1480,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1493,7 +1501,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1513,7 +1521,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1533,7 +1541,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertFalse(r.ran()); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1558,7 +1566,7 @@ public class CompletableFutureTest exten g.complete(v2); checkCompletedNormally(h, null); - assertTrue(r.ran); + assertEquals(r.invocationCount, 1); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1580,7 +1588,7 @@ public class CompletableFutureTest exten f.complete(v1); checkCompletedNormally(h, null); - assertTrue(r.ran); + assertEquals(r.invocationCount, 1); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1620,7 +1628,7 @@ public class CompletableFutureTest exten final CompletableFuture h = m.runAfterBoth(f, g, r); checkCompletedNormally(h, null); - assertTrue(r.ran); + assertEquals(r.invocationCount, 1); checkCompletedNormally(f, v1); checkCompletedNormally(g, v2); } @@ -1646,7 +1654,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertFalse(r.ran); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1667,7 +1675,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertFalse(r.ran); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1687,7 +1695,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(g, ex); - assertFalse(r.ran); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1707,7 +1715,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCFException(h, ex); checkCompletedWithWrappedCFException(f, ex); - assertFalse(r.ran); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1774,7 +1782,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertFalse(r.ran); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1795,7 +1803,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertFalse(r.ran); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1815,7 +1823,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(g); - assertFalse(r.ran); + assertEquals(r.invocationCount, 0); checkCompletedNormally(f, v1); } } @@ -1835,7 +1843,7 @@ public class CompletableFutureTest exten checkCompletedWithWrappedCancellationException(h); checkCancelled(f); - assertFalse(r.ran); + assertEquals(r.invocationCount, 0); checkCompletedNormally(g, v1); } } @@ -1844,212 +1852,931 @@ public class CompletableFutureTest exten * applyToEither result completes normally after normal completion * of either source */ - public void testApplyToEither() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - CompletableFuture g = f.applyToEither(f2, inc); - f.complete(one); - checkCompletedNormally(g, two); - f2.complete(one); - checkCompletedNormally(g, two); + public void testApplyToEither_normalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { - f = new CompletableFuture<>(); - f.complete(one); - f2 = new CompletableFuture<>(); - g = f.applyToEither(f2, inc); - checkCompletedNormally(g, two); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + final CompletableFuture h = m.applyToEither(f, g, r); + + f.complete(v1); + checkCompletedNormally(h, inc(v1)); + g.complete(v2); + + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + checkCompletedNormally(h, inc(v1)); + } + } + + public void testApplyToEither_normalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + final CompletableFuture h = m.applyToEither(f, g, r); + + g.complete(v2); + checkCompletedNormally(h, inc(v2)); + f.complete(v1); + + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + checkCompletedNormally(h, inc(v2)); + } + } + public void testApplyToEither_normalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + + f.complete(v1); + g.complete(v2); + final CompletableFuture h = m.applyToEither(f, g, r); + + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + + // unspecified behavior + assertTrue(Objects.equals(h.join(), inc(v1)) || + Objects.equals(h.join(), inc(v2))); + assertEquals(r.invocationCount, 1); + } } /** * applyToEither result completes exceptionally after exceptional * completion of either source */ - public void testApplyToEither2() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - CompletableFuture g = f.applyToEither(f2, inc); - f.completeExceptionally(new CFException()); - f2.complete(one); - checkCompletedWithWrappedCFException(g); + public void testApplyToEither_exceptionalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - f2.completeExceptionally(new CFException()); - g = f.applyToEither(f2, inc); - checkCompletedWithWrappedCFException(g); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + final CompletableFuture h = m.applyToEither(f, g, r); + final CFException ex = new CFException(); + + f.completeExceptionally(ex); + checkCompletedWithWrappedCFException(h, ex); + g.complete(v1); + + assertEquals(r.invocationCount, 0); + checkCompletedNormally(g, v1); + checkCompletedWithWrappedCFException(f, ex); + checkCompletedWithWrappedCFException(h, ex); + } + } + + public void testApplyToEither_exceptionalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + final CompletableFuture h = m.applyToEither(f, g, r); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); + checkCompletedWithWrappedCFException(h, ex); + f.complete(v1); + + assertEquals(r.invocationCount, 0); + checkCompletedNormally(f, v1); + checkCompletedWithWrappedCFException(g, ex); + checkCompletedWithWrappedCFException(h, ex); + } + } + + public void testApplyToEither_exceptionalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); + f.complete(v1); + final CompletableFuture h = m.applyToEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), inc(v1)); + assertEquals(r.invocationCount, 1); + } catch (CompletionException ok) { + checkCompletedWithWrappedCFException(h, ex); + assertEquals(r.invocationCount, 0); + } + + checkCompletedWithWrappedCFException(g, ex); + checkCompletedNormally(f, v1); + } + } + + public void testApplyToEither_exceptionalCompletion4() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + final CFException ex = new CFException(); + + f.completeExceptionally(ex); + g.complete(v1); + final CompletableFuture h = m.applyToEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), inc(v1)); + assertEquals(r.invocationCount, 1); + } catch (CompletionException ok) { + checkCompletedWithWrappedCFException(h, ex); + assertEquals(r.invocationCount, 0); + } + + checkCompletedWithWrappedCFException(f, ex); + checkCompletedNormally(g, v1); + } } /** * applyToEither result completes exceptionally if action does */ - public void testApplyToEither3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingFunction r = new FailingFunction(); - CompletableFuture g = f.applyToEither(f2, r); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + public void testApplyToEither_actionFailed1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingFunction r = new FailingFunction(); + final CompletableFuture h = m.applyToEither(f, g, r); + + f.complete(v1); + checkCompletedWithWrappedCFException(h); + g.complete(v2); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } + + public void testApplyToEither_actionFailed2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingFunction r = new FailingFunction(); + final CompletableFuture h = m.applyToEither(f, g, r); + + g.complete(v2); + checkCompletedWithWrappedCFException(h); + f.complete(v1); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } } /** * applyToEither result completes exceptionally if either source cancelled */ - public void testApplyToEither4() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - CompletableFuture g = f.applyToEither(f2, inc); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + public void testApplyToEither_sourceCancelled1() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + final CompletableFuture h = m.applyToEither(f, g, r); + + assertTrue(f.cancel(mayInterruptIfRunning)); + checkCompletedWithWrappedCancellationException(h); + g.complete(v1); + + checkCancelled(f); + assertEquals(r.invocationCount, 0); + checkCompletedNormally(g, v1); + checkCompletedWithWrappedCancellationException(h); + } + } + + public void testApplyToEither_sourceCancelled2() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + final CompletableFuture h = m.applyToEither(f, g, r); + + assertTrue(g.cancel(mayInterruptIfRunning)); + checkCompletedWithWrappedCancellationException(h); + f.complete(v1); + + checkCancelled(g); + assertEquals(r.invocationCount, 0); + checkCompletedNormally(f, v1); + checkCompletedWithWrappedCancellationException(h); + } + } + + public void testApplyToEither_sourceCancelled3() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + + assertTrue(g.cancel(mayInterruptIfRunning)); + f.complete(v1); + final CompletableFuture h = m.applyToEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), inc(v1)); + assertEquals(r.invocationCount, 1); + } catch (CompletionException ok) { + checkCompletedWithWrappedCancellationException(h); + assertEquals(r.invocationCount, 0); + } + + checkCancelled(g); + checkCompletedNormally(f, v1); + } + } + + public void testApplyToEither_sourceCancelled4() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncFunction r = new IncFunction(); + + assertTrue(f.cancel(mayInterruptIfRunning)); + g.complete(v1); + final CompletableFuture h = m.applyToEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), inc(v1)); + assertEquals(r.invocationCount, 1); + } catch (CompletionException ok) { + checkCompletedWithWrappedCancellationException(h); + assertEquals(r.invocationCount, 0); + } + + checkCancelled(f); + checkCompletedNormally(g, v1); + } } /** * acceptEither result completes normally after normal completion * of either source */ - public void testAcceptEither() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - IncAction r = new IncAction(); - CompletableFuture g = f.acceptEither(f2, r); - f.complete(one); - checkCompletedNormally(g, null); - f2.complete(one); - checkCompletedNormally(g, null); - assertEquals(r.value, (Integer) 2); + public void testAcceptEither_normalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { - r = new IncAction(); - f = new CompletableFuture<>(); - f.complete(one); - f2 = new CompletableFuture<>(); - g = f.acceptEither(f2, r); - checkCompletedNormally(g, null); - assertEquals(r.value, (Integer) 2); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + final CompletableFuture h = m.acceptEither(f, g, r); + + f.complete(v1); + checkCompletedNormally(h, null); + assertEquals(r.value, inc(v1)); + g.complete(v2); + + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + checkCompletedNormally(h, null); + } + } + + public void testAcceptEither_normalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + final CompletableFuture h = m.acceptEither(f, g, r); + + g.complete(v2); + checkCompletedNormally(h, null); + assertEquals(r.value, inc(v2)); + f.complete(v1); + + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + checkCompletedNormally(h, null); + } + } + public void testAcceptEither_normalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + + f.complete(v1); + g.complete(v2); + final CompletableFuture h = m.acceptEither(f, g, r); + + checkCompletedNormally(h, null); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + + // unspecified behavior + assertTrue(Objects.equals(r.value, inc(v1)) || + Objects.equals(r.value, inc(v2))); + } } /** * acceptEither result completes exceptionally after exceptional * completion of either source */ - public void testAcceptEither2() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - IncAction r = new IncAction(); - CompletableFuture g = f.acceptEither(f2, r); - f.completeExceptionally(new CFException()); - f2.complete(one); - checkCompletedWithWrappedCFException(g); + public void testAcceptEither_exceptionalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { - r = new IncAction(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - f2.completeExceptionally(new CFException()); - g = f.acceptEither(f2, r); - checkCompletedWithWrappedCFException(g); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + final CompletableFuture h = m.acceptEither(f, g, r); + final CFException ex = new CFException(); + + f.completeExceptionally(ex); + checkCompletedWithWrappedCFException(h, ex); + g.complete(v1); + + assertEquals(r.invocationCount, 0); + checkCompletedNormally(g, v1); + checkCompletedWithWrappedCFException(f, ex); + checkCompletedWithWrappedCFException(h, ex); + } + } + + public void testAcceptEither_exceptionalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + final CompletableFuture h = m.acceptEither(f, g, r); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); + checkCompletedWithWrappedCFException(h, ex); + f.complete(v1); + + assertEquals(r.invocationCount, 0); + checkCompletedNormally(f, v1); + checkCompletedWithWrappedCFException(g, ex); + checkCompletedWithWrappedCFException(h, ex); + } + } + + public void testAcceptEither_exceptionalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); + f.complete(v1); + final CompletableFuture h = m.acceptEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), null); + assertEquals(r.invocationCount, 1); + assertEquals(inc(v1), r.value); + } catch (CompletionException ok) { + checkCompletedWithWrappedCFException(h, ex); + assertEquals(r.invocationCount, 0); + } + + checkCompletedWithWrappedCFException(g, ex); + checkCompletedNormally(f, v1); + } + } + + public void testAcceptEither_exceptionalCompletion4() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + final CFException ex = new CFException(); + + f.completeExceptionally(ex); + g.complete(v1); + final CompletableFuture h = m.acceptEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), null); + assertEquals(r.invocationCount, 1); + assertEquals(inc(v1), r.value); + } catch (CompletionException ok) { + checkCompletedWithWrappedCFException(h, ex); + assertEquals(r.invocationCount, 0); + } + + checkCompletedWithWrappedCFException(f, ex); + checkCompletedNormally(g, v1); + } } /** * acceptEither result completes exceptionally if action does */ - public void testAcceptEither3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingConsumer r = new FailingConsumer(); - CompletableFuture g = f.acceptEither(f2, r); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + public void testAcceptEither_actionFailed1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingConsumer r = new FailingConsumer(); + final CompletableFuture h = m.acceptEither(f, g, r); + + f.complete(v1); + checkCompletedWithWrappedCFException(h); + g.complete(v2); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } + + public void testAcceptEither_actionFailed2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingConsumer r = new FailingConsumer(); + final CompletableFuture h = m.acceptEither(f, g, r); + + g.complete(v2); + checkCompletedWithWrappedCFException(h); + f.complete(v1); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } } /** * acceptEither result completes exceptionally if either source cancelled */ - public void testAcceptEither4() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - IncAction r = new IncAction(); - CompletableFuture g = f.acceptEither(f2, r); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + public void testAcceptEither_sourceCancelled1() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + final CompletableFuture h = m.acceptEither(f, g, r); + + assertTrue(f.cancel(mayInterruptIfRunning)); + checkCompletedWithWrappedCancellationException(h); + g.complete(v1); + + checkCancelled(f); + assertEquals(r.invocationCount, 0); + checkCompletedNormally(g, v1); + checkCompletedWithWrappedCancellationException(h); + } + } + + public void testAcceptEither_sourceCancelled2() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + final CompletableFuture h = m.acceptEither(f, g, r); + + assertTrue(g.cancel(mayInterruptIfRunning)); + checkCompletedWithWrappedCancellationException(h); + f.complete(v1); + + checkCancelled(g); + assertEquals(r.invocationCount, 0); + checkCompletedNormally(f, v1); + checkCompletedWithWrappedCancellationException(h); + } + } + + public void testAcceptEither_sourceCancelled3() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + + assertTrue(g.cancel(mayInterruptIfRunning)); + f.complete(v1); + final CompletableFuture h = m.acceptEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), null); + assertEquals(r.invocationCount, 1); + assertEquals(inc(v1), r.value); + } catch (CompletionException ok) { + checkCompletedWithWrappedCancellationException(h); + assertEquals(r.invocationCount, 0); + } + + checkCancelled(g); + checkCompletedNormally(f, v1); + } + } + + public void testAcceptEither_sourceCancelled4() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final IncAction r = new IncAction(); + + assertTrue(f.cancel(mayInterruptIfRunning)); + g.complete(v1); + final CompletableFuture h = m.acceptEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), null); + assertEquals(r.invocationCount, 1); + assertEquals(inc(v1), r.value); + } catch (CompletionException ok) { + checkCompletedWithWrappedCancellationException(h); + assertEquals(r.invocationCount, 0); + } + + checkCancelled(f); + checkCompletedNormally(g, v1); + } } /** * runAfterEither result completes normally after normal completion * of either source */ - public void testRunAfterEither() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterEither(f2, r); - f.complete(one); - checkCompletedNormally(g, null); - f2.complete(one); - checkCompletedNormally(g, null); - assertTrue(r.ran); + public void testRunAfterEither_normalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { - r = new Noop(); - f = new CompletableFuture<>(); - f.complete(one); - f2 = new CompletableFuture<>(); - g = f.runAfterEither(f2, r); - checkCompletedNormally(g, null); - assertTrue(r.ran); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterEither(f, g, r); + + f.complete(v1); + checkCompletedNormally(h, null); + assertEquals(r.invocationCount, 1); + g.complete(v2); + + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + checkCompletedNormally(h, null); + assertEquals(r.invocationCount, 1); + } + } + + public void testRunAfterEither_normalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterEither(f, g, r); + + g.complete(v2); + checkCompletedNormally(h, null); + assertEquals(r.invocationCount, 1); + f.complete(v1); + + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + checkCompletedNormally(h, null); + assertEquals(r.invocationCount, 1); + } + } + public void testRunAfterEither_normalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + + f.complete(v1); + g.complete(v2); + final CompletableFuture h = m.runAfterEither(f, g, r); + + checkCompletedNormally(h, null); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + assertEquals(r.invocationCount, 1); + } } /** * runAfterEither result completes exceptionally after exceptional * completion of either source */ - public void testRunAfterEither2() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterEither(f2, r); - f.completeExceptionally(new CFException()); - f2.complete(one); - checkCompletedWithWrappedCFException(g); + public void testRunAfterEither_exceptionalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { - r = new Noop(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - f2.completeExceptionally(new CFException()); - g = f.runAfterEither(f2, r); - checkCompletedWithWrappedCFException(g); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterEither(f, g, r); + final CFException ex = new CFException(); + + f.completeExceptionally(ex); + checkCompletedWithWrappedCFException(h, ex); + g.complete(v1); + + assertEquals(r.invocationCount, 0); + checkCompletedNormally(g, v1); + checkCompletedWithWrappedCFException(f, ex); + checkCompletedWithWrappedCFException(h, ex); + } + } + + public void testRunAfterEither_exceptionalCompletion2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterEither(f, g, r); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); + checkCompletedWithWrappedCFException(h, ex); + f.complete(v1); + + assertEquals(r.invocationCount, 0); + checkCompletedNormally(f, v1); + checkCompletedWithWrappedCFException(g, ex); + checkCompletedWithWrappedCFException(h, ex); + } + } + + public void testRunAfterEither_exceptionalCompletion3() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CFException ex = new CFException(); + + g.completeExceptionally(ex); + f.complete(v1); + final CompletableFuture h = m.runAfterEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), null); + assertEquals(r.invocationCount, 1); + } catch (CompletionException ok) { + checkCompletedWithWrappedCFException(h, ex); + assertEquals(r.invocationCount, 0); + } + + checkCompletedWithWrappedCFException(g, ex); + checkCompletedNormally(f, v1); + } + } + + public void testRunAfterEither_exceptionalCompletion4() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CFException ex = new CFException(); + + f.completeExceptionally(ex); + g.complete(v1); + final CompletableFuture h = m.runAfterEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), null); + assertEquals(r.invocationCount, 1); + } catch (CompletionException ok) { + checkCompletedWithWrappedCFException(h, ex); + assertEquals(r.invocationCount, 0); + } + + checkCompletedWithWrappedCFException(f, ex); + checkCompletedNormally(g, v1); + } } /** * runAfterEither result completes exceptionally if action does */ - public void testRunAfterEither3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingNoop r = new FailingNoop(); - CompletableFuture g = f.runAfterEither(f2, r); - f2.complete(two); - checkCompletedWithWrappedCFException(g); + public void testRunAfterEither_actionFailed1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingNoop r = new FailingNoop(); + final CompletableFuture h = m.runAfterEither(f, g, r); + + f.complete(v1); + checkCompletedWithWrappedCFException(h); + g.complete(v2); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } + } + + public void testRunAfterEither_actionFailed2() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) + for (Integer v2 : new Integer[] { 2, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final FailingNoop r = new FailingNoop(); + final CompletableFuture h = m.runAfterEither(f, g, r); + + g.complete(v2); + checkCompletedWithWrappedCFException(h); + f.complete(v1); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v2); + } } /** * runAfterEither result completes exceptionally if either source cancelled */ - public void testRunAfterEither4() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterEither(f2, r); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - assertTrue(f2.cancel(true)); - checkCompletedWithWrappedCancellationException(g); + public void testRunAfterEither_sourceCancelled1() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterEither(f, g, r); + + assertTrue(f.cancel(mayInterruptIfRunning)); + checkCompletedWithWrappedCancellationException(h); + g.complete(v1); + + checkCancelled(f); + assertEquals(r.invocationCount, 0); + checkCompletedNormally(g, v1); + checkCompletedWithWrappedCancellationException(h); + } + } + + public void testRunAfterEither_sourceCancelled2() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + final CompletableFuture h = m.runAfterEither(f, g, r); + + assertTrue(g.cancel(mayInterruptIfRunning)); + checkCompletedWithWrappedCancellationException(h); + f.complete(v1); + + checkCancelled(g); + assertEquals(r.invocationCount, 0); + checkCompletedNormally(f, v1); + checkCompletedWithWrappedCancellationException(h); + } + } + + public void testRunAfterEither_sourceCancelled3() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + + assertTrue(g.cancel(mayInterruptIfRunning)); + f.complete(v1); + final CompletableFuture h = m.runAfterEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), null); + assertEquals(r.invocationCount, 1); + } catch (CompletionException ok) { + checkCompletedWithWrappedCancellationException(h); + assertEquals(r.invocationCount, 0); + } + + checkCancelled(g); + checkCompletedNormally(f, v1); + } + } + + public void testRunAfterEither_sourceCancelled4() { + for (ExecutionMode m : ExecutionMode.values()) + for (boolean mayInterruptIfRunning : new boolean[] { true, false }) + for (Integer v1 : new Integer[] { 1, null }) { + + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = new CompletableFuture<>(); + final Noop r = new Noop(); + + assertTrue(f.cancel(mayInterruptIfRunning)); + g.complete(v1); + final CompletableFuture h = m.runAfterEither(f, g, r); + + // unspecified behavior + Integer v; + try { + assertEquals(h.join(), null); + assertEquals(r.invocationCount, 1); + } catch (CompletionException ok) { + checkCompletedWithWrappedCancellationException(h); + assertEquals(r.invocationCount, 0); + } + + checkCancelled(f); + checkCompletedNormally(g, v1); + } } /** @@ -2275,222 +3002,6 @@ public class CompletableFutureTest exten } /** - * applyToEitherAsync result completes normally after normal - * completion of sources - */ - public void testApplyToEitherAsync() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - CompletableFuture g = f.applyToEitherAsync(f2, inc); - f.complete(one); - checkCompletedNormally(g, two); - - f = new CompletableFuture<>(); - f.complete(one); - f2 = new CompletableFuture<>(); - g = f.applyToEitherAsync(f2, inc); - checkCompletedNormally(g, two); - } - - /** - * applyToEitherAsync result completes exceptionally after exceptional - * completion of source - */ - public void testApplyToEitherAsync2() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - CompletableFuture g = f.applyToEitherAsync(f2, inc); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); - - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - f2.completeExceptionally(new CFException()); - g = f.applyToEitherAsync(f2, inc); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * applyToEitherAsync result completes exceptionally if action does - */ - public void testApplyToEitherAsync3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingFunction r = new FailingFunction(); - CompletableFuture g = f.applyToEitherAsync(f2, r); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * applyToEitherAsync result completes exceptionally if either source cancelled - */ - public void testApplyToEitherAsync4() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - CompletableFuture g = f.applyToEitherAsync(f2, inc); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - assertTrue(f2.cancel(true)); - g = f.applyToEitherAsync(f2, inc); - checkCompletedWithWrappedCancellationException(g); - } - - /** - * acceptEitherAsync result completes normally after normal - * completion of sources - */ - public void testAcceptEitherAsync() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - IncAction r = new IncAction(); - CompletableFuture g = f.acceptEitherAsync(f2, r); - f.complete(one); - checkCompletedNormally(g, null); - assertEquals(r.value, (Integer) 2); - - r = new IncAction(); - f = new CompletableFuture<>(); - f.complete(one); - f2 = new CompletableFuture<>(); - g = f.acceptEitherAsync(f2, r); - checkCompletedNormally(g, null); - assertEquals(r.value, (Integer) 2); - } - - /** - * acceptEitherAsync result completes exceptionally after exceptional - * completion of source - */ - public void testAcceptEitherAsync2() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - IncAction r = new IncAction(); - CompletableFuture g = f.acceptEitherAsync(f2, r); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); - - r = new IncAction(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - f2.completeExceptionally(new CFException()); - g = f.acceptEitherAsync(f2, r); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * acceptEitherAsync result completes exceptionally if action does - */ - public void testAcceptEitherAsync3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingConsumer r = new FailingConsumer(); - CompletableFuture g = f.acceptEitherAsync(f2, r); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * acceptEitherAsync result completes exceptionally if either - * source cancelled - */ - public void testAcceptEitherAsync4() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - IncAction r = new IncAction(); - CompletableFuture g = f.acceptEitherAsync(f2, r); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - - r = new IncAction(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - assertTrue(f2.cancel(true)); - g = f.acceptEitherAsync(f2, r); - checkCompletedWithWrappedCancellationException(g); - } - - /** - * runAfterEitherAsync result completes normally after normal - * completion of sources - */ - public void testRunAfterEitherAsync() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterEitherAsync(f2, r); - f.complete(one); - checkCompletedNormally(g, null); - assertTrue(r.ran); - - r = new Noop(); - f = new CompletableFuture<>(); - f.complete(one); - f2 = new CompletableFuture<>(); - g = f.runAfterEitherAsync(f2, r); - checkCompletedNormally(g, null); - assertTrue(r.ran); - } - - /** - * runAfterEitherAsync result completes exceptionally after exceptional - * completion of source - */ - public void testRunAfterEitherAsync2() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterEitherAsync(f2, r); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); - - r = new Noop(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - f2.completeExceptionally(new CFException()); - g = f.runAfterEitherAsync(f2, r); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * runAfterEitherAsync result completes exceptionally if action does - */ - public void testRunAfterEitherAsync3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingNoop r = new FailingNoop(); - CompletableFuture g = f.runAfterEitherAsync(f2, r); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * runAfterEitherAsync result completes exceptionally if either - * source cancelled - */ - public void testRunAfterEitherAsync4() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterEitherAsync(f2, r); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - - r = new Noop(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - assertTrue(f2.cancel(true)); - g = f.runAfterEitherAsync(f2, r); - checkCompletedWithWrappedCancellationException(g); - } - - /** * thenComposeAsync result completes normally after normal * completion of source */ @@ -2714,222 +3225,6 @@ public class CompletableFutureTest exten } /** - * applyToEitherAsync result completes normally after normal - * completion of sources - */ - public void testApplyToEitherAsyncE() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - CompletableFuture g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); - f.complete(one); - checkCompletedNormally(g, two); - - f = new CompletableFuture<>(); - f.complete(one); - f2 = new CompletableFuture<>(); - g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); - checkCompletedNormally(g, two); - } - - /** - * applyToEitherAsync result completes exceptionally after exceptional - * completion of source - */ - public void testApplyToEitherAsync2E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - CompletableFuture g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); - - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - f2.completeExceptionally(new CFException()); - g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * applyToEitherAsync result completes exceptionally if action does - */ - public void testApplyToEitherAsync3E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingFunction r = new FailingFunction(); - CompletableFuture g = f.applyToEitherAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * applyToEitherAsync result completes exceptionally if either source cancelled - */ - public void testApplyToEitherAsync4E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - CompletableFuture g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - assertTrue(f2.cancel(true)); - g = f.applyToEitherAsync(f2, inc, new ThreadExecutor()); - checkCompletedWithWrappedCancellationException(g); - } - - /** - * acceptEitherAsync result completes normally after normal - * completion of sources - */ - public void testAcceptEitherAsyncE() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - IncAction r = new IncAction(); - CompletableFuture g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkCompletedNormally(g, null); - assertEquals(r.value, (Integer) 2); - - r = new IncAction(); - f = new CompletableFuture<>(); - f.complete(one); - f2 = new CompletableFuture<>(); - g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); - checkCompletedNormally(g, null); - assertEquals(r.value, (Integer) 2); - } - - /** - * acceptEitherAsync result completes exceptionally after exceptional - * completion of source - */ - public void testAcceptEitherAsync2E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - IncAction r = new IncAction(); - CompletableFuture g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); - - r = new IncAction(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - f2.completeExceptionally(new CFException()); - g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * acceptEitherAsync result completes exceptionally if action does - */ - public void testAcceptEitherAsync3E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingConsumer r = new FailingConsumer(); - CompletableFuture g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * acceptEitherAsync result completes exceptionally if either - * source cancelled - */ - public void testAcceptEitherAsync4E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - IncAction r = new IncAction(); - CompletableFuture g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - - r = new IncAction(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - assertTrue(f2.cancel(true)); - g = f.acceptEitherAsync(f2, r, new ThreadExecutor()); - checkCompletedWithWrappedCancellationException(g); - } - - /** - * runAfterEitherAsync result completes normally after normal - * completion of sources - */ - public void testRunAfterEitherAsyncE() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkCompletedNormally(g, null); - assertTrue(r.ran); - - r = new Noop(); - f = new CompletableFuture<>(); - f.complete(one); - f2 = new CompletableFuture<>(); - g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); - checkCompletedNormally(g, null); - assertTrue(r.ran); - } - - /** - * runAfterEitherAsync result completes exceptionally after exceptional - * completion of source - */ - public void testRunAfterEitherAsync2E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(g); - - r = new Noop(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - f2.completeExceptionally(new CFException()); - g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * runAfterEitherAsync result completes exceptionally if action does - */ - public void testRunAfterEitherAsync3E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - FailingNoop r = new FailingNoop(); - CompletableFuture g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); - f.complete(one); - checkCompletedWithWrappedCFException(g); - } - - /** - * runAfterEitherAsync result completes exceptionally if either - * source cancelled - */ - public void testRunAfterEitherAsync4E() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture f2 = new CompletableFuture<>(); - Noop r = new Noop(); - CompletableFuture g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); - assertTrue(f.cancel(true)); - checkCompletedWithWrappedCancellationException(g); - - r = new Noop(); - f = new CompletableFuture<>(); - f2 = new CompletableFuture<>(); - assertTrue(f2.cancel(true)); - g = f.runAfterEitherAsync(f2, r, new ThreadExecutor()); - checkCompletedWithWrappedCancellationException(g); - } - - /** * thenComposeAsync result completes normally after normal * completion of source */ @@ -3173,137 +3468,97 @@ public class CompletableFutureTest exten * whenComplete action executes on normal completion, propagating * source result. */ - public void testWhenComplete1() { + public void testWhenComplete_normalCompletion1() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + final AtomicInteger a = new AtomicInteger(); - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture g = - f.whenComplete((Integer x, Throwable t) -> a.getAndIncrement()); - f.complete(three); - checkCompletedNormally(f, three); - checkCompletedNormally(g, three); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = + m.whenComplete(f, + (Integer x, Throwable t) -> { + threadAssertSame(x, v1); + threadAssertNull(t); + a.getAndIncrement(); + }); + f.complete(v1); + checkCompletedNormally(f, v1); + checkCompletedNormally(g, v1); assertEquals(a.get(), 1); + } } /** * whenComplete action executes on exceptional completion, propagating * source result. */ - public void testWhenComplete2() { + public void testWhenComplete_exceptionalCompletion() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { + final AtomicInteger a = new AtomicInteger(); - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture g = - f.whenComplete((Integer x, Throwable t) -> a.getAndIncrement()); - f.completeExceptionally(new CFException()); - assertTrue(f.isCompletedExceptionally()); - assertTrue(g.isCompletedExceptionally()); + final CFException ex = new CFException(); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = m.whenComplete + (f, + (Integer x, Throwable t) -> { + threadAssertNull(x); + threadAssertSame(t, ex); + a.getAndIncrement(); + }); + f.completeExceptionally(ex); + checkCompletedWithWrappedCFException(f, ex); + checkCompletedWithWrappedCFException(g, ex); assertEquals(a.get(), 1); + } } /** * If a whenComplete action throws an exception when triggered by * a normal completion, it completes exceptionally */ - public void testWhenComplete3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture g = - f.whenComplete((Integer x, Throwable t) -> - { throw new CFException(); } ); - f.complete(three); - checkCompletedNormally(f, three); - assertTrue(g.isCompletedExceptionally()); - checkCompletedWithWrappedCFException(g); - } - - /** - * whenCompleteAsync action executes on normal completion, propagating - * source result. - */ - public void testWhenCompleteAsync1() { - final AtomicInteger a = new AtomicInteger(); - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture g = - f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement()); - f.complete(three); - checkCompletedNormally(f, three); - checkCompletedNormally(g, three); - assertEquals(a.get(), 1); - } - - /** - * whenCompleteAsync action executes on exceptional completion, propagating - * source result. - */ - public void testWhenCompleteAsync2() { - final AtomicInteger a = new AtomicInteger(); - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture g = - f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement()); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(f); - checkCompletedWithWrappedCFException(g); - } - - /** - * If a whenCompleteAsync action throws an exception when - * triggered by a normal completion, it completes exceptionally - */ - public void testWhenCompleteAsync3() { - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture g = - f.whenCompleteAsync((Integer x, Throwable t) -> - { throw new CFException(); } ); - f.complete(three); - checkCompletedNormally(f, three); - checkCompletedWithWrappedCFException(g); - } + public void testWhenComplete_actionFailed() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { - /** - * whenCompleteAsync action executes on normal completion, propagating - * source result. - */ - public void testWhenCompleteAsync1e() { - final AtomicInteger a = new AtomicInteger(); - ThreadExecutor exec = new ThreadExecutor(); - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture g = - f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement(), - exec); - f.complete(three); - checkCompletedNormally(f, three); - checkCompletedNormally(g, three); - assertEquals(a.get(), 1); + final CFException ex = new CFException(); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = m.whenComplete + (f, + (Integer x, Throwable t) -> { + threadAssertSame(x, v1); + threadAssertNull(t); + throw ex; + }); + f.complete(v1); + checkCompletedNormally(f, v1); + checkCompletedWithWrappedCFException(g, ex); + } } /** - * whenCompleteAsync action executes on exceptional completion, propagating - * source result. + * If a whenComplete action throws an exception when triggered by + * a source completion that also throws an exception, the source + * exception takes precedence. */ - public void testWhenCompleteAsync2e() { - final AtomicInteger a = new AtomicInteger(); - ThreadExecutor exec = new ThreadExecutor(); - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture g = - f.whenCompleteAsync((Integer x, Throwable t) -> a.getAndIncrement(), - exec); - f.completeExceptionally(new CFException()); - checkCompletedWithWrappedCFException(f); - checkCompletedWithWrappedCFException(g); - } + public void testWhenComplete_actionFailedSourceFailed() { + for (ExecutionMode m : ExecutionMode.values()) + for (Integer v1 : new Integer[] { 1, null }) { - /** - * If a whenCompleteAsync action throws an exception when triggered - * by a normal completion, it completes exceptionally - */ - public void testWhenCompleteAsync3e() { - ThreadExecutor exec = new ThreadExecutor(); - CompletableFuture f = new CompletableFuture<>(); - CompletableFuture g = - f.whenCompleteAsync((Integer x, Throwable t) -> - { throw new CFException(); }, - exec); - f.complete(three); - checkCompletedNormally(f, three); - checkCompletedWithWrappedCFException(g); + final CFException ex1 = new CFException(); + final CFException ex2 = new CFException(); + final CompletableFuture f = new CompletableFuture<>(); + final CompletableFuture g = m.whenComplete + (f, + (Integer x, Throwable t) -> { + threadAssertSame(t, ex1); + threadAssertNull(x); + throw ex2; + }); + f.completeExceptionally(ex1); + checkCompletedWithWrappedCFException(f, ex1); + checkCompletedWithWrappedCFException(g, ex1); + } } /**