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 junit.framework.AssertionFailedError;
21 import junit.framework.Test;
22 import junit.framework.TestSuite;
23
24 import java.lang.reflect.Proxy;
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.Method;
27 import java.util.List;
28 import java.util.ArrayList;
29 import java.util.Set;
30 import java.util.HashSet;
31 import java.util.TimerTask;
32 import java.util.Collection;
33 import java.util.Map;
34 import java.util.Iterator;
35 import java.util.Arrays;
36
37 /***
38 * Unit tests for {@link PoolUtils}.
39 *
40 * @author Sandy McArthur
41 * @version $Revision: 384433 $ $Date: 2006-03-09 00:19:21 -0500 (Thu, 09 Mar 2006) $
42 */
43 public class TestPoolUtils extends TestCase {
44
45 /*** Period between checks for minIdle tests. Increase this if you happen to get too many false failures. */
46 private static final int CHECK_PERIOD = 300;
47
48 /*** Times to let the minIdle check run. */
49 private static final int CHECK_COUNT = 4;
50
51 /*** Sleep time to let the minIdle tests run CHECK_COUNT times. */
52 private static final int CHECK_SLEEP_PERIOD = CHECK_PERIOD * (CHECK_COUNT - 1) + CHECK_PERIOD / 2;
53
54 public static Test suite() {
55 return new TestSuite(TestPoolUtils.class);
56 }
57
58 public void testJavaBeanInstantiation() {
59 new PoolUtils();
60 }
61
62 public void testAdaptKeyedPoolableObjectFactory() throws Exception {
63 try {
64 PoolUtils.adapt((KeyedPoolableObjectFactory)null);
65 fail("PoolUtils.adapt(KeyedPoolableObjectFactory) must not allow null factory.");
66 } catch (IllegalArgumentException iae) {
67
68 }
69 }
70
71 public void testAdaptKeyedPoolableObjectFactoryKey() throws Exception {
72 try {
73 PoolUtils.adapt((KeyedPoolableObjectFactory)null, new Object());
74 fail("PoolUtils.adapt(KeyedPoolableObjectFactory, key) must not allow null factory.");
75 } catch (IllegalArgumentException iae) {
76
77 }
78 try {
79 PoolUtils.adapt((KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, null), null);
80 fail("PoolUtils.adapt(KeyedPoolableObjectFactory, key) must not allow null key.");
81 } catch (IllegalArgumentException iae) {
82
83 }
84
85 final List calledMethods = new ArrayList();
86 final KeyedPoolableObjectFactory kpof =
87 (KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, calledMethods);
88
89 final PoolableObjectFactory pof = PoolUtils.adapt(kpof);
90 final List expectedMethods = invokeEveryMethod(pof);
91 assertEquals(expectedMethods, calledMethods);
92 }
93
94 public void testAdaptPoolableObjectFactory() throws Exception {
95 try {
96 PoolUtils.adapt((PoolableObjectFactory)null);
97 fail("PoolUtils.adapt(PoolableObjectFactory) must not allow null factory.");
98 } catch (IllegalArgumentException iae) {
99
100 }
101
102 final List calledMethods = new ArrayList();
103 final PoolableObjectFactory pof =
104 (PoolableObjectFactory)createProxy(PoolableObjectFactory.class, calledMethods);
105
106 final KeyedPoolableObjectFactory kpof = PoolUtils.adapt(pof);
107 final List expectedMethods = invokeEveryMethod(kpof);
108 assertEquals(expectedMethods, calledMethods);
109 }
110
111 public void testAdaptKeyedObjectPool() throws Exception {
112 try {
113 PoolUtils.adapt((KeyedObjectPool)null);
114 fail("PoolUtils.adapt(KeyedObjectPool) must not allow a null pool.");
115 } catch(IllegalArgumentException iae) {
116
117 }
118 }
119
120 public void testAdaptKeyedObjectPoolKey() throws Exception {
121 try {
122 PoolUtils.adapt((KeyedObjectPool)null, new Object());
123 fail("PoolUtils.adapt(KeyedObjectPool, key) must not allow a null pool.");
124 } catch(IllegalArgumentException iae) {
125
126 }
127 try {
128 PoolUtils.adapt((KeyedObjectPool)createProxy(KeyedObjectPool.class, null), null);
129 fail("PoolUtils.adapt(KeyedObjectPool, key) must not allow a null key.");
130 } catch(IllegalArgumentException iae) {
131
132 }
133
134 final List calledMethods = new ArrayList();
135 final KeyedObjectPool kop = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
136
137 final ObjectPool op = PoolUtils.adapt(kop, new Object());
138 final List expectedMethods = invokeEveryMethod(op);
139 assertEquals(expectedMethods, calledMethods);
140 }
141
142 public void testAdaptObjectPool() throws Exception {
143 try {
144 PoolUtils.adapt((ObjectPool)null);
145 fail("PoolUtils.adapt(ObjectPool) must not allow a null pool.");
146 } catch(IllegalArgumentException iae) {
147
148 }
149
150 final List calledMethods = new ArrayList();
151 final ObjectPool op = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
152
153 final KeyedObjectPool kop = PoolUtils.adapt(op);
154 final List expectedMethods = invokeEveryMethod(kop);
155 assertEquals(expectedMethods, calledMethods);
156 }
157
158 public void testCheckedPoolObjectPool() throws Exception {
159 try {
160 PoolUtils.checkedPool((ObjectPool)null, Object.class);
161 fail("PoolUtils.checkedPool(ObjectPool, Class) must not allow a null pool.");
162 } catch(IllegalArgumentException iae) {
163
164 }
165 try {
166 PoolUtils.checkedPool((ObjectPool)createProxy(ObjectPool.class, null), null);
167 fail("PoolUtils.checkedPool(ObjectPool, Class) must not allow a null type.");
168 } catch(IllegalArgumentException iae) {
169
170 }
171
172 final List calledMethods = new ArrayList();
173 ObjectPool op = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
174
175 ObjectPool cop = PoolUtils.checkedPool(op, Object.class);
176 final List expectedMethods = invokeEveryMethod(cop);
177 assertEquals(expectedMethods, calledMethods);
178
179 op = new BaseObjectPool() {
180 public Object borrowObject() throws Exception {
181 return new Integer(0);
182 }
183 public void returnObject(Object obj) {}
184 public void invalidateObject(Object obj) {}
185 };
186 cop = PoolUtils.checkedPool(op, String.class);
187
188 try {
189 cop.borrowObject();
190 fail("borrowObject should have failed as Integer !instanceof String.");
191 } catch (ClassCastException cce) {
192
193 }
194 try {
195 cop.returnObject(new Integer(1));
196 fail("returnObject should have failed as Integer !instanceof String.");
197 } catch (ClassCastException cce) {
198
199 }
200 try {
201 cop.invalidateObject(new Integer(2));
202 fail("invalidateObject should have failed as Integer !instanceof String.");
203 } catch (ClassCastException cce) {
204
205 }
206 }
207
208 public void testCheckedPoolKeyedObjectPool() throws Exception {
209 try {
210 PoolUtils.checkedPool((KeyedObjectPool)null, Object.class);
211 fail("PoolUtils.checkedPool(KeyedObjectPool, Class) must not allow a null pool.");
212 } catch(IllegalArgumentException iae) {
213
214 }
215 try {
216 PoolUtils.checkedPool((KeyedObjectPool)createProxy(KeyedObjectPool.class, null), null);
217 fail("PoolUtils.checkedPool(KeyedObjectPool, Class) must not allow a null type.");
218 } catch(IllegalArgumentException iae) {
219
220 }
221
222 final List calledMethods = new ArrayList();
223 KeyedObjectPool op = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
224
225 KeyedObjectPool cop = PoolUtils.checkedPool(op, Object.class);
226 final List expectedMethods = invokeEveryMethod(cop);
227 assertEquals(expectedMethods, calledMethods);
228
229
230 op = new BaseKeyedObjectPool() {
231 public Object borrowObject(Object key) {
232 return new Integer(0);
233 }
234
235 public void returnObject(Object key, Object obj) {}
236
237 public void invalidateObject(Object key, Object obj) {}
238 };
239 cop = PoolUtils.checkedPool(op, String.class);
240
241 try {
242 cop.borrowObject(null);
243 fail("borrowObject should have failed as Integer !instanceof String.");
244 } catch (ClassCastException cce) {
245
246 }
247 try {
248 cop.returnObject(null, new Integer(1));
249 fail("returnObject should have failed as Integer !instanceof String.");
250 } catch (ClassCastException cce) {
251
252 }
253 try {
254 cop.invalidateObject(null, new Integer(2));
255 fail("invalidateObject should have failed as Integer !instanceof String.");
256 } catch (ClassCastException cce) {
257
258 }
259 }
260
261 public void testCheckMinIdleObjectPool() throws Exception {
262 try {
263 PoolUtils.checkMinIdle(null, 1, 1);
264 fail("PoolUtils.checkMinIdle(ObjectPool,,) must not allow null pool.");
265 } catch (IllegalArgumentException iae) {
266
267 }
268 try {
269 final ObjectPool pool = (ObjectPool)createProxy(ObjectPool.class, null);
270 PoolUtils.checkMinIdle(pool, -1, 1);
271 fail("PoolUtils.checkMinIdle(ObjectPool,,) must not accept negative min idle values.");
272 } catch (IllegalArgumentException iae) {
273
274 }
275
276
277 AssertionFailedError afe = null;
278 int triesLeft = 3;
279 do {
280 afe = null;
281 try {
282 final List calledMethods = new ArrayList();
283 final ObjectPool pool = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
284 final TimerTask task = PoolUtils.checkMinIdle(pool, 1, CHECK_PERIOD);
285
286 Thread.sleep(CHECK_SLEEP_PERIOD);
287 task.cancel();
288 task.toString();
289
290 final List expectedMethods = new ArrayList();
291 for (int i=0; i < CHECK_COUNT; i++) {
292 expectedMethods.add("getNumIdle");
293 expectedMethods.add("addObject");
294 }
295 expectedMethods.add("toString");
296 assertEquals(expectedMethods, calledMethods);
297 } catch (AssertionFailedError e) {
298 afe = e;
299 }
300 } while (--triesLeft > 0 && afe != null);
301 if (afe != null) {
302 throw afe;
303 }
304 }
305
306 public void testCheckMinIdleKeyedObjectPool() throws Exception {
307 try {
308 PoolUtils.checkMinIdle(null, new Object(), 1, 1);
309 fail("PoolUtils.checkMinIdle(KeyedObjectPool,Object,int,long) must not allow null pool.");
310 } catch (IllegalArgumentException iae) {
311
312 }
313 try {
314 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, null);
315 PoolUtils.checkMinIdle(pool, (Object)null, 1, 1);
316 fail("PoolUtils.checkMinIdle(KeyedObjectPool,Object,int,long) must not accept null keys.");
317 } catch (IllegalArgumentException iae) {
318
319 }
320 try {
321 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, null);
322 PoolUtils.checkMinIdle(pool, new Object(), -1, 1);
323 fail("PoolUtils.checkMinIdle(KeyedObjectPool,Object,int,long) must not accept negative min idle values.");
324 } catch (IllegalArgumentException iae) {
325
326 }
327
328
329 AssertionFailedError afe = null;
330 int triesLeft = 3;
331 do {
332 afe = null;
333 try {
334 final List calledMethods = new ArrayList();
335 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
336 final Object key = new Object();
337 final TimerTask task = PoolUtils.checkMinIdle(pool, key, 1, CHECK_PERIOD);
338
339 Thread.sleep(CHECK_SLEEP_PERIOD);
340 task.cancel();
341 task.toString();
342
343 final List expectedMethods = new ArrayList();
344 for (int i=0; i < CHECK_COUNT; i++) {
345 expectedMethods.add("getNumIdle");
346 expectedMethods.add("addObject");
347 }
348 expectedMethods.add("toString");
349 assertEquals(expectedMethods, calledMethods);
350 } catch (AssertionFailedError e) {
351 afe = e;
352 }
353 } while (--triesLeft > 0 && afe != null);
354 if (afe != null) {
355 throw afe;
356 }
357 }
358
359 public void testCheckMinIdleKeyedObjectPoolKeys() throws Exception {
360 try {
361 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, null);
362 PoolUtils.checkMinIdle(pool, null, 1, 1);
363 fail("PoolUtils.checkMinIdle(KeyedObjectPool,Collection,int,long) must not accept null keys.");
364 } catch (IllegalArgumentException iae) {
365
366 }
367
368
369 AssertionFailedError afe = null;
370 int triesLeft = 3;
371 do {
372 afe = null;
373 try {
374 final List calledMethods = new ArrayList();
375 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
376 final Collection keys = new ArrayList(2);
377 keys.add("one");
378 keys.add("two");
379 final Map tasks = PoolUtils.checkMinIdle(pool, keys, 1, CHECK_PERIOD);
380
381 Thread.sleep(CHECK_SLEEP_PERIOD);
382 final Iterator iter = tasks.values().iterator();
383 while (iter.hasNext()) {
384 final TimerTask task = (TimerTask)iter.next();
385 task.cancel();
386 }
387
388 final List expectedMethods = new ArrayList();
389 for (int i=0; i < CHECK_COUNT * keys.size(); i++) {
390 expectedMethods.add("getNumIdle");
391 expectedMethods.add("addObject");
392 }
393 assertEquals(expectedMethods, calledMethods);
394 } catch (AssertionFailedError e) {
395 afe = e;
396 }
397 } while (--triesLeft > 0 && afe != null);
398 if (afe != null) {
399 throw afe;
400 }
401 }
402
403 public void testPrefillObjectPool() throws Exception {
404 try {
405 PoolUtils.prefill(null, 1);
406 fail("PoolUtils.prefill(ObjectPool,int) must not allow null pool.");
407 } catch (IllegalArgumentException iae) {
408
409 }
410
411 final List calledMethods = new ArrayList();
412 final ObjectPool pool = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
413
414 PoolUtils.prefill(pool, 0);
415 final List expectedMethods = new ArrayList();
416 assertEquals(expectedMethods, calledMethods);
417
418 calledMethods.clear();
419 PoolUtils.prefill(pool, 3);
420 for (int i=0; i < 3; i++) {
421 expectedMethods.add("addObject");
422 }
423 assertEquals(expectedMethods, calledMethods);
424 }
425
426 public void testPrefillKeyedObjectPool() throws Exception {
427 try {
428 PoolUtils.prefill(null, new Object(), 1);
429 fail("PoolUtils.prefill(KeyedObjectPool,Object,int) must not accept null pool.");
430 } catch (IllegalArgumentException iae) {
431
432 }
433 try {
434 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, null);
435 PoolUtils.prefill(pool, (Object)null, 1);
436 fail("PoolUtils.prefill(KeyedObjectPool,Object,int) must not accept null key.");
437 } catch (IllegalArgumentException iae) {
438
439 }
440
441 final List calledMethods = new ArrayList();
442 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
443
444 PoolUtils.prefill(pool, new Object(), 0);
445 final List expectedMethods = new ArrayList();
446 assertEquals(expectedMethods, calledMethods);
447
448 calledMethods.clear();
449 PoolUtils.prefill(pool, new Object(), 3);
450 for (int i=0; i < 3; i++) {
451 expectedMethods.add("addObject");
452 }
453 assertEquals(expectedMethods, calledMethods);
454 }
455
456 public void testPrefillKeyedObjectPoolCollection() throws Exception {
457 try {
458 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, null);
459 PoolUtils.prefill(pool, null, 1);
460 fail("PoolUtils.prefill(KeyedObjectPool,Collection,int) must not accept null keys.");
461 } catch (IllegalArgumentException iae) {
462
463 }
464
465 final List calledMethods = new ArrayList();
466 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
467
468 final Set keys = new HashSet();
469 PoolUtils.prefill(pool, keys, 0);
470 final List expectedMethods = new ArrayList();
471 assertEquals(expectedMethods, calledMethods);
472
473 calledMethods.clear();
474 keys.add(new Integer(1));
475 keys.add("two");
476 keys.add(new Double(3.1415926));
477 PoolUtils.prefill(pool, keys, 3);
478 for (int i=0; i < keys.size() * 3; i++) {
479 expectedMethods.add("addObject");
480 }
481 assertEquals(expectedMethods, calledMethods);
482 }
483
484 public void testSynchronizedPoolObjectPool() throws Exception {
485 try {
486 PoolUtils.synchronizedPool((ObjectPool)null);
487 fail("PoolUtils.synchronizedPool(ObjectPool) must not allow a null pool.");
488 } catch(IllegalArgumentException iae) {
489
490 }
491
492 final List calledMethods = new ArrayList();
493 final ObjectPool op = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
494
495 final ObjectPool sop = PoolUtils.synchronizedPool(op);
496 final List expectedMethods = invokeEveryMethod(sop);
497 assertEquals(expectedMethods, calledMethods);
498
499
500 }
501
502 public void testSynchronizedPoolKeyedObjectPool() throws Exception {
503 try {
504 PoolUtils.synchronizedPool((KeyedObjectPool)null);
505 fail("PoolUtils.synchronizedPool(KeyedObjectPool) must not allow a null pool.");
506 } catch(IllegalArgumentException iae) {
507
508 }
509
510 final List calledMethods = new ArrayList();
511 final KeyedObjectPool kop = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
512
513 final KeyedObjectPool skop = PoolUtils.synchronizedPool(kop);
514 final List expectedMethods = invokeEveryMethod(skop);
515 assertEquals(expectedMethods, calledMethods);
516
517
518 }
519
520 public void testSynchronizedPoolableFactoryPoolableObjectFactory() throws Exception {
521 try {
522 PoolUtils.synchronizedPoolableFactory((PoolableObjectFactory)null);
523 fail("PoolUtils.synchronizedPoolableFactory(PoolableObjectFactory) must not allow a null factory.");
524 } catch(IllegalArgumentException iae) {
525
526 }
527
528 final List calledMethods = new ArrayList();
529 final PoolableObjectFactory pof =
530 (PoolableObjectFactory)createProxy(PoolableObjectFactory.class, calledMethods);
531
532 final PoolableObjectFactory spof = PoolUtils.synchronizedPoolableFactory(pof);
533 final List expectedMethods = invokeEveryMethod(spof);
534 assertEquals(expectedMethods, calledMethods);
535
536
537 }
538
539 public void testSynchronizedPoolableFactoryKeyedPoolableObjectFactory() throws Exception {
540 try {
541 PoolUtils.synchronizedPoolableFactory((KeyedPoolableObjectFactory)null);
542 fail("PoolUtils.synchronizedPoolableFactory(KeyedPoolableObjectFactory) must not allow a null factory.");
543 } catch(IllegalArgumentException iae) {
544
545 }
546
547 final List calledMethods = new ArrayList();
548 final KeyedPoolableObjectFactory kpof =
549 (KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, calledMethods);
550
551 final KeyedPoolableObjectFactory skpof = PoolUtils.synchronizedPoolableFactory(kpof);
552 final List expectedMethods = invokeEveryMethod(skpof);
553 assertEquals(expectedMethods, calledMethods);
554
555
556 }
557
558 private static List invokeEveryMethod(ObjectPool op) throws Exception {
559 op.addObject();
560 op.borrowObject();
561 op.clear();
562 op.close();
563 op.getNumActive();
564 op.getNumIdle();
565 op.invalidateObject(new Object());
566 op.returnObject(new Object());
567 op.setFactory((PoolableObjectFactory)createProxy(PoolableObjectFactory.class, null));
568 op.toString();
569
570 final List expectedMethods = Arrays.asList(new String[] {
571 "addObject", "borrowObject", "clear", "close",
572 "getNumActive", "getNumIdle", "invalidateObject",
573 "returnObject", "setFactory", "toString"
574 });
575 return expectedMethods;
576 }
577
578 private static List invokeEveryMethod(KeyedObjectPool kop) throws Exception {
579 kop.addObject(null);
580 kop.borrowObject(null);
581 kop.clear();
582 kop.clear(null);
583 kop.close();
584 kop.getNumActive();
585 kop.getNumActive(null);
586 kop.getNumIdle();
587 kop.getNumIdle(null);
588 kop.invalidateObject(null, new Object());
589 kop.returnObject(null, new Object());
590 kop.setFactory((KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, null));
591 kop.toString();
592
593 final List expectedMethods = Arrays.asList(new String[] {
594 "addObject", "borrowObject", "clear", "clear", "close",
595 "getNumActive", "getNumActive", "getNumIdle", "getNumIdle", "invalidateObject",
596 "returnObject", "setFactory", "toString"
597 });
598 return expectedMethods;
599 }
600
601 private static List invokeEveryMethod(PoolableObjectFactory pof) throws Exception {
602 pof.activateObject(null);
603 pof.destroyObject(null);
604 pof.makeObject();
605 pof.passivateObject(null);
606 pof.validateObject(null);
607 pof.toString();
608
609 final List expectedMethods = Arrays.asList(new String[] {
610 "activateObject", "destroyObject", "makeObject",
611 "passivateObject", "validateObject", "toString",
612 });
613 return expectedMethods;
614 }
615
616 private static List invokeEveryMethod(KeyedPoolableObjectFactory kpof) throws Exception {
617 kpof.activateObject(null, null);
618 kpof.destroyObject(null, null);
619 kpof.makeObject(null);
620 kpof.passivateObject(null, null);
621 kpof.validateObject(null, null);
622 kpof.toString();
623
624 final List expectedMethods = Arrays.asList(new String[] {
625 "activateObject", "destroyObject", "makeObject",
626 "passivateObject", "validateObject", "toString",
627 });
628 return expectedMethods;
629 }
630
631 private static Object createProxy(final Class clazz, final List logger) {
632 return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz },
633 new MethodCallLogger(logger));
634 }
635
636 private static class MethodCallLogger implements InvocationHandler {
637 private final List calledMethods;
638
639 MethodCallLogger(final List calledMethods) {
640 this.calledMethods = calledMethods;
641 }
642
643 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
644 calledMethods.add(method.getName());
645 if (boolean.class.equals(method.getReturnType())) {
646 return Boolean.FALSE;
647 } else if (int.class.equals(method.getReturnType())) {
648 return new Integer(0);
649 } else if (long.class.equals(method.getReturnType())) {
650 return new Long(0);
651 } else if (Object.class.equals(method.getReturnType())) {
652 return new Object();
653 } else {
654 return null;
655 }
656 }
657 }
658 }