From 0ccab8f32a7149b2ad6bd243cceea6178afc6f1c Mon Sep 17 00:00:00 2001 From: EricLin Date: Sun, 28 Jul 2024 08:25:34 +0800 Subject: [PATCH] add test to ListenableFutureUtils#toCompletableFuture case: interrupt thread --- .../foldright/cffu/ListenableFutureUtils.java | 2 +- .../cffu/ListenableFutureUtilsTest.java | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/cffu-core/src/main/java/io/foldright/cffu/ListenableFutureUtils.java b/cffu-core/src/main/java/io/foldright/cffu/ListenableFutureUtils.java index b52c5e55..d53d4da8 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/ListenableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/ListenableFutureUtils.java @@ -33,7 +33,7 @@ public class ListenableFutureUtils { * Cancelling the result {@link CompletableFuture} will also cancel inner {@link ListenableFuture}. * Use param {@code mayInterruptIfRunning} to control whether to interrupt the thread of {@link ListenableFuture}. *

- * Note: CompletionException caused by this CancellationException is also considered cancellation. + * Note: CompletionException caused by CancellationException is also considered cancellation. *

* We encourage you to avoid using direct write methods in {@link CompletableFuture} so that the underlying * {@link ListenableFuture} can benefit from cancel propagation. diff --git a/cffu-core/src/test/java/io/foldright/cffu/ListenableFutureUtilsTest.java b/cffu-core/src/test/java/io/foldright/cffu/ListenableFutureUtilsTest.java index 5ec0c364..f9a89fa9 100644 --- a/cffu-core/src/test/java/io/foldright/cffu/ListenableFutureUtilsTest.java +++ b/cffu-core/src/test/java/io/foldright/cffu/ListenableFutureUtilsTest.java @@ -10,7 +10,9 @@ import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.JRE; +import java.time.Duration; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; import static io.foldright.cffu.ListenableFutureUtils.*; import static io.foldright.test_utils.TestUtils.*; @@ -129,6 +131,30 @@ void test_lf2cf_setCancellationExceptionToCf_cancellationAndPropagation() throws assertThrowsExactly(CancellationException.class, cf::get); } + @Test + void test_lf2cf_setCancellationExceptionToCf_cancellationAndPropagation_interruption() throws Exception { + final AtomicBoolean interrupted = new AtomicBoolean(false); + final ListenableFuture lf = Futures.submit(() -> { + try { + Thread.sleep(Duration.ofSeconds(10)); + } catch (InterruptedException ex) { + interrupted.set(true); + } + return 42; + }, Executors.newCachedThreadPool()); + final CompletableFuture cf = toCompletableFuture(lf, executorService, true); + + assertTrue(cf.completeExceptionally(new CancellationException())); + waitForAllCfsToComplete(cf); + waitForAllLfsToComplete(lf); + + assertTrue(lf.isCancelled()); + assertThrowsExactly(CancellationException.class, lf::get); + assertTrue(cf.isCancelled()); + assertThrowsExactly(CancellationException.class, cf::get); + assertTrue(interrupted.get()); + } + @Test void test_cf2lf_cancellationAndPropagation() throws Exception { final CompletableFuture cf = new CompletableFuture<>();