936 (CompletableFuture<T> f,
937 CompletionStage<? extends T> g,
938 Function<? super T,U> a);
939 public abstract <T> CompletableFuture<T> exceptionally
940 (CompletableFuture<T> f,
941 Function<Throwable, ? extends T> fn);
942 public abstract <T> CompletableFuture<T> exceptionallyCompose
943 (CompletableFuture<T> f,
944 Function<Throwable, ? extends CompletionStage<T>> fn);
945 }
946
947 /**
948 * exceptionally action is not invoked when source completes
949 * normally, and source result is propagated
950 */
951 public void testExceptionally_normalCompletion() {
952 for (ExecutionMode m : ExecutionMode.values())
953 for (boolean createIncomplete : new boolean[] { true, false })
954 for (Integer v1 : new Integer[] { 1, null })
955 {
956 final CompletableFuture<Integer> f = new CompletableFuture<>();
957 if (!createIncomplete) assertTrue(f.complete(v1));
958 final CompletableFuture<Integer> g = m.exceptionally
959 (f, (Throwable t) -> {
960 threadFail("should not be called");
961 return null; // unreached
962 });
963 if (createIncomplete) assertTrue(f.complete(v1));
964
965 checkCompletedNormally(g, v1);
966 checkCompletedNormally(f, v1);
967 }}
968
969 /**
970 * exceptionally action completes with function value on source
971 * exception
972 */
973 public void testExceptionally_exceptionalCompletion() {
974 for (ExecutionMode m : ExecutionMode.values())
975 for (boolean createIncomplete : new boolean[] { true, false })
976 for (Integer v1 : new Integer[] { 1, null })
977 {
978 final AtomicInteger a = new AtomicInteger(0);
979 final CFException ex = new CFException();
980 final CompletableFuture<Integer> f = new CompletableFuture<>();
981 if (!createIncomplete) f.completeExceptionally(ex);
982 final CompletableFuture<Integer> g = m.exceptionally
983 (f, (Throwable t) -> {
984 m.checkExecutionMode();
985 threadAssertSame(t, ex);
986 a.getAndIncrement();
987 return v1;
988 });
989 if (createIncomplete) f.completeExceptionally(ex);
990
991 checkCompletedNormally(g, v1);
992 assertEquals(1, a.get());
993 }}
994
995 /**
996 * If an "exceptionally action" throws an exception, it completes
997 * exceptionally with that exception
998 */
999 public void testExceptionally_exceptionalCompletionActionFailed() {
1000 for (ExecutionMode m : ExecutionMode.values())
1001 for (boolean createIncomplete : new boolean[] { true, false })
1002 {
1003 final AtomicInteger a = new AtomicInteger(0);
1004 final CFException ex1 = new CFException();
1005 final CFException ex2 = new CFException();
1006 final CompletableFuture<Integer> f = new CompletableFuture<>();
1007 if (!createIncomplete) f.completeExceptionally(ex1);
1008 final CompletableFuture<Integer> g = m.exceptionally
1009 (f, (Throwable t) -> {
1010 m.checkExecutionMode();
1011 threadAssertSame(t, ex1);
1012 a.getAndIncrement();
1013 throw ex2;
1014 });
1015 if (createIncomplete) f.completeExceptionally(ex1);
1016
1017 checkCompletedWithWrappedException(g, ex2);
1018 checkCompletedExceptionally(f, ex1);
1019 assertEquals(1, a.get());
1020 }}
1021
1022 /**
1023 * whenComplete action executes on normal completion, propagating
1024 * source result.
1025 */
1026 public void testWhenComplete_normalCompletion() {
1027 for (ExecutionMode m : ExecutionMode.values())
1028 for (boolean createIncomplete : new boolean[] { true, false })
1029 for (Integer v1 : new Integer[] { 1, null })
1030 {
1031 final AtomicInteger a = new AtomicInteger(0);
1032 final CompletableFuture<Integer> f = new CompletableFuture<>();
1033 if (!createIncomplete) assertTrue(f.complete(v1));
1034 final CompletableFuture<Integer> g = m.whenComplete
1035 (f,
1036 (Integer result, Throwable t) -> {
1037 m.checkExecutionMode();
1038 threadAssertSame(result, v1);
1039 threadAssertNull(t);
1040 a.getAndIncrement();
1041 });
1042 if (createIncomplete) assertTrue(f.complete(v1));
1043
1044 checkCompletedNormally(g, v1);
1045 checkCompletedNormally(f, v1);
1046 assertEquals(1, a.get());
1047 }}
1048
1049 /**
1050 * whenComplete action executes on exceptional completion, propagating
1051 * source result.
1052 */
1053 public void testWhenComplete_exceptionalCompletion() {
1054 for (ExecutionMode m : ExecutionMode.values())
1055 for (boolean createIncomplete : new boolean[] { true, false })
1056 {
1057 final AtomicInteger a = new AtomicInteger(0);
1058 final CFException ex = new CFException();
1059 final CompletableFuture<Integer> f = new CompletableFuture<>();
1060 if (!createIncomplete) f.completeExceptionally(ex);
1061 final CompletableFuture<Integer> g = m.whenComplete
1062 (f,
1063 (Integer result, Throwable t) -> {
1064 m.checkExecutionMode();
1065 threadAssertNull(result);
1066 threadAssertSame(t, ex);
1067 a.getAndIncrement();
1068 });
1069 if (createIncomplete) f.completeExceptionally(ex);
1070
1071 checkCompletedWithWrappedException(g, ex);
1072 checkCompletedExceptionally(f, ex);
1073 assertEquals(1, a.get());
1074 }}
1075
1076 /**
1077 * whenComplete action executes on cancelled source, propagating
1078 * CancellationException.
1079 */
1080 public void testWhenComplete_sourceCancelled() {
1081 for (ExecutionMode m : ExecutionMode.values())
1082 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1083 for (boolean createIncomplete : new boolean[] { true, false })
1084 {
1085 final AtomicInteger a = new AtomicInteger(0);
1086 final CompletableFuture<Integer> f = new CompletableFuture<>();
1087 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1088 final CompletableFuture<Integer> g = m.whenComplete
1089 (f,
1090 (Integer result, Throwable t) -> {
1091 m.checkExecutionMode();
1092 threadAssertNull(result);
1093 threadAssertTrue(t instanceof CancellationException);
1094 a.getAndIncrement();
1095 });
1096 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1097
1098 checkCompletedWithWrappedCancellationException(g);
1099 checkCancelled(f);
1100 assertEquals(1, a.get());
1101 }}
1102
1103 /**
1104 * If a whenComplete action throws an exception when triggered by
1105 * a normal completion, it completes exceptionally
1106 */
1107 public void testWhenComplete_sourceCompletedNormallyActionFailed() {
1108 for (boolean createIncomplete : new boolean[] { true, false })
1109 for (ExecutionMode m : ExecutionMode.values())
1110 for (Integer v1 : new Integer[] { 1, null })
1111 {
1112 final AtomicInteger a = new AtomicInteger(0);
1113 final CFException ex = new CFException();
1114 final CompletableFuture<Integer> f = new CompletableFuture<>();
1115 if (!createIncomplete) assertTrue(f.complete(v1));
1116 final CompletableFuture<Integer> g = m.whenComplete
1117 (f,
1118 (Integer result, Throwable t) -> {
1119 m.checkExecutionMode();
1120 threadAssertSame(result, v1);
1121 threadAssertNull(t);
1122 a.getAndIncrement();
1123 throw ex;
1124 });
1125 if (createIncomplete) assertTrue(f.complete(v1));
1126
1127 checkCompletedWithWrappedException(g, ex);
1128 checkCompletedNormally(f, v1);
1129 assertEquals(1, a.get());
1130 }}
1131
1132 /**
1133 * If a whenComplete action throws an exception when triggered by
1134 * a source completion that also throws an exception, the source
1135 * exception takes precedence (unlike handle)
1136 */
1137 public void testWhenComplete_sourceFailedActionFailed() {
1138 for (boolean createIncomplete : new boolean[] { true, false })
1139 for (ExecutionMode m : ExecutionMode.values())
1140 {
1141 final AtomicInteger a = new AtomicInteger(0);
1142 final CFException ex1 = new CFException();
1143 final CFException ex2 = new CFException();
1144 final CompletableFuture<Integer> f = new CompletableFuture<>();
1145
1146 if (!createIncomplete) f.completeExceptionally(ex1);
1147 final CompletableFuture<Integer> g = m.whenComplete
1148 (f,
1149 (Integer result, Throwable t) -> {
1150 m.checkExecutionMode();
1151 threadAssertSame(t, ex1);
1152 threadAssertNull(result);
1153 a.getAndIncrement();
1154 throw ex2;
1155 });
1156 if (createIncomplete) f.completeExceptionally(ex1);
1157
1158 checkCompletedWithWrappedException(g, ex1);
1159 checkCompletedExceptionally(f, ex1);
1160 if (testImplementationDetails) {
1161 assertEquals(1, ex1.getSuppressed().length);
1162 assertSame(ex2, ex1.getSuppressed()[0]);
1163 }
1164 assertEquals(1, a.get());
1165 }}
1166
1167 /**
1168 * handle action completes normally with function value on normal
1169 * completion of source
1170 */
1171 public void testHandle_normalCompletion() {
1172 for (ExecutionMode m : ExecutionMode.values())
1173 for (boolean createIncomplete : new boolean[] { true, false })
1174 for (Integer v1 : new Integer[] { 1, null })
1175 {
1176 final CompletableFuture<Integer> f = new CompletableFuture<>();
1177 final AtomicInteger a = new AtomicInteger(0);
1178 if (!createIncomplete) assertTrue(f.complete(v1));
1179 final CompletableFuture<Integer> g = m.handle
1180 (f,
1181 (Integer result, Throwable t) -> {
1182 m.checkExecutionMode();
1183 threadAssertSame(result, v1);
1184 threadAssertNull(t);
1185 a.getAndIncrement();
1186 return inc(v1);
1187 });
1188 if (createIncomplete) assertTrue(f.complete(v1));
1189
1190 checkCompletedNormally(g, inc(v1));
1191 checkCompletedNormally(f, v1);
1192 assertEquals(1, a.get());
1193 }}
1194
1195 /**
1196 * handle action completes normally with function value on
1197 * exceptional completion of source
1198 */
1199 public void testHandle_exceptionalCompletion() {
1200 for (ExecutionMode m : ExecutionMode.values())
1201 for (boolean createIncomplete : new boolean[] { true, false })
1202 for (Integer v1 : new Integer[] { 1, null })
1203 {
1204 final CompletableFuture<Integer> f = new CompletableFuture<>();
1205 final AtomicInteger a = new AtomicInteger(0);
1206 final CFException ex = new CFException();
1207 if (!createIncomplete) f.completeExceptionally(ex);
1208 final CompletableFuture<Integer> g = m.handle
1209 (f,
1210 (Integer result, Throwable t) -> {
1211 m.checkExecutionMode();
1212 threadAssertNull(result);
1213 threadAssertSame(t, ex);
1214 a.getAndIncrement();
1215 return v1;
1216 });
1217 if (createIncomplete) f.completeExceptionally(ex);
1218
1219 checkCompletedNormally(g, v1);
1220 checkCompletedExceptionally(f, ex);
1221 assertEquals(1, a.get());
1222 }}
1223
1224 /**
1225 * handle action completes normally with function value on
1226 * cancelled source
1227 */
1228 public void testHandle_sourceCancelled() {
1229 for (ExecutionMode m : ExecutionMode.values())
1230 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1231 for (boolean createIncomplete : new boolean[] { true, false })
1232 for (Integer v1 : new Integer[] { 1, null })
1233 {
1234 final CompletableFuture<Integer> f = new CompletableFuture<>();
1235 final AtomicInteger a = new AtomicInteger(0);
1236 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1237 final CompletableFuture<Integer> g = m.handle
1238 (f,
1239 (Integer result, Throwable t) -> {
1240 m.checkExecutionMode();
1241 threadAssertNull(result);
1242 threadAssertTrue(t instanceof CancellationException);
1243 a.getAndIncrement();
1244 return v1;
1245 });
1246 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1247
1248 checkCompletedNormally(g, v1);
1249 checkCancelled(f);
1250 assertEquals(1, a.get());
1251 }}
1252
1253 /**
1254 * If a "handle action" throws an exception when triggered by
1255 * a normal completion, it completes exceptionally
1256 */
1257 public void testHandle_sourceCompletedNormallyActionFailed() {
1258 for (ExecutionMode m : ExecutionMode.values())
1259 for (boolean createIncomplete : new boolean[] { true, false })
1260 for (Integer v1 : new Integer[] { 1, null })
1261 {
1262 final CompletableFuture<Integer> f = new CompletableFuture<>();
1263 final AtomicInteger a = new AtomicInteger(0);
1264 final CFException ex = new CFException();
1265 if (!createIncomplete) assertTrue(f.complete(v1));
1266 final CompletableFuture<Integer> g = m.handle
1267 (f,
1268 (Integer result, Throwable t) -> {
1269 m.checkExecutionMode();
1270 threadAssertSame(result, v1);
1271 threadAssertNull(t);
1272 a.getAndIncrement();
1273 throw ex;
1274 });
1275 if (createIncomplete) assertTrue(f.complete(v1));
1276
1277 checkCompletedWithWrappedException(g, ex);
1278 checkCompletedNormally(f, v1);
1279 assertEquals(1, a.get());
1280 }}
1281
1282 /**
1283 * If a "handle action" throws an exception when triggered by
1284 * a source completion that also throws an exception, the action
1285 * exception takes precedence (unlike whenComplete)
1286 */
1287 public void testHandle_sourceFailedActionFailed() {
1288 for (boolean createIncomplete : new boolean[] { true, false })
1289 for (ExecutionMode m : ExecutionMode.values())
1290 {
1291 final AtomicInteger a = new AtomicInteger(0);
1292 final CFException ex1 = new CFException();
1293 final CFException ex2 = new CFException();
1294 final CompletableFuture<Integer> f = new CompletableFuture<>();
1295
1296 if (!createIncomplete) f.completeExceptionally(ex1);
1297 final CompletableFuture<Integer> g = m.handle
1298 (f,
1299 (Integer result, Throwable t) -> {
1300 m.checkExecutionMode();
1301 threadAssertNull(result);
1302 threadAssertSame(ex1, t);
1303 a.getAndIncrement();
1304 throw ex2;
1305 });
1306 if (createIncomplete) f.completeExceptionally(ex1);
1307
1308 checkCompletedWithWrappedException(g, ex2);
1309 checkCompletedExceptionally(f, ex1);
1310 assertEquals(1, a.get());
1311 }}
1312
1313 /**
1314 * runAsync completes after running Runnable
1315 */
1316 public void testRunAsync_normalCompletion() {
1317 ExecutionMode[] executionModes = {
1318 ExecutionMode.ASYNC,
1319 ExecutionMode.EXECUTOR,
1320 };
1321 for (ExecutionMode m : executionModes)
1322 {
1323 final Noop r = new Noop(m);
1324 final CompletableFuture<Void> f = m.runAsync(r);
1325 assertNull(f.join());
1326 checkCompletedNormally(f, null);
1327 r.assertInvoked();
1328 }}
1329
1330 /**
3126 checkCancelled(f);
3127 }}
3128
3129 /**
3130 * thenCompose result completes exceptionally if the result of the action does
3131 */
3132 public void testThenCompose_actionReturnsFailingFuture() {
3133 for (ExecutionMode m : ExecutionMode.values())
3134 for (int order = 0; order < 6; order++)
3135 for (Integer v1 : new Integer[] { 1, null })
3136 {
3137 final CFException ex = new CFException();
3138 final CompletableFuture<Integer> f = new CompletableFuture<>();
3139 final CompletableFuture<Integer> g = new CompletableFuture<>();
3140 final CompletableFuture<Integer> h;
3141 // Test all permutations of orders
3142 switch (order) {
3143 case 0:
3144 assertTrue(f.complete(v1));
3145 assertTrue(g.completeExceptionally(ex));
3146 h = m.thenCompose(f, (x -> g));
3147 break;
3148 case 1:
3149 assertTrue(f.complete(v1));
3150 h = m.thenCompose(f, (x -> g));
3151 assertTrue(g.completeExceptionally(ex));
3152 break;
3153 case 2:
3154 assertTrue(g.completeExceptionally(ex));
3155 assertTrue(f.complete(v1));
3156 h = m.thenCompose(f, (x -> g));
3157 break;
3158 case 3:
3159 assertTrue(g.completeExceptionally(ex));
3160 h = m.thenCompose(f, (x -> g));
3161 assertTrue(f.complete(v1));
3162 break;
3163 case 4:
3164 h = m.thenCompose(f, (x -> g));
3165 assertTrue(f.complete(v1));
3166 assertTrue(g.completeExceptionally(ex));
3167 break;
3168 case 5:
3169 h = m.thenCompose(f, (x -> g));
3170 assertTrue(f.complete(v1));
3171 assertTrue(g.completeExceptionally(ex));
3172 break;
3173 default: throw new AssertionError();
3174 }
3175
3176 checkCompletedExceptionally(g, ex);
3177 checkCompletedWithWrappedException(h, ex);
3178 checkCompletedNormally(f, v1);
3179 }}
3180
3181 /**
3182 * exceptionallyCompose result completes normally after normal
3183 * completion of source
3184 */
3185 public void testExceptionallyCompose_normalCompletion() {
3186 for (ExecutionMode m : ExecutionMode.values())
3187 for (boolean createIncomplete : new boolean[] { true, false })
3188 for (Integer v1 : new Integer[] { 1, null })
3189 {
3241 }}
3242
3243 /**
3244 * exceptionallyCompose result completes exceptionally if the
3245 * result of the action does
3246 */
3247 public void testExceptionallyCompose_actionReturnsFailingFuture() {
3248 for (ExecutionMode m : ExecutionMode.values())
3249 for (int order = 0; order < 6; order++)
3250 {
3251 final CFException ex0 = new CFException();
3252 final CFException ex = new CFException();
3253 final CompletableFuture<Integer> f = new CompletableFuture<>();
3254 final CompletableFuture<Integer> g = new CompletableFuture<>();
3255 final CompletableFuture<Integer> h;
3256 // Test all permutations of orders
3257 switch (order) {
3258 case 0:
3259 assertTrue(f.completeExceptionally(ex0));
3260 assertTrue(g.completeExceptionally(ex));
3261 h = m.exceptionallyCompose(f, (x -> g));
3262 break;
3263 case 1:
3264 assertTrue(f.completeExceptionally(ex0));
3265 h = m.exceptionallyCompose(f, (x -> g));
3266 assertTrue(g.completeExceptionally(ex));
3267 break;
3268 case 2:
3269 assertTrue(g.completeExceptionally(ex));
3270 assertTrue(f.completeExceptionally(ex0));
3271 h = m.exceptionallyCompose(f, (x -> g));
3272 break;
3273 case 3:
3274 assertTrue(g.completeExceptionally(ex));
3275 h = m.exceptionallyCompose(f, (x -> g));
3276 assertTrue(f.completeExceptionally(ex0));
3277 break;
3278 case 4:
3279 h = m.exceptionallyCompose(f, (x -> g));
3280 assertTrue(f.completeExceptionally(ex0));
3281 assertTrue(g.completeExceptionally(ex));
3282 break;
3283 case 5:
3284 h = m.exceptionallyCompose(f, (x -> g));
3285 assertTrue(f.completeExceptionally(ex0));
3286 assertTrue(g.completeExceptionally(ex));
3287 break;
3288 default: throw new AssertionError();
3289 }
3290
3291 checkCompletedExceptionally(g, ex);
3292 checkCompletedWithWrappedException(h, ex);
3293 checkCompletedExceptionally(f, ex0);
3294 }}
3295
3296 // other static methods
3297
3298 /**
3299 * allOf(no component futures) returns a future completed normally
3300 * with the value null
3301 */
3302 public void testAllOf_empty() throws Exception {
3303 CompletableFuture<Void> f = CompletableFuture.allOf();
3304 checkCompletedNormally(f, null);
3655
3656 for (CompletableFuture<?> future : futures)
3657 checkCompletedWithWrappedException(future, e.ex);
3658
3659 assertEquals(futures.size(), e.count.get());
3660 }}
3661
3662 /**
3663 * Test submissions to an executor that rejects all tasks, but
3664 * should never be invoked because the dependent future is
3665 * explicitly completed.
3666 */
3667 public void testRejectingExecutorNeverInvoked() {
3668 for (Integer v : new Integer[] { 1, null })
3669 {
3670 final CountingRejectingExecutor e = new CountingRejectingExecutor();
3671
3672 final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
3673 final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
3674
3675 List<CompletableFuture<?>> futures = new ArrayList<>();
3676
3677 List<CompletableFuture<Integer>> srcs = new ArrayList<>();
3678 srcs.add(complete);
3679 srcs.add(incomplete);
3680
3681 List<CompletableFuture<?>> fs = new ArrayList<>();
3682 fs.add(incomplete.thenRunAsync(() -> {}, e));
3683 fs.add(incomplete.thenAcceptAsync(z -> {}, e));
3684 fs.add(incomplete.thenApplyAsync(z -> z, e));
3685
3686 fs.add(incomplete.thenCombineAsync(incomplete, (x, y) -> x, e));
3687 fs.add(incomplete.thenAcceptBothAsync(incomplete, (x, y) -> {}, e));
3688 fs.add(incomplete.runAfterBothAsync(incomplete, () -> {}, e));
3689
3690 fs.add(incomplete.applyToEitherAsync(incomplete, z -> z, e));
3691 fs.add(incomplete.acceptEitherAsync(incomplete, z -> {}, e));
3692 fs.add(incomplete.runAfterEitherAsync(incomplete, () -> {}, e));
3693
3694 fs.add(incomplete.thenComposeAsync(z -> null, e));
3695 fs.add(incomplete.whenCompleteAsync((z, t) -> {}, e));
3696 fs.add(incomplete.handleAsync((z, t) -> null, e));
3697
3698 fs.add(complete.thenCombineAsync(incomplete, (x, y) -> x, e));
3699 fs.add(incomplete.thenCombineAsync(complete, (x, y) -> x, e));
3700
4845 public CompletionStage<T> whenCompleteAsync
4846 (BiConsumer<? super T, ? super Throwable> action) {
4847 return cf.whenCompleteAsync(action); }
4848 public CompletionStage<T> whenCompleteAsync
4849 (BiConsumer<? super T, ? super Throwable> action,
4850 Executor executor) {
4851 return cf.whenCompleteAsync(action, executor); }
4852 public CompletionStage<T> exceptionally
4853 (Function<Throwable, ? extends T> fn) {
4854 return cf.exceptionally(fn); }
4855 }
4856
4857 /**
4858 * default-implemented exceptionallyAsync action is not invoked when
4859 * source completes normally, and source result is propagated
4860 */
4861 public void testDefaultExceptionallyAsync_normalCompletion() {
4862 for (boolean createIncomplete : new boolean[] { true, false })
4863 for (Integer v1 : new Integer[] { 1, null })
4864 {
4865 final CompletableFuture<Integer> f = new CompletableFuture<>();
4866 final DelegatedCompletionStage<Integer> d =
4867 new DelegatedCompletionStage<Integer>(f);
4868 if (!createIncomplete) assertTrue(f.complete(v1));
4869 final CompletionStage<Integer> g = d.exceptionallyAsync
4870 ((Throwable t) -> {
4871 threadFail("should not be called");
4872 return null; // unreached
4873 });
4874 if (createIncomplete) assertTrue(f.complete(v1));
4875
4876 checkCompletedNormally(g.toCompletableFuture(), v1);
4877 }}
4878
4879 /**
4880 * default-implemented exceptionallyAsync action completes with
4881 * function value on source exception
4882 */
4883 public void testDefaultExceptionallyAsync_exceptionalCompletion() {
4884 for (boolean createIncomplete : new boolean[] { true, false })
4885 for (Integer v1 : new Integer[] { 1, null })
4886 {
4887 final AtomicInteger a = new AtomicInteger(0);
4888 final CFException ex = new CFException();
4889 final CompletableFuture<Integer> f = new CompletableFuture<>();
4890 final DelegatedCompletionStage<Integer> d =
4891 new DelegatedCompletionStage<Integer>(f);
4892 if (!createIncomplete) f.completeExceptionally(ex);
4893 final CompletionStage<Integer> g = d.exceptionallyAsync
4894 ((Throwable t) -> {
4895 threadAssertSame(t, ex);
4896 a.getAndIncrement();
4897 return v1;
4898 });
4899 if (createIncomplete) f.completeExceptionally(ex);
4900
4901 checkCompletedNormally(g.toCompletableFuture(), v1);
4902 assertEquals(1, a.get());
4903 }}
4904
4905 /**
4906 * Under default implementation, if an "exceptionally action"
4907 * throws an exception, it completes exceptionally with that
4908 * exception
4909 */
4910 public void testDefaultExceptionallyAsync_exceptionalCompletionActionFailed() {
4911 for (boolean createIncomplete : new boolean[] { true, false })
4912 {
4913 final AtomicInteger a = new AtomicInteger(0);
4914 final CFException ex1 = new CFException();
4915 final CFException ex2 = new CFException();
4916 final CompletableFuture<Integer> f = new CompletableFuture<>();
4917 final DelegatedCompletionStage<Integer> d =
4918 new DelegatedCompletionStage<Integer>(f);
4919 if (!createIncomplete) f.completeExceptionally(ex1);
4920 final CompletionStage<Integer> g = d.exceptionallyAsync
4921 ((Throwable t) -> {
4922 threadAssertSame(t, ex1);
4923 a.getAndIncrement();
4924 throw ex2;
4925 });
4926 if (createIncomplete) f.completeExceptionally(ex1);
4927
4928 checkCompletedWithWrappedException(g.toCompletableFuture(), ex2);
4929 checkCompletedExceptionally(f, ex1);
4930 checkCompletedExceptionally(d.toCompletableFuture(), ex1);
4931 assertEquals(1, a.get());
4932 }}
4933
4934 /**
4935 * default-implemented exceptionallyCompose result completes
4936 * normally after normal completion of source
4937 */
4938 public void testDefaultExceptionallyCompose_normalCompletion() {
4939 for (boolean createIncomplete : new boolean[] { true, false })
4940 for (Integer v1 : new Integer[] { 1, null })
4941 {
4942 final CompletableFuture<Integer> f = new CompletableFuture<>();
4943 final ExceptionalCompletableFutureFunction r =
4944 new ExceptionalCompletableFutureFunction(ExecutionMode.SYNC);
4945 final DelegatedCompletionStage<Integer> d =
4946 new DelegatedCompletionStage<Integer>(f);
4947 if (!createIncomplete) assertTrue(f.complete(v1));
4948 final CompletionStage<Integer> g = d.exceptionallyCompose(r);
4949 if (createIncomplete) assertTrue(f.complete(v1));
4950
4951 checkCompletedNormally(f, v1);
|
936 (CompletableFuture<T> f,
937 CompletionStage<? extends T> g,
938 Function<? super T,U> a);
939 public abstract <T> CompletableFuture<T> exceptionally
940 (CompletableFuture<T> f,
941 Function<Throwable, ? extends T> fn);
942 public abstract <T> CompletableFuture<T> exceptionallyCompose
943 (CompletableFuture<T> f,
944 Function<Throwable, ? extends CompletionStage<T>> fn);
945 }
946
947 /**
948 * exceptionally action is not invoked when source completes
949 * normally, and source result is propagated
950 */
951 public void testExceptionally_normalCompletion() {
952 for (ExecutionMode m : ExecutionMode.values())
953 for (boolean createIncomplete : new boolean[] { true, false })
954 for (Integer v1 : new Integer[] { 1, null })
955 {
956 final AtomicInteger ran = new AtomicInteger(0);
957 final CompletableFuture<Integer> f = new CompletableFuture<>();
958 if (!createIncomplete) assertTrue(f.complete(v1));
959 final CompletableFuture<Integer> g = m.exceptionally
960 (f, (Throwable t) -> {
961 ran.getAndIncrement();
962 throw new AssertionError("should not be called");
963 });
964 if (createIncomplete) assertTrue(f.complete(v1));
965
966 checkCompletedNormally(g, v1);
967 checkCompletedNormally(f, v1);
968 assertEquals(0, ran.get());
969 }}
970
971 /**
972 * exceptionally action completes with function value on source
973 * exception
974 */
975 public void testExceptionally_exceptionalCompletion() {
976 for (ExecutionMode m : ExecutionMode.values())
977 for (boolean createIncomplete : new boolean[] { true, false })
978 for (Integer v1 : new Integer[] { 1, null })
979 {
980 final AtomicInteger ran = new AtomicInteger(0);
981 final CFException ex = new CFException();
982 final CompletableFuture<Integer> f = new CompletableFuture<>();
983 if (!createIncomplete) f.completeExceptionally(ex);
984 final CompletableFuture<Integer> g = m.exceptionally
985 (f, (Throwable t) -> {
986 m.checkExecutionMode();
987 assertSame(t, ex);
988 ran.getAndIncrement();
989 return v1;
990 });
991 if (createIncomplete) f.completeExceptionally(ex);
992
993 checkCompletedNormally(g, v1);
994 assertEquals(1, ran.get());
995 }}
996
997 /**
998 * If an "exceptionally action" throws an exception, it completes
999 * exceptionally with that exception
1000 */
1001 public void testExceptionally_exceptionalCompletionActionFailed() {
1002 for (ExecutionMode m : ExecutionMode.values())
1003 for (boolean createIncomplete : new boolean[] { true, false })
1004 {
1005 final AtomicInteger ran = new AtomicInteger(0);
1006 final CFException ex1 = new CFException();
1007 final CFException ex2 = new CFException();
1008 final CompletableFuture<Integer> f = new CompletableFuture<>();
1009 if (!createIncomplete) f.completeExceptionally(ex1);
1010 final CompletableFuture<Integer> g = m.exceptionally
1011 (f, (Throwable t) -> {
1012 m.checkExecutionMode();
1013 assertSame(t, ex1);
1014 ran.getAndIncrement();
1015 throw ex2;
1016 });
1017 if (createIncomplete) f.completeExceptionally(ex1);
1018
1019 checkCompletedWithWrappedException(g, ex2);
1020 checkCompletedExceptionally(f, ex1);
1021 assertEquals(1, ran.get());
1022 }}
1023
1024 /**
1025 * whenComplete action executes on normal completion, propagating
1026 * source result.
1027 */
1028 public void testWhenComplete_normalCompletion() {
1029 for (ExecutionMode m : ExecutionMode.values())
1030 for (boolean createIncomplete : new boolean[] { true, false })
1031 for (Integer v1 : new Integer[] { 1, null })
1032 {
1033 final AtomicInteger ran = new AtomicInteger(0);
1034 final CompletableFuture<Integer> f = new CompletableFuture<>();
1035 if (!createIncomplete) assertTrue(f.complete(v1));
1036 final CompletableFuture<Integer> g = m.whenComplete
1037 (f,
1038 (Integer result, Throwable t) -> {
1039 m.checkExecutionMode();
1040 assertSame(result, v1);
1041 assertNull(t);
1042 ran.getAndIncrement();
1043 });
1044 if (createIncomplete) assertTrue(f.complete(v1));
1045
1046 checkCompletedNormally(g, v1);
1047 checkCompletedNormally(f, v1);
1048 assertEquals(1, ran.get());
1049 }}
1050
1051 /**
1052 * whenComplete action executes on exceptional completion, propagating
1053 * source result.
1054 */
1055 public void testWhenComplete_exceptionalCompletion() {
1056 for (ExecutionMode m : ExecutionMode.values())
1057 for (boolean createIncomplete : new boolean[] { true, false })
1058 {
1059 final AtomicInteger ran = new AtomicInteger(0);
1060 final CFException ex = new CFException();
1061 final CompletableFuture<Integer> f = new CompletableFuture<>();
1062 if (!createIncomplete) f.completeExceptionally(ex);
1063 final CompletableFuture<Integer> g = m.whenComplete
1064 (f,
1065 (Integer result, Throwable t) -> {
1066 m.checkExecutionMode();
1067 assertNull(result);
1068 assertSame(t, ex);
1069 ran.getAndIncrement();
1070 });
1071 if (createIncomplete) f.completeExceptionally(ex);
1072
1073 checkCompletedWithWrappedException(g, ex);
1074 checkCompletedExceptionally(f, ex);
1075 assertEquals(1, ran.get());
1076 }}
1077
1078 /**
1079 * whenComplete action executes on cancelled source, propagating
1080 * CancellationException.
1081 */
1082 public void testWhenComplete_sourceCancelled() {
1083 for (ExecutionMode m : ExecutionMode.values())
1084 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1085 for (boolean createIncomplete : new boolean[] { true, false })
1086 {
1087 final AtomicInteger ran = new AtomicInteger(0);
1088 final CompletableFuture<Integer> f = new CompletableFuture<>();
1089 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1090 final CompletableFuture<Integer> g = m.whenComplete
1091 (f,
1092 (Integer result, Throwable t) -> {
1093 m.checkExecutionMode();
1094 assertNull(result);
1095 assertTrue(t instanceof CancellationException);
1096 ran.getAndIncrement();
1097 });
1098 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1099
1100 checkCompletedWithWrappedCancellationException(g);
1101 checkCancelled(f);
1102 assertEquals(1, ran.get());
1103 }}
1104
1105 /**
1106 * If a whenComplete action throws an exception when triggered by
1107 * a normal completion, it completes exceptionally
1108 */
1109 public void testWhenComplete_sourceCompletedNormallyActionFailed() {
1110 for (boolean createIncomplete : new boolean[] { true, false })
1111 for (ExecutionMode m : ExecutionMode.values())
1112 for (Integer v1 : new Integer[] { 1, null })
1113 {
1114 final AtomicInteger ran = new AtomicInteger(0);
1115 final CFException ex = new CFException();
1116 final CompletableFuture<Integer> f = new CompletableFuture<>();
1117 if (!createIncomplete) assertTrue(f.complete(v1));
1118 final CompletableFuture<Integer> g = m.whenComplete
1119 (f,
1120 (Integer result, Throwable t) -> {
1121 m.checkExecutionMode();
1122 assertSame(result, v1);
1123 assertNull(t);
1124 ran.getAndIncrement();
1125 throw ex;
1126 });
1127 if (createIncomplete) assertTrue(f.complete(v1));
1128
1129 checkCompletedWithWrappedException(g, ex);
1130 checkCompletedNormally(f, v1);
1131 assertEquals(1, ran.get());
1132 }}
1133
1134 /**
1135 * If a whenComplete action throws an exception when triggered by
1136 * a source completion that also throws an exception, the source
1137 * exception takes precedence (unlike handle)
1138 */
1139 public void testWhenComplete_sourceFailedActionFailed() {
1140 for (boolean createIncomplete : new boolean[] { true, false })
1141 for (ExecutionMode m : ExecutionMode.values())
1142 {
1143 final AtomicInteger ran = new AtomicInteger(0);
1144 final CFException ex1 = new CFException();
1145 final CFException ex2 = new CFException();
1146 final CompletableFuture<Integer> f = new CompletableFuture<>();
1147
1148 if (!createIncomplete) f.completeExceptionally(ex1);
1149 final CompletableFuture<Integer> g = m.whenComplete
1150 (f,
1151 (Integer result, Throwable t) -> {
1152 m.checkExecutionMode();
1153 assertSame(t, ex1);
1154 assertNull(result);
1155 ran.getAndIncrement();
1156 throw ex2;
1157 });
1158 if (createIncomplete) f.completeExceptionally(ex1);
1159
1160 checkCompletedWithWrappedException(g, ex1);
1161 checkCompletedExceptionally(f, ex1);
1162 if (testImplementationDetails) {
1163 assertEquals(1, ex1.getSuppressed().length);
1164 assertSame(ex2, ex1.getSuppressed()[0]);
1165 }
1166 assertEquals(1, ran.get());
1167 }}
1168
1169 /**
1170 * handle action completes normally with function value on normal
1171 * completion of source
1172 */
1173 public void testHandle_normalCompletion() {
1174 for (ExecutionMode m : ExecutionMode.values())
1175 for (boolean createIncomplete : new boolean[] { true, false })
1176 for (Integer v1 : new Integer[] { 1, null })
1177 {
1178 final CompletableFuture<Integer> f = new CompletableFuture<>();
1179 final AtomicInteger ran = new AtomicInteger(0);
1180 if (!createIncomplete) assertTrue(f.complete(v1));
1181 final CompletableFuture<Integer> g = m.handle
1182 (f,
1183 (Integer result, Throwable t) -> {
1184 m.checkExecutionMode();
1185 assertSame(result, v1);
1186 assertNull(t);
1187 ran.getAndIncrement();
1188 return inc(v1);
1189 });
1190 if (createIncomplete) assertTrue(f.complete(v1));
1191
1192 checkCompletedNormally(g, inc(v1));
1193 checkCompletedNormally(f, v1);
1194 assertEquals(1, ran.get());
1195 }}
1196
1197 /**
1198 * handle action completes normally with function value on
1199 * exceptional completion of source
1200 */
1201 public void testHandle_exceptionalCompletion() {
1202 for (ExecutionMode m : ExecutionMode.values())
1203 for (boolean createIncomplete : new boolean[] { true, false })
1204 for (Integer v1 : new Integer[] { 1, null })
1205 {
1206 final CompletableFuture<Integer> f = new CompletableFuture<>();
1207 final AtomicInteger ran = new AtomicInteger(0);
1208 final CFException ex = new CFException();
1209 if (!createIncomplete) f.completeExceptionally(ex);
1210 final CompletableFuture<Integer> g = m.handle
1211 (f,
1212 (Integer result, Throwable t) -> {
1213 m.checkExecutionMode();
1214 assertNull(result);
1215 assertSame(t, ex);
1216 ran.getAndIncrement();
1217 return v1;
1218 });
1219 if (createIncomplete) f.completeExceptionally(ex);
1220
1221 checkCompletedNormally(g, v1);
1222 checkCompletedExceptionally(f, ex);
1223 assertEquals(1, ran.get());
1224 }}
1225
1226 /**
1227 * handle action completes normally with function value on
1228 * cancelled source
1229 */
1230 public void testHandle_sourceCancelled() {
1231 for (ExecutionMode m : ExecutionMode.values())
1232 for (boolean mayInterruptIfRunning : new boolean[] { true, false })
1233 for (boolean createIncomplete : new boolean[] { true, false })
1234 for (Integer v1 : new Integer[] { 1, null })
1235 {
1236 final CompletableFuture<Integer> f = new CompletableFuture<>();
1237 final AtomicInteger ran = new AtomicInteger(0);
1238 if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1239 final CompletableFuture<Integer> g = m.handle
1240 (f,
1241 (Integer result, Throwable t) -> {
1242 m.checkExecutionMode();
1243 assertNull(result);
1244 assertTrue(t instanceof CancellationException);
1245 ran.getAndIncrement();
1246 return v1;
1247 });
1248 if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
1249
1250 checkCompletedNormally(g, v1);
1251 checkCancelled(f);
1252 assertEquals(1, ran.get());
1253 }}
1254
1255 /**
1256 * If a "handle action" throws an exception when triggered by
1257 * a normal completion, it completes exceptionally
1258 */
1259 public void testHandle_sourceCompletedNormallyActionFailed() {
1260 for (ExecutionMode m : ExecutionMode.values())
1261 for (boolean createIncomplete : new boolean[] { true, false })
1262 for (Integer v1 : new Integer[] { 1, null })
1263 {
1264 final CompletableFuture<Integer> f = new CompletableFuture<>();
1265 final AtomicInteger ran = new AtomicInteger(0);
1266 final CFException ex = new CFException();
1267 if (!createIncomplete) assertTrue(f.complete(v1));
1268 final CompletableFuture<Integer> g = m.handle
1269 (f,
1270 (Integer result, Throwable t) -> {
1271 m.checkExecutionMode();
1272 assertSame(result, v1);
1273 assertNull(t);
1274 ran.getAndIncrement();
1275 throw ex;
1276 });
1277 if (createIncomplete) assertTrue(f.complete(v1));
1278
1279 checkCompletedWithWrappedException(g, ex);
1280 checkCompletedNormally(f, v1);
1281 assertEquals(1, ran.get());
1282 }}
1283
1284 /**
1285 * If a "handle action" throws an exception when triggered by
1286 * a source completion that also throws an exception, the action
1287 * exception takes precedence (unlike whenComplete)
1288 */
1289 public void testHandle_sourceFailedActionFailed() {
1290 for (boolean createIncomplete : new boolean[] { true, false })
1291 for (ExecutionMode m : ExecutionMode.values())
1292 {
1293 final AtomicInteger ran = new AtomicInteger(0);
1294 final CFException ex1 = new CFException();
1295 final CFException ex2 = new CFException();
1296 final CompletableFuture<Integer> f = new CompletableFuture<>();
1297
1298 if (!createIncomplete) f.completeExceptionally(ex1);
1299 final CompletableFuture<Integer> g = m.handle
1300 (f,
1301 (Integer result, Throwable t) -> {
1302 m.checkExecutionMode();
1303 assertNull(result);
1304 assertSame(ex1, t);
1305 ran.getAndIncrement();
1306 throw ex2;
1307 });
1308 if (createIncomplete) f.completeExceptionally(ex1);
1309
1310 checkCompletedWithWrappedException(g, ex2);
1311 checkCompletedExceptionally(f, ex1);
1312 assertEquals(1, ran.get());
1313 }}
1314
1315 /**
1316 * runAsync completes after running Runnable
1317 */
1318 public void testRunAsync_normalCompletion() {
1319 ExecutionMode[] executionModes = {
1320 ExecutionMode.ASYNC,
1321 ExecutionMode.EXECUTOR,
1322 };
1323 for (ExecutionMode m : executionModes)
1324 {
1325 final Noop r = new Noop(m);
1326 final CompletableFuture<Void> f = m.runAsync(r);
1327 assertNull(f.join());
1328 checkCompletedNormally(f, null);
1329 r.assertInvoked();
1330 }}
1331
1332 /**
3128 checkCancelled(f);
3129 }}
3130
3131 /**
3132 * thenCompose result completes exceptionally if the result of the action does
3133 */
3134 public void testThenCompose_actionReturnsFailingFuture() {
3135 for (ExecutionMode m : ExecutionMode.values())
3136 for (int order = 0; order < 6; order++)
3137 for (Integer v1 : new Integer[] { 1, null })
3138 {
3139 final CFException ex = new CFException();
3140 final CompletableFuture<Integer> f = new CompletableFuture<>();
3141 final CompletableFuture<Integer> g = new CompletableFuture<>();
3142 final CompletableFuture<Integer> h;
3143 // Test all permutations of orders
3144 switch (order) {
3145 case 0:
3146 assertTrue(f.complete(v1));
3147 assertTrue(g.completeExceptionally(ex));
3148 h = m.thenCompose(f, x -> g);
3149 break;
3150 case 1:
3151 assertTrue(f.complete(v1));
3152 h = m.thenCompose(f, x -> g);
3153 assertTrue(g.completeExceptionally(ex));
3154 break;
3155 case 2:
3156 assertTrue(g.completeExceptionally(ex));
3157 assertTrue(f.complete(v1));
3158 h = m.thenCompose(f, x -> g);
3159 break;
3160 case 3:
3161 assertTrue(g.completeExceptionally(ex));
3162 h = m.thenCompose(f, x -> g);
3163 assertTrue(f.complete(v1));
3164 break;
3165 case 4:
3166 h = m.thenCompose(f, x -> g);
3167 assertTrue(f.complete(v1));
3168 assertTrue(g.completeExceptionally(ex));
3169 break;
3170 case 5:
3171 h = m.thenCompose(f, x -> g);
3172 assertTrue(f.complete(v1));
3173 assertTrue(g.completeExceptionally(ex));
3174 break;
3175 default: throw new AssertionError();
3176 }
3177
3178 checkCompletedExceptionally(g, ex);
3179 checkCompletedWithWrappedException(h, ex);
3180 checkCompletedNormally(f, v1);
3181 }}
3182
3183 /**
3184 * exceptionallyCompose result completes normally after normal
3185 * completion of source
3186 */
3187 public void testExceptionallyCompose_normalCompletion() {
3188 for (ExecutionMode m : ExecutionMode.values())
3189 for (boolean createIncomplete : new boolean[] { true, false })
3190 for (Integer v1 : new Integer[] { 1, null })
3191 {
3243 }}
3244
3245 /**
3246 * exceptionallyCompose result completes exceptionally if the
3247 * result of the action does
3248 */
3249 public void testExceptionallyCompose_actionReturnsFailingFuture() {
3250 for (ExecutionMode m : ExecutionMode.values())
3251 for (int order = 0; order < 6; order++)
3252 {
3253 final CFException ex0 = new CFException();
3254 final CFException ex = new CFException();
3255 final CompletableFuture<Integer> f = new CompletableFuture<>();
3256 final CompletableFuture<Integer> g = new CompletableFuture<>();
3257 final CompletableFuture<Integer> h;
3258 // Test all permutations of orders
3259 switch (order) {
3260 case 0:
3261 assertTrue(f.completeExceptionally(ex0));
3262 assertTrue(g.completeExceptionally(ex));
3263 h = m.exceptionallyCompose(f, x -> g);
3264 break;
3265 case 1:
3266 assertTrue(f.completeExceptionally(ex0));
3267 h = m.exceptionallyCompose(f, x -> g);
3268 assertTrue(g.completeExceptionally(ex));
3269 break;
3270 case 2:
3271 assertTrue(g.completeExceptionally(ex));
3272 assertTrue(f.completeExceptionally(ex0));
3273 h = m.exceptionallyCompose(f, x -> g);
3274 break;
3275 case 3:
3276 assertTrue(g.completeExceptionally(ex));
3277 h = m.exceptionallyCompose(f, x -> g);
3278 assertTrue(f.completeExceptionally(ex0));
3279 break;
3280 case 4:
3281 h = m.exceptionallyCompose(f, x -> g);
3282 assertTrue(f.completeExceptionally(ex0));
3283 assertTrue(g.completeExceptionally(ex));
3284 break;
3285 case 5:
3286 h = m.exceptionallyCompose(f, x -> g);
3287 assertTrue(f.completeExceptionally(ex0));
3288 assertTrue(g.completeExceptionally(ex));
3289 break;
3290 default: throw new AssertionError();
3291 }
3292
3293 checkCompletedExceptionally(g, ex);
3294 checkCompletedWithWrappedException(h, ex);
3295 checkCompletedExceptionally(f, ex0);
3296 }}
3297
3298 // other static methods
3299
3300 /**
3301 * allOf(no component futures) returns a future completed normally
3302 * with the value null
3303 */
3304 public void testAllOf_empty() throws Exception {
3305 CompletableFuture<Void> f = CompletableFuture.allOf();
3306 checkCompletedNormally(f, null);
3657
3658 for (CompletableFuture<?> future : futures)
3659 checkCompletedWithWrappedException(future, e.ex);
3660
3661 assertEquals(futures.size(), e.count.get());
3662 }}
3663
3664 /**
3665 * Test submissions to an executor that rejects all tasks, but
3666 * should never be invoked because the dependent future is
3667 * explicitly completed.
3668 */
3669 public void testRejectingExecutorNeverInvoked() {
3670 for (Integer v : new Integer[] { 1, null })
3671 {
3672 final CountingRejectingExecutor e = new CountingRejectingExecutor();
3673
3674 final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
3675 final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
3676
3677 List<CompletableFuture<?>> fs = new ArrayList<>();
3678 fs.add(incomplete.thenRunAsync(() -> {}, e));
3679 fs.add(incomplete.thenAcceptAsync(z -> {}, e));
3680 fs.add(incomplete.thenApplyAsync(z -> z, e));
3681
3682 fs.add(incomplete.thenCombineAsync(incomplete, (x, y) -> x, e));
3683 fs.add(incomplete.thenAcceptBothAsync(incomplete, (x, y) -> {}, e));
3684 fs.add(incomplete.runAfterBothAsync(incomplete, () -> {}, e));
3685
3686 fs.add(incomplete.applyToEitherAsync(incomplete, z -> z, e));
3687 fs.add(incomplete.acceptEitherAsync(incomplete, z -> {}, e));
3688 fs.add(incomplete.runAfterEitherAsync(incomplete, () -> {}, e));
3689
3690 fs.add(incomplete.thenComposeAsync(z -> null, e));
3691 fs.add(incomplete.whenCompleteAsync((z, t) -> {}, e));
3692 fs.add(incomplete.handleAsync((z, t) -> null, e));
3693
3694 fs.add(complete.thenCombineAsync(incomplete, (x, y) -> x, e));
3695 fs.add(incomplete.thenCombineAsync(complete, (x, y) -> x, e));
3696
4841 public CompletionStage<T> whenCompleteAsync
4842 (BiConsumer<? super T, ? super Throwable> action) {
4843 return cf.whenCompleteAsync(action); }
4844 public CompletionStage<T> whenCompleteAsync
4845 (BiConsumer<? super T, ? super Throwable> action,
4846 Executor executor) {
4847 return cf.whenCompleteAsync(action, executor); }
4848 public CompletionStage<T> exceptionally
4849 (Function<Throwable, ? extends T> fn) {
4850 return cf.exceptionally(fn); }
4851 }
4852
4853 /**
4854 * default-implemented exceptionallyAsync action is not invoked when
4855 * source completes normally, and source result is propagated
4856 */
4857 public void testDefaultExceptionallyAsync_normalCompletion() {
4858 for (boolean createIncomplete : new boolean[] { true, false })
4859 for (Integer v1 : new Integer[] { 1, null })
4860 {
4861 final AtomicInteger ran = new AtomicInteger(0);
4862 final CompletableFuture<Integer> f = new CompletableFuture<>();
4863 final DelegatedCompletionStage<Integer> d =
4864 new DelegatedCompletionStage<Integer>(f);
4865 if (!createIncomplete) assertTrue(f.complete(v1));
4866 final CompletionStage<Integer> g = d.exceptionallyAsync
4867 ((Throwable t) -> {
4868 ran.getAndIncrement();
4869 throw new AssertionError("should not be called");
4870 });
4871 if (createIncomplete) assertTrue(f.complete(v1));
4872
4873 checkCompletedNormally(g.toCompletableFuture(), v1);
4874 checkCompletedNormally(f, v1);
4875 assertEquals(0, ran.get());
4876 }}
4877
4878 /**
4879 * default-implemented exceptionallyAsync action completes with
4880 * function value on source exception
4881 */
4882 public void testDefaultExceptionallyAsync_exceptionalCompletion() {
4883 for (boolean createIncomplete : new boolean[] { true, false })
4884 for (Integer v1 : new Integer[] { 1, null })
4885 {
4886 final AtomicInteger ran = new AtomicInteger(0);
4887 final CFException ex = new CFException();
4888 final CompletableFuture<Integer> f = new CompletableFuture<>();
4889 final DelegatedCompletionStage<Integer> d =
4890 new DelegatedCompletionStage<Integer>(f);
4891 if (!createIncomplete) f.completeExceptionally(ex);
4892 final CompletionStage<Integer> g = d.exceptionallyAsync
4893 ((Throwable t) -> {
4894 assertSame(t, ex);
4895 ran.getAndIncrement();
4896 return v1;
4897 });
4898 if (createIncomplete) f.completeExceptionally(ex);
4899
4900 checkCompletedNormally(g.toCompletableFuture(), v1);
4901 checkCompletedExceptionally(f, ex);
4902 assertEquals(1, ran.get());
4903 }}
4904
4905 /**
4906 * Under default implementation, if an "exceptionally action"
4907 * throws an exception, it completes exceptionally with that
4908 * exception
4909 */
4910 public void testDefaultExceptionallyAsync_exceptionalCompletionActionFailed() {
4911 for (boolean createIncomplete : new boolean[] { true, false })
4912 {
4913 final AtomicInteger ran = new AtomicInteger(0);
4914 final CFException ex1 = new CFException();
4915 final CFException ex2 = new CFException();
4916 final CompletableFuture<Integer> f = new CompletableFuture<>();
4917 final DelegatedCompletionStage<Integer> d =
4918 new DelegatedCompletionStage<Integer>(f);
4919 if (!createIncomplete) f.completeExceptionally(ex1);
4920 final CompletionStage<Integer> g = d.exceptionallyAsync
4921 ((Throwable t) -> {
4922 assertSame(t, ex1);
4923 ran.getAndIncrement();
4924 throw ex2;
4925 });
4926 if (createIncomplete) f.completeExceptionally(ex1);
4927
4928 checkCompletedWithWrappedException(g.toCompletableFuture(), ex2);
4929 checkCompletedExceptionally(f, ex1);
4930 checkCompletedExceptionally(d.toCompletableFuture(), ex1);
4931 assertEquals(1, ran.get());
4932 }}
4933
4934 /**
4935 * default-implemented exceptionallyCompose result completes
4936 * normally after normal completion of source
4937 */
4938 public void testDefaultExceptionallyCompose_normalCompletion() {
4939 for (boolean createIncomplete : new boolean[] { true, false })
4940 for (Integer v1 : new Integer[] { 1, null })
4941 {
4942 final CompletableFuture<Integer> f = new CompletableFuture<>();
4943 final ExceptionalCompletableFutureFunction r =
4944 new ExceptionalCompletableFutureFunction(ExecutionMode.SYNC);
4945 final DelegatedCompletionStage<Integer> d =
4946 new DelegatedCompletionStage<Integer>(f);
4947 if (!createIncomplete) assertTrue(f.complete(v1));
4948 final CompletionStage<Integer> g = d.exceptionallyCompose(r);
4949 if (createIncomplete) assertTrue(f.complete(v1));
4950
4951 checkCompletedNormally(f, v1);
|