1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.pool;
19
20 import junit.framework.TestCase;
21 import junit.framework.AssertionFailedError;
22 import junit.framework.Test;
23 import junit.framework.TestSuite;
24
25 import java.lang.reflect.Proxy;
26 import java.lang.reflect.InvocationHandler;
27 import java.lang.reflect.Method;
28 import java.util.List;
29 import java.util.ArrayList;
30 import java.util.Set;
31 import java.util.HashSet;
32 import java.util.TimerTask;
33 import java.util.Collection;
34 import java.util.Map;
35 import java.util.Iterator;
36 import java.util.Arrays;
37
38 import org.apache.commons.pool.impl.GenericObjectPool;
39 import org.apache.commons.pool.impl.GenericKeyedObjectPool;
40
41
42
43
44
45
46
47 public class TestPoolUtils extends TestCase {
48
49
50 private static final int CHECK_PERIOD = 300;
51
52
53 private static final int CHECK_COUNT = 4;
54
55
56 private static final int CHECK_SLEEP_PERIOD = CHECK_PERIOD * (CHECK_COUNT - 1) + CHECK_PERIOD / 2;
57
58 public static Test suite() {
59 return new TestSuite(TestPoolUtils.class);
60 }
61
62 public void testJavaBeanInstantiation() {
63 new PoolUtils();
64 }
65
66 public void testAdaptKeyedPoolableObjectFactory() throws Exception {
67 try {
68 PoolUtils.adapt((KeyedPoolableObjectFactory)null);
69 fail("PoolUtils.adapt(KeyedPoolableObjectFactory) must not allow null factory.");
70 } catch (IllegalArgumentException iae) {
71
72 }
73 }
74
75 public void testAdaptKeyedPoolableObjectFactoryKey() throws Exception {
76 try {
77 PoolUtils.adapt((KeyedPoolableObjectFactory)null, new Object());
78 fail("PoolUtils.adapt(KeyedPoolableObjectFactory, key) must not allow null factory.");
79 } catch (IllegalArgumentException iae) {
80
81 }
82 try {
83 PoolUtils.adapt((KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, (List)null), null);
84 fail("PoolUtils.adapt(KeyedPoolableObjectFactory, key) must not allow null key.");
85 } catch (IllegalArgumentException iae) {
86
87 }
88
89 final List calledMethods = new ArrayList();
90 final KeyedPoolableObjectFactory kpof =
91 (KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, calledMethods);
92
93 final PoolableObjectFactory pof = PoolUtils.adapt(kpof);
94 final List expectedMethods = invokeEveryMethod(pof);
95 assertEquals(expectedMethods, calledMethods);
96 }
97
98 public void testAdaptPoolableObjectFactory() throws Exception {
99 try {
100 PoolUtils.adapt((PoolableObjectFactory)null);
101 fail("PoolUtils.adapt(PoolableObjectFactory) must not allow null factory.");
102 } catch (IllegalArgumentException iae) {
103
104 }
105
106 final List calledMethods = new ArrayList();
107 final PoolableObjectFactory pof =
108 (PoolableObjectFactory)createProxy(PoolableObjectFactory.class, calledMethods);
109
110 final KeyedPoolableObjectFactory kpof = PoolUtils.adapt(pof);
111 final List expectedMethods = invokeEveryMethod(kpof);
112 assertEquals(expectedMethods, calledMethods);
113 }
114
115 public void testAdaptKeyedObjectPool() throws Exception {
116 try {
117 PoolUtils.adapt((KeyedObjectPool)null);
118 fail("PoolUtils.adapt(KeyedObjectPool) must not allow a null pool.");
119 } catch(IllegalArgumentException iae) {
120
121 }
122 }
123
124 public void testAdaptKeyedObjectPoolKey() throws Exception {
125 try {
126 PoolUtils.adapt((KeyedObjectPool)null, new Object());
127 fail("PoolUtils.adapt(KeyedObjectPool, key) must not allow a null pool.");
128 } catch(IllegalArgumentException iae) {
129
130 }
131 try {
132 PoolUtils.adapt((KeyedObjectPool)createProxy(KeyedObjectPool.class, (List)null), null);
133 fail("PoolUtils.adapt(KeyedObjectPool, key) must not allow a null key.");
134 } catch(IllegalArgumentException iae) {
135
136 }
137
138 final List calledMethods = new ArrayList();
139 final KeyedObjectPool kop = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
140
141 final ObjectPool op = PoolUtils.adapt(kop, new Object());
142 final List expectedMethods = invokeEveryMethod(op);
143 assertEquals(expectedMethods, calledMethods);
144 }
145
146 public void testAdaptObjectPool() throws Exception {
147 try {
148 PoolUtils.adapt((ObjectPool)null);
149 fail("PoolUtils.adapt(ObjectPool) must not allow a null pool.");
150 } catch(IllegalArgumentException iae) {
151
152 }
153
154 final List calledMethods = new ArrayList();
155 final ObjectPool op = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
156
157 final KeyedObjectPool kop = PoolUtils.adapt(op);
158 final List expectedMethods = invokeEveryMethod(kop);
159 assertEquals(expectedMethods, calledMethods);
160 }
161
162 public void testCheckedPoolObjectPool() throws Exception {
163 try {
164 PoolUtils.checkedPool((ObjectPool)null, Object.class);
165 fail("PoolUtils.checkedPool(ObjectPool, Class) must not allow a null pool.");
166 } catch(IllegalArgumentException iae) {
167
168 }
169 try {
170 PoolUtils.checkedPool((ObjectPool)createProxy(ObjectPool.class, (List)null), null);
171 fail("PoolUtils.checkedPool(ObjectPool, Class) must not allow a null type.");
172 } catch(IllegalArgumentException iae) {
173
174 }
175
176 final List calledMethods = new ArrayList();
177 ObjectPool op = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
178
179 ObjectPool cop = PoolUtils.checkedPool(op, Object.class);
180 final List expectedMethods = invokeEveryMethod(cop);
181 assertEquals(expectedMethods, calledMethods);
182
183 op = new BaseObjectPool() {
184 public Object borrowObject() throws Exception {
185 return new Integer(0);
186 }
187 public void returnObject(Object obj) {}
188 public void invalidateObject(Object obj) {}
189 };
190 cop = PoolUtils.checkedPool(op, String.class);
191
192 try {
193 cop.borrowObject();
194 fail("borrowObject should have failed as Integer !instanceof String.");
195 } catch (ClassCastException cce) {
196
197 }
198 try {
199 cop.returnObject(new Integer(1));
200 fail("returnObject should have failed as Integer !instanceof String.");
201 } catch (ClassCastException cce) {
202
203 }
204 try {
205 cop.invalidateObject(new Integer(2));
206 fail("invalidateObject should have failed as Integer !instanceof String.");
207 } catch (ClassCastException cce) {
208
209 }
210 }
211
212 public void testCheckedPoolKeyedObjectPool() throws Exception {
213 try {
214 PoolUtils.checkedPool((KeyedObjectPool)null, Object.class);
215 fail("PoolUtils.checkedPool(KeyedObjectPool, Class) must not allow a null pool.");
216 } catch(IllegalArgumentException iae) {
217
218 }
219 try {
220 PoolUtils.checkedPool((KeyedObjectPool)createProxy(KeyedObjectPool.class, (List)null), null);
221 fail("PoolUtils.checkedPool(KeyedObjectPool, Class) must not allow a null type.");
222 } catch(IllegalArgumentException iae) {
223
224 }
225
226 final List calledMethods = new ArrayList();
227 KeyedObjectPool op = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
228
229 KeyedObjectPool cop = PoolUtils.checkedPool(op, Object.class);
230 final List expectedMethods = invokeEveryMethod(cop);
231 assertEquals(expectedMethods, calledMethods);
232
233
234 op = new BaseKeyedObjectPool() {
235 public Object borrowObject(Object key) {
236 return new Integer(0);
237 }
238
239 public void returnObject(Object key, Object obj) {}
240
241 public void invalidateObject(Object key, Object obj) {}
242 };
243 cop = PoolUtils.checkedPool(op, String.class);
244
245 try {
246 cop.borrowObject(null);
247 fail("borrowObject should have failed as Integer !instanceof String.");
248 } catch (ClassCastException cce) {
249
250 }
251 try {
252 cop.returnObject(null, new Integer(1));
253 fail("returnObject should have failed as Integer !instanceof String.");
254 } catch (ClassCastException cce) {
255
256 }
257 try {
258 cop.invalidateObject(null, new Integer(2));
259 fail("invalidateObject should have failed as Integer !instanceof String.");
260 } catch (ClassCastException cce) {
261
262 }
263 }
264
265 public void testCheckMinIdleObjectPool() throws Exception {
266 try {
267 PoolUtils.checkMinIdle(null, 1, 1);
268 fail("PoolUtils.checkMinIdle(ObjectPool,,) must not allow null pool.");
269 } catch (IllegalArgumentException iae) {
270
271 }
272 try {
273 final ObjectPool pool = (ObjectPool)createProxy(ObjectPool.class, (List)null);
274 PoolUtils.checkMinIdle(pool, -1, 1);
275 fail("PoolUtils.checkMinIdle(ObjectPool,,) must not accept negative min idle values.");
276 } catch (IllegalArgumentException iae) {
277
278 }
279
280 final List calledMethods = new ArrayList();
281
282
283 final PoolableObjectFactory pof = (PoolableObjectFactory)createProxy(PoolableObjectFactory.class, calledMethods);
284 final ObjectPool op = new GenericObjectPool(pof);
285 PoolUtils.checkMinIdle(op, 2, 100);
286 Thread.sleep(400);
287 assertEquals(2, op.getNumIdle());
288 op.close();
289 int makeObjectCount = 0;
290 final Iterator iter = calledMethods.iterator();
291 while (iter.hasNext()) {
292 final String methodName = (String)iter.next();
293 if ("makeObject".equals(methodName)) {
294 makeObjectCount++;
295 }
296 }
297 assertEquals("makeObject should have been called two time", 2, makeObjectCount);
298
299
300 AssertionFailedError afe = null;
301 int triesLeft = 3;
302 do {
303 afe = null;
304 try {
305 calledMethods.clear();
306 final ObjectPool pool = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
307 final TimerTask task = PoolUtils.checkMinIdle(pool, 1, CHECK_PERIOD);
308
309 Thread.sleep(CHECK_SLEEP_PERIOD);
310 task.cancel();
311 task.toString();
312
313 final List expectedMethods = new ArrayList();
314 for (int i=0; i < CHECK_COUNT; i++) {
315 expectedMethods.add("getNumIdle");
316 expectedMethods.add("addObject");
317 }
318 expectedMethods.add("toString");
319 assertEquals(expectedMethods, calledMethods);
320 } catch (AssertionFailedError e) {
321 afe = e;
322 }
323 } while (--triesLeft > 0 && afe != null);
324 if (afe != null) {
325 throw afe;
326 }
327 }
328
329 public void testCheckMinIdleKeyedObjectPool() throws Exception {
330 try {
331 PoolUtils.checkMinIdle(null, new Object(), 1, 1);
332 fail("PoolUtils.checkMinIdle(KeyedObjectPool,Object,int,long) must not allow null pool.");
333 } catch (IllegalArgumentException iae) {
334
335 }
336 try {
337 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, (List)null);
338 PoolUtils.checkMinIdle(pool, (Object)null, 1, 1);
339 fail("PoolUtils.checkMinIdle(KeyedObjectPool,Object,int,long) must not accept null keys.");
340 } catch (IllegalArgumentException iae) {
341
342 }
343 try {
344 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, (List)null);
345 PoolUtils.checkMinIdle(pool, new Object(), -1, 1);
346 fail("PoolUtils.checkMinIdle(KeyedObjectPool,Object,int,long) must not accept negative min idle values.");
347 } catch (IllegalArgumentException iae) {
348
349 }
350
351 final List calledMethods = new ArrayList();
352 final Object key = new Object();
353
354
355 final KeyedPoolableObjectFactory kpof = (KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, calledMethods);
356 final KeyedObjectPool kop = new GenericKeyedObjectPool(kpof);
357 PoolUtils.checkMinIdle(kop, key, 2, 100);
358 Thread.sleep(400);
359 assertEquals(2, kop.getNumIdle(key));
360 assertEquals(2, kop.getNumIdle());
361 kop.close();
362 int makeObjectCount = 0;
363 final Iterator iter = calledMethods.iterator();
364 while (iter.hasNext()) {
365 final String methodName = (String)iter.next();
366 if ("makeObject".equals(methodName)) {
367 makeObjectCount++;
368 }
369 }
370 assertEquals("makeObject should have been called two time", 2, makeObjectCount);
371
372
373 AssertionFailedError afe = null;
374 int triesLeft = 3;
375 do {
376 afe = null;
377 try {
378 calledMethods.clear();
379 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
380 final TimerTask task = PoolUtils.checkMinIdle(pool, key, 1, CHECK_PERIOD);
381
382 Thread.sleep(CHECK_SLEEP_PERIOD);
383 task.cancel();
384 task.toString();
385
386 final List expectedMethods = new ArrayList();
387 for (int i=0; i < CHECK_COUNT; i++) {
388 expectedMethods.add("getNumIdle");
389 expectedMethods.add("addObject");
390 }
391 expectedMethods.add("toString");
392 assertEquals(expectedMethods, calledMethods);
393 } catch (AssertionFailedError e) {
394 afe = e;
395 }
396 } while (--triesLeft > 0 && afe != null);
397 if (afe != null) {
398 throw afe;
399 }
400 }
401
402 public void testCheckMinIdleKeyedObjectPoolKeys() throws Exception {
403 try {
404 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, (List)null);
405 PoolUtils.checkMinIdle(pool, null, 1, 1);
406 fail("PoolUtils.checkMinIdle(KeyedObjectPool,Collection,int,long) must not accept null keys.");
407 } catch (IllegalArgumentException iae) {
408
409 }
410
411
412 AssertionFailedError afe = null;
413 int triesLeft = 3;
414 do {
415 afe = null;
416 try {
417 final List calledMethods = new ArrayList();
418 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
419 final Collection keys = new ArrayList(2);
420 keys.add("one");
421 keys.add("two");
422 final Map tasks = PoolUtils.checkMinIdle(pool, keys, 1, CHECK_PERIOD);
423
424 Thread.sleep(CHECK_SLEEP_PERIOD);
425 final Iterator iter = tasks.values().iterator();
426 while (iter.hasNext()) {
427 final TimerTask task = (TimerTask)iter.next();
428 task.cancel();
429 }
430
431 final List expectedMethods = new ArrayList();
432 for (int i=0; i < CHECK_COUNT * keys.size(); i++) {
433 expectedMethods.add("getNumIdle");
434 expectedMethods.add("addObject");
435 }
436 assertEquals(expectedMethods, calledMethods);
437 } catch (AssertionFailedError e) {
438 afe = e;
439 }
440 } while (--triesLeft > 0 && afe != null);
441 if (afe != null) {
442 throw afe;
443 }
444 }
445
446 public void testPrefillObjectPool() throws Exception {
447 try {
448 PoolUtils.prefill(null, 1);
449 fail("PoolUtils.prefill(ObjectPool,int) must not allow null pool.");
450 } catch (IllegalArgumentException iae) {
451
452 }
453
454 final List calledMethods = new ArrayList();
455 final ObjectPool pool = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
456
457 PoolUtils.prefill(pool, 0);
458 final List expectedMethods = new ArrayList();
459 assertEquals(expectedMethods, calledMethods);
460
461 calledMethods.clear();
462 PoolUtils.prefill(pool, 3);
463 for (int i=0; i < 3; i++) {
464 expectedMethods.add("addObject");
465 }
466 assertEquals(expectedMethods, calledMethods);
467 }
468
469 public void testPrefillKeyedObjectPool() throws Exception {
470 try {
471 PoolUtils.prefill(null, new Object(), 1);
472 fail("PoolUtils.prefill(KeyedObjectPool,Object,int) must not accept null pool.");
473 } catch (IllegalArgumentException iae) {
474
475 }
476 try {
477 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, (List)null);
478 PoolUtils.prefill(pool, (Object)null, 1);
479 fail("PoolUtils.prefill(KeyedObjectPool,Object,int) must not accept null key.");
480 } catch (IllegalArgumentException iae) {
481
482 }
483
484 final List calledMethods = new ArrayList();
485 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
486
487 PoolUtils.prefill(pool, new Object(), 0);
488 final List expectedMethods = new ArrayList();
489 assertEquals(expectedMethods, calledMethods);
490
491 calledMethods.clear();
492 PoolUtils.prefill(pool, new Object(), 3);
493 for (int i=0; i < 3; i++) {
494 expectedMethods.add("addObject");
495 }
496 assertEquals(expectedMethods, calledMethods);
497 }
498
499 public void testPrefillKeyedObjectPoolCollection() throws Exception {
500 try {
501 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, (List)null);
502 PoolUtils.prefill(pool, null, 1);
503 fail("PoolUtils.prefill(KeyedObjectPool,Collection,int) must not accept null keys.");
504 } catch (IllegalArgumentException iae) {
505
506 }
507
508 final List calledMethods = new ArrayList();
509 final KeyedObjectPool pool = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
510
511 final Set keys = new HashSet();
512 PoolUtils.prefill(pool, keys, 0);
513 final List expectedMethods = new ArrayList();
514 assertEquals(expectedMethods, calledMethods);
515
516 calledMethods.clear();
517 keys.add(new Integer(1));
518 keys.add("two");
519 keys.add(new Double(3.1415926));
520 PoolUtils.prefill(pool, keys, 3);
521 for (int i=0; i < keys.size() * 3; i++) {
522 expectedMethods.add("addObject");
523 }
524 assertEquals(expectedMethods, calledMethods);
525 }
526
527 public void testSynchronizedPoolObjectPool() throws Exception {
528 try {
529 PoolUtils.synchronizedPool((ObjectPool)null);
530 fail("PoolUtils.synchronizedPool(ObjectPool) must not allow a null pool.");
531 } catch(IllegalArgumentException iae) {
532
533 }
534
535 final List calledMethods = new ArrayList();
536 final ObjectPool op = (ObjectPool)createProxy(ObjectPool.class, calledMethods);
537
538 final ObjectPool sop = PoolUtils.synchronizedPool(op);
539 final List expectedMethods = invokeEveryMethod(sop);
540 assertEquals(expectedMethods, calledMethods);
541
542
543 }
544
545 public void testSynchronizedPoolKeyedObjectPool() throws Exception {
546 try {
547 PoolUtils.synchronizedPool((KeyedObjectPool)null);
548 fail("PoolUtils.synchronizedPool(KeyedObjectPool) must not allow a null pool.");
549 } catch(IllegalArgumentException iae) {
550
551 }
552
553 final List calledMethods = new ArrayList();
554 final KeyedObjectPool kop = (KeyedObjectPool)createProxy(KeyedObjectPool.class, calledMethods);
555
556 final KeyedObjectPool skop = PoolUtils.synchronizedPool(kop);
557 final List expectedMethods = invokeEveryMethod(skop);
558 assertEquals(expectedMethods, calledMethods);
559
560
561 }
562
563 public void testSynchronizedPoolableFactoryPoolableObjectFactory() throws Exception {
564 try {
565 PoolUtils.synchronizedPoolableFactory((PoolableObjectFactory)null);
566 fail("PoolUtils.synchronizedPoolableFactory(PoolableObjectFactory) must not allow a null factory.");
567 } catch(IllegalArgumentException iae) {
568
569 }
570
571 final List calledMethods = new ArrayList();
572 final PoolableObjectFactory pof =
573 (PoolableObjectFactory)createProxy(PoolableObjectFactory.class, calledMethods);
574
575 final PoolableObjectFactory spof = PoolUtils.synchronizedPoolableFactory(pof);
576 final List expectedMethods = invokeEveryMethod(spof);
577 assertEquals(expectedMethods, calledMethods);
578
579
580 }
581
582 public void testSynchronizedPoolableFactoryKeyedPoolableObjectFactory() throws Exception {
583 try {
584 PoolUtils.synchronizedPoolableFactory((KeyedPoolableObjectFactory)null);
585 fail("PoolUtils.synchronizedPoolableFactory(KeyedPoolableObjectFactory) must not allow a null factory.");
586 } catch(IllegalArgumentException iae) {
587
588 }
589
590 final List calledMethods = new ArrayList();
591 final KeyedPoolableObjectFactory kpof =
592 (KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, calledMethods);
593
594 final KeyedPoolableObjectFactory skpof = PoolUtils.synchronizedPoolableFactory(kpof);
595 final List expectedMethods = invokeEveryMethod(skpof);
596 assertEquals(expectedMethods, calledMethods);
597
598
599 }
600
601 public void testErodingPoolObjectPool() throws Exception {
602 try {
603 PoolUtils.erodingPool((ObjectPool)null);
604 fail("PoolUtils.erodingPool(ObjectPool) must not allow a null pool.");
605 } catch(IllegalArgumentException iae) {
606
607 }
608
609 try {
610 PoolUtils.erodingPool((ObjectPool)null, 1f);
611 fail("PoolUtils.erodingPool(ObjectPool, float) must not allow a null pool.");
612 } catch(IllegalArgumentException iae) {
613
614 }
615
616 try {
617 PoolUtils.erodingPool((ObjectPool)null, 0);
618 fail("PoolUtils.erodingPool(ObjectPool, float) must not allow a non-positive factor.");
619 } catch(IllegalArgumentException iae) {
620
621 }
622
623 final List calledMethods = new ArrayList();
624 final InvocationHandler handler = new MethodCallLogger(calledMethods) {
625 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
626 Object o = super.invoke(proxy, method, args);
627 if (o instanceof Integer) {
628
629 o = new Integer(1);
630 }
631 return o;
632 }
633 };
634
635
636 float factor = 0.01f;
637 final ObjectPool pool = PoolUtils.erodingPool((ObjectPool)createProxy(ObjectPool.class, handler), factor);
638
639 final List expectedMethods = new ArrayList();
640 assertEquals(expectedMethods, calledMethods);
641
642 Object o = pool.borrowObject();
643 expectedMethods.add("borrowObject");
644
645 assertEquals(expectedMethods, calledMethods);
646
647 pool.returnObject(o);
648 expectedMethods.add("returnObject");
649 assertEquals(expectedMethods, calledMethods);
650
651 for (int i=0; i < 5; i ++) {
652 o = pool.borrowObject();
653 expectedMethods.add("borrowObject");
654
655 Thread.sleep(50);
656
657 pool.returnObject(o);
658 expectedMethods.add("returnObject");
659
660 assertEquals(expectedMethods, calledMethods);
661
662 expectedMethods.clear();
663 calledMethods.clear();
664 }
665
666 Thread.sleep(10000);
667
668
669 o = pool.borrowObject();
670 expectedMethods.add("borrowObject");
671 pool.returnObject(o);
672 expectedMethods.add("getNumIdle");
673 expectedMethods.add("invalidateObject");
674 assertEquals(expectedMethods, calledMethods);
675 }
676
677 public void testErodingPoolKeyedObjectPool() throws Exception {
678 try {
679 PoolUtils.erodingPool((KeyedObjectPool)null);
680 fail("PoolUtils.erodingPool(KeyedObjectPool) must not allow a null pool.");
681 } catch(IllegalArgumentException iae) {
682
683 }
684
685 try {
686 PoolUtils.erodingPool((KeyedObjectPool)null, 1f);
687 fail("PoolUtils.erodingPool(KeyedObjectPool, float) must not allow a null pool.");
688 } catch(IllegalArgumentException iae) {
689
690 }
691
692 try {
693 PoolUtils.erodingPool((KeyedObjectPool)null, 0);
694 fail("PoolUtils.erodingPool(ObjectPool, float) must not allow a non-positive factor.");
695 } catch(IllegalArgumentException iae) {
696
697 }
698
699 try {
700 PoolUtils.erodingPool((KeyedObjectPool)null, 1f, true);
701 fail("PoolUtils.erodingPool(KeyedObjectPool, float, boolean) must not allow a null pool.");
702 } catch(IllegalArgumentException iae) {
703
704 }
705
706 try {
707 PoolUtils.erodingPool((KeyedObjectPool)null, 0, false);
708 fail("PoolUtils.erodingPool(ObjectPool, float, boolean) must not allow a non-positive factor.");
709 } catch(IllegalArgumentException iae) {
710
711 }
712
713 final List calledMethods = new ArrayList();
714 final InvocationHandler handler = new MethodCallLogger(calledMethods) {
715 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
716 Object o = super.invoke(proxy, method, args);
717 if (o instanceof Integer) {
718
719 o = new Integer(1);
720 }
721 return o;
722 }
723 };
724
725
726 float factor = 0.01f;
727 final KeyedObjectPool pool = PoolUtils.erodingPool((KeyedObjectPool)createProxy(KeyedObjectPool.class, handler), factor);
728
729 final List expectedMethods = new ArrayList();
730 assertEquals(expectedMethods, calledMethods);
731
732 final Object key = "key";
733
734 Object o = pool.borrowObject(key);
735 expectedMethods.add("borrowObject");
736
737 assertEquals(expectedMethods, calledMethods);
738
739 pool.returnObject(key, o);
740 expectedMethods.add("returnObject");
741 assertEquals(expectedMethods, calledMethods);
742
743 for (int i=0; i < 5; i ++) {
744 o = pool.borrowObject(key);
745 expectedMethods.add("borrowObject");
746
747 Thread.sleep(50);
748
749 pool.returnObject(key, o);
750 expectedMethods.add("returnObject");
751
752 assertEquals(expectedMethods, calledMethods);
753
754 expectedMethods.clear();
755 calledMethods.clear();
756 }
757
758 Thread.sleep(10000);
759
760
761 o = pool.borrowObject(key);
762 expectedMethods.add("borrowObject");
763 pool.returnObject(key, o);
764 expectedMethods.add("getNumIdle");
765 expectedMethods.add("invalidateObject");
766 assertEquals(expectedMethods, calledMethods);
767 }
768
769 public void testErodingPerKeyKeyedObjectPool() throws Exception {
770 try {
771 PoolUtils.erodingPool((KeyedObjectPool)null, 1, true);
772 fail("PoolUtils.erodingPool(KeyedObjectPool) must not allow a null pool.");
773 } catch(IllegalArgumentException iae) {
774
775 }
776
777 try {
778 PoolUtils.erodingPool((KeyedObjectPool)null, 0, true);
779 fail("PoolUtils.erodingPool(ObjectPool, float) must not allow a non-positive factor.");
780 } catch(IllegalArgumentException iae) {
781
782 }
783
784 try {
785 PoolUtils.erodingPool((KeyedObjectPool)null, 1f, true);
786 fail("PoolUtils.erodingPool(KeyedObjectPool, float, boolean) must not allow a null pool.");
787 } catch(IllegalArgumentException iae) {
788
789 }
790
791 final List calledMethods = new ArrayList();
792 final InvocationHandler handler = new MethodCallLogger(calledMethods) {
793 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
794 Object o = super.invoke(proxy, method, args);
795 if (o instanceof Integer) {
796
797 o = new Integer(1);
798 }
799 return o;
800 }
801 };
802
803
804 float factor = 0.01f;
805 final KeyedObjectPool pool = PoolUtils.erodingPool((KeyedObjectPool)createProxy(KeyedObjectPool.class, handler), factor, true);
806
807 final List expectedMethods = new ArrayList();
808 assertEquals(expectedMethods, calledMethods);
809
810 final Object key = "key";
811
812 Object o = pool.borrowObject(key);
813 expectedMethods.add("borrowObject");
814
815 assertEquals(expectedMethods, calledMethods);
816
817 pool.returnObject(key, o);
818 expectedMethods.add("returnObject");
819 assertEquals(expectedMethods, calledMethods);
820
821 for (int i=0; i < 5; i ++) {
822 o = pool.borrowObject(key);
823 expectedMethods.add("borrowObject");
824
825 Thread.sleep(50);
826
827 pool.returnObject(key, o);
828 expectedMethods.add("returnObject");
829
830 assertEquals(expectedMethods, calledMethods);
831
832 expectedMethods.clear();
833 calledMethods.clear();
834 }
835
836 Thread.sleep(10000);
837
838
839 o = pool.borrowObject(key);
840 expectedMethods.add("borrowObject");
841 pool.returnObject(key, o);
842 expectedMethods.add("getNumIdle");
843 expectedMethods.add("invalidateObject");
844 assertEquals(expectedMethods, calledMethods);
845 }
846
847 private static List invokeEveryMethod(ObjectPool op) throws Exception {
848 op.addObject();
849 op.borrowObject();
850 op.clear();
851 op.close();
852 op.getNumActive();
853 op.getNumIdle();
854 op.invalidateObject(new Object());
855 op.returnObject(new Object());
856 op.setFactory((PoolableObjectFactory)createProxy(PoolableObjectFactory.class, (List)null));
857 op.toString();
858
859 final List expectedMethods = Arrays.asList(new String[] {
860 "addObject", "borrowObject", "clear", "close",
861 "getNumActive", "getNumIdle", "invalidateObject",
862 "returnObject", "setFactory", "toString"
863 });
864 return expectedMethods;
865 }
866
867 private static List invokeEveryMethod(KeyedObjectPool kop) throws Exception {
868 kop.addObject(null);
869 kop.borrowObject(null);
870 kop.clear();
871 kop.clear(null);
872 kop.close();
873 kop.getNumActive();
874 kop.getNumActive(null);
875 kop.getNumIdle();
876 kop.getNumIdle(null);
877 kop.invalidateObject(null, new Object());
878 kop.returnObject(null, new Object());
879 kop.setFactory((KeyedPoolableObjectFactory)createProxy(KeyedPoolableObjectFactory.class, (List)null));
880 kop.toString();
881
882 final List expectedMethods = Arrays.asList(new String[] {
883 "addObject", "borrowObject", "clear", "clear", "close",
884 "getNumActive", "getNumActive", "getNumIdle", "getNumIdle", "invalidateObject",
885 "returnObject", "setFactory", "toString"
886 });
887 return expectedMethods;
888 }
889
890 private static List invokeEveryMethod(PoolableObjectFactory pof) throws Exception {
891 pof.activateObject(null);
892 pof.destroyObject(null);
893 pof.makeObject();
894 pof.passivateObject(null);
895 pof.validateObject(null);
896 pof.toString();
897
898 final List expectedMethods = Arrays.asList(new String[] {
899 "activateObject", "destroyObject", "makeObject",
900 "passivateObject", "validateObject", "toString",
901 });
902 return expectedMethods;
903 }
904
905 private static List invokeEveryMethod(KeyedPoolableObjectFactory kpof) throws Exception {
906 kpof.activateObject(null, null);
907 kpof.destroyObject(null, null);
908 kpof.makeObject(null);
909 kpof.passivateObject(null, null);
910 kpof.validateObject(null, null);
911 kpof.toString();
912
913 final List expectedMethods = Arrays.asList(new String[] {
914 "activateObject", "destroyObject", "makeObject",
915 "passivateObject", "validateObject", "toString",
916 });
917 return expectedMethods;
918 }
919
920 private static Object createProxy(final Class clazz, final List logger) {
921 return createProxy(clazz, new MethodCallLogger(logger));
922 }
923
924 private static Object createProxy(final Class clazz, final InvocationHandler handler) {
925 return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, handler);
926 }
927
928 private static class MethodCallLogger implements InvocationHandler {
929 private final List calledMethods;
930
931 MethodCallLogger(final List calledMethods) {
932 this.calledMethods = calledMethods;
933 }
934
935 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
936 calledMethods.add(method.getName());
937 if (boolean.class.equals(method.getReturnType())) {
938 return Boolean.FALSE;
939 } else if (int.class.equals(method.getReturnType())) {
940 return new Integer(0);
941 } else if (long.class.equals(method.getReturnType())) {
942 return new Long(0);
943 } else if (Object.class.equals(method.getReturnType())) {
944 return new Object();
945 } else {
946 return null;
947 }
948 }
949 }
950 }