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 080206716313361eb9fb06eee442c56d5e67d9ba Author: Gary D. Gregory <[email protected]> AuthorDate: Tue Feb 11 07:10:13 2025 -0500 Enable Checkstyle for tests --- pom.xml | 6 +- src/conf/checkstyle-suppressions.xml | 24 + src/conf/checkstyle.xml | 3 - .../commons/pool2/AbstractTestKeyedObjectPool.java | 24 +- .../commons/pool2/AbstractTestObjectPool.java | 14 +- .../pool2/TestBaseKeyedPooledObjectFactory.java | 2 +- .../apache/commons/pool2/TestBaseObjectPool.java | 3 + src/test/java/org/apache/commons/pool2/Waiter.java | 20 +- .../commons/pool2/impl/AtomicIntegerFactory.java | 2 +- .../apache/commons/pool2/impl/CallStackTest.java | 2 +- .../pool2/impl/DisconnectingWaiterFactory.java | 5 +- .../commons/pool2/impl/NoOpCallStackTest.java | 2 +- .../pool2/impl/TestDefaultPooledObject.java | 2 +- .../commons/pool2/impl/TestEvictionTimer.java | 2 +- .../pool2/impl/TestGenericKeyedObjectPool.java | 32 +- .../commons/pool2/impl/TestGenericObjectPool.java | 555 ++++++--------------- .../pool2/impl/TestGenericObjectPoolConfig.java | 4 +- .../TestGenericObjectPoolFactoryCreateFailure.java | 2 +- .../commons/pool2/impl/TestSoftRefOutOfMemory.java | 11 +- .../impl/TestSynchronizedPooledObjectFactory.java | 189 ++++--- .../commons/pool2/performance/PerformanceTest.java | 140 +++--- .../pool2/pool407/AbstractPool407Factory.java | 2 + .../pool2/pool407/KeyedPool407NormalFactory.java | 5 +- .../commons/pool2/pool407/KeyedPool407Test.java | 3 +- .../pool2/pool407/Pool407NormalFactory.java | 3 +- 25 files changed, 395 insertions(+), 662 deletions(-) diff --git a/pom.xml b/pom.xml index 3ecaf8f8..3f4175a0 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ <commons.componentid>pool</commons.componentid> <commons.module.name>org.apache.commons.pool2</commons.module.name> <commons.rc.version>RC3</commons.rc.version> - + <checkstyle.suppress.file>${basedir}/src/conf/checkstyle-suppressions.xml</checkstyle.suppress.file> <!-- Java 8 --> <commons.release.version>2.12.1</commons.release.version> <commons.release.next>2.12.2</commons.release.next> @@ -135,8 +135,10 @@ <artifactId>maven-checkstyle-plugin</artifactId> <configuration> <configLocation>${basedir}/src/conf/checkstyle.xml</configLocation> - <enableRulesSummary>false</enableRulesSummary> <headerLocation>${basedir}/license-header.txt</headerLocation> + <suppressionsLocation>${checkstyle.suppress.file}</suppressionsLocation> + <enableRulesSummary>false</enableRulesSummary> + <includeTestSourceDirectory>true</includeTestSourceDirectory> </configuration> </plugin> <plugin> diff --git a/src/conf/checkstyle-suppressions.xml b/src/conf/checkstyle-suppressions.xml new file mode 100644 index 00000000..9701a56c --- /dev/null +++ b/src/conf/checkstyle-suppressions.xml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> +<!DOCTYPE suppressions PUBLIC + "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" + "https://checkstyle.org/dtds/suppressions_1_2.dtd"> +<!-- SEE: http://checkstyle.sourceforge.net/config.html#Examples --> +<suppressions> + <suppress checks="JavadocPackage" files="src[/\\]test[/\\]java[/\\]" /> +</suppressions> diff --git a/src/conf/checkstyle.xml b/src/conf/checkstyle.xml index c0110e0f..c24c5586 100644 --- a/src/conf/checkstyle.xml +++ b/src/conf/checkstyle.xml @@ -72,9 +72,6 @@ <module name="JavadocVariable"> <property name="scope" value="protected" /> </module> - <module name="OperatorWrap"> - <property name="option" value="eol" /> - </module> <module name="ParenPad" /> <module name="TypecastParenPad" /> <module name="VisibilityModifier"> diff --git a/src/test/java/org/apache/commons/pool2/AbstractTestKeyedObjectPool.java b/src/test/java/org/apache/commons/pool2/AbstractTestKeyedObjectPool.java index 11a93603..1b5706ec 100644 --- a/src/test/java/org/apache/commons/pool2/AbstractTestKeyedObjectPool.java +++ b/src/test/java/org/apache/commons/pool2/AbstractTestKeyedObjectPool.java @@ -172,7 +172,7 @@ public abstract class AbstractTestKeyedObjectPool { } } - protected static final String KEY = "key"; + private static final String KEY = "key"; private KeyedObjectPool<Object, Object> pool; @@ -209,6 +209,7 @@ public abstract class AbstractTestKeyedObjectPool { * throw {@link IllegalArgumentException} * if such a pool cannot be created. * + * @param <E> The exception type. * @param minCapacity Minimum capacity of the pool to create * @return the newly created keyed object pool */ @@ -558,14 +559,11 @@ public abstract class AbstractTestKeyedObjectPool { return; // test not supported } final List<MethodCall> expectedMethods = new ArrayList<>(); - Object obj; - + final Object obj; if (pool instanceof GenericKeyedObjectPool) { ((GenericKeyedObjectPool<Object, Object>) pool).setTestOnBorrow(true); } - // Test correct behavior code paths - // existing idle object should be activated and validated pool.addObject(KEY); clear(factory, expectedMethods); @@ -574,23 +572,18 @@ public abstract class AbstractTestKeyedObjectPool { expectedMethods.add(new MethodCall("validateObject", KEY, ZERO).returned(Boolean.TRUE)); assertEquals(expectedMethods, factory.getMethodCalls()); pool.returnObject(KEY, obj); - // Test exception handling of borrowObject reset(pool, factory, expectedMethods); - // makeObject Exceptions should be propagated to client code from borrowObject factory.setMakeObjectFail(true); - assertThrows(PrivateException.class, () -> pool.borrowObject(KEY), - "Expected borrowObject to propagate makeObject exception."); + assertThrows(PrivateException.class, () -> pool.borrowObject(KEY), "Expected borrowObject to propagate makeObject exception."); expectedMethods.add(new MethodCall("makeObject", KEY)); assertEquals(expectedMethods, factory.getMethodCalls()); - // when activateObject fails in borrowObject, a new object should be // borrowed/created reset(pool, factory, expectedMethods); pool.addObject(KEY); clear(factory, expectedMethods); - factory.setActivateObjectFail(true); expectedMethods.add(new MethodCall("activateObject", KEY, obj)); assertThrows(NoSuchElementException.class, () -> pool.borrowObject(KEY)); @@ -601,13 +594,11 @@ public abstract class AbstractTestKeyedObjectPool { AbstractTestObjectPool.removeDestroyObjectCall(factory.getMethodCalls()); // The exact timing of destroyObject // is flexible here. assertEquals(expectedMethods, factory.getMethodCalls()); - // when validateObject fails in borrowObject, a new object should be // borrowed/created reset(pool, factory, expectedMethods); pool.addObject(KEY); clear(factory, expectedMethods); - factory.setValidateObjectFail(true); // testOnBorrow is on, so this will throw when the newly created instance // fails validation @@ -650,7 +641,7 @@ public abstract class AbstractTestKeyedObjectPool { @Test public void testKPOFCloseUsages() throws Exception { final FailingKeyedPooledObjectFactory factory = new FailingKeyedPooledObjectFactory(); - KeyedObjectPool<Object, Object> pool; + final KeyedObjectPool<Object, Object> pool; try { pool = makeEmptyPool(factory); } catch (final UnsupportedOperationException uoe) { @@ -680,11 +671,8 @@ public abstract class AbstractTestKeyedObjectPool { return; // test not supported } final List<MethodCall> expectedMethods = new ArrayList<>(); - Object obj; - // Test correct behavior code paths - - obj = pool.borrowObject(KEY); + final Object obj = pool.borrowObject(KEY); clear(factory, expectedMethods); // invalidated object should be destroyed diff --git a/src/test/java/org/apache/commons/pool2/AbstractTestObjectPool.java b/src/test/java/org/apache/commons/pool2/AbstractTestObjectPool.java index 4d3800eb..d6cf1ccc 100644 --- a/src/test/java/org/apache/commons/pool2/AbstractTestObjectPool.java +++ b/src/test/java/org/apache/commons/pool2/AbstractTestObjectPool.java @@ -42,11 +42,13 @@ public abstract class AbstractTestObjectPool { calls.removeIf(call -> "destroyObject".equals(call.getName())); } - private static void reset(final ObjectPool<Object> pool, final MethodCallPoolableObjectFactory factory, final List<MethodCall> expectedMethods) throws Exception { + private static void reset(final ObjectPool<Object> pool, final MethodCallPoolableObjectFactory factory, final List<MethodCall> expectedMethods) + throws Exception { pool.clear(); clear(factory, expectedMethods); factory.reset(); } + // Deliberate choice to create a new object in case future unit tests check // for a specific object. private final Integer ZERO = Integer.valueOf(0); @@ -173,14 +175,13 @@ public abstract class AbstractTestObjectPool { ((GenericObjectPool<Object>) pool).setTestOnBorrow(true); } final List<MethodCall> expectedMethods = new ArrayList<>(); - Object obj; // Test correct behavior code paths // existing idle object should be activated and validated pool.addObject(); clear(factory, expectedMethods); - obj = pool.borrowObject(); + final Object obj = pool.borrowObject(); expectedMethods.add(new MethodCall("activateObject", ZERO)); expectedMethods.add(new MethodCall("validateObject", ZERO).returned(Boolean.TRUE)); assertEquals(expectedMethods, factory.getMethodCalls()); @@ -291,18 +292,13 @@ public abstract class AbstractTestObjectPool { return; // test not supported } final List<MethodCall> expectedMethods = new ArrayList<>(); - Object obj; - // Test correct behavior code paths - - obj = pool.borrowObject(); + final Object obj = pool.borrowObject(); clear(factory, expectedMethods); - // invalidated object should be destroyed pool.invalidateObject(obj); expectedMethods.add(new MethodCall("destroyObject", obj)); assertEquals(expectedMethods, factory.getMethodCalls()); - // Test exception handling of invalidateObject reset(pool, factory, expectedMethods); final Object obj2 = pool.borrowObject(); diff --git a/src/test/java/org/apache/commons/pool2/TestBaseKeyedPooledObjectFactory.java b/src/test/java/org/apache/commons/pool2/TestBaseKeyedPooledObjectFactory.java index 6e2ab825..8018ba35 100644 --- a/src/test/java/org/apache/commons/pool2/TestBaseKeyedPooledObjectFactory.java +++ b/src/test/java/org/apache/commons/pool2/TestBaseKeyedPooledObjectFactory.java @@ -45,4 +45,4 @@ public class TestBaseKeyedPooledObjectFactory { factory.destroyObject("key", null); // a no-op assertTrue(factory.validateObject("key", null)); // constant true } -} \ No newline at end of file +} diff --git a/src/test/java/org/apache/commons/pool2/TestBaseObjectPool.java b/src/test/java/org/apache/commons/pool2/TestBaseObjectPool.java index c65d5257..bc430cef 100644 --- a/src/test/java/org/apache/commons/pool2/TestBaseObjectPool.java +++ b/src/test/java/org/apache/commons/pool2/TestBaseObjectPool.java @@ -71,6 +71,9 @@ public class TestBaseObjectPool extends AbstractTestObjectPool { } /** + * This implementation either fails or throws UnsupportedOperationException. + * + * @param <E> The exception type. * @param minCapacity Ignored by this implemented. Used by sub-classes. * @return A newly created empty pool */ diff --git a/src/test/java/org/apache/commons/pool2/Waiter.java b/src/test/java/org/apache/commons/pool2/Waiter.java index 0a3166a4..b5400612 100644 --- a/src/test/java/org/apache/commons/pool2/Waiter.java +++ b/src/test/java/org/apache/commons/pool2/Waiter.java @@ -17,8 +17,11 @@ package org.apache.commons.pool2; +import java.time.Duration; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.lang3.ThreadUtils; + /** * <p>Object created by {@link WaiterFactory}. Maintains active / valid state, * last passivated and idle times. Waits with configurable latency when @@ -28,14 +31,19 @@ import java.util.concurrent.atomic.AtomicInteger; */ public class Waiter { private static final AtomicInteger instanceCount = new AtomicInteger(); - /** TODO Reuse Apache Commons Lang ThreadUtils */ + + /** + * Sleeps for the given duration while ignoring {@link InterruptedException}. + * <p> + * The sleep duration may be shorter than duration if we catch a {@link InterruptedException}. + * </p> + * + * @param millis the length of time to sleep in milliseconds. + */ public static void sleepQuietly(final long millis) { - try { - Thread.sleep(millis); - } catch (final InterruptedException e) { - // be quiet - } + ThreadUtils.sleepQuietly(Duration.ofMillis(millis)); } + private boolean active; private boolean valid; private long latency; diff --git a/src/test/java/org/apache/commons/pool2/impl/AtomicIntegerFactory.java b/src/test/java/org/apache/commons/pool2/impl/AtomicIntegerFactory.java index 015c5bd1..1cd740d8 100644 --- a/src/test/java/org/apache/commons/pool2/impl/AtomicIntegerFactory.java +++ b/src/test/java/org/apache/commons/pool2/impl/AtomicIntegerFactory.java @@ -105,4 +105,4 @@ public class AtomicIntegerFactory public PooledObject<AtomicInteger> wrap(final AtomicInteger integer) { return new DefaultPooledObject<>(integer); } -} \ No newline at end of file +} diff --git a/src/test/java/org/apache/commons/pool2/impl/CallStackTest.java b/src/test/java/org/apache/commons/pool2/impl/CallStackTest.java index 6c8c56af..9856f4fb 100644 --- a/src/test/java/org/apache/commons/pool2/impl/CallStackTest.java +++ b/src/test/java/org/apache/commons/pool2/impl/CallStackTest.java @@ -60,4 +60,4 @@ public class CallStackTest { final String stackTrace = writer.toString(); assertTrue(stackTrace.contains(getClass().getName())); } -} \ No newline at end of file +} 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 11e643d5..b3f89d7a 100644 --- a/src/test/java/org/apache/commons/pool2/impl/DisconnectingWaiterFactory.java +++ b/src/test/java/org/apache/commons/pool2/impl/DisconnectingWaiterFactory.java @@ -57,13 +57,12 @@ 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) { + private static void waitForConnection(final AtomicBoolean connected, final Duration timeBetweenConnectionChecks, final Duration maxWait) { final Instant start = Instant.now(); while (!connected.get()) { try { diff --git a/src/test/java/org/apache/commons/pool2/impl/NoOpCallStackTest.java b/src/test/java/org/apache/commons/pool2/impl/NoOpCallStackTest.java index 091152ce..4b393c6c 100644 --- a/src/test/java/org/apache/commons/pool2/impl/NoOpCallStackTest.java +++ b/src/test/java/org/apache/commons/pool2/impl/NoOpCallStackTest.java @@ -32,4 +32,4 @@ public class NoOpCallStackTest { stack.printStackTrace(new PrintWriter(writer)); assertEquals("", writer.toString()); } -} \ No newline at end of file +} diff --git a/src/test/java/org/apache/commons/pool2/impl/TestDefaultPooledObject.java b/src/test/java/org/apache/commons/pool2/impl/TestDefaultPooledObject.java index d2088eb2..0b788c97 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestDefaultPooledObject.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestDefaultPooledObject.java @@ -159,4 +159,4 @@ public class TestDefaultPooledObject { assertTrue(dpo.getIdleDuration().compareTo(dpo.getActiveTime()) <= 0); assertTrue(dpo.getIdleDuration().toMillis() <= dpo.getActiveTimeMillis()); } -} \ No newline at end of file +} diff --git a/src/test/java/org/apache/commons/pool2/impl/TestEvictionTimer.java b/src/test/java/org/apache/commons/pool2/impl/TestEvictionTimer.java index a7284f52..9e332d4c 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestEvictionTimer.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestEvictionTimer.java @@ -104,4 +104,4 @@ public class TestEvictionTimer { assertEquals(0, EvictionTimer.getNumTasks()); } } -} \ No newline at end of file +} 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 24f008f7..0f00a466 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java @@ -114,7 +114,7 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { /** * Attempts to invalidate an object, swallowing IllegalStateException. */ - static class InvalidateThread implements Runnable { + private static class InvalidateThread implements Runnable { private final String obj; private final KeyedObjectPool<String, String> pool; @@ -309,13 +309,15 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { /** * Very simple test thread that just tries to borrow an object from - * the provided pool with the specified key and returns it + * the provided pool with the specified key and returns it. + * + * @param <T> Type of element in the pool. */ - static class SimpleTestThread<T> implements Runnable { + private static class SimpleTestThread<T> implements Runnable { private final KeyedObjectPool<String, T> pool; private final String key; - public SimpleTestThread(final KeyedObjectPool<String, T> pool, final String key) { + SimpleTestThread(final KeyedObjectPool<String, T> pool, final String key) { this.pool = pool; this.key = key; } @@ -331,7 +333,9 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { } /** - * DefaultEvictionPolicy modified to add latency + * DefaultEvictionPolicy modified to add latency. + * + * @param <T> the type of objects in the pool. */ private static final class SlowEvictionPolicy<T> extends DefaultEvictionPolicy<T> { private final long delay; @@ -341,7 +345,7 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { * * @param delay number of ms of latency to inject in evict */ - public SlowEvictionPolicy(final long delay) { + SlowEvictionPolicy(final long delay) { this.delay = delay; } @@ -353,7 +357,7 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { } } - static class TestThread<T> implements Runnable { + private static class TestThread<T> implements Runnable { private final Random random = new Random(); /** GKOP to hit */ @@ -775,8 +779,9 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { } } - private String formatSettings(final String title, final String s, final int i, final String s0, final boolean b0, final String s1, final int i1, final String s2, final int i2, final String s3, final int i3, - final String s4, final int i4, final String s5, final int i5, final String s6, final int i6, final int zeroLength, final int oneLength, final int twoLength){ + private String formatSettings(final String title, final String s, final int i, final String s0, final boolean b0, final String s1, final int i1, + final String s2, final int i2, final String s3, final int i3, final String s4, final int i4, final String s5, final int i5, final String s6, + final int i6, final int zeroLength, final int oneLength, final int twoLength) { final StringBuilder sb = new StringBuilder(80); sb.append(title).append(' '); sb.append(s).append('=').append(i).append(' '); @@ -1216,7 +1221,7 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { 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. @@ -1279,9 +1284,11 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { } /** - * See https://issues.apache.org/jira/browse/POOL-411?focusedCommentId=17741156&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-17741156 + * 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. + * @throws Exception a test failure. */ @Test public void testConcurrentBorrowAndClear_JiraComment17741156() throws Exception { @@ -1291,7 +1298,6 @@ public class TestGenericKeyedObjectPool extends AbstractTestKeyedObjectPool { final int borrowCycles = 5_000; final int clearCycles = 5_000; final boolean useYield = false; - testConcurrentBorrowAndClear(threadCount, taskCount, addCount, borrowCycles, clearCycles, useYield); } diff --git a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java index 0060d752..133af3da 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPool.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.commons.pool2.impl; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -71,10 +70,9 @@ import org.junit.jupiter.api.Timeout; /** */ public class TestGenericObjectPool extends TestBaseObjectPool { - private final class ConcurrentBorrowAndEvictThread extends Thread { private final boolean borrow; - public String obj; + String obj; public ConcurrentBorrowAndEvictThread(final boolean borrow) { this.borrow = borrow; @@ -95,7 +93,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } private static final class CreateErrorFactory extends BasePooledObjectFactory<String> { - private final Semaphore semaphore = new Semaphore(0); @Override @@ -119,7 +116,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } private static final class CreateFailFactory extends BasePooledObjectFactory<String> { - private final Semaphore semaphore = new Semaphore(0); @Override @@ -142,12 +138,12 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } } - private static final class DummyFactory - extends BasePooledObjectFactory<Object> { + private static final class DummyFactory extends BasePooledObjectFactory<Object> { @Override public Object create() { return null; } + @Override public PooledObject<Object> wrap(final Object value) { return new DefaultPooledObject<>(value); @@ -155,7 +151,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } private static final class EvictionThread<T> extends Thread { - private final GenericObjectPool<T> pool; public EvictionThread(final GenericObjectPool<T> pool) { @@ -173,16 +168,15 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /** - * Factory that creates HashSets. Note that this means - * 0) All instances are initially equal (not discernible by equals) - * 1) Instances are mutable and mutation can cause change in identity / hash code. + * Factory that creates HashSets. Note that this means 0) All instances are initially equal (not discernible by equals) 1) Instances are mutable and + * mutation can cause change in identity / hash code. */ - private static final class HashSetFactory - extends BasePooledObjectFactory<HashSet<String>> { + private static final class HashSetFactory extends BasePooledObjectFactory<HashSet<String>> { @Override public HashSet<String> create() { return new HashSet<>(); } + @Override public PooledObject<HashSet<String>> wrap(final HashSet<String> value) { return new DefaultPooledObject<>(value); @@ -196,13 +190,16 @@ public class TestGenericObjectPool extends TestBaseObjectPool { private final String obj; private final ObjectPool<String> pool; private boolean done; + public InvalidateThread(final ObjectPool<String> pool, final String obj) { this.obj = obj; this.pool = pool; } + public boolean complete() { return done; } + @Override public void run() { try { @@ -217,13 +214,12 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } } - private static final class InvalidFactory - extends BasePooledObjectFactory<Object> { - + private static final class InvalidFactory extends BasePooledObjectFactory<Object> { @Override public Object create() { return new Object(); } + @Override public boolean validateObject(final PooledObject<Object> obj) { Waiter.sleepQuietly(1000); @@ -238,33 +234,19 @@ public class TestGenericObjectPool extends TestBaseObjectPool { public static class SimpleFactory implements PooledObjectFactory<String> { int makeCounter; - int activationCounter; - int validateCounter; - int activeCount; - boolean evenValid = true; - boolean oddValid = true; - boolean exceptionOnPassivate; - boolean exceptionOnActivate; - boolean exceptionOnDestroy; - boolean exceptionOnValidate; - boolean enableValidation = true; - long destroyLatency; - long makeLatency; - long validateLatency; - int maxTotal = Integer.MAX_VALUE; public SimpleFactory() { @@ -338,8 +320,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool { synchronized (this) { activeCount++; if (activeCount > maxTotal) { - throw new IllegalStateException( - "Too many active instances: " + activeCount); + throw new IllegalStateException("Too many active instances: " + activeCount); } waitLatency = makeLatency; } @@ -436,46 +417,36 @@ public class TestGenericObjectPool extends TestBaseObjectPool { throw new RuntimeException("validation failed"); } if (validate) { - return counter%2 == 0 ? evenTest : oddTest; + return counter % 2 == 0 ? evenTest : oddTest; } return true; } } public static class TestEvictionPolicy<T> implements EvictionPolicy<T> { - private final AtomicInteger callCount = new AtomicInteger(); @Override - public boolean evict(final EvictionConfig config, final PooledObject<T> underTest, - final int idleCount) { + public boolean evict(final EvictionConfig config, final PooledObject<T> underTest, final int idleCount) { return callCount.incrementAndGet() > 1500; } } static class TestThread<T> implements Runnable { - /** Source of random delay times */ private final Random random; - /** Pool to borrow from */ private final ObjectPool<T> pool; - /** Number of borrow attempts */ private final int iter; - /** Delay before each borrow attempt */ private final int startDelay; - /** Time to hold each borrowed object before returning it */ private final int holdTime; - /** Whether or not start and hold time are randomly generated */ private final boolean randomDelay; - /** Object expected to be borrowed (fail otherwise) */ private final Object expectedObject; - private volatile boolean complete; private volatile boolean failed; private volatile Throwable error; @@ -492,26 +463,23 @@ public class TestGenericObjectPool extends TestBaseObjectPool { this(pool, iter, delay, true, null); } - public TestThread(final ObjectPool<T> pool, final int iter, final int delay, - final boolean randomDelay) { + public TestThread(final ObjectPool<T> pool, final int iter, final int delay, final boolean randomDelay) { this(pool, iter, delay, randomDelay, null); } - public TestThread(final ObjectPool<T> pool, final int iter, final int delay, - final boolean randomDelay, final Object obj) { + public TestThread(final ObjectPool<T> pool, final int iter, final int delay, final boolean randomDelay, final Object obj) { this(pool, iter, delay, delay, randomDelay, obj); } - public TestThread(final ObjectPool<T> pool, final int iter, final int startDelay, - final int holdTime, final boolean randomDelay, final Object obj) { - this.pool = pool; - this.iter = iter; - this.startDelay = startDelay; - this.holdTime = holdTime; - this.randomDelay = randomDelay; - this.random = this.randomDelay ? new Random() : null; - this.expectedObject = obj; - } + public TestThread(final ObjectPool<T> pool, final int iter, final int startDelay, final int holdTime, final boolean randomDelay, final Object obj) { + this.pool = pool; + this.iter = iter; + this.startDelay = startDelay; + this.holdTime = holdTime; + this.randomDelay = randomDelay; + this.random = this.randomDelay ? new Random() : null; + this.expectedObject = obj; + } public boolean complete() { return complete; @@ -536,14 +504,12 @@ public class TestGenericObjectPool extends TestBaseObjectPool { complete = true; break; } - if (expectedObject != null && !expectedObject.equals(obj)) { error = new Throwable("Expected: " + expectedObject + " found: " + obj); failed = true; complete = true; break; } - Waiter.sleepQuietly(actualHoldTime); try { pool.returnObject(obj); @@ -559,16 +525,14 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /* - * Very simple test thread that just tries to borrow an object from - * the provided pool returns it after a wait + * Very simple test thread that just tries to borrow an object from the provided pool returns it after a wait */ static class WaitingTestThread extends Thread { private final GenericObjectPool<String> pool; private final long pause; private Throwable thrown; - private long preBorrowMillis; // just before borrow - private long postBorrowMillis; // borrow returned + private long postBorrowMillis; // borrow returned private long postReturnMillis; // after object was returned private long endedMillis; private String objectId; @@ -591,58 +555,40 @@ public class TestGenericObjectPool extends TestBaseObjectPool { postReturnMillis = System.currentTimeMillis(); } catch (final Throwable e) { thrown = e; - } finally{ + } finally { endedMillis = System.currentTimeMillis(); } } } - private static final boolean DISPLAY_THREAD_DETAILS= - Boolean.getBoolean("TestGenericObjectPool.display.thread.details"); // To pass this to a Maven test, use: // mvn test -DargLine="-DTestGenericObjectPool.display.thread.details=true" // @see https://issues.apache.org/jira/browse/SUREFIRE-121 - - protected GenericObjectPool<String> genericObjectPool; - + private static final boolean DISPLAY_THREAD_DETAILS = Boolean.getBoolean("TestGenericObjectPool.display.thread.details"); + private GenericObjectPool<String> genericObjectPool; private SimpleFactory simpleFactory; @SuppressWarnings("deprecation") private void assertConfiguration(final GenericObjectPoolConfig<?> expected, final GenericObjectPool<?> actual) { - assertEquals(Boolean.valueOf(expected.getTestOnCreate()), Boolean.valueOf(actual.getTestOnCreate()), - "testOnCreate"); - assertEquals(Boolean.valueOf(expected.getTestOnBorrow()), Boolean.valueOf(actual.getTestOnBorrow()), - "testOnBorrow"); - assertEquals(Boolean.valueOf(expected.getTestOnReturn()), Boolean.valueOf(actual.getTestOnReturn()), - "testOnReturn"); - assertEquals(Boolean.valueOf(expected.getTestWhileIdle()), Boolean.valueOf(actual.getTestWhileIdle()), - "testWhileIdle"); - assertEquals(Boolean.valueOf(expected.getBlockWhenExhausted()), Boolean.valueOf(actual.getBlockWhenExhausted()), - "whenExhaustedAction"); + assertEquals(Boolean.valueOf(expected.getTestOnCreate()), Boolean.valueOf(actual.getTestOnCreate()), "testOnCreate"); + assertEquals(Boolean.valueOf(expected.getTestOnBorrow()), Boolean.valueOf(actual.getTestOnBorrow()), "testOnBorrow"); + assertEquals(Boolean.valueOf(expected.getTestOnReturn()), Boolean.valueOf(actual.getTestOnReturn()), "testOnReturn"); + assertEquals(Boolean.valueOf(expected.getTestWhileIdle()), Boolean.valueOf(actual.getTestWhileIdle()), "testWhileIdle"); + assertEquals(Boolean.valueOf(expected.getBlockWhenExhausted()), Boolean.valueOf(actual.getBlockWhenExhausted()), "whenExhaustedAction"); assertEquals(expected.getMaxTotal(), actual.getMaxTotal(), "maxTotal"); assertEquals(expected.getMaxIdle(), actual.getMaxIdle(), "maxIdle"); assertEquals(expected.getMaxWaitMillis(), actual.getMaxWaitMillis(), "maxWaitDuration"); assertEquals(expected.getMaxWaitDuration(), actual.getMaxWaitDuration(), "maxWaitDuration"); - assertEquals(expected.getMinEvictableIdleTimeMillis(), actual.getMinEvictableIdleTimeMillis(), - "minEvictableIdleTimeMillis"); - assertEquals(expected.getMinEvictableIdleTime(), actual.getMinEvictableIdleTime(), - "minEvictableIdleTime"); - assertEquals(expected.getMinEvictableIdleDuration(), actual.getMinEvictableIdleDuration(), - "minEvictableIdleDuration"); - assertEquals(expected.getNumTestsPerEvictionRun(), actual.getNumTestsPerEvictionRun(), - "numTestsPerEvictionRun"); - assertEquals(expected.getEvictorShutdownTimeoutDuration(), actual.getEvictorShutdownTimeoutDuration(), - "evictorShutdownTimeoutDuration"); - assertEquals(expected.getEvictorShutdownTimeoutMillis(), actual.getEvictorShutdownTimeoutMillis(), - "evictorShutdownTimeoutMillis"); - assertEquals(expected.getEvictorShutdownTimeout(), actual.getEvictorShutdownTimeout(), - "evictorShutdownTimeout"); - assertEquals(expected.getTimeBetweenEvictionRunsMillis(), actual.getTimeBetweenEvictionRunsMillis(), - "timeBetweenEvictionRunsMillis"); - assertEquals(expected.getDurationBetweenEvictionRuns(), actual.getTimeBetweenEvictionRuns(), - "timeBetweenEvictionRuns"); - assertEquals(expected.getTimeBetweenEvictionRuns(), actual.getTimeBetweenEvictionRuns(), - "timeBetweenEvictionRuns"); + assertEquals(expected.getMinEvictableIdleTimeMillis(), actual.getMinEvictableIdleTimeMillis(), "minEvictableIdleTimeMillis"); + assertEquals(expected.getMinEvictableIdleTime(), actual.getMinEvictableIdleTime(), "minEvictableIdleTime"); + assertEquals(expected.getMinEvictableIdleDuration(), actual.getMinEvictableIdleDuration(), "minEvictableIdleDuration"); + assertEquals(expected.getNumTestsPerEvictionRun(), actual.getNumTestsPerEvictionRun(), "numTestsPerEvictionRun"); + assertEquals(expected.getEvictorShutdownTimeoutDuration(), actual.getEvictorShutdownTimeoutDuration(), "evictorShutdownTimeoutDuration"); + assertEquals(expected.getEvictorShutdownTimeoutMillis(), actual.getEvictorShutdownTimeoutMillis(), "evictorShutdownTimeoutMillis"); + assertEquals(expected.getEvictorShutdownTimeout(), actual.getEvictorShutdownTimeout(), "evictorShutdownTimeout"); + assertEquals(expected.getTimeBetweenEvictionRunsMillis(), actual.getTimeBetweenEvictionRunsMillis(), "timeBetweenEvictionRunsMillis"); + assertEquals(expected.getDurationBetweenEvictionRuns(), actual.getTimeBetweenEvictionRuns(), "timeBetweenEvictionRuns"); + assertEquals(expected.getTimeBetweenEvictionRuns(), actual.getTimeBetweenEvictionRuns(), "timeBetweenEvictionRuns"); } private void checkEvict(final boolean lifo) throws Exception { @@ -741,7 +687,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } } } - trackerFactory = new VisitTrackerFactory<>(); try (GenericObjectPool<VisitTracker<Object>> trackerPool = new GenericObjectPool<>(trackerFactory)) { trackerPool.setNumTestsPerEvictionRun(3); @@ -770,15 +715,12 @@ public class TestGenericObjectPool extends TestBaseObjectPool { for (int i = 0; i < 8; i++) { final VisitTracker<Object> tracker = trackerPool.borrowObject(); if (tracker.getId() != 0) { - assertEquals(1, tracker.getValidateCount(), - "Instance " + tracker.getId() + " visited wrong number of times."); + assertEquals(1, tracker.getValidateCount(), "Instance " + tracker.getId() + " visited wrong number of times."); } else { - assertEquals(2, tracker.getValidateCount(), - "Instance " + tracker.getId() + " visited wrong number of times."); + assertEquals(2, tracker.getValidateCount(), "Instance " + tracker.getId() + " visited wrong number of times."); } } } - // Randomly generate a pools with random numTests // and make sure evictor cycles through elements appropriately final int[] smallPrimes = { 2, 3, 5, 7 }; @@ -799,16 +741,13 @@ public class TestGenericObjectPool extends TestBaseObjectPool { for (int k = 0; k < instanceCount; k++) { trackerPool.addObject(); } - // Execute a random number of evictor runs final int runs = 10 + random.nextInt(50); for (int k = 0; k < runs; k++) { trackerPool.evict(); } - // Number of times evictor should have cycled through the pool final int cycleCount = runs * trackerPool.getNumTestsPerEvictionRun() / instanceCount; - // Look at elements and make sure they are visited cycleCount // or cycleCount + 1 times VisitTracker<Object> tracker = null; @@ -891,8 +830,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool { protected ObjectPool<String> makeEmptyPool(final int minCap) { final GenericObjectPool<String> mtPool = new GenericObjectPool<>(new SimpleFactory()); mtPool.setMaxTotal(minCap); - mtPool.setMaxIdle(minCap); - return mtPool; + mtPool.setMaxIdle(minCap); + return mtPool; } @Override @@ -900,10 +839,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool { return new GenericObjectPool<>(fac); } - /** - * Kicks off <numThreads> test threads, each of which will go through - * <iterations> borrow-return cycles with random delay times <= delay - * in between. + /* + * Kicks off numThreads test threads, each of which will go through iterations borrow-return cycles with random delay times <= delay in between. */ private <T> void runTestThreads(final int numThreads, final int iterations, final int delay, final GenericObjectPool<T> testPool) { final TestThread<T>[] threads = new TestThread[numThreads]; @@ -932,12 +869,10 @@ public class TestGenericObjectPool extends TestBaseObjectPool { public void tearDown() throws Exception { final ObjectName jmxName = genericObjectPool.getJmxName(); final String poolName = Objects.toString(jmxName, null); - genericObjectPool.clear(); genericObjectPool.close(); genericObjectPool = null; simpleFactory = null; - final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); final Set<ObjectName> result = mbs.queryNames(new ObjectName("org.apache.commoms.pool2:type=GenericObjectPool,*"), null); // There should be no registered pools at this point @@ -954,7 +889,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { mbs.unregisterMBean(name); } assertEquals(0, registeredPoolCount, msg.toString()); - // Make sure that EvictionTimer executor is shut down. Thread.yield(); if (EvictionTimer.getExecutor() != null) { @@ -967,9 +901,9 @@ public class TestGenericObjectPool extends TestBaseObjectPool { * Check that a pool that starts an evictor, but is never closed does not leave EvictionTimer executor running. Confirmation check is in * {@link #tearDown()}. * - * @throws TestException Custom exception + * @throws TestException Custom exception * @throws InterruptedException if any thread has interrupted the current thread. The <em>interrupted status</em> of the current thread is cleared when this - * exception is thrown. + * exception is thrown. */ @SuppressWarnings("deprecation") @Test @@ -979,7 +913,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { GenericObjectPool<String> abandoned = new GenericObjectPool<>(simpleFactory, config); abandoned.setDurationBetweenEvictionRuns(Duration.ofMillis(100)); // Starts evictor assertEquals(abandoned.getRemoveAbandonedTimeout(), abandoned.getRemoveAbandonedTimeoutDuration().getSeconds()); - // This is ugly, but forces GC to hit the pool final WeakReference<GenericObjectPool<String>> ref = new WeakReference<>(abandoned); abandoned = null; @@ -1017,37 +950,29 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /* - * Note: This test relies on timing for correct execution. There *should* be - * enough margin for this to work correctly on most (all?) systems but be - * aware of this if you see a failure of this test. + * Note: This test relies on timing for correct execution. There *should* be enough margin for this to work correctly on most (all?) systems but be aware of + * this if you see a failure of this test. */ - @SuppressWarnings({ - "rawtypes", "unchecked" - }) + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS) public void testBorrowObjectFairness() throws Exception { - final int numThreads = 40; final int maxTotal = 40; - final GenericObjectPoolConfig config = new GenericObjectPoolConfig(); config.setMaxTotal(maxTotal); config.setMaxIdle(maxTotal); config.setFairness(true); config.setLifo(false); - genericObjectPool = new GenericObjectPool(simpleFactory, config); - // Exhaust the pool final String[] objects = new String[maxTotal]; for (int i = 0; i < maxTotal; i++) { objects[i] = genericObjectPool.borrowObject(); } - // Start and park threads waiting to borrow objects final TestThread[] threads = new TestThread[numThreads]; - for(int i=0;i<numThreads;i++) { + for (int i = 0; i < numThreads; i++) { threads[i] = new TestThread(genericObjectPool, 1, 0, 2000, false, String.valueOf(i % maxTotal)); final Thread t = new Thread(threads[i]); t.start(); @@ -1058,12 +983,10 @@ public class TestGenericObjectPool extends TestBaseObjectPool { fail(e.toString()); } } - // Return objects, other threads should get served in order for (int i = 0; i < maxTotal; i++) { genericObjectPool.returnObject(objects[i]); } - // Wait for threads to finish for (int i = 0; i < numThreads; i++) { while (!threads[i].complete()) { @@ -1131,11 +1054,9 @@ public class TestGenericObjectPool extends TestBaseObjectPool { // In the initial state, the active duration is the time between "now" and the creation time. // In the initial state, the idle duration is the time between "now" and the last return, which is the creation time. // But... this PO might have already been used in other tests in this class. - final Instant lastBorrowInstant1 = po.getLastBorrowInstant(); final Instant lastReturnInstant1 = po.getLastReturnInstant(); final Instant lastUsedInstant1 = po.getLastUsedInstant(); - assertTrue(po.getCreateInstant().compareTo(lastBorrowInstant1) <= 0); assertTrue(po.getCreateInstant().compareTo(lastReturnInstant1) <= 0); assertTrue(po.getCreateInstant().compareTo(lastUsedInstant1) <= 0); @@ -1143,11 +1064,9 @@ public class TestGenericObjectPool extends TestBaseObjectPool { assertTrue(po.getCreateTime() <= lastBorrowInstant1.toEpochMilli()); assertTrue(po.getCreateTime() <= lastReturnInstant1.toEpochMilli()); assertTrue(po.getCreateTime() <= lastUsedInstant1.toEpochMilli()); - // Sleep MUST be "long enough" to detect that more than 0 milliseconds have elapsed. // Need an API in Java 8 to get the clock granularity. Thread.sleep(200); - assertFalse(po.getActiveDuration().isNegative()); assertFalse(po.getActiveDuration().isZero()); // We use greaterThanOrEqualTo instead of equal because "now" many be different when each argument is evaluated. @@ -1164,38 +1083,32 @@ public class TestGenericObjectPool extends TestBaseObjectPool { assertTrue(po.getCreateInstant().compareTo(po.getLastBorrowInstant()) <= 0); assertTrue(po.getCreateInstant().compareTo(po.getLastReturnInstant()) <= 0); assertTrue(po.getCreateInstant().compareTo(po.getLastUsedInstant()) <= 0); - assertTrue(lastBorrowInstant1.compareTo(po.getLastBorrowInstant()) <= 0); assertTrue(lastReturnInstant1.compareTo(po.getLastReturnInstant()) <= 0); assertTrue(lastUsedInstant1.compareTo(po.getLastUsedInstant()) <= 0); - genericObjectPool.returnObject(object); - assertFalse(po.getActiveDuration().isNegative()); assertFalse(po.getActiveDuration().isZero()); assertTrue(po.getActiveDuration().toMillis() <= po.getActiveTimeMillis()); assertTrue(po.getActiveDuration().compareTo(po.getActiveTime()) <= 0); - assertTrue(lastBorrowInstant1.compareTo(po.getLastBorrowInstant()) <= 0); assertTrue(lastReturnInstant1.compareTo(po.getLastReturnInstant()) <= 0); assertTrue(lastUsedInstant1.compareTo(po.getLastUsedInstant()) <= 0); } /** - * On first borrow, first object fails validation, second object is OK. - * Subsequent borrows are OK. This was POOL-152. + * On first borrow, first object fails validation, second object is OK. Subsequent borrows are OK. This was POOL-152. + * * @throws Exception */ @Test @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS) public void testBrokenFactoryShouldNotBlockPool() throws Exception { final int maxTotal = 1; - simpleFactory.setMaxTotal(maxTotal); genericObjectPool.setMaxTotal(maxTotal); genericObjectPool.setBlockWhenExhausted(true); genericObjectPool.setTestOnBorrow(true); - // First borrow object will need to create a new object which will fail // validation. String obj = null; @@ -1210,10 +1123,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool { assertNotNull(ex); assertInstanceOf(NoSuchElementException.class, ex); assertNull(obj); - // Configure factory to create valid objects so subsequent borrows work simpleFactory.setValid(true); - // Subsequent borrows should be OK obj = genericObjectPool.borrowObject(); assertNotNull(obj); @@ -1272,34 +1183,24 @@ public class TestGenericObjectPool extends TestBaseObjectPool { @Test @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS) public void testConcurrentBorrowAndEvict() throws Exception { - genericObjectPool.setMaxTotal(1); genericObjectPool.addObject(); - for (int i = 0; i < 5000; i++) { - final ConcurrentBorrowAndEvictThread one = - new ConcurrentBorrowAndEvictThread(true); - final ConcurrentBorrowAndEvictThread two = - new ConcurrentBorrowAndEvictThread(false); - + final ConcurrentBorrowAndEvictThread one = new ConcurrentBorrowAndEvictThread(true); + final ConcurrentBorrowAndEvictThread two = new ConcurrentBorrowAndEvictThread(false); one.start(); two.start(); one.join(); two.join(); - genericObjectPool.returnObject(one.obj); - - /* Uncomment this for a progress indication - if (i % 10 == 0) { - System.out.println(i/10); - } - */ + /* + * Uncomment this for a progress indication if (i % 10 == 0) { System.out.println(i/10); } + */ } } /** - * POOL-231 - verify that concurrent invalidates of the same object do not - * corrupt pool destroyCount. + * POOL-231 - verify that concurrent invalidates of the same object do not corrupt pool destroyCount. * * @throws Exception May occur in some failure modes */ @@ -1353,14 +1254,12 @@ public class TestGenericObjectPool extends TestBaseObjectPool { @Test public void testConstructorNullFactory() { // add dummy assert (won't be invoked because of IAE) to avoid "unused" warning - assertThrows(IllegalArgumentException.class, - () -> new GenericObjectPool<>(null)); + assertThrows(IllegalArgumentException.class, () -> new GenericObjectPool<>(null)); } @Test @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS) public void testConstructors() { - // Make constructor arguments all different from defaults final int minIdle = 2; final Duration maxWaitDuration = Duration.ofMillis(3); @@ -1382,31 +1281,19 @@ public class TestGenericObjectPool extends TestBaseObjectPool { assertEquals(BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS, dummyPool.getMaxWaitMillis()); assertEquals(GenericObjectPoolConfig.DEFAULT_MIN_IDLE, dummyPool.getMinIdle()); assertEquals(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL, dummyPool.getMaxTotal()); - assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, - dummyPool.getMinEvictableIdleTimeMillis()); - assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME, - dummyPool.getMinEvictableIdleTime()); - assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME, - dummyPool.getMinEvictableIdleDuration()); - assertEquals(BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN, - dummyPool.getNumTestsPerEvictionRun()); - assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW), - Boolean.valueOf(dummyPool.getTestOnBorrow())); - assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN), - Boolean.valueOf(dummyPool.getTestOnReturn())); - assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE), - Boolean.valueOf(dummyPool.getTestWhileIdle())); - assertEquals(BaseObjectPoolConfig.DEFAULT_DURATION_BETWEEN_EVICTION_RUNS, - dummyPool.getDurationBetweenEvictionRuns()); - assertEquals(BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, - dummyPool.getTimeBetweenEvictionRunsMillis()); - assertEquals(BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS, - dummyPool.getTimeBetweenEvictionRuns()); - assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED), - Boolean.valueOf(dummyPool.getBlockWhenExhausted())); + assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, dummyPool.getMinEvictableIdleTimeMillis()); + assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME, dummyPool.getMinEvictableIdleTime()); + assertEquals(BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME, dummyPool.getMinEvictableIdleDuration()); + assertEquals(BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN, dummyPool.getNumTestsPerEvictionRun()); + assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW), Boolean.valueOf(dummyPool.getTestOnBorrow())); + assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN), Boolean.valueOf(dummyPool.getTestOnReturn())); + assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE), Boolean.valueOf(dummyPool.getTestWhileIdle())); + assertEquals(BaseObjectPoolConfig.DEFAULT_DURATION_BETWEEN_EVICTION_RUNS, dummyPool.getDurationBetweenEvictionRuns()); + assertEquals(BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, dummyPool.getTimeBetweenEvictionRunsMillis()); + assertEquals(BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS, dummyPool.getTimeBetweenEvictionRuns()); + assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED), Boolean.valueOf(dummyPool.getBlockWhenExhausted())); assertEquals(Boolean.valueOf(BaseObjectPoolConfig.DEFAULT_LIFO), Boolean.valueOf(dummyPool.getLifo())); } - final GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>(); config.setLifo(lifo); config.setMaxIdle(maxIdle); @@ -1442,20 +1329,18 @@ public class TestGenericObjectPool extends TestBaseObjectPool { @Test @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS) public void testDefaultConfiguration() { - assertConfiguration(new GenericObjectPoolConfig<>(),genericObjectPool); + assertConfiguration(new GenericObjectPoolConfig<>(), genericObjectPool); } /** - * Verifies that when a factory's makeObject produces instances that are not - * discernible by equals, the pool can handle them. + * Verifies that when a factory's makeObject produces instances that are not discernible by equals, the pool can handle them. * * JIRA: POOL-283 */ @Test public void testEqualsIndiscernible() throws Exception { final HashSetFactory factory = new HashSetFactory(); - try (final GenericObjectPool<HashSet<String>> pool = new GenericObjectPool<>(factory, - new GenericObjectPoolConfig<>())) { + try (final GenericObjectPool<HashSet<String>> pool = new GenericObjectPool<>(factory, new GenericObjectPoolConfig<>())) { final HashSet<String> s1 = pool.borrowObject(); final HashSet<String> s2 = pool.borrowObject(); pool.returnObject(s1); @@ -1465,36 +1350,28 @@ public class TestGenericObjectPool extends TestBaseObjectPool { @Test public void testErrorFactoryDoesNotBlockThreads() throws Exception { - final CreateErrorFactory factory = new CreateErrorFactory(); try (final GenericObjectPool<String> createFailFactoryPool = new GenericObjectPool<>(factory)) { - createFailFactoryPool.setMaxTotal(1); - // Try and borrow the first object from the pool final WaitingTestThread thread1 = new WaitingTestThread(createFailFactoryPool, 0); thread1.start(); - // Wait for thread to reach semaphore while (!factory.hasQueuedThreads()) { Thread.sleep(200); } - // Try and borrow the second object from the pool final WaitingTestThread thread2 = new WaitingTestThread(createFailFactoryPool, 0); thread2.start(); // Pool will not call factory since maximum number of object creations // are already queued. - // Thread 2 will wait on an object being returned to the pool // Give thread 2 a chance to reach this state Thread.sleep(1000); - // Release thread1 factory.release(); // Pre-release thread2 factory.release(); - // Both threads should now complete. boolean threadRunning = true; int count = 0; @@ -1506,15 +1383,13 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } assertFalse(thread1.isAlive()); assertFalse(thread2.isAlive()); - assertTrue(thread1.thrown instanceof UnknownError); assertTrue(thread2.thrown instanceof UnknownError); } } /** - * Tests addObject contention between ensureMinIdle triggered by - * the Evictor with minIdle > 0 and borrowObject. + * Tests addObject contention between ensureMinIdle triggered by the Evictor with minIdle > 0 and borrowObject. * * @throws Exception May occur in some failure modes */ @@ -1532,7 +1407,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool { final Thread borrowerThread = new Thread(borrower); // Set evictor to run in 100 ms - will create idle instance genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100)); - borrowerThread.start(); // Off to the races + borrowerThread.start(); // Off to the races borrowerThread.join(); assertFalse(borrower.failed()); } @@ -1552,7 +1427,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(250)); genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(500)); genericObjectPool.setTestWhileIdle(true); - final String[] active = new String[500]; for (int i = 0; i < 500; i++) { active[i] = genericObjectPool.borrowObject(); @@ -1560,7 +1434,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { for (int i = 0; i < 500; i++) { genericObjectPool.returnObject(active[i]); } - Waiter.sleepQuietly(1000L); assertTrue(genericObjectPool.getNumIdle() < 500, "Should be less than 500 idle, found " + genericObjectPool.getNumIdle()); Waiter.sleepQuietly(600L); @@ -1573,14 +1446,12 @@ public class TestGenericObjectPool extends TestBaseObjectPool { assertTrue(genericObjectPool.getNumIdle() < 100, "Should be less than 100 idle, found " + genericObjectPool.getNumIdle()); Waiter.sleepQuietly(600L); assertEquals(0, genericObjectPool.getNumIdle(), "Should be zero idle, found " + genericObjectPool.getNumIdle()); - for (int i = 0; i < 500; i++) { active[i] = genericObjectPool.borrowObject(); } for (int i = 0; i < 500; i++) { genericObjectPool.returnObject(active[i]); } - Waiter.sleepQuietly(1000L); assertTrue(genericObjectPool.getNumIdle() < 500, "Should be less than 500 idle, found " + genericObjectPool.getNumIdle()); Waiter.sleepQuietly(600L); @@ -1598,9 +1469,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool { @Test @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS) public void testEvictionInvalid() throws Exception { - try (final GenericObjectPool<Object> invalidFactoryPool = new GenericObjectPool<>(new InvalidFactory())) { - invalidFactoryPool.setMaxIdle(1); invalidFactoryPool.setMaxTotal(1); invalidFactoryPool.setTestOnBorrow(false); @@ -1608,26 +1477,20 @@ public class TestGenericObjectPool extends TestBaseObjectPool { invalidFactoryPool.setTestWhileIdle(true); invalidFactoryPool.setMinEvictableIdleTime(Duration.ofSeconds(100)); invalidFactoryPool.setNumTestsPerEvictionRun(1); - final Object p = invalidFactoryPool.borrowObject(); invalidFactoryPool.returnObject(p); - // Run eviction in a separate thread final Thread t = new EvictionThread<>(invalidFactoryPool); t.start(); - // Sleep to make sure evictor has started Thread.sleep(300); - try { invalidFactoryPool.borrowObject(1); } catch (final NoSuchElementException nsee) { // Ignore } - // Make sure evictor has finished Thread.sleep(1000); - // Should have an empty pool assertEquals(0, invalidFactoryPool.getNumIdle(), "Idle count different than expected."); assertEquals(0, invalidFactoryPool.getNumActive(), "Total count different than expected."); @@ -1635,8 +1498,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /** - * Test to make sure evictor visits least recently used objects first, - * regardless of FIFO/LIFO. + * Test to make sure evictor visits least recently used objects first, regardless of FIFO/LIFO. * * JIRA: POOL-86 * @@ -1660,28 +1522,21 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(250)); genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(500)); genericObjectPool.setTestWhileIdle(true); - // ClassNotFoundException assertThrows(IllegalArgumentException.class, () -> genericObjectPool.setEvictionPolicyClassName(Long.toString(System.currentTimeMillis())), "setEvictionPolicyClassName must throw an error if the class name is invalid."); - // InstantiationException assertThrows(IllegalArgumentException.class, () -> genericObjectPool.setEvictionPolicyClassName(java.io.Serializable.class.getName()), "setEvictionPolicyClassName must throw an error if the class name is invalid."); - // IllegalAccessException assertThrows(IllegalArgumentException.class, () -> genericObjectPool.setEvictionPolicyClassName(java.util.Collections.class.getName()), "setEvictionPolicyClassName must throw an error if the class name is invalid."); - assertThrows(IllegalArgumentException.class, () -> genericObjectPool.setEvictionPolicyClassName(java.lang.String.class.getName()), () -> "setEvictionPolicyClassName must throw an error if a class that does not implement EvictionPolicy is specified."); - genericObjectPool.setEvictionPolicy(new TestEvictionPolicy<>()); assertEquals(TestEvictionPolicy.class.getName(), genericObjectPool.getEvictionPolicyClassName()); - genericObjectPool.setEvictionPolicyClassName(TestEvictionPolicy.class.getName()); assertEquals(TestEvictionPolicy.class.getName(), genericObjectPool.getEvictionPolicyClassName()); - final String[] active = new String[500]; for (int i = 0; i < 500; i++) { active[i] = genericObjectPool.borrowObject(); @@ -1689,7 +1544,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { for (int i = 0; i < 500; i++) { genericObjectPool.returnObject(active[i]); } - // Eviction policy ignores first 1500 attempts to evict and then always // evicts. After 1s, there should have been two runs of 500 tests so no // evictions @@ -1725,9 +1579,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool { return new DefaultPooledObject<>(value); } } - try (final GenericObjectPool<TimeTest> timePool = new GenericObjectPool<>(new TimeTest())) { - timePool.setMaxIdle(5); timePool.setMaxTotal(5); timePool.setNumTestsPerEvictionRun(5); @@ -1736,23 +1588,19 @@ public class TestGenericObjectPool extends TestBaseObjectPool { timePool.setMinEvictableIdleTime(Duration.ofSeconds(3)); timePool.setSoftMinEvictableIdleTime(TestConstants.ONE_SECOND_DURATION); timePool.setMinIdle(2); - final TimeTest[] active = new TimeTest[5]; final Long[] creationTime = new Long[5]; for (int i = 0; i < 5; i++) { active[i] = timePool.borrowObject(); creationTime[i] = Long.valueOf(active[i].getCreateTimeMillis()); } - for (int i = 0; i < 5; i++) { timePool.returnObject(active[i]); } - // Soft evict all but minIdle(2) Thread.sleep(1500L); timePool.evict(); assertEquals(2, timePool.getNumIdle(), "Idle count different than expected."); - // Hard evict the rest. Thread.sleep(2000L); timePool.evict(); @@ -1769,7 +1617,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setNumTestsPerEvictionRun(-2); genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(50)); genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100)); - final String[] active = new String[6]; for (int i = 0; i < 6; i++) { active[i] = genericObjectPool.borrowObject(); @@ -1777,7 +1624,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { for (int i = 0; i < 6; i++) { genericObjectPool.returnObject(active[i]); } - Waiter.sleepQuietly(100L); assertTrue(genericObjectPool.getNumIdle() <= 6, "Should at most 6 idle, found " + genericObjectPool.getNumIdle()); Waiter.sleepQuietly(100L); @@ -1795,8 +1641,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /** - * Verifies that the evictor visits objects in expected order - * and frequency. + * Verifies that the evictor visits objects in expected order and frequency. * * @throws Exception May occur in some failure modes */ @@ -1820,12 +1665,9 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setMaxIdle(1); genericObjectPool.setMinEvictableIdleTime(Duration.ZERO); genericObjectPool.setTestWhileIdle(true); - final String active = genericObjectPool.borrowObject(); genericObjectPool.returnObject(active); - simpleFactory.setThrowExceptionOnValidate(true); - assertThrows(RuntimeException.class, () -> genericObjectPool.evict()); assertEquals(0, genericObjectPool.getNumActive()); assertEquals(0, genericObjectPool.getNumIdle()); @@ -1845,7 +1687,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { final String obj = genericObjectPool.borrowObject(); assertEquals(1, genericObjectPool.getNumActive()); assertEquals(0, genericObjectPool.getNumIdle()); - genericObjectPool.returnObject(obj); simpleFactory.setValid(false); // Validation will now fail on activation when borrowObject returns @@ -1886,41 +1727,33 @@ public class TestGenericObjectPool extends TestBaseObjectPool { final String obj = genericObjectPool.borrowObject(); simpleFactory.setThrowExceptionOnPassivate(true); genericObjectPool.returnObject(obj); - assertEquals(0,genericObjectPool.getNumIdle()); + assertEquals(0, genericObjectPool.getNumIdle()); } @Test public void testFailingFactoryDoesNotBlockThreads() throws Exception { - final CreateFailFactory factory = new CreateFailFactory(); try (final GenericObjectPool<String> createFailFactoryPool = new GenericObjectPool<>(factory)) { - createFailFactoryPool.setMaxTotal(1); - // Try and borrow the first object from the pool final WaitingTestThread thread1 = new WaitingTestThread(createFailFactoryPool, 0); thread1.start(); - // Wait for thread to reach semaphore while (!factory.hasQueuedThreads()) { Thread.sleep(200); } - // Try and borrow the second object from the pool final WaitingTestThread thread2 = new WaitingTestThread(createFailFactoryPool, 0); thread2.start(); // Pool will not call factory since maximum number of object creations // are already queued. - // Thread 2 will wait on an object being returned to the pool // Give thread 2 a chance to reach this state Thread.sleep(1000); - // Release thread1 factory.release(); // Pre-release thread2 factory.release(); - // Both threads should now complete. boolean threadRunning = true; int count = 0; @@ -1932,7 +1765,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } assertFalse(thread1.isAlive()); assertFalse(thread2.isAlive()); - assertTrue(thread1.thrown instanceof UnsupportedCharsetException); assertTrue(thread2.thrown instanceof UnsupportedCharsetException); } @@ -1971,47 +1803,41 @@ public class TestGenericObjectPool extends TestBaseObjectPool { @Test public void testGetFactoryType_PoolUtilsSynchronizedDefaultPooledFactory() { - try (final GenericObjectPool<String> pool = new GenericObjectPool<>( - PoolUtils.synchronizedPooledFactory(createDefaultPooledObjectFactory()))) { + try (final GenericObjectPool<String> pool = new GenericObjectPool<>(PoolUtils.synchronizedPooledFactory(createDefaultPooledObjectFactory()))) { assertNotNull(pool.getFactoryType()); } } @Test public void testGetFactoryType_PoolUtilsSynchronizedNullPooledFactory() { - try (final GenericObjectPool<String> pool = new GenericObjectPool<>( - PoolUtils.synchronizedPooledFactory(createNullPooledObjectFactory()))) { + try (final GenericObjectPool<String> pool = new GenericObjectPool<>(PoolUtils.synchronizedPooledFactory(createNullPooledObjectFactory()))) { assertNotNull(pool.getFactoryType()); } } @Test public void testGetFactoryType_SynchronizedDefaultPooledObjectFactory() { - try (final GenericObjectPool<String> pool = new GenericObjectPool<>( - new TestSynchronizedPooledObjectFactory<>(createDefaultPooledObjectFactory()))) { + try (final GenericObjectPool<String> pool = new GenericObjectPool<>(new TestSynchronizedPooledObjectFactory<>(createDefaultPooledObjectFactory()))) { assertNotNull(pool.getFactoryType()); } } @Test public void testGetFactoryType_SynchronizedNullPooledObjectFactory() { - try (final GenericObjectPool<String> pool = new GenericObjectPool<>( - new TestSynchronizedPooledObjectFactory<>(createNullPooledObjectFactory()))) { + try (final GenericObjectPool<String> pool = new GenericObjectPool<>(new TestSynchronizedPooledObjectFactory<>(createNullPooledObjectFactory()))) { assertNotNull(pool.getFactoryType()); } } @Test public void testGetStatsString() { - try (final GenericObjectPool<String> pool = new GenericObjectPool<>( - new TestSynchronizedPooledObjectFactory<>(createNullPooledObjectFactory()))) { + try (final GenericObjectPool<String> pool = new GenericObjectPool<>(new TestSynchronizedPooledObjectFactory<>(createNullPooledObjectFactory()))) { assertNotNull(pool.getStatsString()); } } /** - * Verify that threads waiting on a depleted pool get served when a checked out object is - * invalidated. + * Verify that threads waiting on a depleted pool get served when a checked out object is invalidated. * * JIRA: POOL-240 * @@ -2052,7 +1878,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { final Set<ObjectName> result = mbs.queryNames(oname, null); assertEquals(1, result.size()); genericObjectPool.jmxUnregister(); - final GenericObjectPoolConfig<String> config = new GenericObjectPoolConfig<>(); config.setJmxEnabled(false); try (final GenericObjectPool<String> poolWithoutJmx = new GenericObjectPool<>(simpleFactory, config)) { @@ -2060,7 +1885,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { config.setJmxEnabled(true); poolWithoutJmx.jmxUnregister(); } - config.setJmxNameBase(null); try (final GenericObjectPool<String> poolWithDefaultJmxNameBase = new GenericObjectPool<>(simpleFactory, config)) { assertNotNull(poolWithDefaultJmxNameBase.getJmxName()); @@ -2086,19 +1910,15 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /** - * Simplest example of recovery from factory outage. - * A thread gets into parked wait on the deque when there is capacity to create, but - * creates are failing due to factory outage. Verify that the borrower is served - * once the factory is back online. + * Simplest example of recovery from factory outage. A thread gets into parked wait on the deque when there is capacity to create, but creates are failing + * due to factory outage. Verify that the borrower is served once the factory is back online. */ @Test @Disabled @Timeout(value = 1000, unit = TimeUnit.MILLISECONDS) public void testLivenessOnTransientFactoryFailure() throws Exception { - final DisconnectingWaiterFactory<String> factory = new DisconnectingWaiterFactory<>( - DisconnectingWaiterFactory.DEFAULT_DISCONNECTED_CREATE_ACTION, - DisconnectingWaiterFactory.DEFAULT_DISCONNECTED_LIFECYCLE_ACTION, - obj -> false // all instances fail validation + final DisconnectingWaiterFactory<String> factory = new DisconnectingWaiterFactory<>(DisconnectingWaiterFactory.DEFAULT_DISCONNECTED_CREATE_ACTION, + DisconnectingWaiterFactory.DEFAULT_DISCONNECTED_LIFECYCLE_ACTION, obj -> false // all instances fail validation ); final GenericObjectPool<Waiter> pool = new GenericObjectPool<>(factory); pool.setMaxWait(Duration.ofMillis(100)); @@ -2118,7 +1938,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool { // t is blocked waiting on the deque Thread.sleep(10); factory.disconnect(); - pool.returnObject(w); // validation fails, so no return + pool.returnObject(w); // validation fails, so no return Thread.sleep(10); factory.connect(); // Borrower should be able to be served now @@ -2130,11 +1950,8 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /** - * Test the following scenario: - * Thread 1 borrows an instance - * Thread 2 starts to borrow another instance before thread 1 returns its instance - * Thread 1 returns its instance while thread 2 is validating its newly created instance - * The test verifies that the instance created by Thread 2 is not leaked. + * Test the following scenario: Thread 1 borrows an instance Thread 2 starts to borrow another instance before thread 1 returns its instance Thread 1 + * returns its instance while thread 2 is validating its newly created instance The test verifies that the instance created by Thread 2 is not leaked. * * @throws Exception May occur in some failure modes */ @@ -2204,18 +2021,15 @@ public class TestGenericObjectPool extends TestBaseObjectPool { final int numIter = 20; final int delay = 25; final int maxTotal = 10; - simpleFactory.setMaxTotal(maxTotal); genericObjectPool.setMaxTotal(maxTotal); genericObjectPool.setBlockWhenExhausted(true); genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(-1)); - // this is important to trigger POOL-356 genericObjectPool.setMaxIdle(0); - // Start threads to borrow objects final TestThread[] threads = new TestThread[numThreads]; - for(int i=0;i<numThreads;i++) { + for (int i = 0; i < numThreads; i++) { // Factor of 2 on iterations so main thread does work whilst other // threads are running. Factor of 2 on delay so average delay for // other threads == actual delay for main thread @@ -2225,7 +2039,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } // Give the threads a chance to start doing some work Waiter.sleepQuietly(100L); - for (int i = 0; i < numIter; i++) { String obj = null; try { @@ -2250,7 +2063,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } } } - for (int i = 0; i < numThreads; i++) { while (!threads[i].complete()) { Waiter.sleepQuietly(500L); @@ -2267,7 +2079,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { public void testMaxTotal() throws Exception { genericObjectPool.setMaxTotal(3); genericObjectPool.setBlockWhenExhausted(false); - genericObjectPool.borrowObject(); genericObjectPool.borrowObject(); genericObjectPool.borrowObject(); @@ -2275,16 +2086,15 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /** - * Verifies that maxTotal is not exceeded when factory destroyObject - * has high latency, testOnReturn is set and there is high incidence of - * validation failures. + * Verifies that maxTotal is not exceeded when factory destroyObject has high latency, testOnReturn is set and there is high incidence of validation + * failures. */ @Test @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS) public void testMaxTotalInvariant() { final int maxTotal = 15; - simpleFactory.setEvenValid(false); // Every other validation fails - simpleFactory.setDestroyLatency(100); // Destroy takes 100 ms + simpleFactory.setEvenValid(false); // Every other validation fails + simpleFactory.setDestroyLatency(100); // Destroy takes 100 ms simpleFactory.setMaxTotal(maxTotal); // (makes - destroys) bound simpleFactory.setValidationEnabled(true); genericObjectPool.setMaxTotal(maxTotal); @@ -2303,15 +2113,13 @@ public class TestGenericObjectPool extends TestBaseObjectPool { final int numIter = 20; final int delay = 25; final int maxTotal = 10; - simpleFactory.setMaxTotal(maxTotal); genericObjectPool.setMaxTotal(maxTotal); genericObjectPool.setBlockWhenExhausted(true); genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(-1)); - // Start threads to borrow objects final TestThread[] threads = new TestThread[numThreads]; - for(int i=0;i<numThreads;i++) { + for (int i = 0; i < numThreads; i++) { // Factor of 2 on iterations so main thread does work whilst other // threads are running. Factor of 2 on delay so average delay for // other threads == actual delay for main thread @@ -2321,7 +2129,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } // Give the threads a chance to start doing some work Waiter.sleepQuietly(5000); - for (int i = 0; i < numIter; i++) { String obj = null; try { @@ -2346,12 +2153,11 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } } } - for (int i = 0; i < numThreads; i++) { - while(!threads[i].complete()) { + while (!threads[i].complete()) { Waiter.sleepQuietly(500L); } - if(threads[i].failed()) { + if (threads[i].failed()) { fail("Thread " + i + " failed: " + threads[i].error.toString()); } } @@ -2366,12 +2172,10 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /* - * Test multi-threaded pool access. - * Multiple threads, but maxTotal only allows half the threads to succeed. + * Test multi-threaded pool access. Multiple threads, but maxTotal only allows half the threads to succeed. * - * This test was prompted by Continuum build failures in the Commons DBCP test case: - * TestPerUserPoolDataSource.testMultipleThreads2() - * Let's see if the this fails on Continuum too! + * This test was prompted by Continuum build failures in the Commons DBCP test case: TestPerUserPoolDataSource.testMultipleThreads2() Let's see if the this + * fails on Continuum too! */ @Test @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS) @@ -2394,27 +2198,18 @@ public class TestGenericObjectPool extends TestBaseObjectPool { int failed = 0; for (final WaitingTestThread element : wtt) { element.join(); - if (element.thrown != null){ + if (element.thrown != null) { failed++; } } - if (DISPLAY_THREAD_DETAILS || wtt.length/2 != failed){ - System.out.println( - "MaxWait: " + maxWait + - " HoldTime: " + holdTime + - " MaxTotal: " + threads + - " Threads: " + wtt.length + - " Failed: " + failed - ); + if (DISPLAY_THREAD_DETAILS || wtt.length / 2 != failed) { + System.out.println("MaxWait: " + maxWait + " HoldTime: " + holdTime + " MaxTotal: " + threads + " Threads: " + wtt.length + " Failed: " + failed); for (final WaitingTestThread wt : wtt) { - System.out.println( - "PreBorrow: " + (wt.preBorrowMillis - originMillis) + - " PostBorrow: " + (wt.postBorrowMillis != 0 ? wt.postBorrowMillis - originMillis : -1) + - " BorrowTime: " + (wt.postBorrowMillis != 0 ? wt.postBorrowMillis - wt.preBorrowMillis : -1) + - " PostReturn: " + (wt.postReturnMillis != 0 ? wt.postReturnMillis - originMillis : -1) + - " Ended: " + (wt.endedMillis - originMillis) + - " ObjId: " + wt.objectId - ); + System.out.println("PreBorrow: " + (wt.preBorrowMillis - originMillis) + " PostBorrow: " + + (wt.postBorrowMillis != 0 ? wt.postBorrowMillis - originMillis : -1) + " BorrowTime: " + + (wt.postBorrowMillis != 0 ? wt.postBorrowMillis - wt.preBorrowMillis : -1) + " PostReturn: " + + (wt.postReturnMillis != 0 ? wt.postReturnMillis - originMillis : -1) + " Ended: " + (wt.endedMillis - originMillis) + " ObjId: " + + wt.objectId); } } assertEquals(wtt.length / 2, failed, "Expected half the threads to fail"); @@ -2430,27 +2225,20 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(50)); genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100)); genericObjectPool.setTestWhileIdle(true); - Waiter.sleepQuietly(150L); assertEquals(5, genericObjectPool.getNumIdle(), "Should be 5 idle, found " + genericObjectPool.getNumIdle()); - final String[] active = new String[5]; active[0] = genericObjectPool.borrowObject(); - Waiter.sleepQuietly(150L); assertEquals(5, genericObjectPool.getNumIdle(), "Should be 5 idle, found " + genericObjectPool.getNumIdle()); - for (int i = 1; i < 5; i++) { active[i] = genericObjectPool.borrowObject(); } - Waiter.sleepQuietly(150L); assertEquals(5, genericObjectPool.getNumIdle(), "Should be 5 idle, found " + genericObjectPool.getNumIdle()); - for (int i = 0; i < 5; i++) { genericObjectPool.returnObject(active[i]); } - Waiter.sleepQuietly(150L); assertEquals(10, genericObjectPool.getNumIdle(), "Should be 10 idle, found " + genericObjectPool.getNumIdle()); } @@ -2465,47 +2253,35 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(50)); genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(100)); genericObjectPool.setTestWhileIdle(true); - Waiter.sleepQuietly(150L); assertEquals(5, genericObjectPool.getNumIdle(), "Should be 5 idle, found " + genericObjectPool.getNumIdle()); - final String[] active = new String[10]; - Waiter.sleepQuietly(150L); assertEquals(5, genericObjectPool.getNumIdle(), "Should be 5 idle, found " + genericObjectPool.getNumIdle()); - for (int i = 0; i < 5; i++) { active[i] = genericObjectPool.borrowObject(); } - Waiter.sleepQuietly(150L); assertEquals(5, genericObjectPool.getNumIdle(), "Should be 5 idle, found " + genericObjectPool.getNumIdle()); - - for(int i = 0 ; i < 5 ; i++) { + for (int i = 0; i < 5; i++) { genericObjectPool.returnObject(active[i]); } - Waiter.sleepQuietly(150L); assertEquals(10, genericObjectPool.getNumIdle(), "Should be 10 idle, found " + genericObjectPool.getNumIdle()); - for (int i = 0; i < 10; i++) { active[i] = genericObjectPool.borrowObject(); } - Waiter.sleepQuietly(150L); assertEquals(0, genericObjectPool.getNumIdle(), "Should be 0 idle, found " + genericObjectPool.getNumIdle()); - for (int i = 0; i < 10; i++) { genericObjectPool.returnObject(active[i]); } - Waiter.sleepQuietly(150L); assertEquals(10, genericObjectPool.getNumIdle(), "Should be 10 idle, found " + genericObjectPool.getNumIdle()); } /** - * Verifies that returning an object twice (without borrow in between) causes ISE - * but does not re-validate or re-passivate the instance. + * Verifies that returning an object twice (without borrow in between) causes ISE but does not re-validate or re-passivate the instance. * * JIRA: POOL-285 */ @@ -2533,39 +2309,29 @@ public class TestGenericObjectPool extends TestBaseObjectPool { @Test public void testMultipleReturnOfSameObject() throws Exception { try (final GenericObjectPool<String> pool = new GenericObjectPool<>(simpleFactory, new GenericObjectPoolConfig<>())) { - assertEquals(0, pool.getNumActive()); assertEquals(0, pool.getNumIdle()); - final String obj = pool.borrowObject(); - assertEquals(1, pool.getNumActive()); assertEquals(0, pool.getNumIdle()); - pool.returnObject(obj); - assertEquals(0, pool.getNumActive()); assertEquals(1, pool.getNumIdle()); - - assertThrows(IllegalStateException.class, - () -> pool.returnObject(obj)); - + assertThrows(IllegalStateException.class, () -> pool.returnObject(obj)); assertEquals(0, pool.getNumActive()); assertEquals(1, pool.getNumIdle()); } } /** - * Verifies that when a borrowed object is mutated in a way that does not - * preserve equality and hash code, the pool can recognized it on return. + * Verifies that when a borrowed object is mutated in a way that does not preserve equality and hash code, the pool can recognized it on return. * * JIRA: POOL-284 */ @Test public void testMutable() throws Exception { final HashSetFactory factory = new HashSetFactory(); - try (final GenericObjectPool<HashSet<String>> pool = new GenericObjectPool<>(factory, - new GenericObjectPoolConfig<>())) { + try (final GenericObjectPool<HashSet<String>> pool = new GenericObjectPool<>(factory, new GenericObjectPoolConfig<>())) { final HashSet<String> s1 = pool.borrowObject(); final HashSet<String> s2 = pool.borrowObject(); s1.add("One"); @@ -2630,16 +2396,15 @@ public class TestGenericObjectPool extends TestBaseObjectPool { /** * Verify that when a factory returns a null object, pool methods throw NPE. + * * @throws InterruptedException */ @Test @Timeout(value = 1000, unit = TimeUnit.MILLISECONDS) public void testNPEOnFactoryNull() throws Exception { - final DisconnectingWaiterFactory<String> factory = new DisconnectingWaiterFactory<>( - () -> null, // Override default to always return null from makeObject - DisconnectingWaiterFactory.DEFAULT_DISCONNECTED_LIFECYCLE_ACTION, - DisconnectingWaiterFactory.DEFAULT_DISCONNECTED_VALIDATION_ACTION - ); + final DisconnectingWaiterFactory<String> factory = new DisconnectingWaiterFactory<>(() -> null, // Override default to always return null from + // makeObject + DisconnectingWaiterFactory.DEFAULT_DISCONNECTED_LIFECYCLE_ACTION, DisconnectingWaiterFactory.DEFAULT_DISCONNECTED_VALIDATION_ACTION); final GenericObjectPool<Waiter> pool = new GenericObjectPool<>(factory); pool.setTestOnBorrow(true); pool.setMaxTotal(-1); @@ -2682,7 +2447,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool { assertEquals(1, genericObjectPool.getNumIdle()); } - @Test/* maxWaitMillis x2 + padding */ + @Test /* maxWaitMillis x2 + padding */ @Timeout(value = 1200, unit = TimeUnit.MILLISECONDS) public void testReturnBorrowObjectWithingMaxWaitDuration() throws Exception { final Duration maxWaitDuration = Duration.ofMillis(500); @@ -2701,7 +2466,7 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } } - @Test/* maxWaitMillis x2 + padding */ + @Test /* maxWaitMillis x2 + padding */ @Timeout(value = 1200, unit = TimeUnit.MILLISECONDS) public void testReturnBorrowObjectWithingMaxWaitMillis() throws Exception { final long maxWaitMillis = 500; @@ -2721,34 +2486,25 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } /** - * This is the test case for POOL-263. It is disabled since it will always - * pass without artificial delay being injected into GOP.returnObject() and - * a way to this hasn't currently been found that doesn't involve - * polluting the GOP implementation. The artificial delay needs to be - * inserted just before the final call to isLifo() in the returnObject() - * method. + * This is the test case for POOL-263. It is disabled since it will always pass without artificial delay being injected into GOP.returnObject() and a way to + * this hasn't currently been found that doesn't involve polluting the GOP implementation. The artificial delay needs to be inserted just before the final + * call to isLifo() in the returnObject() method. */ - //@Test + // @Test @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS) public void testReturnObject() throws Exception { - genericObjectPool.setMaxTotal(1); genericObjectPool.setMaxIdle(-1); final String active = genericObjectPool.borrowObject(); - assertEquals(1, genericObjectPool.getNumActive()); assertEquals(0, genericObjectPool.getNumIdle()); - final Thread t = new Thread(() -> genericObjectPool.close()); t.start(); - genericObjectPool.returnObject(active); - // Wait for the close() thread to complete while (t.isAlive()) { Thread.sleep(50); } - assertEquals(0, genericObjectPool.getNumIdle()); } @@ -2881,7 +2637,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setMaxTotal(6); genericObjectPool.setNumTestsPerEvictionRun(6); genericObjectPool.setMinEvictableIdleTime(Duration.ofMillis(100)); - for (int j = 0; j < 2; j++) { // populate the pool { @@ -2893,19 +2648,14 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.returnObject(active[i]); } } - // note that it stays populated assertEquals(6, genericObjectPool.getNumIdle(), "Should have 6 idle"); - // start the evictor genericObjectPool.setTimeBetweenEvictionRuns(Duration.ofMillis(50)); - // wait a second (well, .2 seconds) Waiter.sleepQuietly(200L); - // assert that the evictor has cleared out the pool assertEquals(0, genericObjectPool.getNumIdle(), "Should have 0 idle"); - // stop the evictor genericObjectPool.startEvictor(Duration.ZERO); } @@ -2925,15 +2675,11 @@ public class TestGenericObjectPool extends TestBaseObjectPool { swallowedExceptions.add(e); }; genericObjectPool.setSwallowedExceptionListener(listener); - final Exception e1 = new Exception(); final Exception e2 = new ArrayIndexOutOfBoundsException(); - genericObjectPool.swallowException(e1); genericObjectPool.swallowException(e2); - assertThrows(OutOfMemoryError.class, () -> genericObjectPool.swallowException(e1)); - assertEquals(2, swallowedExceptions.size()); } @@ -2957,7 +2703,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { assertThrows(NoSuchElementException.class, () -> genericObjectPool.borrowObject()); genericObjectPool.returnObject(obj2); genericObjectPool.returnObject(obj); - genericObjectPool.borrowObject(); genericObjectPool.borrowObject(); } @@ -2993,11 +2738,10 @@ public class TestGenericObjectPool extends TestBaseObjectPool { // Should have one idle, one out now assertEquals(1, genericObjectPool.getNumIdle()); assertEquals(1, genericObjectPool.getNumActive()); - } + } /** - * Verify that threads waiting on a depleted pool get served when a returning object fails - * validation. + * Verify that threads waiting on a depleted pool get served when a returning object fails validation. * * JIRA: POOL-240 * @@ -3034,21 +2778,17 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setTestOnBorrow(false); genericObjectPool.setTestOnReturn(false); genericObjectPool.setTestWhileIdle(false); - final String o1 = genericObjectPool.borrowObject(); assertEquals("0", o1); final Timer t = new Timer(); - t.schedule( - new TimerTask() { - @Override - public void run() { - genericObjectPool.returnObject(o1); - } - }, 3000); - + t.schedule(new TimerTask() { + @Override + public void run() { + genericObjectPool.returnObject(o1); + } + }, 3000); final String o2 = genericObjectPool.borrowObject(); assertEquals("0", o2); - assertEquals(1, simpleFactory.validateCounter); } @@ -3077,22 +2817,17 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setBlockWhenExhausted(true); genericObjectPool.setMaxWaitMillis(-1); final Object obj1 = genericObjectPool.borrowObject(); - // Make sure an object was obtained assertNotNull(obj1); - // Create a separate thread to try and borrow another object final WaitingTestThread wtt = new WaitingTestThread(genericObjectPool, 200); wtt.start(); // Give wtt time to start Thread.sleep(200); - // close the pool (Bug POOL-189) genericObjectPool.close(); - // Give interrupt time to take effect Thread.sleep(200); - // Check thread was interrupted assertTrue(wtt.thrown instanceof InterruptedException); } @@ -3104,26 +2839,20 @@ public class TestGenericObjectPool extends TestBaseObjectPool { genericObjectPool.setBlockWhenExhausted(true); genericObjectPool.setMaxWaitMillis(-1); final String obj1 = genericObjectPool.borrowObject(); - // Make sure on object was obtained assertNotNull(obj1); - // Create a separate thread to try and borrow another object final WaitingTestThread wtt = new WaitingTestThread(genericObjectPool, 200000); wtt.start(); // Give wtt time to start Thread.sleep(200); wtt.interrupt(); - // Give interrupt time to take effect Thread.sleep(200); - // Check thread was interrupted assertTrue(wtt.thrown instanceof InterruptedException); - // Return object to the pool genericObjectPool.returnObject(obj1); - // Bug POOL-162 - check there is now an object in the pool genericObjectPool.setMaxWaitMillis(10L); String obj2 = null; @@ -3136,7 +2865,6 @@ public class TestGenericObjectPool extends TestBaseObjectPool { } genericObjectPool.returnObject(obj2); genericObjectPool.close(); - } @Test @@ -3151,5 +2879,4 @@ public class TestGenericObjectPool extends TestBaseObjectPool { assertEquals(1, genericObjectPool.getNumIdle()); genericObjectPool.close(); } - } diff --git a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolConfig.java b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolConfig.java index b5e9be3d..464f2743 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolConfig.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolConfig.java @@ -17,9 +17,11 @@ package org.apache.commons.pool2.impl; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import java.time.Duration; + import org.apache.commons.pool2.PooledObject; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolFactoryCreateFailure.java b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolFactoryCreateFailure.java index 4a7d34ab..43833a86 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolFactoryCreateFailure.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestGenericObjectPoolFactoryCreateFailure.java @@ -141,4 +141,4 @@ public class TestGenericObjectPoolFactoryCreateFailure { } } -} \ No newline at end of file +} diff --git a/src/test/java/org/apache/commons/pool2/impl/TestSoftRefOutOfMemory.java b/src/test/java/org/apache/commons/pool2/impl/TestSoftRefOutOfMemory.java index 33efae4a..c7e9f267 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestSoftRefOutOfMemory.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestSoftRefOutOfMemory.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import org.apache.commons.lang3.ArrayFill; import org.apache.commons.pool2.BasePooledObjectFactory; import org.apache.commons.pool2.PooledObject; import org.junit.jupiter.api.AfterEach; @@ -38,9 +39,7 @@ public class TestSoftRefOutOfMemory { private int counter; public LargePoolableObjectFactory(final int size) { - final char[] data = new char[size]; - Arrays.fill(data, '.'); - buffer = new String(data); + buffer = new StringBuffer().append(ArrayFill.fill(new char[size], '.')).toString(); } @Override @@ -73,7 +72,7 @@ public class TestSoftRefOutOfMemory { // depend on the returned object to be eventually garbaged // collected. Either way, making sure a new String instance // is returned eliminated false failures. - return new String(); + return new StringBuffer().toString(); } @Override @@ -115,7 +114,7 @@ public class TestSoftRefOutOfMemory { // depend on the returned object to be eventually garbaged // collected. Either way, making sure a new String instance // is returned eliminated false failures. - return new String(String.valueOf(counter)); + return new StringBuffer().append(counter).toString(); } @Override public PooledObject<String> wrap(final String value) { @@ -289,4 +288,4 @@ public class TestSoftRefOutOfMemory { assertEquals(1, pool.getNumIdle()); } -} \ No newline at end of file +} diff --git a/src/test/java/org/apache/commons/pool2/impl/TestSynchronizedPooledObjectFactory.java b/src/test/java/org/apache/commons/pool2/impl/TestSynchronizedPooledObjectFactory.java index d54b01c3..11017ed3 100644 --- a/src/test/java/org/apache/commons/pool2/impl/TestSynchronizedPooledObjectFactory.java +++ b/src/test/java/org/apache/commons/pool2/impl/TestSynchronizedPooledObjectFactory.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.commons.pool2.impl; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -26,111 +25,107 @@ import org.apache.commons.pool2.PooledObjectFactory; /** * Copies PoolUtil's private static final class SynchronizedPooledObjectFactory. * - * A fully synchronized PooledObjectFactory that wraps a PooledObjectFactory and - * synchronizes access to the wrapped factory methods. + * A fully synchronized PooledObjectFactory that wraps a PooledObjectFactory and synchronizes access to the wrapped factory methods. * <p> - * <strong>Note:</strong> This should not be used on pool implementations that already - * provide proper synchronization such as the pools provided in the Commons Pool - * library. + * <strong>Note:</strong> This should not be used on pool implementations that already provide proper synchronization such as the pools provided in the Commons + * Pool library. * </p> + * + * @param <T> Type of element managed in this factory. */ final class TestSynchronizedPooledObjectFactory<T> implements PooledObjectFactory<T> { + /** Synchronization lock */ + private final WriteLock writeLock = new ReentrantReadWriteLock().writeLock(); + /** Wrapped factory */ + private final PooledObjectFactory<T> factory; - /** Synchronization lock */ - private final WriteLock writeLock = new ReentrantReadWriteLock().writeLock(); - - /** Wrapped factory */ - private final PooledObjectFactory<T> factory; - - /** - * Constructs a SynchronizedPoolableObjectFactory wrapping the given factory. - * - * @param factory - * underlying factory to wrap - * @throws IllegalArgumentException - * if the factory is null - */ - TestSynchronizedPooledObjectFactory(final PooledObjectFactory<T> factory) throws IllegalArgumentException { - if (factory == null) { - throw new IllegalArgumentException("factory must not be null."); - } - this.factory = factory; - } + /** + * Constructs a SynchronizedPoolableObjectFactory wrapping the given factory. + * + * @param factory underlying factory to wrap + * @throws IllegalArgumentException if the factory is null + */ + TestSynchronizedPooledObjectFactory(final PooledObjectFactory<T> factory) throws IllegalArgumentException { + if (factory == null) { + throw new IllegalArgumentException("factory must not be null."); + } + this.factory = factory; + } - /** - * {@inheritDoc} - */ - @Override - public void activateObject(final PooledObject<T> p) throws Exception { - writeLock.lock(); - try { - factory.activateObject(p); - } finally { - writeLock.unlock(); - } - } + /** + * {@inheritDoc} + */ + @Override + public void activateObject(final PooledObject<T> p) throws Exception { + writeLock.lock(); + try { + factory.activateObject(p); + } finally { + writeLock.unlock(); + } + } - /** - * {@inheritDoc} - */ - @Override - public void destroyObject(final PooledObject<T> p) throws Exception { - writeLock.lock(); - try { - factory.destroyObject(p); - } finally { - writeLock.unlock(); - } - } + /** + * {@inheritDoc} + */ + @Override + public void destroyObject(final PooledObject<T> p) throws Exception { + writeLock.lock(); + try { + factory.destroyObject(p); + } finally { + writeLock.unlock(); + } + } - /** - * {@inheritDoc} - */ - @Override - public PooledObject<T> makeObject() throws Exception { - writeLock.lock(); - try { - return factory.makeObject(); - } finally { - writeLock.unlock(); - } - } + /** + * {@inheritDoc} + */ + @Override + public PooledObject<T> makeObject() throws Exception { + writeLock.lock(); + try { + return factory.makeObject(); + } finally { + writeLock.unlock(); + } + } - /** - * {@inheritDoc} - */ - @Override - public void passivateObject(final PooledObject<T> p) throws Exception { - writeLock.lock(); - try { - factory.passivateObject(p); - } finally { - writeLock.unlock(); - } - } + /** + * {@inheritDoc} + */ + @Override + public void passivateObject(final PooledObject<T> p) throws Exception { + writeLock.lock(); + try { + factory.passivateObject(p); + } finally { + writeLock.unlock(); + } + } - /** - * {@inheritDoc} - */ - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append("SynchronizedPoolableObjectFactory"); - sb.append("{factory=").append(factory); - sb.append('}'); - return sb.toString(); - } + /** + * {@inheritDoc} + */ + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("SynchronizedPoolableObjectFactory"); + sb.append("{factory=").append(factory); + sb.append('}'); + return sb.toString(); + } - /** - * {@inheritDoc} - */ - @Override - public boolean validateObject(final PooledObject<T> p) { - writeLock.lock(); - try { - return factory.validateObject(p); - } finally { - writeLock.unlock(); - } - } + /** + * {@inheritDoc} + */ + @Override + public boolean validateObject(final PooledObject<T> p) { + writeLock.lock(); + try { + return factory.validateObject(p); + } finally { + writeLock.unlock(); + } + } } diff --git a/src/test/java/org/apache/commons/pool2/performance/PerformanceTest.java b/src/test/java/org/apache/commons/pool2/performance/PerformanceTest.java index ce9b5ba9..237f742f 100644 --- a/src/test/java/org/apache/commons/pool2/performance/PerformanceTest.java +++ b/src/test/java/org/apache/commons/pool2/performance/PerformanceTest.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.commons.pool2.performance; import java.time.Duration; @@ -32,7 +31,6 @@ import org.apache.commons.pool2.impl.GenericObjectPool; * Multi-thread performance test */ public class PerformanceTest { - final class PerfTask implements Callable<TaskStats> { final TaskStats taskStats = new TaskStats(); long borrowTimeNanos; @@ -40,113 +38,99 @@ public class PerformanceTest { @Override public TaskStats call() { - runOnce(); // warmup - for (int i = 0; i < nrIterations; i++) { - runOnce(); - taskStats.totalBorrowNanos += borrowTimeNanos; - taskStats.totalReturnNanos += returnTimeNanos; - taskStats.nrSamples++; - if (logLevel >= 2) { - final String name = "thread" + Thread.currentThread().getName(); - System.out.println("result " + taskStats.nrSamples + '\t' + - name + '\t' + "borrow time: " + Duration.ofNanos(borrowTimeNanos) + '\t' + - "return time: " + Duration.ofNanos(returnTimeNanos) + '\t' + "waiting: " + - taskStats.waiting + '\t' + "complete: " + - taskStats.complete); - } - } - return taskStats; - } - - public void runOnce() { - try { - taskStats.waiting++; - if (logLevel >= 5) { - final String name = "thread" + Thread.currentThread().getName(); - System.out.println(name + - " waiting: " + taskStats.waiting + - " complete: " + taskStats.complete); + runOnce(); // warmup + for (int i = 0; i < nrIterations; i++) { + runOnce(); + taskStats.totalBorrowNanos += borrowTimeNanos; + taskStats.totalReturnNanos += returnTimeNanos; + taskStats.nrSamples++; + if (logLevel >= 2) { + final String name = "thread" + Thread.currentThread().getName(); + System.out.println( + "result " + taskStats.nrSamples + '\t' + name + '\t' + "borrow time: " + Duration.ofNanos(borrowTimeNanos) + '\t' + "return time: " + + Duration.ofNanos(returnTimeNanos) + '\t' + "waiting: " + taskStats.waiting + '\t' + "complete: " + taskStats.complete); + } } - final long bbeginNanos = System.nanoTime(); - final Integer o = pool.borrowObject(); - final long bendNanos = System.nanoTime(); - taskStats.waiting--; + return taskStats; + } - if (logLevel >= 3) { - final String name = "thread" + Thread.currentThread().getName(); - System.out.println(name + - " waiting: " + taskStats.waiting + - " complete: " + taskStats.complete); + public void runOnce() { + try { + taskStats.waiting++; + if (logLevel >= 5) { + final String name = "thread" + Thread.currentThread().getName(); + System.out.println(name + " waiting: " + taskStats.waiting + " complete: " + taskStats.complete); + } + final long bbeginNanos = System.nanoTime(); + final Integer o = pool.borrowObject(); + final long bendNanos = System.nanoTime(); + taskStats.waiting--; + if (logLevel >= 3) { + final String name = "thread" + Thread.currentThread().getName(); + System.out.println(name + " waiting: " + taskStats.waiting + " complete: " + taskStats.complete); + } + final long rbeginNanos = System.nanoTime(); + pool.returnObject(o); + final long rendNanos = System.nanoTime(); + Thread.yield(); + taskStats.complete++; + borrowTimeNanos = bendNanos - bbeginNanos; + returnTimeNanos = rendNanos - rbeginNanos; + } catch (final Exception e) { + e.printStackTrace(); } - - final long rbeginNanos = System.nanoTime(); - pool.returnObject(o); - final long rendNanos = System.nanoTime(); - Thread.yield(); - taskStats.complete++; - borrowTimeNanos = bendNanos - bbeginNanos; - returnTimeNanos = rendNanos - rbeginNanos; - } catch (final Exception e) { - e.printStackTrace(); } } - } + private static final class TaskStats { - public int waiting; - public int complete; - public long totalBorrowNanos; - public long totalReturnNanos; - public int nrSamples; + int waiting; + int complete; + long totalBorrowNanos; + long totalReturnNanos; + int nrSamples; } public static void main(final String[] args) { final PerformanceTest test = new PerformanceTest(); test.setLogLevel(0); System.out.println("Increase threads"); - test.run(1, 50, 5, 5); - test.run(1, 100, 5, 5); - test.run(1, 200, 5, 5); - test.run(1, 400, 5, 5); - + test.run(1, 50, 5, 5); + test.run(1, 100, 5, 5); + test.run(1, 200, 5, 5); + test.run(1, 400, 5, 5); System.out.println("Increase threads & poolSize"); - test.run(1, 50, 5, 5); + test.run(1, 50, 5, 5); test.run(1, 100, 10, 10); test.run(1, 200, 20, 20); test.run(1, 400, 40, 40); - System.out.println("Increase maxIdle"); - test.run(1, 400, 40, 5); + test.run(1, 400, 40, 5); test.run(1, 400, 40, 40); - // System.out.println("Show creation/destruction of objects"); // test.setLogLevel(4); // test.run(1, 400, 40, 5); } private int logLevel; - private int nrIterations = 5; - private GenericObjectPool<Integer> pool; private void run(final int iterations, final int nrThreads, final int maxTotal, final int maxIdle) { this.nrIterations = iterations; - final SleepingObjectFactory factory = new SleepingObjectFactory(); - if (logLevel >= 4) { factory.setDebug(true); } + if (logLevel >= 4) { + factory.setDebug(true); + } pool = new GenericObjectPool<>(factory); pool.setMaxTotal(maxTotal); pool.setMaxIdle(maxIdle); pool.setTestOnBorrow(true); - final ExecutorService threadPool = Executors.newFixedThreadPool(nrThreads); - final List<Callable<TaskStats>> tasks = new ArrayList<>(); for (int i = 0; i < nrThreads; i++) { tasks.add(new PerfTask()); Thread.yield(); } - if (logLevel >= 1) { System.out.println("created"); } @@ -157,15 +141,17 @@ public class PerformanceTest { } catch (final InterruptedException e) { e.printStackTrace(); } - - if (logLevel >= 1) { System.out.println("started"); } + if (logLevel >= 1) { + System.out.println("started"); + } Thread.yield(); - - if (logLevel >= 1) { System.out.println("go"); } + if (logLevel >= 1) { + System.out.println("go"); + } Thread.yield(); - - if (logLevel >= 1) { System.out.println("finish"); } - + if (logLevel >= 1) { + System.out.println("finish"); + } final TaskStats aggregate = new TaskStats(); if (futures != null) { for (final Future<TaskStats> future : futures) { @@ -184,7 +170,6 @@ public class PerformanceTest { } } } - final Duration totalBorrowDuration = Duration.ofNanos(aggregate.totalBorrowNanos); final Duration totalReturnDuration = Duration.ofNanos(aggregate.totalReturnNanos); System.out.println("-----------------------------------------"); @@ -197,7 +182,6 @@ public class PerformanceTest { System.out.println("totalReturnTime: " + totalReturnDuration); System.out.println("avg BorrowTime: " + totalBorrowDuration.dividedBy(aggregate.nrSamples)); System.out.println("avg ReturnTime: " + totalReturnDuration.dividedBy(aggregate.nrSamples)); - threadPool.shutdown(); } diff --git a/src/test/java/org/apache/commons/pool2/pool407/AbstractPool407Factory.java b/src/test/java/org/apache/commons/pool2/pool407/AbstractPool407Factory.java index e2a911db..3a12ec34 100644 --- a/src/test/java/org/apache/commons/pool2/pool407/AbstractPool407Factory.java +++ b/src/test/java/org/apache/commons/pool2/pool407/AbstractPool407Factory.java @@ -28,6 +28,8 @@ public abstract class AbstractPool407Factory extends BasePooledObjectFactory<Poo /** * Tests whether the subclass relies on the Pool's implementation of makeObject(). If the subclass returns false, then it implements makeObject(), in which * case makeObject() returns a bad object like null or a null wrapper. + * + * @return whether the subclass relies on the Pool's implementation of makeObject(). */ abstract boolean isDefaultMakeObject(); diff --git a/src/test/java/org/apache/commons/pool2/pool407/KeyedPool407NormalFactory.java b/src/test/java/org/apache/commons/pool2/pool407/KeyedPool407NormalFactory.java index 8ff88bd8..afa0a57d 100644 --- a/src/test/java/org/apache/commons/pool2/pool407/KeyedPool407NormalFactory.java +++ b/src/test/java/org/apache/commons/pool2/pool407/KeyedPool407NormalFactory.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.commons.pool2.pool407; import org.apache.commons.pool2.PooledObject; @@ -24,7 +23,6 @@ import org.apache.commons.pool2.impl.DefaultPooledObject; * Tests POOL-407. */ public final class KeyedPool407NormalFactory extends AbstractKeyedPool407Factory { - private final KeyedPool407Fixture fixture; KeyedPool407NormalFactory(final KeyedPool407Fixture fixture) { @@ -34,7 +32,8 @@ public final class KeyedPool407NormalFactory extends AbstractKeyedPool407Factory @Override public KeyedPool407Fixture create(final String key) { // This is key to the test, creation failed and returns null for instance see - // https://github.com/openhab/openhab-core/blob/main/bundles/org.openhab.core.io.transport.modbus/src/main/java/org/openhab/core/io/transport/modbus/internal/pooling/ModbusSlaveConnectionFactoryImpl.java#L163 + // https://github.com/openhab/openhab-core/blob/main/bundles/org.openhab.core.io.transport.modbus/ + // src/main/java/org/openhab/core/io/transport/modbus/internal/pooling/ModbusSlaveConnectionFactoryImpl.java#L163 // the test passes when this returns new Pool407Fixture(); return fixture; } diff --git a/src/test/java/org/apache/commons/pool2/pool407/KeyedPool407Test.java b/src/test/java/org/apache/commons/pool2/pool407/KeyedPool407Test.java index c69980c5..59e332cc 100644 --- a/src/test/java/org/apache/commons/pool2/pool407/KeyedPool407Test.java +++ b/src/test/java/org/apache/commons/pool2/pool407/KeyedPool407Test.java @@ -56,7 +56,8 @@ public class KeyedPool407Test extends AbstractPool407Test { private static final String KEY = "key"; - protected void assertShutdown(final ExecutorService executor, final Duration poolConfigMaxWait, final AbstractKeyedPool407Factory factory) throws Exception { + protected void assertShutdown(final ExecutorService executor, final Duration poolConfigMaxWait, final AbstractKeyedPool407Factory factory) + throws Exception { // Old note: This never finishes when the factory makes nulls because two threads are stuck forever // If a factory always returns a null object or a null poolable object, then we will wait forever. // This would also be true is object validation always fails. diff --git a/src/test/java/org/apache/commons/pool2/pool407/Pool407NormalFactory.java b/src/test/java/org/apache/commons/pool2/pool407/Pool407NormalFactory.java index 03ade541..34629f4a 100644 --- a/src/test/java/org/apache/commons/pool2/pool407/Pool407NormalFactory.java +++ b/src/test/java/org/apache/commons/pool2/pool407/Pool407NormalFactory.java @@ -37,7 +37,8 @@ public final class Pool407NormalFactory extends AbstractPool407Factory { // // Old note: // This is key to the test, creation failed and returns null for instance see - // https://github.com/openhab/openhab-core/blob/main/bundles/org.openhab.core.io.transport.modbus/src/main/java/org/openhab/core/io/transport/modbus/internal/pooling/ModbusSlaveConnectionFactoryImpl.java#L163 + // https://github.com/openhab/openhab-core/blob/main/bundles/org.openhab.core.io.transport.modbus/ + // src/main/java/org/openhab/core/io/transport/modbus/internal/pooling/ModbusSlaveConnectionFactoryImpl.java#L163 // the test passes when this returns new Pool407Fixture(); return fixture; }
