001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.pool.impl; 019 020 import java.util.BitSet; 021 import java.util.HashMap; 022 import java.util.NoSuchElementException; 023 024 import junit.framework.Test; 025 import junit.framework.TestSuite; 026 027 import org.apache.commons.pool.KeyedObjectPool; 028 import org.apache.commons.pool.KeyedPoolableObjectFactory; 029 import org.apache.commons.pool.TestBaseKeyedObjectPool; 030 031 /** 032 * @author Rodney Waldhoff 033 * @version $Revision: 775703 $ $Date: 2009-05-17 12:39:51 -0400 (Sun, 17 May 2009) $ 034 */ 035 public class TestStackKeyedObjectPool extends TestBaseKeyedObjectPool { 036 public TestStackKeyedObjectPool(String testName) { 037 super(testName); 038 } 039 040 public static Test suite() { 041 return new TestSuite(TestStackKeyedObjectPool.class); 042 } 043 044 protected KeyedObjectPool makeEmptyPool(int mincapacity) { 045 StackKeyedObjectPool pool = new StackKeyedObjectPool(new SimpleFactory(),mincapacity); 046 return pool; 047 } 048 049 protected KeyedObjectPool makeEmptyPool(KeyedPoolableObjectFactory factory) { 050 return new StackKeyedObjectPool(factory); 051 } 052 053 protected Object getNthObject(Object key, int n) { 054 return String.valueOf(key) + String.valueOf(n); 055 } 056 057 protected Object makeKey(int n) { 058 return String.valueOf(n); 059 } 060 061 private StackKeyedObjectPool pool = null; 062 063 public void setUp() throws Exception { 064 super.setUp(); 065 pool = new StackKeyedObjectPool( 066 new KeyedPoolableObjectFactory() { 067 int counter = 0; 068 public Object makeObject(Object key) { return String.valueOf(key) + String.valueOf(counter++); } 069 public void destroyObject(Object key, Object obj) { } 070 public boolean validateObject(Object key, Object obj) { return true; } 071 public void activateObject(Object key, Object obj) { } 072 public void passivateObject(Object key, Object obj) { } 073 } 074 ); 075 } 076 077 078 public void tearDown() throws Exception { 079 super.tearDown(); 080 pool = null; 081 } 082 083 public void testCloseBug() throws Exception { 084 { 085 Object obj0 = pool.borrowObject(""); 086 Object obj1 = pool.borrowObject(""); 087 assertEquals(2,pool.getNumActive("")); 088 assertEquals(0,pool.getNumIdle("")); 089 pool.returnObject("",obj1); 090 pool.returnObject("",obj0); 091 assertEquals(0,pool.getNumActive("")); 092 assertEquals(2,pool.getNumIdle("")); 093 } 094 { 095 Object obj0 = pool.borrowObject("2"); 096 Object obj1 = pool.borrowObject("2"); 097 assertEquals(2,pool.getNumActive("2")); 098 assertEquals(0,pool.getNumIdle("2")); 099 pool.returnObject("2",obj1); 100 pool.returnObject("2",obj0); 101 assertEquals(0,pool.getNumActive("2")); 102 assertEquals(2,pool.getNumIdle("2")); 103 } 104 pool.close(); 105 } 106 107 public void testIdleCap() throws Exception { 108 Object[] active = new Object[100]; 109 for(int i=0;i<100;i++) { 110 active[i] = pool.borrowObject(""); 111 } 112 assertEquals(100,pool.getNumActive("")); 113 assertEquals(0,pool.getNumIdle("")); 114 for(int i=0;i<100;i++) { 115 pool.returnObject("",active[i]); 116 assertEquals(99 - i,pool.getNumActive("")); 117 assertEquals((i < 8 ? i+1 : 8),pool.getNumIdle("")); 118 } 119 } 120 121 public void testPoolWithNullFactory() throws Exception { 122 KeyedObjectPool pool = new StackKeyedObjectPool(10); 123 for(int i=0;i<10;i++) { 124 pool.returnObject("X",new Integer(i)); 125 } 126 for(int j=0;j<3;j++) { 127 Integer[] borrowed = new Integer[10]; 128 BitSet found = new BitSet(); 129 for(int i=0;i<10;i++) { 130 borrowed[i] = (Integer)(pool.borrowObject("X")); 131 assertNotNull(borrowed); 132 assertTrue(!found.get(borrowed[i].intValue())); 133 found.set(borrowed[i].intValue()); 134 } 135 for(int i=0;i<10;i++) { 136 pool.returnObject("X",borrowed[i]); 137 } 138 } 139 pool.invalidateObject("X",pool.borrowObject("X")); 140 pool.invalidateObject("X",pool.borrowObject("X")); 141 pool.clear("X"); 142 pool.clear(); 143 } 144 145 public void testVariousConstructors() throws Exception { 146 { 147 StackKeyedObjectPool pool = new StackKeyedObjectPool(); 148 assertNotNull(pool); 149 } 150 { 151 StackKeyedObjectPool pool = new StackKeyedObjectPool(10); 152 assertNotNull(pool); 153 } 154 { 155 StackKeyedObjectPool pool = new StackKeyedObjectPool(10,5); 156 assertNotNull(pool); 157 } 158 { 159 StackKeyedObjectPool pool = new StackKeyedObjectPool(null); 160 assertNotNull(pool); 161 } 162 { 163 StackKeyedObjectPool pool = new StackKeyedObjectPool(null,10); 164 assertNotNull(pool); 165 } 166 { 167 StackKeyedObjectPool pool = new StackKeyedObjectPool(null,10,5); 168 assertNotNull(pool); 169 } 170 } 171 172 public void testToString() throws Exception { 173 StackKeyedObjectPool pool = new StackKeyedObjectPool(new SimpleFactory()); 174 assertNotNull(pool.toString()); 175 Object obj = pool.borrowObject("key"); 176 assertNotNull(pool.toString()); 177 pool.returnObject("key",obj); 178 assertNotNull(pool.toString()); 179 } 180 181 public void testBorrowFromEmptyPoolWithNullFactory() throws Exception { 182 KeyedObjectPool pool = new StackKeyedObjectPool(); 183 try { 184 pool.borrowObject("x"); 185 fail("Expected NoSuchElementException"); 186 } catch(NoSuchElementException e) { 187 // expected 188 } 189 } 190 191 public void testSetFactory() throws Exception { 192 KeyedObjectPool pool = new StackKeyedObjectPool(); 193 try { 194 pool.borrowObject("x"); 195 fail("Expected NoSuchElementException"); 196 } catch(NoSuchElementException e) { 197 // expected 198 } 199 pool.setFactory(new SimpleFactory()); 200 Object obj = pool.borrowObject("x"); 201 assertNotNull(obj); 202 pool.returnObject("x",obj); 203 } 204 205 public void testCantResetFactoryWithActiveObjects() throws Exception { 206 KeyedObjectPool pool = new StackKeyedObjectPool(); 207 pool.setFactory(new SimpleFactory()); 208 Object obj = pool.borrowObject("x"); 209 assertNotNull(obj); 210 211 try { 212 pool.setFactory(new SimpleFactory()); 213 fail("Expected IllegalStateException"); 214 } catch(IllegalStateException e) { 215 // expected 216 } 217 } 218 219 public void testCanResetFactoryWithoutActiveObjects() throws Exception { 220 KeyedObjectPool pool = new StackKeyedObjectPool(); 221 { 222 pool.setFactory(new SimpleFactory()); 223 Object obj = pool.borrowObject("x"); 224 assertNotNull(obj); 225 pool.returnObject("x",obj); 226 } 227 { 228 pool.setFactory(new SimpleFactory()); 229 Object obj = pool.borrowObject("x"); 230 assertNotNull(obj); 231 pool.returnObject("x",obj); 232 } 233 } 234 235 public void testBorrowReturnWithSometimesInvalidObjects() throws Exception { 236 KeyedObjectPool pool = new StackKeyedObjectPool( 237 new KeyedPoolableObjectFactory() { 238 int counter = 0; 239 public Object makeObject(Object key) { return new Integer(counter++); } 240 public void destroyObject(Object key, Object obj) { } 241 public boolean validateObject(Object key, Object obj) { 242 if(obj instanceof Integer) { 243 return ((((Integer)obj).intValue() % 2) == 1); 244 } else { 245 return false; 246 } 247 } 248 public void activateObject(Object key, Object obj) { } 249 public void passivateObject(Object key, Object obj) { 250 if(obj instanceof Integer) { 251 if((((Integer)obj).intValue() % 3) == 0) { 252 throw new RuntimeException("Couldn't passivate"); 253 } 254 } else { 255 throw new RuntimeException("Couldn't passivate"); 256 } 257 } 258 } 259 ); 260 261 Object[] obj = new Object[10]; 262 for(int i=0;i<10;i++) { 263 Object object = null; 264 int k = 0; 265 while (object == null && k < 100) { // bound not really needed 266 try { 267 k++; 268 object = pool.borrowObject("key"); 269 obj[i] = object; 270 } catch (NoSuchElementException ex) { 271 // Expected for evens, which fail validation 272 } 273 } 274 assertEquals("Each time we borrow, get one more active.", i+1, pool.getNumActive()); 275 } 276 // 1,3,5,...,19 pass validation, get checked out 277 for(int i=0;i<10;i++) { 278 pool.returnObject("key",obj[i]); 279 assertEquals("Each time we borrow, get one less active.", 9-i, pool.getNumActive()); 280 } 281 // 3, 9, 15 fail passivation. 282 assertEquals(7,pool.getNumIdle()); 283 assertEquals(new Integer(19), pool.borrowObject("key")); 284 assertEquals(new Integer(17), pool.borrowObject("key")); 285 assertEquals(new Integer(13), pool.borrowObject("key")); 286 assertEquals(new Integer(11), pool.borrowObject("key")); 287 assertEquals(new Integer(7), pool.borrowObject("key")); 288 assertEquals(new Integer(5), pool.borrowObject("key")); 289 assertEquals(new Integer(1), pool.borrowObject("key")); 290 } 291 292 class SimpleFactory implements KeyedPoolableObjectFactory { 293 HashMap map = new HashMap(); 294 public Object makeObject(Object key) { 295 int counter = 0; 296 Integer Counter = (Integer)(map.get(key)); 297 if(null != Counter) { 298 counter = Counter.intValue(); 299 } 300 map.put(key,new Integer(counter + 1)); 301 return String.valueOf(key) + String.valueOf(counter); 302 } 303 public void destroyObject(Object key, Object obj) { } 304 public boolean validateObject(Object key, Object obj) { return true; } 305 public void activateObject(Object key, Object obj) { } 306 public void passivateObject(Object key, Object obj) { } 307 } 308 309 protected boolean isLifo() { 310 return true; 311 } 312 313 protected boolean isFifo() { 314 return false; 315 } 316 }