This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-pool.git
The following commit(s) were added to refs/heads/master by this push:
new 10be40cf Sort members
10be40cf is described below
commit 10be40cfad8e2baf6356321e3a4c9f824a228a5d
Author: Gary D. Gregory <[email protected]>
AuthorDate: Mon Apr 14 07:24:13 2025 -0400
Sort members
---
.../impl/TestResilientPooledObjectFactory.java | 334 ++++++++++-----------
1 file changed, 167 insertions(+), 167 deletions(-)
diff --git
a/src/test/java/org/apache/commons/pool3/impl/TestResilientPooledObjectFactory.java
b/src/test/java/org/apache/commons/pool3/impl/TestResilientPooledObjectFactory.java
index cef6341a..515b9d64 100644
---
a/src/test/java/org/apache/commons/pool3/impl/TestResilientPooledObjectFactory.java
+++
b/src/test/java/org/apache/commons/pool3/impl/TestResilientPooledObjectFactory.java
@@ -28,94 +28,183 @@ import org.apache.commons.pool3.PooledObjectFactory;
import org.junit.jupiter.api.Test;
public class TestResilientPooledObjectFactory {
+ /**
+ * Factory that suffers outages and fails in configurable ways when it is
down.
+ */
+ class FailingFactory implements PooledObjectFactory<String, Exception> {
+
+ /** Whether or not the factory is up */
+ private boolean up = true;
+
+ /** Whether or not to fail silently */
+ private boolean silentFail = true;
+
+ /** Whether or not to hang */
+ private boolean hang;
+
+ @Override
+ public void activateObject(final PooledObject<String> p) throws
Exception {
+ }
+
+ public void crash() {
+ this.up = false;
+ }
+
+ @Override
+ public void destroyObject(final PooledObject<String> p) throws
Exception {
+ }
+
+ @Override
+ public PooledObject<String> makeObject() throws Exception {
+ if (up) {
+ return new DefaultPooledObject<>(UUID.randomUUID().toString());
+ }
+ if (!silentFail) {
+ throw new Exception("makeObject failed");
+ }
+ if (hang) {
+ while (!up) {
+ try {
+ Thread.sleep(1000);
+ } catch (final InterruptedException e) {
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void passivateObject(final PooledObject<String> p) throws
Exception {
+ }
+
+ public void recover() {
+ this.up = true;
+ }
+
+ public void setHang(final boolean hang) {
+ this.hang = hang;
+ }
+
+ public void setSilentFail(final boolean silentFail) {
+ this.silentFail = silentFail;
+ }
+
+ @Override
+ public boolean validateObject(final PooledObject<String> p) {
+ return up;
+ }
+ }
+
@Test
- public void testTransientFailure() throws Exception {
+ public void testAdderStartStop() throws Exception {
final FailingFactory ff = new FailingFactory();
// Make the factory fail with exception immediately on make
- ff.setHang(false);
- ff.setSilentFail(false);
+ ff.setSilentFail(true);
final ResilientPooledObjectFactory<String, Exception> rf = new
ResilientPooledObjectFactory<>(ff,
- 5, Duration.ofMillis(100), Duration.ofMinutes(10),
Duration.ofMillis(100));
+ 5, Duration.ofMillis(200), Duration.ofMinutes(10),
Duration.ofMillis(20));
// Create a pool with a max size of 2, using the resilient factory
final GenericObjectPool<String, Exception> pool = new
GenericObjectPool<>(rf);
pool.setMaxTotal(2);
pool.setBlockWhenExhausted(true);
pool.setTestOnReturn(true);
- // Tell the factory what pool it is attached to (a little awkward)
rf.setPool(pool);
- rf.startMonitor(Duration.ofMillis(20)); // 20ms monitor interval
- // Base factory is up
- assertTrue(rf.isUp());
- // Check out a couple of objects
+ rf.startMonitor();
+ // Exhasut the pool
final String s1 = pool.borrowObject();
final String s2 = pool.borrowObject();
- // Start a borrower that will wait
+ // Start a borrower that will block waiting
new Thread() {
@Override
public void run() {
try {
- pool.borrowObject();
+ final String s = pool.borrowObject();
} catch (final Exception e) {
}
}
}.start();
- // Wait for the borrower to join wait queue
+ // Wait for the borrower to get in the queue
try {
- Thread.sleep(200);
+ Thread.sleep(50);
} catch (final InterruptedException e) {
}
-
// Crash the base factory
ff.crash();
- // Resilient factory does not know the base factory is down until a
make is
- // attempted
- assertTrue(rf.isUp());
- assertEquals(1, pool.getNumWaiters());
- pool.returnObject(s1);
- pool.returnObject(s2);
- assertEquals(0, pool.getNumIdle());
- assertEquals(1, pool.getNumWaiters());
- // Wait for the monitor to pick up the failed create which should
happen on
- // validation destroy
+ // Return object will create capacity in the pool
+ try {
+ pool.returnObject(s1);
+ } catch (final Exception e) {
+ }
+ // Wait for the adder to run
try {
Thread.sleep(100);
} catch (final InterruptedException e) {
}
- assertFalse(rf.isUp());
- // Adder should be running, but failing
+ // Adder should be running
assertTrue(rf.isAdderRunning());
-
- // Pool should have one take waiter
- assertEquals(1, pool.getNumWaiters());
-
// Restart the factory
ff.recover();
// Wait for the adder to succeed
try {
- Thread.sleep(100);
+ Thread.sleep(200);
} catch (final InterruptedException e) {
}
// Pool should have no waiters
- assertTrue(pool.getNumWaiters() == 0);
- // Add 5 objects to clear the rf log
- // First have to expand the pool
+ assertEquals(0, pool.getNumWaiters());
+ // Adder should still be running because there is a failure in the log
+ assertTrue(rf.isAdderRunning());
+ // Expand the pool - don't try this at home
pool.setMaxTotal(10);
- for (int i = 0; i < 5; i++) {
+ // Run enough adds to homogenize the log
+ for (int i = 0; i < 6; i++) {
pool.addObject();
}
- // Wait for monitor to run
+ // Wait for the monitor to run
try {
Thread.sleep(200);
} catch (final InterruptedException e) {
}
- // rf should be up now
assertTrue(rf.isUp());
-
// Adder should be stopped
assertFalse(rf.isAdderRunning());
+ }
- pool.close();
+ @Test
+ public void testConstructorWithDefaults() {
+ final FailingFactory ff = new FailingFactory();
+ final ResilientPooledObjectFactory<String, Exception> rf = new
ResilientPooledObjectFactory<>(ff);
+ assertFalse(rf.isMonitorRunning());
+ assertFalse(rf.isAdderRunning());
+ assertEquals(ResilientPooledObjectFactory.getDefaultLogSize(),
rf.getLogSize());
+
assertEquals(ResilientPooledObjectFactory.getDefaultTimeBetweenChecks(),
rf.getTimeBetweenChecks());
+ assertEquals(ResilientPooledObjectFactory.getDefaultDelay(),
rf.getDelay());
+ assertEquals(ResilientPooledObjectFactory.getDefaultLookBack(),
rf.getLookBack());
+ assertEquals(0, rf.getMakeObjectLog().size());
+ rf.setLogSize(5);
+ assertEquals(5, rf.getLogSize());
+ rf.setTimeBetweenChecks(Duration.ofMillis(200));
+ }
+
+ @Test
+ public void testIsMonitorRunning() throws Exception {
+ final FailingFactory ff = new FailingFactory();
+ // Make the factory fail with exception immediately on make
+ ff.setSilentFail(true);
+ final ResilientPooledObjectFactory<String, Exception> rf = new
ResilientPooledObjectFactory<>(ff,
+ 5, Duration.ofMillis(200), Duration.ofMinutes(10),
Duration.ofMillis(20));
+ final GenericObjectPool<String, Exception> pool = new
GenericObjectPool<>(rf);
+ rf.setPool(pool);
+ rf.startMonitor();
+ assertTrue(rf.isMonitorRunning());
rf.stopMonitor();
+ assertFalse(rf.isMonitorRunning());
+ rf.startMonitor();
+ pool.close();
+ // Wait for monitor to run so it can kill itself
+ try {
+ Thread.sleep(200);
+ } catch (final InterruptedException e) {
+ }
+ assertFalse(rf.isMonitorRunning());
}
@Test
@@ -197,181 +286,92 @@ public class TestResilientPooledObjectFactory {
}
@Test
- public void testAdderStartStop() throws Exception {
+ public void testTransientFailure() throws Exception {
final FailingFactory ff = new FailingFactory();
// Make the factory fail with exception immediately on make
- ff.setSilentFail(true);
+ ff.setHang(false);
+ ff.setSilentFail(false);
final ResilientPooledObjectFactory<String, Exception> rf = new
ResilientPooledObjectFactory<>(ff,
- 5, Duration.ofMillis(200), Duration.ofMinutes(10),
Duration.ofMillis(20));
+ 5, Duration.ofMillis(100), Duration.ofMinutes(10),
Duration.ofMillis(100));
// Create a pool with a max size of 2, using the resilient factory
final GenericObjectPool<String, Exception> pool = new
GenericObjectPool<>(rf);
pool.setMaxTotal(2);
pool.setBlockWhenExhausted(true);
pool.setTestOnReturn(true);
+ // Tell the factory what pool it is attached to (a little awkward)
rf.setPool(pool);
- rf.startMonitor();
- // Exhasut the pool
+ rf.startMonitor(Duration.ofMillis(20)); // 20ms monitor interval
+ // Base factory is up
+ assertTrue(rf.isUp());
+ // Check out a couple of objects
final String s1 = pool.borrowObject();
final String s2 = pool.borrowObject();
- // Start a borrower that will block waiting
+ // Start a borrower that will wait
new Thread() {
@Override
public void run() {
try {
- final String s = pool.borrowObject();
+ pool.borrowObject();
} catch (final Exception e) {
}
}
}.start();
- // Wait for the borrower to get in the queue
+ // Wait for the borrower to join wait queue
try {
- Thread.sleep(50);
+ Thread.sleep(200);
} catch (final InterruptedException e) {
}
+
// Crash the base factory
ff.crash();
- // Return object will create capacity in the pool
- try {
- pool.returnObject(s1);
- } catch (final Exception e) {
- }
- // Wait for the adder to run
+ // Resilient factory does not know the base factory is down until a
make is
+ // attempted
+ assertTrue(rf.isUp());
+ assertEquals(1, pool.getNumWaiters());
+ pool.returnObject(s1);
+ pool.returnObject(s2);
+ assertEquals(0, pool.getNumIdle());
+ assertEquals(1, pool.getNumWaiters());
+ // Wait for the monitor to pick up the failed create which should
happen on
+ // validation destroy
try {
Thread.sleep(100);
} catch (final InterruptedException e) {
}
- // Adder should be running
+ assertFalse(rf.isUp());
+ // Adder should be running, but failing
assertTrue(rf.isAdderRunning());
+
+ // Pool should have one take waiter
+ assertEquals(1, pool.getNumWaiters());
+
// Restart the factory
ff.recover();
// Wait for the adder to succeed
try {
- Thread.sleep(200);
+ Thread.sleep(100);
} catch (final InterruptedException e) {
}
// Pool should have no waiters
- assertEquals(0, pool.getNumWaiters());
- // Adder should still be running because there is a failure in the log
- assertTrue(rf.isAdderRunning());
- // Expand the pool - don't try this at home
+ assertTrue(pool.getNumWaiters() == 0);
+ // Add 5 objects to clear the rf log
+ // First have to expand the pool
pool.setMaxTotal(10);
- // Run enough adds to homogenize the log
- for (int i = 0; i < 6; i++) {
+ for (int i = 0; i < 5; i++) {
pool.addObject();
}
- // Wait for the monitor to run
+ // Wait for monitor to run
try {
Thread.sleep(200);
} catch (final InterruptedException e) {
}
+ // rf should be up now
assertTrue(rf.isUp());
+
// Adder should be stopped
assertFalse(rf.isAdderRunning());
- }
- @Test
- public void testIsMonitorRunning() throws Exception {
- final FailingFactory ff = new FailingFactory();
- // Make the factory fail with exception immediately on make
- ff.setSilentFail(true);
- final ResilientPooledObjectFactory<String, Exception> rf = new
ResilientPooledObjectFactory<>(ff,
- 5, Duration.ofMillis(200), Duration.ofMinutes(10),
Duration.ofMillis(20));
- final GenericObjectPool<String, Exception> pool = new
GenericObjectPool<>(rf);
- rf.setPool(pool);
- rf.startMonitor();
- assertTrue(rf.isMonitorRunning());
- rf.stopMonitor();
- assertFalse(rf.isMonitorRunning());
- rf.startMonitor();
pool.close();
- // Wait for monitor to run so it can kill itself
- try {
- Thread.sleep(200);
- } catch (final InterruptedException e) {
- }
- assertFalse(rf.isMonitorRunning());
- }
-
- @Test
- public void testConstructorWithDefaults() {
- final FailingFactory ff = new FailingFactory();
- final ResilientPooledObjectFactory<String, Exception> rf = new
ResilientPooledObjectFactory<>(ff);
- assertFalse(rf.isMonitorRunning());
- assertFalse(rf.isAdderRunning());
- assertEquals(ResilientPooledObjectFactory.getDefaultLogSize(),
rf.getLogSize());
-
assertEquals(ResilientPooledObjectFactory.getDefaultTimeBetweenChecks(),
rf.getTimeBetweenChecks());
- assertEquals(ResilientPooledObjectFactory.getDefaultDelay(),
rf.getDelay());
- assertEquals(ResilientPooledObjectFactory.getDefaultLookBack(),
rf.getLookBack());
- assertEquals(0, rf.getMakeObjectLog().size());
- rf.setLogSize(5);
- assertEquals(5, rf.getLogSize());
- rf.setTimeBetweenChecks(Duration.ofMillis(200));
- }
-
- /**
- * Factory that suffers outages and fails in configurable ways when it is
down.
- */
- class FailingFactory implements PooledObjectFactory<String, Exception> {
-
- /** Whether or not the factory is up */
- private boolean up = true;
-
- /** Whether or not to fail silently */
- private boolean silentFail = true;
-
- /** Whether or not to hang */
- private boolean hang;
-
- public void crash() {
- this.up = false;
- }
-
- public void recover() {
- this.up = true;
- }
-
- public void setSilentFail(final boolean silentFail) {
- this.silentFail = silentFail;
- }
-
- public void setHang(final boolean hang) {
- this.hang = hang;
- }
-
- @Override
- public PooledObject<String> makeObject() throws Exception {
- if (up) {
- return new DefaultPooledObject<>(UUID.randomUUID().toString());
- }
- if (!silentFail) {
- throw new Exception("makeObject failed");
- }
- if (hang) {
- while (!up) {
- try {
- Thread.sleep(1000);
- } catch (final InterruptedException e) {
- }
- }
- }
- return null;
- }
-
- @Override
- public void destroyObject(final PooledObject<String> p) throws
Exception {
- }
-
- @Override
- public boolean validateObject(final PooledObject<String> p) {
- return up;
- }
-
- @Override
- public void activateObject(final PooledObject<String> p) throws
Exception {
- }
-
- @Override
- public void passivateObject(final PooledObject<String> p) throws
Exception {
- }
+ rf.stopMonitor();
}
}