1   /*
2    * Copyright 1999-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.pool.impl;
18  
19  import java.util.BitSet;
20  import java.util.HashMap;
21  import java.util.NoSuchElementException;
22  
23  import junit.framework.Test;
24  import junit.framework.TestSuite;
25  
26  import org.apache.commons.pool.KeyedObjectPool;
27  import org.apache.commons.pool.KeyedPoolableObjectFactory;
28  import org.apache.commons.pool.TestKeyedObjectPool;
29  
30  /***
31   * @author Rodney Waldhoff
32   * @version $Revision: 383290 $ $Date: 2006-03-05 02:00:15 -0500 (Sun, 05 Mar 2006) $
33   */
34  public class TestStackKeyedObjectPool extends TestKeyedObjectPool {
35      public TestStackKeyedObjectPool(String testName) {
36          super(testName);
37      }
38  
39      public static Test suite() {
40          return new TestSuite(TestStackKeyedObjectPool.class);
41      }
42  
43      protected KeyedObjectPool makeEmptyPool(int mincapacity) {
44          StackKeyedObjectPool pool = new StackKeyedObjectPool(new SimpleFactory(),mincapacity);
45          return pool;
46      }
47      
48      protected Object getNthObject(Object key, int n) {
49          return String.valueOf(key) + String.valueOf(n);
50      }
51      
52      protected Object makeKey(int n) {
53          return String.valueOf(n);
54      }
55  
56      private StackKeyedObjectPool pool = null;
57  
58      public void setUp() throws Exception {
59          super.setUp();
60          pool = new StackKeyedObjectPool(
61              new KeyedPoolableObjectFactory()  {
62                  int counter = 0;
63                  public Object makeObject(Object key) { return String.valueOf(key) + String.valueOf(counter++); }
64                  public void destroyObject(Object key, Object obj) { }
65                  public boolean validateObject(Object key, Object obj) { return true; }
66                  public void activateObject(Object key, Object obj) { }
67                  public void passivateObject(Object key, Object obj) { }
68              }
69              );
70      }
71  
72      
73      public void tearDown() throws Exception {
74          super.tearDown();
75          pool = null;
76      }
77  
78      public void testCloseBug() throws Exception {
79          {
80              Object obj0 = pool.borrowObject("");
81              Object obj1 = pool.borrowObject("");
82              assertEquals(2,pool.getNumActive(""));
83              assertEquals(0,pool.getNumIdle(""));
84              pool.returnObject("",obj1);
85              pool.returnObject("",obj0);
86              assertEquals(0,pool.getNumActive(""));
87              assertEquals(2,pool.getNumIdle(""));
88          }
89          {
90              Object obj0 = pool.borrowObject("2");
91              Object obj1 = pool.borrowObject("2");
92              assertEquals(2,pool.getNumActive("2"));
93              assertEquals(0,pool.getNumIdle("2"));
94              pool.returnObject("2",obj1);
95              pool.returnObject("2",obj0);
96              assertEquals(0,pool.getNumActive("2"));
97              assertEquals(2,pool.getNumIdle("2"));
98          }
99          pool.close();
100     }
101 
102     public void testIdleCap() throws Exception {
103         Object[] active = new Object[100];
104         for(int i=0;i<100;i++) {
105             active[i] = pool.borrowObject("");
106         }
107         assertEquals(100,pool.getNumActive(""));
108         assertEquals(0,pool.getNumIdle(""));
109         for(int i=0;i<100;i++) {
110             pool.returnObject("",active[i]);
111             assertEquals(99 - i,pool.getNumActive(""));
112             assertEquals((i < 8 ? i+1 : 8),pool.getNumIdle(""));
113         }
114     }
115     
116     public void testPoolWithNullFactory() throws Exception {
117         KeyedObjectPool pool = new StackKeyedObjectPool(10);
118         for(int i=0;i<10;i++) {
119             pool.returnObject("X",new Integer(i));
120         }
121         for(int j=0;j<3;j++) {
122             Integer[] borrowed = new Integer[10];
123             BitSet found = new BitSet();
124             for(int i=0;i<10;i++) {
125                 borrowed[i] = (Integer)(pool.borrowObject("X"));
126                 assertNotNull(borrowed);
127                 assertTrue(!found.get(borrowed[i].intValue()));
128                 found.set(borrowed[i].intValue());
129             }
130             for(int i=0;i<10;i++) {
131                 pool.returnObject("X",borrowed[i]);
132             }
133         }
134         pool.invalidateObject("X",pool.borrowObject("X"));
135         pool.invalidateObject("X",pool.borrowObject("X"));
136         pool.clear("X");        
137         pool.clear();        
138     }
139     
140     public void testVariousConstructors() throws Exception {
141         {
142             StackKeyedObjectPool pool = new StackKeyedObjectPool();
143             assertNotNull(pool);
144         }
145         {
146             StackKeyedObjectPool pool = new StackKeyedObjectPool(10);
147             assertNotNull(pool);
148         }
149         {
150             StackKeyedObjectPool pool = new StackKeyedObjectPool(10,5);
151             assertNotNull(pool);
152         }
153         {
154             StackKeyedObjectPool pool = new StackKeyedObjectPool(null);
155             assertNotNull(pool);
156         }
157         {
158             StackKeyedObjectPool pool = new StackKeyedObjectPool(null,10);
159             assertNotNull(pool);
160         }
161         {
162             StackKeyedObjectPool pool = new StackKeyedObjectPool(null,10,5);
163             assertNotNull(pool);
164         }
165     }
166     
167     public void testToString() throws Exception {
168         StackKeyedObjectPool pool = new StackKeyedObjectPool(new SimpleFactory());
169         assertNotNull(pool.toString());
170         Object obj = pool.borrowObject("key");
171         assertNotNull(pool.toString());
172         pool.returnObject("key",obj);
173         assertNotNull(pool.toString());
174     }
175         
176     public void testBorrowFromEmptyPoolWithNullFactory() throws Exception {
177         KeyedObjectPool pool = new StackKeyedObjectPool();
178         try {
179             pool.borrowObject("x");
180             fail("Expected NoSuchElementException");
181         } catch(NoSuchElementException e) {
182             // expected
183         }
184     }
185     
186     public void testSetFactory() throws Exception {
187         KeyedObjectPool pool = new StackKeyedObjectPool();
188         try {
189             pool.borrowObject("x");
190             fail("Expected NoSuchElementException");
191         } catch(NoSuchElementException e) {
192             // expected
193         }
194         pool.setFactory(new SimpleFactory());
195         Object obj = pool.borrowObject("x");
196         assertNotNull(obj);
197         pool.returnObject("x",obj);
198     }
199 
200     public void testCantResetFactoryWithActiveObjects() throws Exception {
201         KeyedObjectPool pool = new StackKeyedObjectPool();
202         pool.setFactory(new SimpleFactory());
203         Object obj = pool.borrowObject("x");
204         assertNotNull(obj);
205 
206         try {
207             pool.setFactory(new SimpleFactory());
208             fail("Expected IllegalStateException");
209         } catch(IllegalStateException e) {
210             // expected
211         }        
212     }
213     
214     public void testCanResetFactoryWithoutActiveObjects() throws Exception {
215         KeyedObjectPool pool = new StackKeyedObjectPool();
216         {
217             pool.setFactory(new SimpleFactory());
218             Object obj = pool.borrowObject("x");        
219             assertNotNull(obj);
220             pool.returnObject("x",obj);
221         }
222         {
223             pool.setFactory(new SimpleFactory());
224             Object obj = pool.borrowObject("x");        
225             assertNotNull(obj);
226             pool.returnObject("x",obj);
227         }
228     }
229 
230     public void testBorrowReturnWithSometimesInvalidObjects() throws Exception {
231         KeyedObjectPool pool = new StackKeyedObjectPool();
232         pool.setFactory(
233             new KeyedPoolableObjectFactory() {
234                 int counter = 0;
235                 public Object makeObject(Object key) { return new Integer(counter++); }
236                 public void destroyObject(Object key, Object obj) { }
237                 public boolean validateObject(Object key, Object obj) {
238                     if(obj instanceof Integer) {
239                         return ((((Integer)obj).intValue() % 2) == 1);
240                     } else {
241                         return false;
242                     }
243                 }
244                 public void activateObject(Object key, Object obj) { }
245                 public void passivateObject(Object key, Object obj) { 
246                     if(obj instanceof Integer) {
247                         if((((Integer)obj).intValue() % 3) == 0) {
248                             throw new RuntimeException("Couldn't passivate");
249                         }
250                     } else {
251                         throw new RuntimeException("Couldn't passivate");
252                     }
253                 }
254             }
255         );
256 
257         Object[] obj = new Object[10];
258         for(int i=0;i<10;i++) {
259             obj[i] = pool.borrowObject("key");
260         }
261         for(int i=0;i<10;i++) {
262             pool.returnObject("key",obj[i]);
263         }
264         assertEquals(3,pool.getNumIdle("key"));
265     }
266  
267     class SimpleFactory implements KeyedPoolableObjectFactory {
268         HashMap map = new HashMap();
269         public Object makeObject(Object key) { 
270             int counter = 0;
271             Integer Counter = (Integer)(map.get(key));
272             if(null != Counter) {
273                 counter = Counter.intValue();
274             }
275             map.put(key,new Integer(counter + 1));                       
276             return String.valueOf(key) + String.valueOf(counter); 
277         }
278         public void destroyObject(Object key, Object obj) { }
279         public boolean validateObject(Object key, Object obj) { return true; }
280         public void activateObject(Object key, Object obj) { }
281         public void passivateObject(Object key, Object obj) { }
282     }
283 
284     protected boolean isLifo() {
285         return true;
286     }
287 
288     protected boolean isFifo() {
289         return false;
290     }
291 }