use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.
the class CompletableFutureTest method testWhenComplete_normalCompletion.
/**
* whenComplete action executes on normal completion, propagating
* source result.
*/
public void testWhenComplete_normalCompletion() {
for (ExecutionMode m : ExecutionMode.values()) for (boolean createIncomplete : new boolean[] { true, false }) for (Integer v1 : new Integer[] { 1, null }) {
final AtomicInteger a = new AtomicInteger(0);
final CompletableFuture<Integer> f = new CompletableFuture<>();
if (!createIncomplete)
assertTrue(f.complete(v1));
final CompletableFuture<Integer> g = m.whenComplete(f, (Integer result, Throwable t) -> {
m.checkExecutionMode();
threadAssertSame(result, v1);
threadAssertNull(t);
a.getAndIncrement();
});
if (createIncomplete)
assertTrue(f.complete(v1));
checkCompletedNormally(g, v1);
checkCompletedNormally(f, v1);
assertEquals(1, a.get());
}
}
use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.
the class CompletableFutureTest method testMinimalCompletionStage_minimality.
/**
* Minimal completion stages throw UOE for most non-CompletionStage methods
*/
public void testMinimalCompletionStage_minimality() {
if (!testImplementationDetails)
return;
Function<Method, String> toSignature = method -> method.getName() + Arrays.toString(method.getParameterTypes());
Predicate<Method> isNotStatic = method -> (method.getModifiers() & Modifier.STATIC) == 0;
List<Method> minimalMethods = RefStreams.of(Object.class, CompletionStage.class).flatMap(klazz -> RefStreams.of(klazz.getMethods())).filter(isNotStatic).collect(Collectors.toList());
// Methods from CompletableFuture permitted NOT to throw UOE
String[] signatureWhitelist = { "newIncompleteFuture[]", "defaultExecutor[]", "minimalCompletionStage[]", "copy[]" };
Set<String> permittedMethodSignatures = RefStreams.concat(StreamSupport.stream(minimalMethods).map(toSignature), RefStreams.of(signatureWhitelist)).collect(Collectors.toSet());
List<Method> allMethods = RefStreams.of(CompletableFuture.class.getMethods()).filter(isNotStatic).filter(method -> !permittedMethodSignatures.contains(toSignature.apply(method))).collect(Collectors.toList());
List<CompletionStage<Integer>> stages = new ArrayList<CompletionStage<Integer>>();
CompletionStage<Integer> min = new CompletableFuture<Integer>().minimalCompletionStage();
stages.add(min);
stages.add(min.thenApply(x -> x));
stages.add(CompletableFuture.completedStage(1));
stages.add(CompletableFuture.failedStage(new CFException()));
List<Method> bugs = new ArrayList<>();
for (Method method : allMethods) {
Class<?>[] parameterTypes = method.getParameterTypes();
Object[] args = new Object[parameterTypes.length];
// Manufacture boxed primitives for primitive params
for (int i = 0; i < args.length; i++) {
Class<?> type = parameterTypes[i];
if (type == boolean.class)
args[i] = false;
else if (type == int.class)
args[i] = 0;
else if (type == long.class)
args[i] = 0L;
}
for (CompletionStage<Integer> stage : stages) {
try {
method.invoke(stage, args);
bugs.add(method);
} catch (java.lang.reflect.InvocationTargetException expected) {
if (!(expected.getCause() instanceof UnsupportedOperationException)) {
bugs.add(method);
// expected.getCause().printStackTrace();
}
} catch (Exception bad) {
throw new Error(bad);
}
}
}
if (!bugs.isEmpty())
throw new Error("Methods did not throw UOE: " + bugs);
}
use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.
the class CompletableFutureTest method testExceptionally_exceptionalCompletionActionFailed.
/**
* If an "exceptionally action" throws an exception, it completes
* exceptionally with that exception
*/
public void testExceptionally_exceptionalCompletionActionFailed() {
for (boolean createIncomplete : new boolean[] { true, false }) {
final AtomicInteger a = new AtomicInteger(0);
final CFException ex1 = new CFException();
final CFException ex2 = new CFException();
final CompletableFuture<Integer> f = new CompletableFuture<>();
if (!createIncomplete)
f.completeExceptionally(ex1);
final CompletableFuture<Integer> g = f.exceptionally((Throwable t) -> {
ExecutionMode.SYNC.checkExecutionMode();
threadAssertSame(t, ex1);
a.getAndIncrement();
throw ex2;
});
if (createIncomplete)
f.completeExceptionally(ex1);
checkCompletedWithWrappedException(g, ex2);
checkCompletedExceptionally(f, ex1);
assertEquals(1, a.get());
}
}
use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.
the class CompletableFutureTest method testMinimalCompletionStage.
/**
* minimalCompletionStage returns a CompletableFuture that is
* completed normally, with the same value, when source is.
*/
public void testMinimalCompletionStage() {
CompletableFuture<Integer> f = new CompletableFuture<>();
CompletionStage<Integer> g = f.minimalCompletionStage();
AtomicInteger x = new AtomicInteger(0);
AtomicReference<Throwable> r = new AtomicReference<>();
checkIncomplete(f);
g.whenComplete((v, e) -> {
if (e != null)
r.set(e);
else
x.set(v);
});
f.complete(1);
checkCompletedNormally(f, 1);
assertEquals(x.get(), 1);
assertNull(r.get());
}
use of java8.util.concurrent.CompletableFuture in project streamsupport by stefan-zobel.
the class CompletableFutureTest method testManyDependents.
/**
* A single CompletableFuture with many dependents.
* A demo of scalability - runtime is O(n).
*/
public void testManyDependents() throws Throwable {
final int n = expensiveTests ? 1_000_000 : 10;
final CompletableFuture<Void> head = new CompletableFuture<>();
final CompletableFuture<Void> complete = CompletableFuture.completedFuture((Void) null);
final AtomicInteger count = new AtomicInteger(0);
for (int i = 0; i < n; i++) {
head.thenRun(() -> count.getAndIncrement());
head.thenAccept(x -> count.getAndIncrement());
head.thenApply(x -> count.getAndIncrement());
head.runAfterBoth(complete, () -> count.getAndIncrement());
head.thenAcceptBoth(complete, (x, y) -> count.getAndIncrement());
head.thenCombine(complete, (x, y) -> count.getAndIncrement());
complete.runAfterBoth(head, () -> count.getAndIncrement());
complete.thenAcceptBoth(head, (x, y) -> count.getAndIncrement());
complete.thenCombine(head, (x, y) -> count.getAndIncrement());
head.runAfterEither(new CompletableFuture<Void>(), () -> count.getAndIncrement());
head.acceptEither(new CompletableFuture<Void>(), x -> count.getAndIncrement());
head.applyToEither(new CompletableFuture<Void>(), x -> count.getAndIncrement());
new CompletableFuture<Void>().runAfterEither(head, () -> count.getAndIncrement());
new CompletableFuture<Void>().acceptEither(head, x -> count.getAndIncrement());
new CompletableFuture<Void>().applyToEither(head, x -> count.getAndIncrement());
}
head.complete(null);
assertEquals(5 * 3 * n, count.get());
}
Aggregations