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.80 by jsr166, Mon Jun 16 17:29:03 2014 UTC vs.
Revision 1.101 by jsr166, Sun Feb 22 04:34:44 2015 UTC

# Line 5 | Line 5
5   * http://creativecommons.org/publicdomain/zero/1.0/
6   */
7  
8 < import junit.framework.*;
8 > import static java.util.concurrent.TimeUnit.MILLISECONDS;
9 > import static java.util.concurrent.TimeUnit.SECONDS;
10 >
11 > import java.util.ArrayList;
12 > import java.util.List;
13 > import java.util.Objects;
14   import java.util.concurrent.Callable;
10 import java.util.concurrent.Executor;
11 import java.util.concurrent.ExecutorService;
12 import java.util.concurrent.Executors;
15   import java.util.concurrent.CancellationException;
14 import java.util.concurrent.CountDownLatch;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.Future;
16   import java.util.concurrent.CompletableFuture;
17   import java.util.concurrent.CompletionException;
18   import java.util.concurrent.CompletionStage;
19 + import java.util.concurrent.ExecutionException;
20 + import java.util.concurrent.Executor;
21   import java.util.concurrent.ForkJoinPool;
22   import java.util.concurrent.ForkJoinTask;
23   import java.util.concurrent.TimeoutException;
24   import java.util.concurrent.atomic.AtomicInteger;
24 import static java.util.concurrent.TimeUnit.MILLISECONDS;
25 import static java.util.concurrent.TimeUnit.SECONDS;
26 import java.util.*;
27 import java.util.function.Supplier;
28 import java.util.function.Consumer;
25   import java.util.function.BiConsumer;
30 import java.util.function.Function;
26   import java.util.function.BiFunction;
27 + import java.util.function.Consumer;
28 + import java.util.function.Function;
29 + import java.util.function.Supplier;
30 +
31 + import junit.framework.Test;
32 + import junit.framework.TestSuite;
33  
34   public class CompletableFutureTest extends JSR166TestCase {
35  
# Line 57 | Line 58 | public class CompletableFutureTest exten
58      }
59  
60      <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
61 <        try {
62 <            assertEquals(value, f.get(LONG_DELAY_MS, MILLISECONDS));
62 <        } catch (Throwable fail) { threadUnexpectedException(fail); }
61 >        checkTimedGet(f, value);
62 >
63          try {
64              assertEquals(value, f.join());
65          } catch (Throwable fail) { threadUnexpectedException(fail); }
# Line 76 | Line 76 | public class CompletableFutureTest exten
76      }
77  
78      void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
79 +        long startTime = System.nanoTime();
80 +        long timeoutMillis = LONG_DELAY_MS;
81          try {
82 <            f.get(LONG_DELAY_MS, MILLISECONDS);
82 >            f.get(timeoutMillis, MILLISECONDS);
83              shouldThrow();
84          } catch (ExecutionException success) {
85              assertTrue(success.getCause() instanceof CFException);
86          } catch (Throwable fail) { threadUnexpectedException(fail); }
87 +        assertTrue(millisElapsedSince(startTime) < timeoutMillis/2);
88 +
89          try {
90              f.join();
91              shouldThrow();
# Line 107 | Line 111 | public class CompletableFutureTest exten
111  
112      <U> void checkCompletedExceptionallyWithRootCause(CompletableFuture<U> f,
113                                                        Throwable ex) {
114 +        long startTime = System.nanoTime();
115 +        long timeoutMillis = LONG_DELAY_MS;
116          try {
117 <            f.get(LONG_DELAY_MS, MILLISECONDS);
117 >            f.get(timeoutMillis, MILLISECONDS);
118              shouldThrow();
119          } catch (ExecutionException success) {
120              assertSame(ex, success.getCause());
121          } catch (Throwable fail) { threadUnexpectedException(fail); }
122 +        assertTrue(millisElapsedSince(startTime) < timeoutMillis/2);
123 +
124          try {
125              f.join();
126              shouldThrow();
# Line 158 | Line 166 | public class CompletableFutureTest exten
166      }
167  
168      void checkCancelled(CompletableFuture<?> f) {
169 +        long startTime = System.nanoTime();
170 +        long timeoutMillis = LONG_DELAY_MS;
171          try {
172 <            f.get(LONG_DELAY_MS, MILLISECONDS);
172 >            f.get(timeoutMillis, MILLISECONDS);
173              shouldThrow();
174          } catch (CancellationException success) {
175          } catch (Throwable fail) { threadUnexpectedException(fail); }
176 +        assertTrue(millisElapsedSince(startTime) < timeoutMillis/2);
177 +
178          try {
179              f.join();
180              shouldThrow();
# Line 183 | Line 195 | public class CompletableFutureTest exten
195      }
196  
197      void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
198 +        long startTime = System.nanoTime();
199 +        long timeoutMillis = LONG_DELAY_MS;
200          try {
201 <            f.get(LONG_DELAY_MS, MILLISECONDS);
201 >            f.get(timeoutMillis, MILLISECONDS);
202              shouldThrow();
203          } catch (ExecutionException success) {
204              assertTrue(success.getCause() instanceof CancellationException);
205          } catch (Throwable fail) { threadUnexpectedException(fail); }
206 +        assertTrue(millisElapsedSince(startTime) < timeoutMillis/2);
207 +
208          try {
209              f.join();
210              shouldThrow();
# Line 257 | Line 273 | public class CompletableFutureTest exten
273      {
274          CompletableFuture<Integer> f = new CompletableFuture<>();
275          checkIncomplete(f);
276 <        assertTrue(f.cancel(true));
277 <        assertTrue(f.cancel(true));
276 >        assertTrue(f.cancel(mayInterruptIfRunning));
277 >        assertTrue(f.cancel(mayInterruptIfRunning));
278 >        assertTrue(f.cancel(!mayInterruptIfRunning));
279          checkCancelled(f);
280      }}
281  
# Line 530 | Line 547 | public class CompletableFutureTest exten
547          }
548      }
549  
533
550      class CompletableFutureInc extends CheckedIntegerAction
551          implements Function<Integer, CompletableFuture<Integer>>
552      {
# Line 569 | Line 585 | public class CompletableFutureTest exten
585          }
586      }
587  
588 +    static final boolean defaultExecutorIsCommonPool
589 +        = ForkJoinPool.getCommonPoolParallelism() > 1;
590 +
591      /**
592       * Permits the testing of parallel code for the 3 different
593       * execution modes without copy/pasting all the test methods.
594       */
595      enum ExecutionMode {
596 <        DEFAULT {
596 >        SYNC {
597              public void checkExecutionMode() {
598                  assertFalse(ThreadExecutor.startedCurrentThread());
599                  assertNull(ForkJoinTask.getPool());
# Line 650 | Line 669 | public class CompletableFutureTest exten
669  
670          ASYNC {
671              public void checkExecutionMode() {
672 <                assertSame(ForkJoinPool.commonPool(),
673 <                           ForkJoinTask.getPool());
672 >                assertEquals(defaultExecutorIsCommonPool,
673 >                             (ForkJoinPool.commonPool() == ForkJoinTask.getPool()));
674              }
675              public CompletableFuture<Void> runAsync(Runnable a) {
676                  return CompletableFuture.runAsync(a);
# Line 875 | Line 894 | public class CompletableFutureTest exten
894          if (!createIncomplete) f.completeExceptionally(ex);
895          final CompletableFuture<Integer> g = f.exceptionally
896              ((Throwable t) -> {
897 <                ExecutionMode.DEFAULT.checkExecutionMode();
897 >                ExecutionMode.SYNC.checkExecutionMode();
898                  threadAssertSame(t, ex);
899                  a.getAndIncrement();
900                  return v1;
# Line 888 | Line 907 | public class CompletableFutureTest exten
907  
908      public void testExceptionally_exceptionalCompletionActionFailed() {
909          for (boolean createIncomplete : new boolean[] { true, false })
891        for (Integer v1 : new Integer[] { 1, null })
910      {
911          final AtomicInteger a = new AtomicInteger(0);
912          final CFException ex1 = new CFException();
# Line 897 | Line 915 | public class CompletableFutureTest exten
915          if (!createIncomplete) f.completeExceptionally(ex1);
916          final CompletableFuture<Integer> g = f.exceptionally
917              ((Throwable t) -> {
918 <                ExecutionMode.DEFAULT.checkExecutionMode();
918 >                ExecutionMode.SYNC.checkExecutionMode();
919                  threadAssertSame(t, ex1);
920                  a.getAndIncrement();
921                  throw ex2;
# Line 942 | Line 960 | public class CompletableFutureTest exten
960      public void testWhenComplete_exceptionalCompletion() {
961          for (ExecutionMode m : ExecutionMode.values())
962          for (boolean createIncomplete : new boolean[] { true, false })
945        for (Integer v1 : new Integer[] { 1, null })
963      {
964          final AtomicInteger a = new AtomicInteger(0);
965          final CFException ex = new CFException();
# Line 1027 | Line 1044 | public class CompletableFutureTest exten
1044      public void testWhenComplete_actionFailedSourceFailed() {
1045          for (boolean createIncomplete : new boolean[] { true, false })
1046          for (ExecutionMode m : ExecutionMode.values())
1030        for (Integer v1 : new Integer[] { 1, null })
1047      {
1048          final AtomicInteger a = new AtomicInteger(0);
1049          final CFException ex1 = new CFException();
# Line 1264 | Line 1280 | public class CompletableFutureTest exten
1280       */
1281      public void testThenRun_normalCompletion() {
1282          for (ExecutionMode m : ExecutionMode.values())
1267        for (boolean createIncomplete : new boolean[] { true, false })
1283          for (Integer v1 : new Integer[] { 1, null })
1284      {
1285          final CompletableFuture<Integer> f = new CompletableFuture<>();
1286 <        final Noop r = new Noop(m);
1287 <        if (!createIncomplete) assertTrue(f.complete(v1));
1273 <        final CompletableFuture<Void> g = m.thenRun(f, r);
1274 <        if (createIncomplete) {
1275 <            checkIncomplete(g);
1276 <            assertTrue(f.complete(v1));
1277 <        }
1286 >        final Noop[] rs = new Noop[6];
1287 >        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1288  
1289 <        checkCompletedNormally(g, null);
1289 >        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1290 >        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1291 >        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1292 >        checkIncomplete(h0);
1293 >        checkIncomplete(h1);
1294 >        checkIncomplete(h2);
1295 >        assertTrue(f.complete(v1));
1296 >        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1297 >        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1298 >        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1299 >
1300 >        checkCompletedNormally(h0, null);
1301 >        checkCompletedNormally(h1, null);
1302 >        checkCompletedNormally(h2, null);
1303 >        checkCompletedNormally(h3, null);
1304 >        checkCompletedNormally(h4, null);
1305 >        checkCompletedNormally(h5, null);
1306          checkCompletedNormally(f, v1);
1307 <        r.assertInvoked();
1307 >        for (Noop r : rs) r.assertInvoked();
1308      }}
1309  
1310      /**
# Line 1287 | Line 1313 | public class CompletableFutureTest exten
1313       */
1314      public void testThenRun_exceptionalCompletion() {
1315          for (ExecutionMode m : ExecutionMode.values())
1290        for (boolean createIncomplete : new boolean[] { true, false })
1316      {
1317          final CFException ex = new CFException();
1318          final CompletableFuture<Integer> f = new CompletableFuture<>();
1319 <        final Noop r = new Noop(m);
1320 <        if (!createIncomplete) f.completeExceptionally(ex);
1296 <        final CompletableFuture<Void> g = m.thenRun(f, r);
1297 <        if (createIncomplete) {
1298 <            checkIncomplete(g);
1299 <            f.completeExceptionally(ex);
1300 <        }
1319 >        final Noop[] rs = new Noop[6];
1320 >        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1321  
1322 <        checkCompletedWithWrappedException(g, ex);
1322 >        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1323 >        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1324 >        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1325 >        checkIncomplete(h0);
1326 >        checkIncomplete(h1);
1327 >        checkIncomplete(h2);
1328 >        assertTrue(f.completeExceptionally(ex));
1329 >        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1330 >        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1331 >        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1332 >
1333 >        checkCompletedWithWrappedException(h0, ex);
1334 >        checkCompletedWithWrappedException(h1, ex);
1335 >        checkCompletedWithWrappedException(h2, ex);
1336 >        checkCompletedWithWrappedException(h3, ex);
1337 >        checkCompletedWithWrappedException(h4, ex);
1338 >        checkCompletedWithWrappedException(h5, ex);
1339          checkCompletedExceptionally(f, ex);
1340 <        r.assertNotInvoked();
1340 >        for (Noop r : rs) r.assertNotInvoked();
1341      }}
1342  
1343      /**
# Line 1309 | Line 1345 | public class CompletableFutureTest exten
1345       */
1346      public void testThenRun_sourceCancelled() {
1347          for (ExecutionMode m : ExecutionMode.values())
1312        for (boolean createIncomplete : new boolean[] { true, false })
1348          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1349      {
1350          final CompletableFuture<Integer> f = new CompletableFuture<>();
1351 <        final Noop r = new Noop(m);
1352 <        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1318 <        final CompletableFuture<Void> g = m.thenRun(f, r);
1319 <        if (createIncomplete) {
1320 <            checkIncomplete(g);
1321 <            assertTrue(f.cancel(mayInterruptIfRunning));
1322 <        }
1351 >        final Noop[] rs = new Noop[6];
1352 >        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
1353  
1354 <        checkCompletedWithWrappedCancellationException(g);
1354 >        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1355 >        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1356 >        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1357 >        checkIncomplete(h0);
1358 >        checkIncomplete(h1);
1359 >        checkIncomplete(h2);
1360 >        assertTrue(f.cancel(mayInterruptIfRunning));
1361 >        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1362 >        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1363 >        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1364 >
1365 >        checkCompletedWithWrappedCancellationException(h0);
1366 >        checkCompletedWithWrappedCancellationException(h1);
1367 >        checkCompletedWithWrappedCancellationException(h2);
1368 >        checkCompletedWithWrappedCancellationException(h3);
1369 >        checkCompletedWithWrappedCancellationException(h4);
1370 >        checkCompletedWithWrappedCancellationException(h5);
1371          checkCancelled(f);
1372 <        r.assertNotInvoked();
1372 >        for (Noop r : rs) r.assertNotInvoked();
1373      }}
1374  
1375      /**
# Line 1331 | Line 1377 | public class CompletableFutureTest exten
1377       */
1378      public void testThenRun_actionFailed() {
1379          for (ExecutionMode m : ExecutionMode.values())
1334        for (boolean createIncomplete : new boolean[] { true, false })
1380          for (Integer v1 : new Integer[] { 1, null })
1381      {
1382          final CompletableFuture<Integer> f = new CompletableFuture<>();
1383 <        final FailingRunnable r = new FailingRunnable(m);
1384 <        if (!createIncomplete) assertTrue(f.complete(v1));
1340 <        final CompletableFuture<Void> g = m.thenRun(f, r);
1341 <        if (createIncomplete) {
1342 <            checkIncomplete(g);
1343 <            assertTrue(f.complete(v1));
1344 <        }
1383 >        final FailingRunnable[] rs = new FailingRunnable[6];
1384 >        for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
1385  
1386 <        checkCompletedWithWrappedCFException(g);
1386 >        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
1387 >        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
1388 >        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
1389 >        assertTrue(f.complete(v1));
1390 >        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
1391 >        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
1392 >        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
1393 >
1394 >        checkCompletedWithWrappedCFException(h0);
1395 >        checkCompletedWithWrappedCFException(h1);
1396 >        checkCompletedWithWrappedCFException(h2);
1397 >        checkCompletedWithWrappedCFException(h3);
1398 >        checkCompletedWithWrappedCFException(h4);
1399 >        checkCompletedWithWrappedCFException(h5);
1400          checkCompletedNormally(f, v1);
1401      }}
1402  
# Line 1352 | Line 1405 | public class CompletableFutureTest exten
1405       */
1406      public void testThenApply_normalCompletion() {
1407          for (ExecutionMode m : ExecutionMode.values())
1355        for (boolean createIncomplete : new boolean[] { true, false })
1408          for (Integer v1 : new Integer[] { 1, null })
1409      {
1410          final CompletableFuture<Integer> f = new CompletableFuture<>();
1411 <        final IncFunction r = new IncFunction(m);
1412 <        if (!createIncomplete) assertTrue(f.complete(v1));
1361 <        final CompletableFuture<Integer> g = m.thenApply(f, r);
1362 <        if (createIncomplete) {
1363 <            checkIncomplete(g);
1364 <            assertTrue(f.complete(v1));
1365 <        }
1411 >        final IncFunction[] rs = new IncFunction[4];
1412 >        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1413  
1414 <        checkCompletedNormally(g, inc(v1));
1414 >        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1415 >        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1416 >        checkIncomplete(h0);
1417 >        checkIncomplete(h1);
1418 >        assertTrue(f.complete(v1));
1419 >        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1420 >        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1421 >
1422 >        checkCompletedNormally(h0, inc(v1));
1423 >        checkCompletedNormally(h1, inc(v1));
1424 >        checkCompletedNormally(h2, inc(v1));
1425 >        checkCompletedNormally(h3, inc(v1));
1426          checkCompletedNormally(f, v1);
1427 <        r.assertValue(inc(v1));
1427 >        for (IncFunction r : rs) r.assertValue(inc(v1));
1428      }}
1429  
1430      /**
# Line 1375 | Line 1433 | public class CompletableFutureTest exten
1433       */
1434      public void testThenApply_exceptionalCompletion() {
1435          for (ExecutionMode m : ExecutionMode.values())
1378        for (boolean createIncomplete : new boolean[] { true, false })
1436      {
1437          final CFException ex = new CFException();
1438          final CompletableFuture<Integer> f = new CompletableFuture<>();
1439 <        final IncFunction r = new IncFunction(m);
1440 <        if (!createIncomplete) f.completeExceptionally(ex);
1384 <        final CompletableFuture<Integer> g = m.thenApply(f, r);
1385 <        if (createIncomplete) {
1386 <            checkIncomplete(g);
1387 <            f.completeExceptionally(ex);
1388 <        }
1439 >        final IncFunction[] rs = new IncFunction[4];
1440 >        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1441  
1442 <        checkCompletedWithWrappedException(g, ex);
1442 >        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1443 >        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1444 >        assertTrue(f.completeExceptionally(ex));
1445 >        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1446 >        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1447 >
1448 >        checkCompletedWithWrappedException(h0, ex);
1449 >        checkCompletedWithWrappedException(h1, ex);
1450 >        checkCompletedWithWrappedException(h2, ex);
1451 >        checkCompletedWithWrappedException(h3, ex);
1452          checkCompletedExceptionally(f, ex);
1453 <        r.assertNotInvoked();
1453 >        for (IncFunction r : rs) r.assertNotInvoked();
1454      }}
1455  
1456      /**
# Line 1397 | Line 1458 | public class CompletableFutureTest exten
1458       */
1459      public void testThenApply_sourceCancelled() {
1460          for (ExecutionMode m : ExecutionMode.values())
1400        for (boolean createIncomplete : new boolean[] { true, false })
1461          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1462      {
1463          final CompletableFuture<Integer> f = new CompletableFuture<>();
1464 <        final IncFunction r = new IncFunction(m);
1465 <        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1406 <        final CompletableFuture<Integer> g = m.thenApply(f, r);
1407 <        if (createIncomplete) {
1408 <            checkIncomplete(g);
1409 <            assertTrue(f.cancel(mayInterruptIfRunning));
1410 <        }
1464 >        final IncFunction[] rs = new IncFunction[4];
1465 >        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
1466  
1467 <        checkCompletedWithWrappedCancellationException(g);
1467 >        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1468 >        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1469 >        assertTrue(f.cancel(mayInterruptIfRunning));
1470 >        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1471 >        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1472 >
1473 >        checkCompletedWithWrappedCancellationException(h0);
1474 >        checkCompletedWithWrappedCancellationException(h1);
1475 >        checkCompletedWithWrappedCancellationException(h2);
1476 >        checkCompletedWithWrappedCancellationException(h3);
1477          checkCancelled(f);
1478 <        r.assertNotInvoked();
1478 >        for (IncFunction r : rs) r.assertNotInvoked();
1479      }}
1480  
1481      /**
# Line 1419 | Line 1483 | public class CompletableFutureTest exten
1483       */
1484      public void testThenApply_actionFailed() {
1485          for (ExecutionMode m : ExecutionMode.values())
1422        for (boolean createIncomplete : new boolean[] { true, false })
1486          for (Integer v1 : new Integer[] { 1, null })
1487      {
1488          final CompletableFuture<Integer> f = new CompletableFuture<>();
1489 <        final FailingFunction r = new FailingFunction(m);
1490 <        if (!createIncomplete) assertTrue(f.complete(v1));
1428 <        final CompletableFuture<Integer> g = m.thenApply(f, r);
1429 <        if (createIncomplete) {
1430 <            checkIncomplete(g);
1431 <            assertTrue(f.complete(v1));
1432 <        }
1489 >        final FailingFunction[] rs = new FailingFunction[4];
1490 >        for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
1491  
1492 <        checkCompletedWithWrappedCFException(g);
1492 >        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
1493 >        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
1494 >        assertTrue(f.complete(v1));
1495 >        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
1496 >        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
1497 >
1498 >        checkCompletedWithWrappedCFException(h0);
1499 >        checkCompletedWithWrappedCFException(h1);
1500 >        checkCompletedWithWrappedCFException(h2);
1501 >        checkCompletedWithWrappedCFException(h3);
1502          checkCompletedNormally(f, v1);
1503      }}
1504  
# Line 1440 | Line 1507 | public class CompletableFutureTest exten
1507       */
1508      public void testThenAccept_normalCompletion() {
1509          for (ExecutionMode m : ExecutionMode.values())
1443        for (boolean createIncomplete : new boolean[] { true, false })
1510          for (Integer v1 : new Integer[] { 1, null })
1511      {
1512          final CompletableFuture<Integer> f = new CompletableFuture<>();
1513 <        final NoopConsumer r = new NoopConsumer(m);
1514 <        if (!createIncomplete) assertTrue(f.complete(v1));
1449 <        final CompletableFuture<Void> g = m.thenAccept(f, r);
1450 <        if (createIncomplete) {
1451 <            checkIncomplete(g);
1452 <            assertTrue(f.complete(v1));
1453 <        }
1513 >        final NoopConsumer[] rs = new NoopConsumer[4];
1514 >        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1515  
1516 <        checkCompletedNormally(g, null);
1517 <        r.assertValue(v1);
1516 >        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1517 >        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1518 >        checkIncomplete(h0);
1519 >        checkIncomplete(h1);
1520 >        assertTrue(f.complete(v1));
1521 >        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1522 >        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1523 >
1524 >        checkCompletedNormally(h0, null);
1525 >        checkCompletedNormally(h1, null);
1526 >        checkCompletedNormally(h2, null);
1527 >        checkCompletedNormally(h3, null);
1528          checkCompletedNormally(f, v1);
1529 +        for (NoopConsumer r : rs) r.assertValue(v1);
1530      }}
1531  
1532      /**
# Line 1463 | Line 1535 | public class CompletableFutureTest exten
1535       */
1536      public void testThenAccept_exceptionalCompletion() {
1537          for (ExecutionMode m : ExecutionMode.values())
1466        for (boolean createIncomplete : new boolean[] { true, false })
1538      {
1539          final CFException ex = new CFException();
1540          final CompletableFuture<Integer> f = new CompletableFuture<>();
1541 <        final NoopConsumer r = new NoopConsumer(m);
1542 <        if (!createIncomplete) f.completeExceptionally(ex);
1472 <        final CompletableFuture<Void> g = m.thenAccept(f, r);
1473 <        if (createIncomplete) {
1474 <            checkIncomplete(g);
1475 <            f.completeExceptionally(ex);
1476 <        }
1541 >        final NoopConsumer[] rs = new NoopConsumer[4];
1542 >        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1543  
1544 <        checkCompletedWithWrappedException(g, ex);
1544 >        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1545 >        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1546 >        assertTrue(f.completeExceptionally(ex));
1547 >        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1548 >        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1549 >
1550 >        checkCompletedWithWrappedException(h0, ex);
1551 >        checkCompletedWithWrappedException(h1, ex);
1552 >        checkCompletedWithWrappedException(h2, ex);
1553 >        checkCompletedWithWrappedException(h3, ex);
1554          checkCompletedExceptionally(f, ex);
1555 <        r.assertNotInvoked();
1555 >        for (NoopConsumer r : rs) r.assertNotInvoked();
1556      }}
1557  
1558      /**
# Line 1485 | Line 1560 | public class CompletableFutureTest exten
1560       */
1561      public void testThenAccept_sourceCancelled() {
1562          for (ExecutionMode m : ExecutionMode.values())
1488        for (boolean createIncomplete : new boolean[] { true, false })
1563          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1564      {
1565          final CompletableFuture<Integer> f = new CompletableFuture<>();
1566 <        final NoopConsumer r = new NoopConsumer(m);
1567 <        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1494 <        final CompletableFuture<Void> g = m.thenAccept(f, r);
1495 <        if (createIncomplete) {
1496 <            checkIncomplete(g);
1497 <            assertTrue(f.cancel(mayInterruptIfRunning));
1498 <        }
1566 >        final NoopConsumer[] rs = new NoopConsumer[4];
1567 >        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
1568  
1569 <        checkCompletedWithWrappedCancellationException(g);
1569 >        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1570 >        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1571 >        assertTrue(f.cancel(mayInterruptIfRunning));
1572 >        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1573 >        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1574 >
1575 >        checkCompletedWithWrappedCancellationException(h0);
1576 >        checkCompletedWithWrappedCancellationException(h1);
1577 >        checkCompletedWithWrappedCancellationException(h2);
1578 >        checkCompletedWithWrappedCancellationException(h3);
1579          checkCancelled(f);
1580 <        r.assertNotInvoked();
1580 >        for (NoopConsumer r : rs) r.assertNotInvoked();
1581      }}
1582  
1583      /**
# Line 1507 | Line 1585 | public class CompletableFutureTest exten
1585       */
1586      public void testThenAccept_actionFailed() {
1587          for (ExecutionMode m : ExecutionMode.values())
1510        for (boolean createIncomplete : new boolean[] { true, false })
1588          for (Integer v1 : new Integer[] { 1, null })
1589      {
1590          final CompletableFuture<Integer> f = new CompletableFuture<>();
1591 <        final FailingConsumer r = new FailingConsumer(m);
1592 <        if (!createIncomplete) f.complete(v1);
1516 <        final CompletableFuture<Void> g = m.thenAccept(f, r);
1517 <        if (createIncomplete) {
1518 <            checkIncomplete(g);
1519 <            f.complete(v1);
1520 <        }
1591 >        final FailingConsumer[] rs = new FailingConsumer[4];
1592 >        for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
1593  
1594 <        checkCompletedWithWrappedCFException(g);
1594 >        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
1595 >        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
1596 >        assertTrue(f.complete(v1));
1597 >        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
1598 >        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
1599 >
1600 >        checkCompletedWithWrappedCFException(h0);
1601 >        checkCompletedWithWrappedCFException(h1);
1602 >        checkCompletedWithWrappedCFException(h2);
1603 >        checkCompletedWithWrappedCFException(h3);
1604          checkCompletedNormally(f, v1);
1605      }}
1606  
# Line 1535 | Line 1616 | public class CompletableFutureTest exten
1616      {
1617          final CompletableFuture<Integer> f = new CompletableFuture<>();
1618          final CompletableFuture<Integer> g = new CompletableFuture<>();
1619 <        final SubtractFunction r1 = new SubtractFunction(m);
1620 <        final SubtractFunction r2 = new SubtractFunction(m);
1540 <        final SubtractFunction r3 = new SubtractFunction(m);
1619 >        final SubtractFunction[] rs = new SubtractFunction[6];
1620 >        for (int i = 0; i < rs.length; i++) rs[i] = new SubtractFunction(m);
1621  
1622          final CompletableFuture<Integer> fst =  fFirst ? f : g;
1623          final CompletableFuture<Integer> snd = !fFirst ? f : g;
1624          final Integer w1 =  fFirst ? v1 : v2;
1625          final Integer w2 = !fFirst ? v1 : v2;
1626  
1627 <        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
1627 >        final CompletableFuture<Integer> h0 = m.thenCombine(f, g, rs[0]);
1628 >        final CompletableFuture<Integer> h1 = m.thenCombine(fst, fst, rs[1]);
1629          assertTrue(fst.complete(w1));
1630 <        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
1631 <        checkIncomplete(h1);
1632 <        checkIncomplete(h2);
1633 <        r1.assertNotInvoked();
1634 <        r2.assertNotInvoked();
1630 >        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, rs[2]);
1631 >        final CompletableFuture<Integer> h3 = m.thenCombine(fst, fst, rs[3]);
1632 >        checkIncomplete(h0); rs[0].assertNotInvoked();
1633 >        checkIncomplete(h2); rs[2].assertNotInvoked();
1634 >        checkCompletedNormally(h1, subtract(w1, w1));
1635 >        checkCompletedNormally(h3, subtract(w1, w1));
1636 >        rs[1].assertValue(subtract(w1, w1));
1637 >        rs[3].assertValue(subtract(w1, w1));
1638          assertTrue(snd.complete(w2));
1639 <        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
1639 >        final CompletableFuture<Integer> h4 = m.thenCombine(f, g, rs[4]);
1640  
1641 <        checkCompletedNormally(h1, subtract(v1, v2));
1641 >        checkCompletedNormally(h0, subtract(v1, v2));
1642          checkCompletedNormally(h2, subtract(v1, v2));
1643 <        checkCompletedNormally(h3, subtract(v1, v2));
1644 <        r1.assertValue(subtract(v1, v2));
1645 <        r2.assertValue(subtract(v1, v2));
1646 <        r3.assertValue(subtract(v1, v2));
1643 >        checkCompletedNormally(h4, subtract(v1, v2));
1644 >        rs[0].assertValue(subtract(v1, v2));
1645 >        rs[2].assertValue(subtract(v1, v2));
1646 >        rs[4].assertValue(subtract(v1, v2));
1647 >
1648          checkCompletedNormally(f, v1);
1649          checkCompletedNormally(g, v2);
1650      }}
# Line 1680 | Line 1765 | public class CompletableFutureTest exten
1765          checkCompletedWithWrappedCFException(h1);
1766          checkCompletedWithWrappedCFException(h2);
1767          checkCompletedWithWrappedCFException(h3);
1768 +        r1.assertInvoked();
1769 +        r2.assertInvoked();
1770 +        r3.assertInvoked();
1771          checkCompletedNormally(f, v1);
1772          checkCompletedNormally(g, v2);
1773      }}
# Line 1841 | Line 1929 | public class CompletableFutureTest exten
1929          checkCompletedWithWrappedCFException(h1);
1930          checkCompletedWithWrappedCFException(h2);
1931          checkCompletedWithWrappedCFException(h3);
1932 +        r1.assertInvoked();
1933 +        r2.assertInvoked();
1934 +        r3.assertInvoked();
1935          checkCompletedNormally(f, v1);
1936          checkCompletedNormally(g, v2);
1937      }}
# Line 1851 | Line 1942 | public class CompletableFutureTest exten
1942       */
1943      public void testRunAfterBoth_normalCompletion() {
1944          for (ExecutionMode m : ExecutionMode.values())
1854        for (boolean createIncomplete : new boolean[] { true, false })
1945          for (boolean fFirst : new boolean[] { true, false })
1946          for (Integer v1 : new Integer[] { 1, null })
1947          for (Integer v2 : new Integer[] { 2, null })
1948      {
1949          final CompletableFuture<Integer> f = new CompletableFuture<>();
1950          final CompletableFuture<Integer> g = new CompletableFuture<>();
1951 <        final Noop r = new Noop(m);
1951 >        final Noop r1 = new Noop(m);
1952 >        final Noop r2 = new Noop(m);
1953 >        final Noop r3 = new Noop(m);
1954  
1955 <        assertTrue(fFirst ? f.complete(v1) : g.complete(v2));
1956 <        if (!createIncomplete)
1957 <            assertTrue(!fFirst ? f.complete(v1) : g.complete(v2));
1958 <        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
1867 <        if (createIncomplete) {
1868 <            checkIncomplete(h);
1869 <            r.assertNotInvoked();
1870 <            assertTrue(!fFirst ? f.complete(v1) : g.complete(v2));
1871 <        }
1955 >        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1956 >        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1957 >        final Integer w1 =  fFirst ? v1 : v2;
1958 >        final Integer w2 = !fFirst ? v1 : v2;
1959  
1960 <        checkCompletedNormally(h, null);
1961 <        r.assertInvoked();
1960 >        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
1961 >        assertTrue(fst.complete(w1));
1962 >        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
1963 >        checkIncomplete(h1);
1964 >        checkIncomplete(h2);
1965 >        r1.assertNotInvoked();
1966 >        r2.assertNotInvoked();
1967 >        assertTrue(snd.complete(w2));
1968 >        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
1969 >
1970 >        checkCompletedNormally(h1, null);
1971 >        checkCompletedNormally(h2, null);
1972 >        checkCompletedNormally(h3, null);
1973 >        r1.assertInvoked();
1974 >        r2.assertInvoked();
1975 >        r3.assertInvoked();
1976          checkCompletedNormally(f, v1);
1977          checkCompletedNormally(g, v2);
1978      }}
# Line 1880 | Line 1981 | public class CompletableFutureTest exten
1981       * runAfterBoth result completes exceptionally after exceptional
1982       * completion of either source
1983       */
1984 <    public void testRunAfterBoth_exceptionalCompletion() {
1984 >    public void testRunAfterBoth_exceptionalCompletion() throws Throwable {
1985          for (ExecutionMode m : ExecutionMode.values())
1885        for (boolean createIncomplete : new boolean[] { true, false })
1986          for (boolean fFirst : new boolean[] { true, false })
1987 +        for (boolean failFirst : new boolean[] { true, false })
1988          for (Integer v1 : new Integer[] { 1, null })
1989      {
1990          final CompletableFuture<Integer> f = new CompletableFuture<>();
1991          final CompletableFuture<Integer> g = new CompletableFuture<>();
1992          final CFException ex = new CFException();
1993 <        final Noop r = new Noop(m);
1993 >        final Noop r1 = new Noop(m);
1994 >        final Noop r2 = new Noop(m);
1995 >        final Noop r3 = new Noop(m);
1996  
1997 <        assertTrue((fFirst ? f : g).complete(v1));
1998 <        if (!createIncomplete)
1999 <            assertTrue((!fFirst ? f : g).completeExceptionally(ex));
2000 <        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
2001 <        if (createIncomplete) {
2002 <            checkIncomplete(h);
2003 <            assertTrue((!fFirst ? f : g).completeExceptionally(ex));
2004 <        }
1997 >        final CompletableFuture<Integer> fst =  fFirst ? f : g;
1998 >        final CompletableFuture<Integer> snd = !fFirst ? f : g;
1999 >        final Callable<Boolean> complete1 = failFirst ?
2000 >            () -> fst.completeExceptionally(ex) :
2001 >            () -> fst.complete(v1);
2002 >        final Callable<Boolean> complete2 = failFirst ?
2003 >            () -> snd.complete(v1) :
2004 >            () -> snd.completeExceptionally(ex);
2005  
2006 <        checkCompletedWithWrappedException(h, ex);
2007 <        r.assertNotInvoked();
2008 <        checkCompletedNormally(fFirst ? f : g, v1);
2009 <        checkCompletedExceptionally(!fFirst ? f : g, ex);
2006 >        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2007 >        assertTrue(complete1.call());
2008 >        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2009 >        checkIncomplete(h1);
2010 >        checkIncomplete(h2);
2011 >        assertTrue(complete2.call());
2012 >        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2013 >
2014 >        checkCompletedWithWrappedException(h1, ex);
2015 >        checkCompletedWithWrappedException(h2, ex);
2016 >        checkCompletedWithWrappedException(h3, ex);
2017 >        r1.assertNotInvoked();
2018 >        r2.assertNotInvoked();
2019 >        r3.assertNotInvoked();
2020 >        checkCompletedNormally(failFirst ? snd : fst, v1);
2021 >        checkCompletedExceptionally(failFirst ? fst : snd, ex);
2022      }}
2023  
2024      /**
2025       * runAfterBoth result completes exceptionally if either source cancelled
2026       */
2027 <    public void testRunAfterBoth_sourceCancelled() {
2027 >    public void testRunAfterBoth_sourceCancelled() throws Throwable {
2028          for (ExecutionMode m : ExecutionMode.values())
2029          for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1915        for (boolean createIncomplete : new boolean[] { true, false })
2030          for (boolean fFirst : new boolean[] { true, false })
2031 +        for (boolean failFirst : new boolean[] { true, false })
2032          for (Integer v1 : new Integer[] { 1, null })
2033      {
2034          final CompletableFuture<Integer> f = new CompletableFuture<>();
2035          final CompletableFuture<Integer> g = new CompletableFuture<>();
2036 <        final Noop r = new Noop(m);
2036 >        final Noop r1 = new Noop(m);
2037 >        final Noop r2 = new Noop(m);
2038 >        final Noop r3 = new Noop(m);
2039  
2040 <        assertTrue((fFirst ? f : g).complete(v1));
2041 <        if (!createIncomplete)
2042 <            assertTrue((!fFirst ? f : g).cancel(mayInterruptIfRunning));
2043 <        final CompletableFuture<Void> h = m.runAfterBoth(f, g, r);
2044 <        if (createIncomplete) {
2045 <            checkIncomplete(h);
2046 <            assertTrue((!fFirst ? f : g).cancel(mayInterruptIfRunning));
2047 <        }
2040 >        final CompletableFuture<Integer> fst =  fFirst ? f : g;
2041 >        final CompletableFuture<Integer> snd = !fFirst ? f : g;
2042 >        final Callable<Boolean> complete1 = failFirst ?
2043 >            () -> fst.cancel(mayInterruptIfRunning) :
2044 >            () -> fst.complete(v1);
2045 >        final Callable<Boolean> complete2 = failFirst ?
2046 >            () -> snd.complete(v1) :
2047 >            () -> snd.cancel(mayInterruptIfRunning);
2048  
2049 <        checkCompletedWithWrappedCancellationException(h);
2050 <        checkCancelled(!fFirst ? f : g);
2051 <        r.assertNotInvoked();
2052 <        checkCompletedNormally(fFirst ? f : g, v1);
2049 >        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2050 >        assertTrue(complete1.call());
2051 >        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2052 >        checkIncomplete(h1);
2053 >        checkIncomplete(h2);
2054 >        assertTrue(complete2.call());
2055 >        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2056 >
2057 >        checkCompletedWithWrappedCancellationException(h1);
2058 >        checkCompletedWithWrappedCancellationException(h2);
2059 >        checkCompletedWithWrappedCancellationException(h3);
2060 >        r1.assertNotInvoked();
2061 >        r2.assertNotInvoked();
2062 >        r3.assertNotInvoked();
2063 >        checkCompletedNormally(failFirst ? snd : fst, v1);
2064 >        checkCancelled(failFirst ? fst : snd);
2065      }}
2066  
2067      /**
# Line 1948 | Line 2077 | public class CompletableFutureTest exten
2077          final CompletableFuture<Integer> g = new CompletableFuture<>();
2078          final FailingRunnable r1 = new FailingRunnable(m);
2079          final FailingRunnable r2 = new FailingRunnable(m);
2080 +        final FailingRunnable r3 = new FailingRunnable(m);
2081  
2082 <        CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2083 <        assertTrue(fFirst ? f.complete(v1) : g.complete(v2));
2084 <        assertTrue(!fFirst ? f.complete(v1) : g.complete(v2));
2085 <        CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2082 >        final CompletableFuture<Integer> fst =  fFirst ? f : g;
2083 >        final CompletableFuture<Integer> snd = !fFirst ? f : g;
2084 >        final Integer w1 =  fFirst ? v1 : v2;
2085 >        final Integer w2 = !fFirst ? v1 : v2;
2086 >
2087 >        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
2088 >        assertTrue(fst.complete(w1));
2089 >        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
2090 >        assertTrue(snd.complete(w2));
2091 >        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
2092  
2093          checkCompletedWithWrappedCFException(h1);
2094          checkCompletedWithWrappedCFException(h2);
2095 +        checkCompletedWithWrappedCFException(h3);
2096 +        r1.assertInvoked();
2097 +        r2.assertInvoked();
2098 +        r3.assertInvoked();
2099          checkCompletedNormally(f, v1);
2100          checkCompletedNormally(g, v2);
2101      }}
# Line 2851 | Line 2991 | public class CompletableFutureTest exten
2991          checkCancelled(f);
2992      }}
2993  
2994 +    /**
2995 +     * thenCompose result completes exceptionally if the result of the action does
2996 +     */
2997 +    public void testThenCompose_actionReturnsFailingFuture() {
2998 +        for (ExecutionMode m : ExecutionMode.values())
2999 +        for (int order = 0; order < 6; order++)
3000 +        for (Integer v1 : new Integer[] { 1, null })
3001 +    {
3002 +        final CFException ex = new CFException();
3003 +        final CompletableFuture<Integer> f = new CompletableFuture<>();
3004 +        final CompletableFuture<Integer> g = new CompletableFuture<>();
3005 +        final CompletableFuture<Integer> h;
3006 +        // Test all permutations of orders
3007 +        switch (order) {
3008 +        case 0:
3009 +            assertTrue(f.complete(v1));
3010 +            assertTrue(g.completeExceptionally(ex));
3011 +            h = m.thenCompose(f, (x -> g));
3012 +            break;
3013 +        case 1:
3014 +            assertTrue(f.complete(v1));
3015 +            h = m.thenCompose(f, (x -> g));
3016 +            assertTrue(g.completeExceptionally(ex));
3017 +            break;
3018 +        case 2:
3019 +            assertTrue(g.completeExceptionally(ex));
3020 +            assertTrue(f.complete(v1));
3021 +            h = m.thenCompose(f, (x -> g));
3022 +            break;
3023 +        case 3:
3024 +            assertTrue(g.completeExceptionally(ex));
3025 +            h = m.thenCompose(f, (x -> g));
3026 +            assertTrue(f.complete(v1));
3027 +            break;
3028 +        case 4:
3029 +            h = m.thenCompose(f, (x -> g));
3030 +            assertTrue(f.complete(v1));
3031 +            assertTrue(g.completeExceptionally(ex));
3032 +            break;
3033 +        case 5:
3034 +            h = m.thenCompose(f, (x -> g));
3035 +            assertTrue(f.complete(v1));
3036 +            assertTrue(g.completeExceptionally(ex));
3037 +            break;
3038 +        default: throw new AssertionError();
3039 +        }
3040 +
3041 +        checkCompletedExceptionally(g, ex);
3042 +        checkCompletedWithWrappedException(h, ex);
3043 +        checkCompletedNormally(f, v1);
3044 +    }}
3045 +
3046      // other static methods
3047  
3048      /**
# Line 2867 | Line 3059 | public class CompletableFutureTest exten
3059       * when all components complete normally
3060       */
3061      public void testAllOf_normal() throws Exception {
3062 <        for (int k = 1; k < 20; ++k) {
3062 >        for (int k = 1; k < 10; k++) {
3063              CompletableFuture<Integer>[] fs
3064                  = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3065 <            for (int i = 0; i < k; ++i)
3065 >            for (int i = 0; i < k; i++)
3066                  fs[i] = new CompletableFuture<>();
3067              CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3068 <            for (int i = 0; i < k; ++i) {
3068 >            for (int i = 0; i < k; i++) {
3069                  checkIncomplete(f);
3070                  checkIncomplete(CompletableFuture.allOf(fs));
3071                  fs[i].complete(one);
# Line 2884 | Line 3076 | public class CompletableFutureTest exten
3076      }
3077  
3078      public void testAllOf_backwards() throws Exception {
3079 <        for (int k = 1; k < 20; ++k) {
3079 >        for (int k = 1; k < 10; k++) {
3080              CompletableFuture<Integer>[] fs
3081                  = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3082 <            for (int i = 0; i < k; ++i)
3082 >            for (int i = 0; i < k; i++)
3083                  fs[i] = new CompletableFuture<>();
3084              CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3085              for (int i = k - 1; i >= 0; i--) {
# Line 2900 | Line 3092 | public class CompletableFutureTest exten
3092          }
3093      }
3094  
3095 +    public void testAllOf_exceptional() throws Exception {
3096 +        for (int k = 1; k < 10; k++) {
3097 +            CompletableFuture<Integer>[] fs
3098 +                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
3099 +            CFException ex = new CFException();
3100 +            for (int i = 0; i < k; i++)
3101 +                fs[i] = new CompletableFuture<>();
3102 +            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
3103 +            for (int i = 0; i < k; i++) {
3104 +                checkIncomplete(f);
3105 +                checkIncomplete(CompletableFuture.allOf(fs));
3106 +                if (i != k/2) {
3107 +                    fs[i].complete(i);
3108 +                    checkCompletedNormally(fs[i], i);
3109 +                } else {
3110 +                    fs[i].completeExceptionally(ex);
3111 +                    checkCompletedExceptionally(fs[i], ex);
3112 +                }
3113 +            }
3114 +            checkCompletedWithWrappedException(f, ex);
3115 +            checkCompletedWithWrappedException(CompletableFuture.allOf(fs), ex);
3116 +        }
3117 +    }
3118 +
3119      /**
3120       * anyOf(no component futures) returns an incomplete future
3121       */
3122      public void testAnyOf_empty() throws Exception {
3123 +        for (Integer v1 : new Integer[] { 1, null })
3124 +    {
3125          CompletableFuture<Object> f = CompletableFuture.anyOf();
3126          checkIncomplete(f);
3127 <    }
3127 >
3128 >        f.complete(v1);
3129 >        checkCompletedNormally(f, v1);
3130 >    }}
3131  
3132      /**
3133       * anyOf returns a future completed normally with a value when
3134       * a component future does
3135       */
3136      public void testAnyOf_normal() throws Exception {
3137 <        for (int k = 0; k < 10; ++k) {
3137 >        for (int k = 0; k < 10; k++) {
3138              CompletableFuture[] fs = new CompletableFuture[k];
3139 <            for (int i = 0; i < k; ++i)
3139 >            for (int i = 0; i < k; i++)
3140                  fs[i] = new CompletableFuture<>();
3141              CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3142              checkIncomplete(f);
3143 <            for (int i = 0; i < k; ++i) {
3144 <                fs[i].complete(one);
3145 <                checkCompletedNormally(f, one);
3146 <                checkCompletedNormally(CompletableFuture.anyOf(fs), one);
3143 >            for (int i = 0; i < k; i++) {
3144 >                fs[i].complete(i);
3145 >                checkCompletedNormally(f, 0);
3146 >                int x = (int) CompletableFuture.anyOf(fs).join();
3147 >                assertTrue(0 <= x && x <= i);
3148 >            }
3149 >        }
3150 >    }
3151 >    public void testAnyOf_normal_backwards() throws Exception {
3152 >        for (int k = 0; k < 10; k++) {
3153 >            CompletableFuture[] fs = new CompletableFuture[k];
3154 >            for (int i = 0; i < k; i++)
3155 >                fs[i] = new CompletableFuture<>();
3156 >            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3157 >            checkIncomplete(f);
3158 >            for (int i = k - 1; i >= 0; i--) {
3159 >                fs[i].complete(i);
3160 >                checkCompletedNormally(f, k - 1);
3161 >                int x = (int) CompletableFuture.anyOf(fs).join();
3162 >                assertTrue(i <= x && x <= k - 1);
3163              }
3164          }
3165      }
# Line 2931 | Line 3168 | public class CompletableFutureTest exten
3168       * anyOf result completes exceptionally when any component does.
3169       */
3170      public void testAnyOf_exceptional() throws Exception {
3171 <        for (int k = 0; k < 10; ++k) {
3171 >        for (int k = 0; k < 10; k++) {
3172 >            CompletableFuture[] fs = new CompletableFuture[k];
3173 >            CFException[] exs = new CFException[k];
3174 >            for (int i = 0; i < k; i++) {
3175 >                fs[i] = new CompletableFuture<>();
3176 >                exs[i] = new CFException();
3177 >            }
3178 >            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3179 >            checkIncomplete(f);
3180 >            for (int i = 0; i < k; i++) {
3181 >                fs[i].completeExceptionally(exs[i]);
3182 >                checkCompletedWithWrappedException(f, exs[0]);
3183 >                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3184 >            }
3185 >        }
3186 >    }
3187 >
3188 >    public void testAnyOf_exceptional_backwards() throws Exception {
3189 >        for (int k = 0; k < 10; k++) {
3190              CompletableFuture[] fs = new CompletableFuture[k];
3191 <            for (int i = 0; i < k; ++i)
3191 >            CFException[] exs = new CFException[k];
3192 >            for (int i = 0; i < k; i++) {
3193                  fs[i] = new CompletableFuture<>();
3194 +                exs[i] = new CFException();
3195 +            }
3196              CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
3197              checkIncomplete(f);
3198 <            for (int i = 0; i < k; ++i) {
3199 <                fs[i].completeExceptionally(new CFException());
3200 <                checkCompletedWithWrappedCFException(f);
3198 >            for (int i = k - 1; i >= 0; i--) {
3199 >                fs[i].completeExceptionally(exs[i]);
3200 >                checkCompletedWithWrappedException(f, exs[k - 1]);
3201                  checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
3202              }
3203          }
# Line 2952 | Line 3210 | public class CompletableFutureTest exten
3210          CompletableFuture<Integer> f = new CompletableFuture<>();
3211          CompletableFuture<Integer> g = new CompletableFuture<>();
3212          CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
2955        CompletableFuture<?> h;
3213          ThreadExecutor exec = new ThreadExecutor();
3214  
3215          Runnable[] throwingActions = {
3216              () -> CompletableFuture.supplyAsync(null),
3217              () -> CompletableFuture.supplyAsync(null, exec),
3218 <            () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.DEFAULT, 42), null),
3218 >            () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.SYNC, 42), null),
3219  
3220              () -> CompletableFuture.runAsync(null),
3221              () -> CompletableFuture.runAsync(null, exec),
# Line 3063 | Line 3320 | public class CompletableFutureTest exten
3320          assertSame(f, f.toCompletableFuture());
3321      }
3322  
3323 < //     public void testRunAfterEither_resultDeterminedAtTimeOfCreation() {
3324 < //         for (ExecutionMode m : ExecutionMode.values())
3325 < //         for (boolean mayInterruptIfRunning : new boolean[] { true, false })
3326 < //         for (Integer v1 : new Integer[] { 1, null })
3327 < //     {
3328 < //         final CompletableFuture<Integer> f = new CompletableFuture<>();
3329 < //         final CompletableFuture<Integer> g = new CompletableFuture<>();
3330 < //         final Noop[] rs = new Noop[2];
3331 < //         for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
3332 < //         f.complete(v1);
3333 < //         final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
3334 < //         final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
3335 < //         assertTrue(g.cancel(mayInterruptIfRunning));
3336 < //         checkCompletedNormally(h0, null);
3337 < //         checkCompletedNormally(h1, null);
3338 < //         for (Noop r : rs) r.assertInvoked();
3339 < //     }}
3323 >    //--- tests of implementation details; not part of official tck ---
3324 >
3325 >    Object resultOf(CompletableFuture<?> f) {
3326 >        try {
3327 >            java.lang.reflect.Field resultField
3328 >                = CompletableFuture.class.getDeclaredField("result");
3329 >            resultField.setAccessible(true);
3330 >            return resultField.get(f);
3331 >        } catch (Throwable t) { throw new AssertionError(t); }
3332 >    }
3333 >
3334 >    public void testExceptionPropagationReusesResultObject() {
3335 >        if (!testImplementationDetails) return;
3336 >        for (ExecutionMode m : ExecutionMode.values())
3337 >    {
3338 >        final CFException ex = new CFException();
3339 >        final CompletableFuture<Integer> v42 = CompletableFuture.completedFuture(42);
3340 >        final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
3341 >
3342 >        List<Function<CompletableFuture<Integer>, CompletableFuture<?>>> funs
3343 >            = new ArrayList<>();
3344 >
3345 >        funs.add((y) -> m.thenRun(y, new Noop(m)));
3346 >        funs.add((y) -> m.thenAccept(y, new NoopConsumer(m)));
3347 >        funs.add((y) -> m.thenApply(y, new IncFunction(m)));
3348 >
3349 >        funs.add((y) -> m.runAfterEither(y, incomplete, new Noop(m)));
3350 >        funs.add((y) -> m.acceptEither(y, incomplete, new NoopConsumer(m)));
3351 >        funs.add((y) -> m.applyToEither(y, incomplete, new IncFunction(m)));
3352 >
3353 >        funs.add((y) -> m.runAfterBoth(y, v42, new Noop(m)));
3354 >        funs.add((y) -> m.thenAcceptBoth(y, v42, new SubtractAction(m)));
3355 >        funs.add((y) -> m.thenCombine(y, v42, new SubtractFunction(m)));
3356 >
3357 >        funs.add((y) -> m.whenComplete(y, (Integer x, Throwable t) -> {}));
3358 >
3359 >        funs.add((y) -> m.thenCompose(y, new CompletableFutureInc(m)));
3360 >
3361 >        funs.add((y) -> CompletableFuture.allOf(new CompletableFuture<?>[] {y, v42}));
3362 >        funs.add((y) -> CompletableFuture.anyOf(new CompletableFuture<?>[] {y, incomplete}));
3363 >
3364 >        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3365 >                 fun : funs) {
3366 >            CompletableFuture<Integer> f = new CompletableFuture<>();
3367 >            f.completeExceptionally(ex);
3368 >            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3369 >            checkCompletedWithWrappedException(src, ex);
3370 >            CompletableFuture<?> dep = fun.apply(src);
3371 >            checkCompletedWithWrappedException(dep, ex);
3372 >            assertSame(resultOf(src), resultOf(dep));
3373 >        }
3374 >
3375 >        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3376 >                 fun : funs) {
3377 >            CompletableFuture<Integer> f = new CompletableFuture<>();
3378 >            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3379 >            CompletableFuture<?> dep = fun.apply(src);
3380 >            f.completeExceptionally(ex);
3381 >            checkCompletedWithWrappedException(src, ex);
3382 >            checkCompletedWithWrappedException(dep, ex);
3383 >            assertSame(resultOf(src), resultOf(dep));
3384 >        }
3385 >
3386 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
3387 >        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3388 >                 fun : funs) {
3389 >            CompletableFuture<Integer> f = new CompletableFuture<>();
3390 >            f.cancel(mayInterruptIfRunning);
3391 >            checkCancelled(f);
3392 >            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3393 >            checkCompletedWithWrappedCancellationException(src);
3394 >            CompletableFuture<?> dep = fun.apply(src);
3395 >            checkCompletedWithWrappedCancellationException(dep);
3396 >            assertSame(resultOf(src), resultOf(dep));
3397 >        }
3398 >
3399 >        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
3400 >        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
3401 >                 fun : funs) {
3402 >            CompletableFuture<Integer> f = new CompletableFuture<>();
3403 >            CompletableFuture<Integer> src = m.thenApply(f, new IncFunction(m));
3404 >            CompletableFuture<?> dep = fun.apply(src);
3405 >            f.cancel(mayInterruptIfRunning);
3406 >            checkCancelled(f);
3407 >            checkCompletedWithWrappedCancellationException(src);
3408 >            checkCompletedWithWrappedCancellationException(dep);
3409 >            assertSame(resultOf(src), resultOf(dep));
3410 >        }
3411 >    }}
3412  
3413   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines