1 16 17 package org.apache.commons.dbcp; 18 19 import java.util.Vector ; 20 21 import junit.framework.Test; 22 import junit.framework.TestCase; 23 import junit.framework.TestSuite; 24 25 import org.apache.commons.pool.PoolableObjectFactory; 26 27 33 public class TestAbandonedObjectPool extends TestCase { 34 private AbandonedObjectPool pool = null; 35 private AbandonedConfig config = null; 36 37 public TestAbandonedObjectPool(String testName) { 38 super(testName); 39 } 40 41 public static Test suite() { 42 return new TestSuite(TestAbandonedObjectPool.class); 43 } 44 45 public void setUp() throws Exception { 46 super.setUp(); 47 config = new AbandonedConfig(); 48 49 52 config.setRemoveAbandoned(true); 53 config.setRemoveAbandonedTimeout(1); 54 pool = new AbandonedObjectPool(new SimpleFactory(), config); 55 } 56 57 public void tearDown() throws Exception { 58 super.tearDown(); 59 pool.close(); 60 pool = null; 61 } 62 63 67 public void testConcurrentInvalidation() throws Exception { 68 final int POOL_SIZE = 30; 69 pool.setMaxActive(POOL_SIZE); 70 pool.setMaxIdle(POOL_SIZE); 71 pool.setWhenExhaustedAction(AbandonedObjectPool.WHEN_EXHAUSTED_FAIL); 72 73 Vector vec = new Vector (); 75 for (int i = 0; i < POOL_SIZE; i++) { 76 vec.add(pool.borrowObject()); 77 } 78 79 for (int i = 0; i < vec.size(); i++) { 81 ((PooledTestObject)vec.elementAt(i)).setAbandoned(true); 82 } 83 84 final int CONCURRENT_BORROWS = 5; 86 Thread [] threads = new Thread [CONCURRENT_BORROWS]; 87 for (int i = 0; i < CONCURRENT_BORROWS; i++) { 88 threads[i] = new ConcurrentBorrower(vec); 89 threads[i].start(); 90 } 91 92 for (int i = 0; i < CONCURRENT_BORROWS; i++) { 94 threads[i].join(); 95 } 96 97 for (int i = 0; i < vec.size(); i++) { 99 PooledTestObject pto = (PooledTestObject)vec.elementAt(i); 100 if (pto.isActive()) { 101 pool.returnObject(pto); 102 } 103 } 104 105 assertTrue("numActive should have been 0, was " + pool.getNumActive(), pool.getNumActive() == 0); 107 } 108 109 class ConcurrentBorrower extends Thread { 110 private Vector _borrowed; 111 112 public ConcurrentBorrower(Vector borrowed) { 113 _borrowed = borrowed; 114 } 115 116 public void run() { 117 try { 118 _borrowed.add(pool.borrowObject()); 119 } catch (Exception e) { 120 } 122 } 123 } 124 125 class SimpleFactory implements PoolableObjectFactory { 126 127 public Object makeObject() { 128 return new PooledTestObject(config); 129 } 130 131 public boolean validateObject(Object obj) { return true; } 132 133 public void activateObject(Object obj) { 134 ((PooledTestObject)obj).setActive(true); 135 } 136 137 public void passivateObject(Object obj) { 138 ((PooledTestObject)obj).setActive(false); 139 } 140 141 public void destroyObject(Object obj) { 142 ((PooledTestObject)obj).setActive(false); 143 Thread.yield(); 146 } 147 } 148 } 149 150 class PooledTestObject extends AbandonedTrace { 151 private boolean active = false; 152 private int _hash = 0; 153 private boolean _abandoned = false; 154 155 private static int hash = 1; 156 157 public PooledTestObject(AbandonedConfig config) { 158 super(config); 159 _hash = hash++; 160 } 161 162 public synchronized void setActive(boolean b) { 163 active = b; 164 } 165 166 public synchronized boolean isActive() { 167 return active; 168 } 169 170 public int hashCode() { 171 return _hash; 172 } 173 174 public void setAbandoned(boolean b) { 175 _abandoned = b; 176 } 177 178 protected long getLastUsed() { 179 if (_abandoned) { 180 return 1; 183 } else { 184 return 0; 186 } 187 } 188 189 public boolean equals(Object obj) { 190 if (!(obj instanceof PooledTestObject)) return false; 191 return obj.hashCode() == hashCode(); 192 } 193 } 194 195 | Popular Tags |