This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch POOL_2_X in repository https://gitbox.apache.org/repos/asf/commons-pool.git
commit 70991e8cd9ef0de7d5502af23f10dc35e371f67e Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Tue Jul 18 10:27:36 2023 -0400 Sort test methods --- .../org/apache/commons/pool2/TestException.java | 8 +- .../pool2/impl/DisconnectingWaiterFactory.java | 168 +++++++++--------- .../pool2/impl/TestGenericKeyedObjectPool.java | 194 ++++++++++----------- 3 files changed, 185 insertions(+), 185 deletions(-) diff --git a/src/test/java/org/apache/commons/pool2/TestException.java b/src/test/java/org/apache/commons/pool2/TestException.java index a18e58e6..04fc60ef 100644 --- a/src/test/java/org/apache/commons/pool2/TestException.java +++ b/src/test/java/org/apache/commons/pool2/TestException.java @@ -28,16 +28,16 @@ public class TestException extends Exception { // empty } - public TestException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); + public TestException(final String message) { + super(message); } public TestException(final String message, final Throwable cause) { super(message, cause); } - public TestException(final String message) { - super(message); + public TestException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); } public TestException(final Throwable cause) { diff --git a/src/test/java/org/apache/commons/pool2/impl/DisconnectingWaiterFactory.java b/src/test/java/org/apache/commons/pool2/impl/DisconnectingWaiterFactory.java index 36c6cfad..5b7429e9 100644 --- a/src/test/java/org/apache/commons/pool2/impl/DisconnectingWaiterFactory.java +++ b/src/test/java/org/apache/commons/pool2/impl/DisconnectingWaiterFactory.java @@ -29,17 +29,6 @@ import org.apache.commons.pool2.Waiter; import org.apache.commons.pool2.WaiterFactory; public class DisconnectingWaiterFactory<K> extends WaiterFactory<K> { - /** - * - * A WaiterFactory that simulates a resource required by factory methods going - * down (and coming back). - * <p> - * When connected, this factory behaves like a normal WaiterFactory. - * When disconnected, factory methods are determined by functional parameters. - * </p> - */ - private final AtomicBoolean connected = new AtomicBoolean(true); - private static final Duration DEFAULT_TIME_BETWEEN_CONNECTION_CHECKS = Duration.ofMillis(100); private static final Duration DEFAULT_MAX_WAIT = Duration.ofSeconds(10); @@ -68,6 +57,37 @@ public class DisconnectingWaiterFactory<K> extends WaiterFactory<K> { */ protected static final Predicate<PooledObject<Waiter>> DEFAULT_DISCONNECTED_VALIDATION_ACTION = w -> false; + /** + * Blocks until connected or maxWait is exceeded. + * + * @throws TimeoutException if maxWait is exceeded. + */ + private static void waitForConnection(final AtomicBoolean connected, + final Duration timeBetweenConnectionChecks, final Duration maxWait) { + final Instant start = Instant.now(); + while (!connected.get()) { + try { + Thread.sleep(timeBetweenConnectionChecks.toMillis()); + } catch (final InterruptedException e) { + e.printStackTrace(); + } + if (Duration.between(start, Instant.now()).compareTo(maxWait) > 0) { + throw new IllegalStateException(new TimeoutException("Timed out waiting for connection")); + } + } + } + + /** + * + * A WaiterFactory that simulates a resource required by factory methods going + * down (and coming back). + * <p> + * When connected, this factory behaves like a normal WaiterFactory. + * When disconnected, factory methods are determined by functional parameters. + * </p> + */ + private final AtomicBoolean connected = new AtomicBoolean(true); + /** Time between reconnection checks */ final Duration timeBetweenConnectionChecks; @@ -89,6 +109,11 @@ public class DisconnectingWaiterFactory<K> extends WaiterFactory<K> { /** Function to perform for validate when invoked in disconnected mode */ final Predicate<PooledObject<Waiter>> disconnectedValidationAction; + public DisconnectingWaiterFactory() { + this(DEFAULT_DISCONNECTED_CREATE_ACTION, DEFAULT_DISCONNECTED_LIFECYCLE_ACTION, + DEFAULT_DISCONNECTED_VALIDATION_ACTION); + } + public DisconnectingWaiterFactory(final long activateLatency, final long destroyLatency, final long makeLatency, final long passivateLatency, final long validateLatency, final long waiterLatency) { @@ -133,34 +158,57 @@ public class DisconnectingWaiterFactory<K> extends WaiterFactory<K> { this.disconnectedValidationAction = disconnectedValidationAction; } - public DisconnectingWaiterFactory() { - this(DEFAULT_DISCONNECTED_CREATE_ACTION, DEFAULT_DISCONNECTED_LIFECYCLE_ACTION, - DEFAULT_DISCONNECTED_VALIDATION_ACTION); - } - - private boolean validate(final PooledObject<Waiter> obj) { + private void activate(final PooledObject<Waiter> obj) { if (connected.get()) { - return super.validateObject(obj); + super.activateObject(obj); + } else { + disconnectedLifcycleAction.accept(obj); } - return disconnectedValidationAction.test(obj); } @Override - public boolean validateObject(final K key, final PooledObject<Waiter> obj) { - return validate(obj); + public void activateObject(final K key, final PooledObject<Waiter> obj) { + activate(obj); } @Override - public boolean validateObject(final PooledObject<Waiter> obj) { - return validate(obj); + public void activateObject(final PooledObject<Waiter> obj) { + activate(obj); } - private void activate(final PooledObject<Waiter> obj) { + /** + * Reconnect the factory. + */ + public void connect() { + connected.set(true); + } + /* + * TODO: add builder to clean up constructors and make maxWait, + * timeBetweenConnectionChecks configurable. + */ + + /** + * Disconnect the factory. + */ + public void disconnect() { + connected.set(false); + } + + private PooledObject<Waiter> make() { if (connected.get()) { - super.activateObject(obj); - } else { - disconnectedLifcycleAction.accept(obj); + return super.makeObject(); } + return disconnectedCreateAction.get(); + } + + @Override + public PooledObject<Waiter> makeObject() { + return make(); + } + + @Override + public PooledObject<Waiter> makeObject(final K key) { + return make(); } private void passivate(final PooledObject<Waiter> obj) { @@ -181,69 +229,21 @@ public class DisconnectingWaiterFactory<K> extends WaiterFactory<K> { passivate(obj); } - @Override - public void activateObject(final K key, final PooledObject<Waiter> obj) { - activate(obj); - } - - @Override - public void activateObject(final PooledObject<Waiter> obj) { - activate(obj); - } - - @Override - public PooledObject<Waiter> makeObject(final K key) { - return make(); - } - - @Override - public PooledObject<Waiter> makeObject() { - return make(); - } - - private PooledObject<Waiter> make() { + private boolean validate(final PooledObject<Waiter> obj) { if (connected.get()) { - return super.makeObject(); - } - return disconnectedCreateAction.get(); - } - - /** - * Blocks until connected or maxWait is exceeded. - * - * @throws TimeoutException if maxWait is exceeded. - */ - private static void waitForConnection(final AtomicBoolean connected, - final Duration timeBetweenConnectionChecks, final Duration maxWait) { - final Instant start = Instant.now(); - while (!connected.get()) { - try { - Thread.sleep(timeBetweenConnectionChecks.toMillis()); - } catch (final InterruptedException e) { - e.printStackTrace(); - } - if (Duration.between(start, Instant.now()).compareTo(maxWait) > 0) { - throw new IllegalStateException(new TimeoutException("Timed out waiting for connection")); - } + return super.validateObject(obj); } + return disconnectedValidationAction.test(obj); } - /** - * Disconnect the factory. - */ - public void disconnect() { - connected.set(false); + @Override + public boolean validateObject(final K key, final PooledObject<Waiter> obj) { + return validate(obj); } - /** - * Reconnect the factory. - */ - public void connect() { - connected.set(true); + @Override + public boolean validateObject(final PooledObject<Waiter> obj) { + return validate(obj); } - /* - * TODO: add builder to clean up constructors and make maxWait, - * timeBetweenConnectionChecks configurable. - */ } diff --git a/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java b/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java index ff24933a..51612780 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java @@ -993,102 +993,6 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { } } - /** - * Tests POOL-411, or least tries to reproduce the NPE, but does not. - * - * @throws TestException a test failure. - */ - @Test - public void testConcurrentBorrowAndClear() throws Exception { - final int threadCount = 64; - final int taskCount = 64; - final int addCount = 1; - final int borrowCycles = 1024; - final int clearCycles = 1024; - final boolean useYield = true; - - testConcurrentBorrowAndClear(threadCount, taskCount, addCount, borrowCycles, clearCycles, useYield); - } - - /** - * See https://issues.apache.org/jira/browse/POOL-411?focusedCommentId=17741156&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-17741156 - * - * @throws TestException a test failure. - */ - @Test - public void testConcurrentBorrowAndClear_JiraComment17741156() throws Exception { - final int threadCount = 2; - final int taskCount = 2; - final int addCount = 1; - final int borrowCycles = 5_000; - final int clearCycles = 5_000; - final boolean useYield = false; - - testConcurrentBorrowAndClear(threadCount, taskCount, addCount, borrowCycles, clearCycles, useYield); - } - - /** - * Tests POOL-411, or least tries to reproduce the NPE, but does not. - * - * @throws Exception a test failure. - */ - private void testConcurrentBorrowAndClear(final int threadCount, final int taskCount, final int addCount, final int borrowCycles, final int clearCycles, - final boolean useYield) throws Exception { - final GenericKeyedObjectPoolConfig<String> config = new GenericKeyedObjectPoolConfig<>(); - final int maxTotalPerKey = borrowCycles + 1; - config.setMaxTotalPerKey(threadCount); - config.setMaxIdlePerKey(threadCount); - config.setMaxTotal(maxTotalPerKey * threadCount); - config.setBlockWhenExhausted(false); // pool exhausted indicates a bug in the test - - gkoPool = new GenericKeyedObjectPool<>(simpleFactory, config); - final String key = "0"; - gkoPool.addObjects(Arrays.asList(key), threadCount); - // all objects in the pool are now idle. - - final ExecutorService threadPool = Executors.newFixedThreadPool(threadCount); - final List<Future<?>> futures = new ArrayList<>(); - try { - for (int t = 0; t < taskCount; t++) { - futures.add(threadPool.submit(() -> { - for (int i = 0; i < clearCycles; i++) { - if (useYield) { - Thread.yield(); - } - gkoPool.clear(key, true); - try { - gkoPool.addObjects(Arrays.asList(key), addCount); - } catch (Exception e) { - fail(e); - } - } - })); - futures.add(threadPool.submit(() -> { - try { - for (int i = 0; i < borrowCycles; i++) { - if (useYield) { - Thread.yield(); - } - final String pooled = gkoPool.borrowObject(key); - gkoPool.returnObject(key, pooled); - } - } catch (Exception e) { - fail(e); - } - })); - } - futures.forEach(f -> { - try { - f.get(); - } catch (InterruptedException | ExecutionException e) { - fail(e); - } - }); - } finally { - threadPool.shutdownNow(); - } - } - /** * POOL-192 * Verify that clear(key) does not leak capacity. @@ -1155,7 +1059,6 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { } } - /** * POOL-391 Verify that when clear(key) is called with reuseCapacity true, * capacity freed is reused and allocated to most loaded pools. @@ -1301,6 +1204,103 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { } } + + /** + * Tests POOL-411, or least tries to reproduce the NPE, but does not. + * + * @throws TestException a test failure. + */ + @Test + public void testConcurrentBorrowAndClear() throws Exception { + final int threadCount = 64; + final int taskCount = 64; + final int addCount = 1; + final int borrowCycles = 1024; + final int clearCycles = 1024; + final boolean useYield = true; + + testConcurrentBorrowAndClear(threadCount, taskCount, addCount, borrowCycles, clearCycles, useYield); + } + + /** + * Tests POOL-411, or least tries to reproduce the NPE, but does not. + * + * @throws Exception a test failure. + */ + private void testConcurrentBorrowAndClear(final int threadCount, final int taskCount, final int addCount, final int borrowCycles, final int clearCycles, + final boolean useYield) throws Exception { + final GenericKeyedObjectPoolConfig<String> config = new GenericKeyedObjectPoolConfig<>(); + final int maxTotalPerKey = borrowCycles + 1; + config.setMaxTotalPerKey(threadCount); + config.setMaxIdlePerKey(threadCount); + config.setMaxTotal(maxTotalPerKey * threadCount); + config.setBlockWhenExhausted(false); // pool exhausted indicates a bug in the test + + gkoPool = new GenericKeyedObjectPool<>(simpleFactory, config); + final String key = "0"; + gkoPool.addObjects(Arrays.asList(key), threadCount); + // all objects in the pool are now idle. + + final ExecutorService threadPool = Executors.newFixedThreadPool(threadCount); + final List<Future<?>> futures = new ArrayList<>(); + try { + for (int t = 0; t < taskCount; t++) { + futures.add(threadPool.submit(() -> { + for (int i = 0; i < clearCycles; i++) { + if (useYield) { + Thread.yield(); + } + gkoPool.clear(key, true); + try { + gkoPool.addObjects(Arrays.asList(key), addCount); + } catch (Exception e) { + fail(e); + } + } + })); + futures.add(threadPool.submit(() -> { + try { + for (int i = 0; i < borrowCycles; i++) { + if (useYield) { + Thread.yield(); + } + final String pooled = gkoPool.borrowObject(key); + gkoPool.returnObject(key, pooled); + } + } catch (Exception e) { + fail(e); + } + })); + } + futures.forEach(f -> { + try { + f.get(); + } catch (InterruptedException | ExecutionException e) { + fail(e); + } + }); + } finally { + threadPool.shutdownNow(); + } + } + + /** + * See https://issues.apache.org/jira/browse/POOL-411?focusedCommentId=17741156&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-17741156 + * + * @throws TestException a test failure. + */ + @Test + public void testConcurrentBorrowAndClear_JiraComment17741156() throws Exception { + final int threadCount = 2; + final int taskCount = 2; + final int addCount = 1; + final int borrowCycles = 5_000; + final int clearCycles = 5_000; + final boolean useYield = false; + + testConcurrentBorrowAndClear(threadCount, taskCount, addCount, borrowCycles, clearCycles, useYield); + } + /** * POOL-231 - verify that concurrent invalidates of the same object do not * corrupt pool destroyCount.