From 4a98e5b5fe262691aba3fb2a1fa1afed29d42722 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 3 Feb 2021 14:36:21 +0100 Subject: [PATCH] Polishing #1611 Add unit test for cancel in-flight connection creation. --- .../support/BoundedAsyncPoolUnitTests.java | 76 +++++++++++++++---- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/src/test/java/io/lettuce/core/support/BoundedAsyncPoolUnitTests.java b/src/test/java/io/lettuce/core/support/BoundedAsyncPoolUnitTests.java index f1b7b237e6..b366fbf4d9 100644 --- a/src/test/java/io/lettuce/core/support/BoundedAsyncPoolUnitTests.java +++ b/src/test/java/io/lettuce/core/support/BoundedAsyncPoolUnitTests.java @@ -15,8 +15,7 @@ */ package io.lettuce.core.support; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.*; import java.util.ArrayList; import java.util.List; @@ -38,9 +37,11 @@ class BoundedAsyncPoolUnitTests { private AtomicInteger counter = new AtomicInteger(); + private List destroyed = new ArrayList<>(); private AsyncObjectFactory STRING_OBJECT_FACTORY = new AsyncObjectFactory() { + @Override public CompletableFuture create() { return CompletableFuture.completedFuture(counter.incrementAndGet() + ""); @@ -56,6 +57,7 @@ public CompletableFuture destroy(String object) { public CompletableFuture validate(String object) { return CompletableFuture.completedFuture(true); } + }; @Test @@ -119,8 +121,8 @@ public CompletableFuture validate(String object) { @Test void shouldCreateMinIdleObject() { - BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, BoundedPoolConfig.builder().minIdle(2) - .build()); + BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, + BoundedPoolConfig.builder().minIdle(2).build()); assertThat(pool.getIdle()).isEqualTo(2); assertThat(pool.getObjectCount()).isEqualTo(2); @@ -129,8 +131,8 @@ void shouldCreateMinIdleObject() { @Test void shouldCreateMaintainMinIdleObject() { - BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, BoundedPoolConfig.builder().minIdle(2) - .build()); + BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, + BoundedPoolConfig.builder().minIdle(2).build()); TestFutures.awaitOrTimeout(pool.acquire()); @@ -141,8 +143,8 @@ void shouldCreateMaintainMinIdleObject() { @Test void shouldCreateMaintainMinMaxIdleObject() { - BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, BoundedPoolConfig.builder().minIdle(2) - .maxTotal(2).build()); + BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, + BoundedPoolConfig.builder().minIdle(2).maxTotal(2).build()); TestFutures.awaitOrTimeout(pool.acquire()); @@ -176,8 +178,8 @@ void shouldReuseObjects() { @Test void shouldDestroyIdle() { - BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, BoundedPoolConfig.builder().maxIdle(2) - .maxTotal(5).build()); + BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, + BoundedPoolConfig.builder().maxIdle(2).maxTotal(5).build()); List objects = new ArrayList<>(); for (int i = 0; i < 3; i++) { @@ -200,8 +202,8 @@ void shouldDestroyIdle() { @Test void shouldExhaustPool() { - BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, BoundedPoolConfig.builder().maxTotal(4) - .build()); + BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, + BoundedPoolConfig.builder().maxTotal(4).build()); String object1 = TestFutures.getOrTimeout(pool.acquire()); String object2 = TestFutures.getOrTimeout(pool.acquire()); @@ -228,8 +230,8 @@ void shouldExhaustPool() { @Test void shouldClearPool() { - BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, BoundedPoolConfig.builder().maxTotal(4) - .build()); + BoundedAsyncPool pool = new BoundedAsyncPool<>(STRING_OBJECT_FACTORY, + BoundedPoolConfig.builder().maxTotal(4).build()); for (int i = 0; i < 20; i++) { @@ -257,6 +259,7 @@ void shouldExhaustPoolConcurrent() { List> progress = new ArrayList<>(); AsyncObjectFactory IN_PROGRESS = new AsyncObjectFactory() { + @Override public CompletableFuture create() { @@ -276,6 +279,7 @@ public CompletableFuture destroy(String object) { public CompletableFuture validate(String object) { return CompletableFuture.completedFuture(true); } + }; BoundedAsyncPool pool = new BoundedAsyncPool<>(IN_PROGRESS, BoundedPoolConfig.builder().maxTotal(4).build()); @@ -304,6 +308,7 @@ void shouldConcurrentlyFail() { List> progress = new ArrayList<>(); AsyncObjectFactory IN_PROGRESS = new AsyncObjectFactory() { + @Override public CompletableFuture create() { @@ -323,6 +328,7 @@ public CompletableFuture destroy(String object) { public CompletableFuture validate(String object) { return CompletableFuture.completedFuture(true); } + }; BoundedAsyncPool pool = new BoundedAsyncPool<>(IN_PROGRESS, BoundedPoolConfig.builder().maxTotal(4).build()); @@ -343,4 +349,46 @@ public CompletableFuture validate(String object) { assertThat(pool.getObjectCount()).isZero(); assertThat(pool.getCreationInProgress()).isZero(); } + + @Test + void cancelShouldReturnObjectToPool() { + + List> progress = new ArrayList<>(); + AsyncObjectFactory IN_PROGRESS = new AsyncObjectFactory() { + + @Override + public CompletableFuture create() { + + CompletableFuture future = new CompletableFuture<>(); + progress.add(future); + + return future; + } + + @Override + public CompletableFuture destroy(String object) { + destroyed.add(object); + return CompletableFuture.completedFuture(null); + } + + @Override + public CompletableFuture validate(String object) { + return CompletableFuture.completedFuture(true); + } + + }; + + BoundedAsyncPool pool = new BoundedAsyncPool<>(IN_PROGRESS, + BoundedPoolConfig.builder().maxTotal(1).maxIdle(0).build()); + + CompletableFuture acquire = pool.acquire(); + + assertThat(acquire).isNotCompleted(); + acquire.cancel(false); + assertThat(acquire).isCancelled(); + + progress.get(0).complete("after-cancel"); + assertThat(destroyed).contains("after-cancel"); + } + }