1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.pool;
18
19 import junit.framework.TestCase;
20 import org.apache.commons.pool.impl.GenericObjectPool;
21 import org.apache.commons.pool.impl.StackObjectPool;
22 import org.apache.commons.pool.impl.SoftReferenceObjectPool;
23
24 import java.util.List;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.NoSuchElementException;
28
29
30
31
32
33
34
35 public abstract class TestObjectPool extends TestCase {
36 public TestObjectPool(String testName) {
37 super(testName);
38 }
39
40
41
42
43
44
45
46
47 protected abstract ObjectPool makeEmptyPool(PoolableObjectFactory factory) throws UnsupportedOperationException;
48
49 public void testClosedPoolBehavior() throws Exception {
50 final ObjectPool pool;
51 try {
52 pool = makeEmptyPool(new MethodCallPoolableObjectFactory());
53 } catch (UnsupportedOperationException uoe) {
54 return;
55 }
56 Object o1 = pool.borrowObject();
57 Object o2 = pool.borrowObject();
58
59 pool.close();
60
61 try {
62 pool.addObject();
63 fail("A closed pool must throw an IllegalStateException when addObject is called.");
64 } catch (IllegalStateException ise) {
65
66 }
67
68 try {
69 pool.borrowObject();
70 fail("A closed pool must throw an IllegalStateException when borrowObject is called.");
71 } catch (IllegalStateException ise) {
72
73 }
74
75
76 if (pool.getNumIdle() >= 0) {
77 assertEquals("A closed pool shouldn't have any idle objects.", 0, pool.getNumIdle());
78 }
79 if (pool.getNumActive() >= 0) {
80 assertEquals("A closed pool should still keep count of active objects.", 2, pool.getNumActive());
81 }
82 pool.returnObject(o1);
83 if (pool.getNumIdle() >= 0) {
84 assertEquals("returnObject should not add items back into the idle object pool for a closed pool.", 0, pool.getNumIdle());
85 }
86 if (pool.getNumActive() >= 0) {
87 assertEquals("A closed pool should still keep count of active objects.", 1, pool.getNumActive());
88 }
89 pool.invalidateObject(o2);
90 if (pool.getNumIdle() >= 0) {
91 assertEquals("invalidateObject must not add items back into the idle object pool.", 0, pool.getNumIdle());
92 }
93 if (pool.getNumActive() >= 0) {
94 assertEquals("A closed pool should still keep count of active objects.", 0, pool.getNumActive());
95 }
96 pool.clear();
97 pool.close();
98 }
99
100 private final Integer ZERO = new Integer(0);
101 private final Integer ONE = new Integer(1);
102
103 public void testPOFAddObjectUsage() throws Exception {
104 final MethodCallPoolableObjectFactory factory = new MethodCallPoolableObjectFactory();
105 final ObjectPool pool;
106 try {
107 pool = makeEmptyPool(factory);
108 } catch(UnsupportedOperationException uoe) {
109 return;
110 }
111 final List expectedMethods = new ArrayList();
112
113 assertEquals(0, pool.getNumActive());
114 assertEquals(0, pool.getNumIdle());
115
116 pool.addObject();
117 assertEquals(0, pool.getNumActive());
118 assertEquals(1, pool.getNumIdle());
119 expectedMethods.add(new MethodCall("makeObject").returned(ZERO));
120
121 if (pool instanceof StackObjectPool ||
122 pool instanceof SoftReferenceObjectPool) {
123 expectedMethods.add(new MethodCall(
124 "validateObject", ZERO).returned(Boolean.TRUE));
125 }
126 expectedMethods.add(new MethodCall("passivateObject", ZERO));
127 assertEquals(expectedMethods, factory.getMethodCalls());
128
129
130 reset(pool, factory, expectedMethods);
131
132
133 factory.setMakeObjectFail(true);
134 try {
135 pool.addObject();
136 fail("Expected addObject to propagate makeObject exception.");
137 } catch (PrivateException pe) {
138
139 }
140 expectedMethods.add(new MethodCall("makeObject"));
141 assertEquals(expectedMethods, factory.getMethodCalls());
142
143 clear(factory, expectedMethods);
144
145
146 factory.setMakeObjectFail(false);
147 factory.setPassivateObjectFail(true);
148 try {
149 pool.addObject();
150 fail("Expected addObject to propagate passivateObject exception.");
151 } catch (PrivateException pe) {
152
153 }
154 expectedMethods.add(new MethodCall("makeObject").returned(ONE));
155
156 if (pool instanceof StackObjectPool ||
157 pool instanceof SoftReferenceObjectPool) {
158 expectedMethods.add(new MethodCall(
159 "validateObject", ONE).returned(Boolean.TRUE));
160 }
161 expectedMethods.add(new MethodCall("passivateObject", ONE));
162 assertEquals(expectedMethods, factory.getMethodCalls());
163 }
164
165 public void testPOFBorrowObjectUsages() throws Exception {
166 final MethodCallPoolableObjectFactory factory = new MethodCallPoolableObjectFactory();
167 final ObjectPool pool;
168 try {
169 pool = makeEmptyPool(factory);
170 } catch (UnsupportedOperationException uoe) {
171 return;
172 }
173 if (pool instanceof GenericObjectPool) {
174 ((GenericObjectPool) pool).setTestOnBorrow(true);
175 }
176 final List expectedMethods = new ArrayList();
177 Object obj;
178
179
180
181
182 pool.addObject();
183 clear(factory, expectedMethods);
184 obj = pool.borrowObject();
185 expectedMethods.add(new MethodCall("activateObject", ZERO));
186 expectedMethods.add(new MethodCall("validateObject", ZERO).returned(Boolean.TRUE));
187 assertEquals(expectedMethods, factory.getMethodCalls());
188 pool.returnObject(obj);
189
190
191 reset(pool, factory, expectedMethods);
192
193
194 factory.setMakeObjectFail(true);
195 try {
196 obj = pool.borrowObject();
197 fail("Expected borrowObject to propagate makeObject exception.");
198 } catch (PrivateException pe) {
199
200 }
201 expectedMethods.add(new MethodCall("makeObject"));
202 assertEquals(expectedMethods, factory.getMethodCalls());
203
204
205
206 reset(pool, factory, expectedMethods);
207 pool.addObject();
208 clear(factory, expectedMethods);
209
210 factory.setActivateObjectFail(true);
211 expectedMethods.add(new MethodCall("activateObject", obj));
212 try {
213 obj = pool.borrowObject();
214 fail("Expecting NoSuchElementException");
215 } catch (NoSuchElementException ex) {
216
217 }
218
219 expectedMethods.add(new MethodCall("makeObject").returned(ONE));
220 expectedMethods.add(new MethodCall("activateObject", ONE));
221 removeDestroyObjectCall(factory.getMethodCalls());
222 assertEquals(expectedMethods, factory.getMethodCalls());
223
224
225 reset(pool, factory, expectedMethods);
226 pool.addObject();
227 clear(factory, expectedMethods);
228
229 factory.setValidateObjectFail(true);
230 expectedMethods.add(new MethodCall("activateObject", ZERO));
231 expectedMethods.add(new MethodCall("validateObject", ZERO));
232 try {
233 obj = pool.borrowObject();
234 } catch (NoSuchElementException ex) {
235
236 }
237
238
239 expectedMethods.add(new MethodCall("makeObject").returned(ONE));
240 expectedMethods.add(new MethodCall("activateObject", ONE));
241 expectedMethods.add(new MethodCall("validateObject", ONE));
242 removeDestroyObjectCall(factory.getMethodCalls());
243
244 assertTrue(factory.getMethodCalls().containsAll(expectedMethods));
245 }
246
247 public void testPOFReturnObjectUsages() throws Exception {
248 final MethodCallPoolableObjectFactory factory = new MethodCallPoolableObjectFactory();
249 final ObjectPool pool;
250 try {
251 pool = makeEmptyPool(factory);
252 } catch (UnsupportedOperationException uoe) {
253 return;
254 }
255 final List expectedMethods = new ArrayList();
256 Object obj;
257
258
259 obj = pool.borrowObject();
260 clear(factory, expectedMethods);
261
262
263 pool.returnObject(obj);
264
265 if (pool instanceof StackObjectPool ||
266 pool instanceof SoftReferenceObjectPool) {
267 expectedMethods.add(new MethodCall(
268 "validateObject", obj).returned(Boolean.TRUE));
269 }
270 expectedMethods.add(new MethodCall("passivateObject", obj));
271 assertEquals(expectedMethods, factory.getMethodCalls());
272
273
274 reset(pool, factory, expectedMethods);
275 pool.addObject();
276 pool.addObject();
277 pool.addObject();
278 assertEquals(3, pool.getNumIdle());
279
280 obj = pool.borrowObject();
281 pool.borrowObject();
282 assertEquals(1, pool.getNumIdle());
283 assertEquals(2, pool.getNumActive());
284 clear(factory, expectedMethods);
285 factory.setPassivateObjectFail(true);
286 pool.returnObject(obj);
287
288 if (pool instanceof StackObjectPool ||
289 pool instanceof SoftReferenceObjectPool) {
290 expectedMethods.add(new MethodCall(
291 "validateObject", obj).returned(Boolean.TRUE));
292 }
293 expectedMethods.add(new MethodCall("passivateObject", obj));
294 removeDestroyObjectCall(factory.getMethodCalls());
295 assertEquals(expectedMethods, factory.getMethodCalls());
296 assertEquals(1, pool.getNumIdle());
297 assertEquals(1, pool.getNumActive());
298
299
300 reset(pool, factory, expectedMethods);
301 obj = pool.borrowObject();
302 clear(factory, expectedMethods);
303 factory.setPassivateObjectFail(true);
304 factory.setDestroyObjectFail(true);
305 pool.returnObject(obj);
306 }
307
308 public void testPOFInvalidateObjectUsages() throws Exception {
309 final MethodCallPoolableObjectFactory factory = new MethodCallPoolableObjectFactory();
310 final ObjectPool pool;
311 try {
312 pool = makeEmptyPool(factory);
313 } catch (UnsupportedOperationException uoe) {
314 return;
315 }
316 final List expectedMethods = new ArrayList();
317 Object obj;
318
319
320
321 obj = pool.borrowObject();
322 clear(factory, expectedMethods);
323
324
325 pool.invalidateObject(obj);
326 expectedMethods.add(new MethodCall("destroyObject", obj));
327 assertEquals(expectedMethods, factory.getMethodCalls());
328
329
330 reset(pool, factory, expectedMethods);
331 obj = pool.borrowObject();
332 clear(factory, expectedMethods);
333 factory.setDestroyObjectFail(true);
334 try {
335 pool.invalidateObject(obj);
336 fail("Expecting destroy exception to propagate");
337 } catch (PrivateException ex) {
338
339 }
340 Thread.sleep(250);
341 removeDestroyObjectCall(factory.getMethodCalls());
342 assertEquals(expectedMethods, factory.getMethodCalls());
343 }
344
345 public void testPOFClearUsages() throws Exception {
346 final MethodCallPoolableObjectFactory factory = new MethodCallPoolableObjectFactory();
347 final ObjectPool pool;
348 try {
349 pool = makeEmptyPool(factory);
350 } catch (UnsupportedOperationException uoe) {
351 return;
352 }
353 final List expectedMethods = new ArrayList();
354
355
356 PoolUtils.prefill(pool, 5);
357 pool.clear();
358
359
360 reset(pool, factory, expectedMethods);
361 factory.setDestroyObjectFail(true);
362 PoolUtils.prefill(pool, 5);
363 pool.clear();
364 }
365
366 public void testPOFCloseUsages() throws Exception {
367 final MethodCallPoolableObjectFactory factory = new MethodCallPoolableObjectFactory();
368 ObjectPool pool;
369 try {
370 pool = makeEmptyPool(factory);
371 } catch (UnsupportedOperationException uoe) {
372 return;
373 }
374 final List expectedMethods = new ArrayList();
375
376
377 PoolUtils.prefill(pool, 5);
378 pool.close();
379
380
381
382 try {
383 pool = makeEmptyPool(factory);
384 } catch (UnsupportedOperationException uoe) {
385 return;
386 }
387 reset(pool, factory, expectedMethods);
388 factory.setDestroyObjectFail(true);
389 PoolUtils.prefill(pool, 5);
390 pool.close();
391 }
392
393 public void testSetFactory() throws Exception {
394 ObjectPool pool;
395 try {
396 pool = makeEmptyPool(new MethodCallPoolableObjectFactory());
397 } catch (UnsupportedOperationException uoe) {
398 return;
399 }
400 final MethodCallPoolableObjectFactory factory = new MethodCallPoolableObjectFactory();
401 try {
402 pool.setFactory(factory);
403 } catch (UnsupportedOperationException uoe) {
404 return;
405 }
406 }
407
408 public void testToString() {
409 ObjectPool pool;
410 try {
411 pool = makeEmptyPool(new MethodCallPoolableObjectFactory());
412 } catch (UnsupportedOperationException uoe) {
413 return;
414 }
415 pool.toString();
416 }
417
418 static void removeDestroyObjectCall(List calls) {
419 Iterator iter = calls.iterator();
420 while (iter.hasNext()) {
421 MethodCall call = (MethodCall)iter.next();
422 if ("destroyObject".equals(call.getName())) {
423 iter.remove();
424 }
425 }
426 }
427
428 private static void reset(final ObjectPool pool, final MethodCallPoolableObjectFactory factory, final List expectedMethods) throws Exception {
429 pool.clear();
430 clear(factory, expectedMethods);
431 factory.reset();
432 }
433
434 private static void clear(final MethodCallPoolableObjectFactory factory, final List expectedMethods) {
435 factory.getMethodCalls().clear();
436 expectedMethods.clear();
437 }
438 }