1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.pool.impl;
19
20 import java.util.NoSuchElementException;
21 import java.util.Random;
22
23 import org.apache.commons.pool.BasePoolableObjectFactory;
24 import org.apache.commons.pool.ObjectPool;
25 import org.apache.commons.pool.PoolUtils;
26 import org.apache.commons.pool.PoolableObjectFactory;
27 import org.apache.commons.pool.TestBaseObjectPool;
28 import org.apache.commons.pool.VisitTracker;
29 import org.apache.commons.pool.VisitTrackerFactory;
30
31
32
33
34
35
36
37 public class TestGenericObjectPool extends TestBaseObjectPool {
38 public TestGenericObjectPool(String testName) {
39 super(testName);
40 }
41
42 protected ObjectPool makeEmptyPool(int mincap) {
43 GenericObjectPool pool = new GenericObjectPool(new SimpleFactory());
44 pool.setMaxActive(mincap);
45 pool.setMaxIdle(mincap);
46 return pool;
47 }
48
49 protected ObjectPool makeEmptyPool(final PoolableObjectFactory factory) {
50 return new GenericObjectPool(factory);
51 }
52
53 protected Object getNthObject(int n) {
54 return String.valueOf(n);
55 }
56
57 public void setUp() throws Exception {
58 super.setUp();
59 pool = new GenericObjectPool(new SimpleFactory());
60 }
61
62 public void tearDown() throws Exception {
63 super.tearDown();
64 pool.clear();
65 pool.close();
66 pool = null;
67 }
68
69 public void testWhenExhaustedGrow() throws Exception {
70 pool.setMaxActive(1);
71 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);
72 Object obj1 = pool.borrowObject();
73 assertNotNull(obj1);
74 Object obj2 = pool.borrowObject();
75 assertNotNull(obj2);
76 pool.returnObject(obj2);
77 pool.returnObject(obj1);
78 pool.close();
79 }
80
81 public void testWhenExhaustedFail() throws Exception {
82 pool.setMaxActive(1);
83 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
84 Object obj1 = pool.borrowObject();
85 assertNotNull(obj1);
86 try {
87 pool.borrowObject();
88 fail("Expected NoSuchElementException");
89 } catch(NoSuchElementException e) {
90
91 }
92 pool.returnObject(obj1);
93 assertEquals(1, pool.getNumIdle());
94 pool.close();
95 }
96
97 public void testWhenExhaustedBlock() throws Exception {
98 pool.setMaxActive(1);
99 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
100 pool.setMaxWait(10L);
101 Object obj1 = pool.borrowObject();
102 assertNotNull(obj1);
103 try {
104 pool.borrowObject();
105 fail("Expected NoSuchElementException");
106 } catch(NoSuchElementException e) {
107
108 }
109 pool.returnObject(obj1);
110 pool.close();
111 }
112
113 public void testWhenExhaustedBlockInterupt() throws Exception {
114 pool.setMaxActive(1);
115 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
116 pool.setMaxWait(0);
117 Object obj1 = pool.borrowObject();
118
119
120 assertNotNull(obj1);
121
122
123 WaitingTestThread wtt = new WaitingTestThread(pool, 200);
124 wtt.start();
125
126 Thread.sleep(200);
127 wtt.interrupt();
128
129
130 Thread.sleep(200);
131
132
133 assertTrue(wtt._thrown instanceof InterruptedException);
134
135
136 pool.returnObject(obj1);
137
138
139 pool.setMaxWait(10L);
140 Object obj2 = null;
141 try {
142 obj2 = pool.borrowObject();
143 assertNotNull(obj2);
144 } catch(NoSuchElementException e) {
145
146 fail("NoSuchElementException not expected");
147 }
148 pool.returnObject(obj2);
149 pool.close();
150 }
151
152 public void testWhenExhaustedBlockClosePool() throws Exception {
153 pool.setMaxActive(1);
154 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
155 pool.setMaxWait(0);
156 Object obj1 = pool.borrowObject();
157
158
159 assertNotNull(obj1);
160
161
162 WaitingTestThread wtt = new WaitingTestThread(pool, 200);
163 wtt.start();
164
165 Thread.sleep(200);
166
167
168 pool.close();
169
170
171 Thread.sleep(200);
172
173
174 assertTrue(wtt._thrown instanceof IllegalStateException);
175 }
176
177 public void testEvictWhileEmpty() throws Exception {
178 pool.evict();
179 pool.evict();
180 pool.close();
181 }
182
183
184
185
186
187 public void testEvictAddObjects() throws Exception {
188 SimpleFactory factory = new SimpleFactory();
189 factory.setMakeLatency(300);
190 factory.setMaxActive(2);
191 GenericObjectPool pool = new GenericObjectPool(factory);
192 pool.setMaxActive(2);
193 pool.setMinIdle(1);
194 pool.borrowObject();
195
196
197 TestThread borrower = new TestThread(pool, 1, 150, false);
198 Thread borrowerThread = new Thread(borrower);
199
200 pool.setTimeBetweenEvictionRunsMillis(100);
201 borrowerThread.start();
202 borrowerThread.join();
203 assertTrue(!borrower.failed());
204 pool.close();
205 }
206
207 public void testEvictLIFO() throws Exception {
208 checkEvict(true);
209 }
210
211 public void testEvictFIFO() throws Exception {
212 checkEvict(false);
213 }
214
215 public void checkEvict(boolean lifo) throws Exception {
216
217 final SimpleFactory factory = new SimpleFactory();
218 final GenericObjectPool pool = new GenericObjectPool(factory);
219 pool.setSoftMinEvictableIdleTimeMillis(10);
220 pool.setMinIdle(2);
221 pool.setTestWhileIdle(true);
222 pool.setLifo(lifo);
223 PoolUtils.prefill(pool, 5);
224 pool.evict();
225 factory.setEvenValid(false);
226 factory.setOddValid(false);
227 factory.setThrowExceptionOnActivate(true);
228 pool.evict();
229 PoolUtils.prefill(pool, 5);
230 factory.setThrowExceptionOnActivate(false);
231 factory.setThrowExceptionOnPassivate(true);
232 pool.evict();
233 factory.setThrowExceptionOnPassivate(false);
234 factory.setEvenValid(true);
235 factory.setOddValid(true);
236 Thread.sleep(125);
237 pool.evict();
238 assertEquals(2, pool.getNumIdle());
239 }
240
241
242
243
244
245
246
247 public void testEvictionOrder() throws Exception {
248 checkEvictionOrder(false);
249 checkEvictionOrder(true);
250 }
251
252 private void checkEvictionOrder(boolean lifo) throws Exception {
253 SimpleFactory factory = new SimpleFactory();
254 GenericObjectPool pool = new GenericObjectPool(factory);
255 pool.setNumTestsPerEvictionRun(2);
256 pool.setMinEvictableIdleTimeMillis(100);
257 pool.setLifo(lifo);
258 for (int i = 0; i < 5; i++) {
259 pool.addObject();
260 Thread.sleep(100);
261 }
262
263 pool.evict();
264 Object obj = pool.borrowObject();
265 assertTrue("oldest not evicted", !obj.equals("0"));
266 assertTrue("second oldest not evicted", !obj.equals("1"));
267
268 assertEquals("Wrong instance returned", lifo ? "4" : "2" , obj);
269
270
271 factory = new SimpleFactory();
272 pool = new GenericObjectPool(factory);
273 pool.setNumTestsPerEvictionRun(2);
274 pool.setMinEvictableIdleTimeMillis(100);
275 pool.setLifo(lifo);
276 for (int i = 0; i < 5; i++) {
277 pool.addObject();
278 Thread.sleep(100);
279 }
280 pool.evict();
281 pool.evict();
282 obj = pool.borrowObject();
283 assertEquals("Wrong instance remaining in pool", "4", obj);
284 }
285
286
287
288
289
290 public void testEvictorVisiting() throws Exception {
291 checkEvictorVisiting(true);
292 checkEvictorVisiting(false);
293 }
294
295 private void checkEvictorVisiting(boolean lifo) throws Exception {
296 VisitTrackerFactory factory = new VisitTrackerFactory();
297 GenericObjectPool pool = new GenericObjectPool(factory);
298 pool.setNumTestsPerEvictionRun(2);
299 pool.setMinEvictableIdleTimeMillis(-1);
300 pool.setTestWhileIdle(true);
301 pool.setLifo(lifo);
302 pool.setTestOnReturn(false);
303 pool.setTestOnBorrow(false);
304 for (int i = 0; i < 8; i++) {
305 pool.addObject();
306 }
307 pool.evict();
308 Object obj = pool.borrowObject();
309 pool.returnObject(obj);
310 obj = pool.borrowObject();
311 pool.returnObject(obj);
312
313
314
315 pool.evict();
316 for (int i = 0; i < 8; i++) {
317 VisitTracker tracker = (VisitTracker) pool.borrowObject();
318 if (tracker.getId() >= 4) {
319 assertEquals("Unexpected instance visited " + tracker.getId(),
320 0, tracker.getValidateCount());
321 } else {
322 assertEquals("Instance " + tracker.getId() +
323 " visited wrong number of times.",
324 1, tracker.getValidateCount());
325 }
326 }
327
328 factory = new VisitTrackerFactory();
329 pool = new GenericObjectPool(factory);
330 pool.setNumTestsPerEvictionRun(3);
331 pool.setMinEvictableIdleTimeMillis(-1);
332 pool.setTestWhileIdle(true);
333 pool.setLifo(lifo);
334 pool.setTestOnReturn(false);
335 pool.setTestOnBorrow(false);
336 for (int i = 0; i < 8; i++) {
337 pool.addObject();
338 }
339 pool.evict();
340 pool.evict();
341 obj = pool.borrowObject();
342 pool.returnObject(obj);
343 obj = pool.borrowObject();
344 pool.returnObject(obj);
345 obj = pool.borrowObject();
346 pool.returnObject(obj);
347
348
349
350
351 pool.evict();
352
353 for (int i = 0; i < 8; i++) {
354 VisitTracker tracker = (VisitTracker) pool.borrowObject();
355 if (tracker.getId() != 0) {
356 assertEquals("Instance " + tracker.getId() +
357 " visited wrong number of times.",
358 1, tracker.getValidateCount());
359 } else {
360 assertEquals("Instance " + tracker.getId() +
361 " visited wrong number of times.",
362 2, tracker.getValidateCount());
363 }
364 }
365
366
367 int[] smallPrimes = {2, 3, 5, 7};
368 Random random = new Random();
369 random.setSeed(System.currentTimeMillis());
370 for (int i = 0; i < 4; i++) {
371 pool.setNumTestsPerEvictionRun(smallPrimes[i]);
372 for (int j = 0; j < 5; j++) {
373 pool = new GenericObjectPool(factory);
374 pool.setNumTestsPerEvictionRun(3);
375 pool.setMinEvictableIdleTimeMillis(-1);
376 pool.setTestWhileIdle(true);
377 pool.setLifo(lifo);
378 pool.setTestOnReturn(false);
379 pool.setTestOnBorrow(false);
380 pool.setMaxIdle(-1);
381 int instanceCount = 10 + random.nextInt(20);
382 pool.setMaxActive(instanceCount);
383 for (int k = 0; k < instanceCount; k++) {
384 pool.addObject();
385 }
386
387
388 int runs = 10 + random.nextInt(50);
389 for (int k = 0; k < runs; k++) {
390 pool.evict();
391 }
392
393
394 int cycleCount = (runs * pool.getNumTestsPerEvictionRun())
395 / instanceCount;
396
397
398
399 VisitTracker tracker = null;
400 int visitCount = 0;
401 for (int k = 0; k < instanceCount; k++) {
402 tracker = (VisitTracker) pool.borrowObject();
403 assertTrue(pool.getNumActive() <= pool.getMaxActive());
404 visitCount = tracker.getValidateCount();
405 assertTrue(visitCount >= cycleCount &&
406 visitCount <= cycleCount + 1);
407 }
408 }
409 }
410 }
411
412 public void testExceptionOnPassivateDuringReturn() throws Exception {
413 SimpleFactory factory = new SimpleFactory();
414 GenericObjectPool pool = new GenericObjectPool(factory);
415 Object obj = pool.borrowObject();
416 factory.setThrowExceptionOnPassivate(true);
417 pool.returnObject(obj);
418 assertEquals(0,pool.getNumIdle());
419 pool.close();
420 }
421
422 public void testExceptionOnDestroyDuringBorrow() throws Exception {
423 SimpleFactory factory = new SimpleFactory();
424 factory.setThrowExceptionOnDestroy(true);
425 GenericObjectPool pool = new GenericObjectPool(factory);
426 pool.setTestOnBorrow(true);
427 pool.borrowObject();
428 factory.setValid(false);
429 try {
430 pool.borrowObject();
431 fail("Expecting NoSuchElementException");
432 } catch (NoSuchElementException ex) {
433
434 }
435 assertEquals(1, pool.getNumActive());
436 assertEquals(0, pool.getNumIdle());
437 }
438
439 public void testExceptionOnDestroyDuringReturn() throws Exception {
440 SimpleFactory factory = new SimpleFactory();
441 factory.setThrowExceptionOnDestroy(true);
442 GenericObjectPool pool = new GenericObjectPool(factory);
443 pool.setTestOnReturn(true);
444 Object obj1 = pool.borrowObject();
445 pool.borrowObject();
446 factory.setValid(false);
447 pool.returnObject(obj1);
448 assertEquals(1, pool.getNumActive());
449 assertEquals(0, pool.getNumIdle());
450 }
451
452 public void testExceptionOnActivateDuringBorrow() throws Exception {
453 SimpleFactory factory = new SimpleFactory();
454 GenericObjectPool pool = new GenericObjectPool(factory);
455 Object obj1 = pool.borrowObject();
456 Object obj2 = pool.borrowObject();
457 pool.returnObject(obj1);
458 pool.returnObject(obj2);
459 factory.setThrowExceptionOnActivate(true);
460 factory.setEvenValid(false);
461
462
463 Object obj = pool.borrowObject();
464 assertEquals(1, pool.getNumActive());
465 assertEquals(0, pool.getNumIdle());
466
467 pool.returnObject(obj);
468 factory.setValid(false);
469
470
471 try {
472 obj1 = pool.borrowObject();
473 fail("Expecting NoSuchElementException");
474 } catch (NoSuchElementException ex) {
475
476 }
477 assertEquals(0, pool.getNumActive());
478 assertEquals(0, pool.getNumIdle());
479 }
480
481 public void testSetFactoryWithActiveObjects() throws Exception {
482 GenericObjectPool pool = new GenericObjectPool();
483 pool.setMaxIdle(10);
484 pool.setFactory(new SimpleFactory());
485 Object obj = pool.borrowObject();
486 assertNotNull(obj);
487 try {
488 pool.setFactory(null);
489 fail("Expected IllegalStateException");
490 } catch(IllegalStateException e) {
491
492 }
493 try {
494 pool.setFactory(new SimpleFactory());
495 fail("Expected IllegalStateException");
496 } catch(IllegalStateException e) {
497
498 }
499 }
500
501 public void testSetFactoryWithNoActiveObjects() throws Exception {
502 GenericObjectPool pool = new GenericObjectPool();
503 pool.setMaxIdle(10);
504 pool.setFactory(new SimpleFactory());
505 Object obj = pool.borrowObject();
506 pool.returnObject(obj);
507 assertEquals(1,pool.getNumIdle());
508 pool.setFactory(new SimpleFactory());
509 assertEquals(0,pool.getNumIdle());
510 }
511
512 public void testNegativeMaxActive() throws Exception {
513 pool.setMaxActive(-1);
514 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
515 Object obj = pool.borrowObject();
516 assertEquals(getNthObject(0),obj);
517 pool.returnObject(obj);
518 }
519
520 public void testMaxIdle() throws Exception {
521 pool.setMaxActive(100);
522 pool.setMaxIdle(8);
523 Object[] active = new Object[100];
524 for(int i=0;i<100;i++) {
525 active[i] = pool.borrowObject();
526 }
527 assertEquals(100,pool.getNumActive());
528 assertEquals(0,pool.getNumIdle());
529 for(int i=0;i<100;i++) {
530 pool.returnObject(active[i]);
531 assertEquals(99 - i,pool.getNumActive());
532 assertEquals((i < 8 ? i+1 : 8),pool.getNumIdle());
533 }
534 }
535
536 public void testMaxIdleZero() throws Exception {
537 pool.setMaxActive(100);
538 pool.setMaxIdle(0);
539 Object[] active = new Object[100];
540 for(int i=0;i<100;i++) {
541 active[i] = pool.borrowObject();
542 }
543 assertEquals(100,pool.getNumActive());
544 assertEquals(0,pool.getNumIdle());
545 for(int i=0;i<100;i++) {
546 pool.returnObject(active[i]);
547 assertEquals(99 - i,pool.getNumActive());
548 assertEquals(0, pool.getNumIdle());
549 }
550 }
551
552 public void testMaxActive() throws Exception {
553 pool.setMaxActive(3);
554 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
555
556 pool.borrowObject();
557 pool.borrowObject();
558 pool.borrowObject();
559 try {
560 pool.borrowObject();
561 fail("Expected NoSuchElementException");
562 } catch(NoSuchElementException e) {
563
564 }
565 }
566
567 public void testTimeoutNoLeak() throws Exception {
568 pool.setMaxActive(2);
569 pool.setMaxWait(10);
570 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
571 Object obj = pool.borrowObject();
572 Object obj2 = pool.borrowObject();
573 try {
574 pool.borrowObject();
575 fail("Expecting NoSuchElementException");
576 } catch (NoSuchElementException ex) {
577
578 }
579 pool.returnObject(obj2);
580 pool.returnObject(obj);
581
582 obj = pool.borrowObject();
583 obj2 = pool.borrowObject();
584 }
585
586 public void testMaxActiveZero() throws Exception {
587 pool.setMaxActive(0);
588 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
589
590 try {
591 pool.borrowObject();
592 fail("Expected NoSuchElementException");
593 } catch(NoSuchElementException e) {
594
595 }
596 }
597
598 public void testMaxActiveUnderLoad() {
599
600 int numThreads = 199;
601 int numIter = 20;
602 int delay = 25;
603 int maxActive = 10;
604
605 SimpleFactory factory = new SimpleFactory();
606 factory.setMaxActive(maxActive);
607 pool.setFactory(factory);
608 pool.setMaxActive(maxActive);
609 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
610 pool.setTimeBetweenEvictionRunsMillis(-1);
611
612
613 TestThread[] threads = new TestThread[numThreads];
614 for(int i=0;i<numThreads;i++) {
615
616
617
618 threads[i] = new TestThread(pool, numIter * 2, delay * 2);
619 Thread t = new Thread(threads[i]);
620 t.start();
621 }
622
623 try {
624 Thread.sleep(5000);
625 } catch(InterruptedException e) {
626
627 }
628
629 for (int i = 0; i < numIter; i++) {
630 Object obj = null;
631 try {
632 try {
633 Thread.sleep(delay);
634 } catch(InterruptedException e) {
635
636 }
637 obj = pool.borrowObject();
638
639 if (pool.getNumActive() > pool.getMaxActive()) {
640 throw new IllegalStateException("Too many active objects");
641 }
642 try {
643 Thread.sleep(delay);
644 } catch(InterruptedException e) {
645
646 }
647 } catch (Exception e) {
648
649 e.printStackTrace();
650 fail("Exception on borrow");
651 } finally {
652 if (obj != null) {
653 try {
654 pool.returnObject(obj);
655 } catch (Exception e) {
656
657 }
658 }
659 }
660 }
661
662 for(int i=0;i<numThreads;i++) {
663 while(!(threads[i]).complete()) {
664 try {
665 Thread.sleep(500L);
666 } catch(InterruptedException e) {
667
668 }
669 }
670 if(threads[i].failed()) {
671 fail("Thread "+i+" failed: "+threads[i]._error.toString());
672 }
673 }
674 }
675
676 public void testInvalidWhenExhaustedAction() throws Exception {
677 try {
678 pool.setWhenExhaustedAction(Byte.MAX_VALUE);
679 fail("Expected IllegalArgumentException");
680 } catch(IllegalArgumentException e) {
681
682 }
683
684 try {
685 ObjectPool pool = new GenericObjectPool(
686 new SimpleFactory(),
687 GenericObjectPool.DEFAULT_MAX_ACTIVE,
688 Byte.MAX_VALUE,
689 GenericObjectPool.DEFAULT_MAX_WAIT,
690 GenericObjectPool.DEFAULT_MAX_IDLE,
691 false,
692 false,
693 GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
694 GenericObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
695 GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
696 false
697 );
698 assertNotNull(pool);
699 fail("Expected IllegalArgumentException");
700 } catch(IllegalArgumentException e) {
701
702 }
703 }
704
705 public void testSettersAndGetters() throws Exception {
706 GenericObjectPool pool = new GenericObjectPool();
707 {
708 pool.setFactory(new SimpleFactory());
709 }
710 {
711 pool.setMaxActive(123);
712 assertEquals(123,pool.getMaxActive());
713 }
714 {
715 pool.setMaxIdle(12);
716 assertEquals(12,pool.getMaxIdle());
717 }
718 {
719 pool.setMaxWait(1234L);
720 assertEquals(1234L,pool.getMaxWait());
721 }
722 {
723 pool.setMinEvictableIdleTimeMillis(12345L);
724 assertEquals(12345L,pool.getMinEvictableIdleTimeMillis());
725 }
726 {
727 pool.setNumTestsPerEvictionRun(11);
728 assertEquals(11,pool.getNumTestsPerEvictionRun());
729 }
730 {
731 pool.setTestOnBorrow(true);
732 assertTrue(pool.getTestOnBorrow());
733 pool.setTestOnBorrow(false);
734 assertTrue(!pool.getTestOnBorrow());
735 }
736 {
737 pool.setTestOnReturn(true);
738 assertTrue(pool.getTestOnReturn());
739 pool.setTestOnReturn(false);
740 assertTrue(!pool.getTestOnReturn());
741 }
742 {
743 pool.setTestWhileIdle(true);
744 assertTrue(pool.getTestWhileIdle());
745 pool.setTestWhileIdle(false);
746 assertTrue(!pool.getTestWhileIdle());
747 }
748 {
749 pool.setTimeBetweenEvictionRunsMillis(11235L);
750 assertEquals(11235L,pool.getTimeBetweenEvictionRunsMillis());
751 }
752 {
753 pool.setSoftMinEvictableIdleTimeMillis(12135L);
754 assertEquals(12135L,pool.getSoftMinEvictableIdleTimeMillis());
755 }
756 {
757 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
758 assertEquals(GenericObjectPool.WHEN_EXHAUSTED_BLOCK,pool.getWhenExhaustedAction());
759 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
760 assertEquals(GenericObjectPool.WHEN_EXHAUSTED_FAIL,pool.getWhenExhaustedAction());
761 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);
762 assertEquals(GenericObjectPool.WHEN_EXHAUSTED_GROW,pool.getWhenExhaustedAction());
763 }
764 }
765
766 public void testDefaultConfiguration() throws Exception {
767 GenericObjectPool pool = new GenericObjectPool();
768 assertConfiguration(new GenericObjectPool.Config(),pool);
769 }
770
771 public void testConstructors() throws Exception {
772 {
773 GenericObjectPool pool = new GenericObjectPool();
774 assertConfiguration(new GenericObjectPool.Config(),pool);
775 }
776 {
777 GenericObjectPool pool = new GenericObjectPool(new SimpleFactory());
778 assertConfiguration(new GenericObjectPool.Config(),pool);
779 }
780 {
781 GenericObjectPool.Config expected = new GenericObjectPool.Config();
782 expected.maxActive = 2;
783 expected.maxIdle = 3;
784 expected.maxWait = 5L;
785 expected.minEvictableIdleTimeMillis = 7L;
786 expected.numTestsPerEvictionRun = 9;
787 expected.testOnBorrow = true;
788 expected.testOnReturn = true;
789 expected.testWhileIdle = true;
790 expected.timeBetweenEvictionRunsMillis = 11L;
791 expected.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
792 GenericObjectPool pool = new GenericObjectPool(null,expected);
793 assertConfiguration(expected,pool);
794 }
795 {
796 GenericObjectPool.Config expected = new GenericObjectPool.Config();
797 expected.maxActive = 2;
798 GenericObjectPool pool = new GenericObjectPool(null,expected.maxActive);
799 assertConfiguration(expected,pool);
800 }
801 {
802 GenericObjectPool.Config expected = new GenericObjectPool.Config();
803 expected.maxActive = 2;
804 expected.maxWait = 5L;
805 expected.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
806 GenericObjectPool pool = new GenericObjectPool(null,expected.maxActive,expected.whenExhaustedAction,expected.maxWait);
807 assertConfiguration(expected,pool);
808 }
809 {
810 GenericObjectPool.Config expected = new GenericObjectPool.Config();
811 expected.maxActive = 2;
812 expected.maxWait = 5L;
813 expected.testOnBorrow = true;
814 expected.testOnReturn = true;
815 expected.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
816 GenericObjectPool pool = new GenericObjectPool(null,expected.maxActive,expected.whenExhaustedAction,expected.maxWait,expected.testOnBorrow,expected.testOnReturn);
817 assertConfiguration(expected,pool);
818 }
819 {
820 GenericObjectPool.Config expected = new GenericObjectPool.Config();
821 expected.maxActive = 2;
822 expected.maxIdle = 3;
823 expected.maxWait = 5L;
824 expected.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
825 GenericObjectPool pool = new GenericObjectPool(null,expected.maxActive,expected.whenExhaustedAction,expected.maxWait,expected.maxIdle);
826 assertConfiguration(expected,pool);
827 }
828 {
829 GenericObjectPool.Config expected = new GenericObjectPool.Config();
830 expected.maxActive = 2;
831 expected.maxIdle = 3;
832 expected.maxWait = 5L;
833 expected.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
834 expected.testOnBorrow = true;
835 expected.testOnReturn = true;
836 GenericObjectPool pool = new GenericObjectPool(null,expected.maxActive,expected.whenExhaustedAction,expected.maxWait,expected.maxIdle,expected.testOnBorrow,expected.testOnReturn);
837 assertConfiguration(expected,pool);
838 }
839 {
840 GenericObjectPool.Config expected = new GenericObjectPool.Config();
841 expected.maxActive = 2;
842 expected.maxIdle = 3;
843 expected.maxWait = 5L;
844 expected.minEvictableIdleTimeMillis = 7L;
845 expected.numTestsPerEvictionRun = 9;
846 expected.testOnBorrow = true;
847 expected.testOnReturn = true;
848 expected.testWhileIdle = true;
849 expected.timeBetweenEvictionRunsMillis = 11L;
850 expected.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
851 GenericObjectPool pool = new GenericObjectPool(null,expected.maxActive, expected.whenExhaustedAction, expected.maxWait, expected.maxIdle, expected.testOnBorrow, expected.testOnReturn, expected.timeBetweenEvictionRunsMillis, expected.numTestsPerEvictionRun, expected.minEvictableIdleTimeMillis, expected.testWhileIdle);
852 assertConfiguration(expected,pool);
853 }
854 {
855 GenericObjectPool.Config expected = new GenericObjectPool.Config();
856 expected.maxActive = 2;
857 expected.maxIdle = 3;
858 expected.minIdle = 1;
859 expected.maxWait = 5L;
860 expected.minEvictableIdleTimeMillis = 7L;
861 expected.numTestsPerEvictionRun = 9;
862 expected.testOnBorrow = true;
863 expected.testOnReturn = true;
864 expected.testWhileIdle = true;
865 expected.timeBetweenEvictionRunsMillis = 11L;
866 expected.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
867 GenericObjectPool pool = new GenericObjectPool(null,expected.maxActive, expected.whenExhaustedAction, expected.maxWait, expected.maxIdle, expected.minIdle, expected.testOnBorrow, expected.testOnReturn, expected.timeBetweenEvictionRunsMillis, expected.numTestsPerEvictionRun, expected.minEvictableIdleTimeMillis, expected.testWhileIdle);
868 assertConfiguration(expected,pool);
869 }
870 }
871
872 public void testSetConfig() throws Exception {
873 GenericObjectPool.Config expected = new GenericObjectPool.Config();
874 GenericObjectPool pool = new GenericObjectPool();
875 assertConfiguration(expected,pool);
876 expected.maxActive = 2;
877 expected.maxIdle = 3;
878 expected.maxWait = 5L;
879 expected.minEvictableIdleTimeMillis = 7L;
880 expected.numTestsPerEvictionRun = 9;
881 expected.testOnBorrow = true;
882 expected.testOnReturn = true;
883 expected.testWhileIdle = true;
884 expected.timeBetweenEvictionRunsMillis = 11L;
885 expected.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
886 pool.setConfig(expected);
887 assertConfiguration(expected,pool);
888 }
889
890 public void testDebugInfo() throws Exception {
891 GenericObjectPool pool = new GenericObjectPool(new SimpleFactory());
892 pool.setMaxIdle(3);
893 assertNotNull(pool.debugInfo());
894 Object obj = pool.borrowObject();
895 assertNotNull(pool.debugInfo());
896 pool.returnObject(obj);
897 assertNotNull(pool.debugInfo());
898 }
899
900 public void testStartAndStopEvictor() throws Exception {
901
902 pool.setMaxIdle(6);
903 pool.setMaxActive(6);
904 pool.setNumTestsPerEvictionRun(6);
905 pool.setMinEvictableIdleTimeMillis(100L);
906
907 for(int j=0;j<2;j++) {
908
909 {
910 Object[] active = new Object[6];
911 for(int i=0;i<6;i++) {
912 active[i] = pool.borrowObject();
913 }
914 for(int i=0;i<6;i++) {
915 pool.returnObject(active[i]);
916 }
917 }
918
919
920 assertEquals("Should have 6 idle",6,pool.getNumIdle());
921
922
923 pool.setTimeBetweenEvictionRunsMillis(50L);
924
925
926 try { Thread.sleep(200L); } catch(InterruptedException e) { }
927
928
929 assertEquals("Should have 0 idle",0,pool.getNumIdle());
930
931
932 pool.startEvictor(0L);
933 }
934 }
935
936 public void testEvictionWithNegativeNumTests() throws Exception {
937
938 pool.setMaxIdle(6);
939 pool.setMaxActive(6);
940 pool.setNumTestsPerEvictionRun(-2);
941 pool.setMinEvictableIdleTimeMillis(50L);
942 pool.setTimeBetweenEvictionRunsMillis(100L);
943
944 Object[] active = new Object[6];
945 for(int i=0;i<6;i++) {
946 active[i] = pool.borrowObject();
947 }
948 for(int i=0;i<6;i++) {
949 pool.returnObject(active[i]);
950 }
951
952 try { Thread.sleep(100L); } catch(InterruptedException e) { }
953 assertTrue("Should at most 6 idle, found " + pool.getNumIdle(),pool.getNumIdle() <= 6);
954 try { Thread.sleep(100L); } catch(InterruptedException e) { }
955 assertTrue("Should at most 3 idle, found " + pool.getNumIdle(),pool.getNumIdle() <= 3);
956 try { Thread.sleep(100L); } catch(InterruptedException e) { }
957 assertTrue("Should be at most 2 idle, found " + pool.getNumIdle(),pool.getNumIdle() <= 2);
958 try { Thread.sleep(100L); } catch(InterruptedException e) { }
959 assertEquals("Should be zero idle, found " + pool.getNumIdle(),0,pool.getNumIdle());
960 }
961
962 public void testEviction() throws Exception {
963 pool.setMaxIdle(500);
964 pool.setMaxActive(500);
965 pool.setNumTestsPerEvictionRun(100);
966 pool.setMinEvictableIdleTimeMillis(250L);
967 pool.setTimeBetweenEvictionRunsMillis(500L);
968 pool.setTestWhileIdle(true);
969
970 Object[] active = new Object[500];
971 for(int i=0;i<500;i++) {
972 active[i] = pool.borrowObject();
973 }
974 for(int i=0;i<500;i++) {
975 pool.returnObject(active[i]);
976 }
977
978 try { Thread.sleep(1000L); } catch(InterruptedException e) { }
979 assertTrue("Should be less than 500 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 500);
980 try { Thread.sleep(600L); } catch(InterruptedException e) { }
981 assertTrue("Should be less than 400 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 400);
982 try { Thread.sleep(600L); } catch(InterruptedException e) { }
983 assertTrue("Should be less than 300 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 300);
984 try { Thread.sleep(600L); } catch(InterruptedException e) { }
985 assertTrue("Should be less than 200 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 200);
986 try { Thread.sleep(600L); } catch(InterruptedException e) { }
987 assertTrue("Should be less than 100 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 100);
988 try { Thread.sleep(600L); } catch(InterruptedException e) { }
989 assertEquals("Should be zero idle, found " + pool.getNumIdle(),0,pool.getNumIdle());
990
991 for(int i=0;i<500;i++) {
992 active[i] = pool.borrowObject();
993 }
994 for(int i=0;i<500;i++) {
995 pool.returnObject(active[i]);
996 }
997
998 try { Thread.sleep(1000L); } catch(InterruptedException e) { }
999 assertTrue("Should be less than 500 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 500);
1000 try { Thread.sleep(600L); } catch(InterruptedException e) { }
1001 assertTrue("Should be less than 400 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 400);
1002 try { Thread.sleep(600L); } catch(InterruptedException e) { }
1003 assertTrue("Should be less than 300 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 300);
1004 try { Thread.sleep(600L); } catch(InterruptedException e) { }
1005 assertTrue("Should be less than 200 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 200);
1006 try { Thread.sleep(600L); } catch(InterruptedException e) { }
1007 assertTrue("Should be less than 100 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 100);
1008 try { Thread.sleep(600L); } catch(InterruptedException e) { }
1009 assertEquals("Should be zero idle, found " + pool.getNumIdle(),0,pool.getNumIdle());
1010 }
1011
1012 public void testEvictionSoftMinIdle() throws Exception {
1013 GenericObjectPool pool = null;
1014
1015 class TimeTest extends BasePoolableObjectFactory {
1016 private final long createTime;
1017 public TimeTest() {
1018 createTime = System.currentTimeMillis();
1019 }
1020 public Object makeObject() throws Exception {
1021 return new TimeTest();
1022 }
1023 public long getCreateTime() {
1024 return createTime;
1025 }
1026 }
1027
1028 pool = new GenericObjectPool(new TimeTest());
1029
1030 pool.setMaxIdle(5);
1031 pool.setMaxActive(5);
1032 pool.setNumTestsPerEvictionRun(5);
1033 pool.setMinEvictableIdleTimeMillis(3000L);
1034 pool.setSoftMinEvictableIdleTimeMillis(1000L);
1035 pool.setMinIdle(2);
1036
1037 Object[] active = new Object[5];
1038 Long[] creationTime = new Long[5] ;
1039 for(int i=0;i<5;i++) {
1040 active[i] = pool.borrowObject();
1041 creationTime[i] = new Long(((TimeTest)active[i]).getCreateTime());
1042 }
1043
1044 for(int i=0;i<5;i++) {
1045 pool.returnObject(active[i]);
1046 }
1047
1048
1049 Thread.sleep(1500L);
1050 pool.evict();
1051 assertEquals("Idle count different than expected.", 2, pool.getNumIdle());
1052
1053
1054 Thread.sleep(2000L);
1055 pool.evict();
1056 assertEquals("Idle count different than expected.", 0, pool.getNumIdle());
1057 }
1058
1059 public void testMinIdle() throws Exception {
1060 pool.setMaxIdle(500);
1061 pool.setMinIdle(5);
1062 pool.setMaxActive(10);
1063 pool.setNumTestsPerEvictionRun(0);
1064 pool.setMinEvictableIdleTimeMillis(50L);
1065 pool.setTimeBetweenEvictionRunsMillis(100L);
1066 pool.setTestWhileIdle(true);
1067
1068 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1069 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
1070
1071 Object[] active = new Object[5];
1072 active[0] = pool.borrowObject();
1073
1074 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1075 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
1076
1077 for(int i=1 ; i<5 ; i++) {
1078 active[i] = pool.borrowObject();
1079 }
1080
1081 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1082 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
1083
1084 for(int i=0 ; i<5 ; i++) {
1085 pool.returnObject(active[i]);
1086 }
1087
1088 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1089 assertTrue("Should be 10 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 10);
1090 }
1091
1092 public void testMinIdleMaxActive() throws Exception {
1093 pool.setMaxIdle(500);
1094 pool.setMinIdle(5);
1095 pool.setMaxActive(10);
1096 pool.setNumTestsPerEvictionRun(0);
1097 pool.setMinEvictableIdleTimeMillis(50L);
1098 pool.setTimeBetweenEvictionRunsMillis(100L);
1099 pool.setTestWhileIdle(true);
1100
1101 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1102 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
1103
1104 Object[] active = new Object[10];
1105
1106 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1107 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
1108
1109 for(int i=0 ; i<5 ; i++) {
1110 active[i] = pool.borrowObject();
1111 }
1112
1113 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1114 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
1115
1116 for(int i=0 ; i<5 ; i++) {
1117 pool.returnObject(active[i]);
1118 }
1119
1120 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1121 assertTrue("Should be 10 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 10);
1122
1123 for(int i=0 ; i<10 ; i++) {
1124 active[i] = pool.borrowObject();
1125 }
1126
1127 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1128 assertTrue("Should be 0 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 0);
1129
1130 for(int i=0 ; i<10 ; i++) {
1131 pool.returnObject(active[i]);
1132 }
1133
1134 try { Thread.sleep(150L); } catch(InterruptedException e) { }
1135 assertTrue("Should be 10 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 10);
1136 }
1137
1138
1139
1140
1141
1142
1143 public void runTestThreads(int numThreads, int iterations, int delay) {
1144 TestThread[] threads = new TestThread[numThreads];
1145 for(int i=0;i<numThreads;i++) {
1146 threads[i] = new TestThread(pool,iterations,delay);
1147 Thread t = new Thread(threads[i]);
1148 t.start();
1149 }
1150 for(int i=0;i<numThreads;i++) {
1151 while(!(threads[i]).complete()) {
1152 try {
1153 Thread.sleep(500L);
1154 } catch(InterruptedException e) {
1155
1156 }
1157 }
1158 if(threads[i].failed()) {
1159 fail("Thread "+i+" failed: "+threads[i]._error.toString());
1160 }
1161 }
1162 }
1163
1164 public void testThreaded1() throws Exception {
1165 pool.setMaxActive(15);
1166 pool.setMaxIdle(15);
1167 pool.setMaxWait(1000L);
1168 runTestThreads(20, 100, 50);
1169 }
1170
1171
1172
1173
1174
1175
1176 public void testMaxActiveInvariant() throws Exception {
1177 int maxActive = 15;
1178 SimpleFactory factory = new SimpleFactory();
1179 factory.setEvenValid(false);
1180 factory.setDestroyLatency(100);
1181 factory.setMaxActive(maxActive);
1182 factory.setValidationEnabled(true);
1183 pool = new GenericObjectPool(factory);
1184 pool.setMaxActive(maxActive);
1185 pool.setMaxIdle(-1);
1186 pool.setTestOnReturn(true);
1187 pool.setMaxWait(1000L);
1188 runTestThreads(5, 10, 50);
1189 }
1190
1191 public void testConcurrentBorrowAndEvict() throws Exception {
1192
1193 pool.setMaxActive(1);
1194 pool.addObject();
1195
1196 for( int i=0; i<5000; i++) {
1197 ConcurrentBorrowAndEvictThread one =
1198 new ConcurrentBorrowAndEvictThread(true);
1199 ConcurrentBorrowAndEvictThread two =
1200 new ConcurrentBorrowAndEvictThread(false);
1201
1202 one.start();
1203 two.start();
1204 one.join();
1205 two.join();
1206
1207 pool.returnObject(one.obj);
1208
1209
1210
1211
1212
1213
1214 }
1215 }
1216
1217 private class ConcurrentBorrowAndEvictThread extends Thread {
1218 private boolean borrow;
1219 public Object obj;
1220
1221 public ConcurrentBorrowAndEvictThread(boolean borrow) {
1222 this.borrow = borrow;
1223 }
1224
1225 public void run() {
1226 try {
1227 if (borrow) {
1228 obj = pool.borrowObject();
1229 } else {
1230 pool.evict();
1231 }
1232 } catch (Exception e) {
1233 }
1234 }
1235
1236 static class TestThread implements Runnable {
1237 private final java.util.Random _random = new java.util.Random();
1238
1239
1240 private final ObjectPool _pool;
1241 private final int _iter;
1242 private final int _delay;
1243 private final boolean _randomDelay;
1244 private final Object _expectedObject;
1245
1246 private volatile boolean _complete = false;
1247 private volatile boolean _failed = false;
1248 private volatile Throwable _error;
1249
1250 public TestThread(ObjectPool pool) {
1251 this(pool, 100, 50, true, null);
1252 }
1253
1254 public TestThread(ObjectPool pool, int iter) {
1255 this(pool, iter, 50, true, null);
1256 }
1257
1258 public TestThread(ObjectPool pool, int iter, int delay) {
1259 this(pool, iter, delay, true, null);
1260 }
1261
1262 public TestThread(ObjectPool pool, int iter, int delay,
1263 boolean randomDelay) {
1264 this(pool, iter, delay, randomDelay, null);
1265 }
1266
1267 public TestThread(ObjectPool pool, int iter, int delay,
1268 boolean randomDelay, Object obj) {
1269 _pool = pool;
1270 _iter = iter;
1271 _delay = delay;
1272 _randomDelay = randomDelay;
1273 _expectedObject = obj;
1274 }
1275
1276 public boolean complete() {
1277 return _complete;
1278 }
1279
1280 public boolean failed() {
1281 return _failed;
1282 }
1283
1284 public void run() {
1285 for(int i=0;i<_iter;i++) {
1286 long delay =
1287 _randomDelay ? (long)_random.nextInt(_delay) : _delay;
1288 try {
1289 Thread.sleep(delay);
1290 } catch(InterruptedException e) {
1291
1292 }
1293 Object obj = null;
1294 try {
1295 obj = _pool.borrowObject();
1296 } catch(Exception e) {
1297 _error = e;
1298 _failed = true;
1299 _complete = true;
1300 break;
1301 }
1302
1303 if (_expectedObject != null && !_expectedObject.equals(obj)) {
1304 _error = new Throwable("Expected: "+_expectedObject+ " found: "+obj);
1305 _failed = true;
1306 _complete = true;
1307 break;
1308 }
1309
1310 try {
1311 Thread.sleep(delay);
1312 } catch(InterruptedException e) {
1313
1314 }
1315 try {
1316 _pool.returnObject(obj);
1317 } catch(Exception e) {
1318 _error = e;
1319 _failed = true;
1320 _complete = true;
1321 break;
1322 }
1323 }
1324 _complete = true;
1325 }
1326 }
1327
1328 public void testFIFO() throws Exception {
1329 pool.setLifo(false);
1330 pool.addObject();
1331 pool.addObject();
1332 pool.addObject();
1333 assertEquals("Oldest", "0", pool.borrowObject());
1334 assertEquals("Middle", "1", pool.borrowObject());
1335 assertEquals("Youngest", "2", pool.borrowObject());
1336 assertEquals("new-3", "3", pool.borrowObject());
1337 pool.returnObject("r");
1338 assertEquals("returned", "r", pool.borrowObject());
1339 assertEquals("new-4", "4", pool.borrowObject());
1340 }
1341
1342 public void testLIFO() throws Exception {
1343 pool.setLifo(true);
1344 pool.addObject();
1345 pool.addObject();
1346 pool.addObject();
1347 assertEquals("Youngest", "2", pool.borrowObject());
1348 assertEquals("Middle", "1", pool.borrowObject());
1349 assertEquals("Oldest", "0", pool.borrowObject());
1350 assertEquals("new-3", "3", pool.borrowObject());
1351 pool.returnObject("r");
1352 assertEquals("returned", "r", pool.borrowObject());
1353 assertEquals("new-4", "4", pool.borrowObject());
1354 }
1355
1356 public void testAddObject() throws Exception {
1357 assertEquals("should be zero idle", 0, pool.getNumIdle());
1358 pool.addObject();
1359 assertEquals("should be one idle", 1, pool.getNumIdle());
1360 assertEquals("should be zero active", 0, pool.getNumActive());
1361 Object obj = pool.borrowObject();
1362 assertEquals("should be zero idle", 0, pool.getNumIdle());
1363 assertEquals("should be one active", 1, pool.getNumActive());
1364 pool.returnObject(obj);
1365 assertEquals("should be one idle", 1, pool.getNumIdle());
1366 assertEquals("should be zero active", 0, pool.getNumActive());
1367
1368 ObjectPool op = new GenericObjectPool();
1369 try {
1370 op.addObject();
1371 fail("Expected IllegalStateException when there is no factory.");
1372 } catch (IllegalStateException ise) {
1373
1374 }
1375 op.close();
1376 }
1377
1378 protected GenericObjectPool pool = null;
1379
1380 private void assertConfiguration(GenericObjectPool.Config expected, GenericObjectPool actual) throws Exception {
1381 assertEquals("testOnBorrow",expected.testOnBorrow,actual.getTestOnBorrow());
1382 assertEquals("testOnReturn",expected.testOnReturn,actual.getTestOnReturn());
1383 assertEquals("testWhileIdle",expected.testWhileIdle,actual.getTestWhileIdle());
1384 assertEquals("whenExhaustedAction",expected.whenExhaustedAction,actual.getWhenExhaustedAction());
1385 assertEquals("maxActive",expected.maxActive,actual.getMaxActive());
1386 assertEquals("maxIdle",expected.maxIdle,actual.getMaxIdle());
1387 assertEquals("maxWait",expected.maxWait,actual.getMaxWait());
1388 assertEquals("minEvictableIdleTimeMillis",expected.minEvictableIdleTimeMillis,actual.getMinEvictableIdleTimeMillis());
1389 assertEquals("numTestsPerEvictionRun",expected.numTestsPerEvictionRun,actual.getNumTestsPerEvictionRun());
1390 assertEquals("timeBetweenEvictionRunsMillis",expected.timeBetweenEvictionRunsMillis,actual.getTimeBetweenEvictionRunsMillis());
1391 }
1392
1393 public class SimpleFactory implements PoolableObjectFactory {
1394 public SimpleFactory() {
1395 this(true);
1396 }
1397 public SimpleFactory(boolean valid) {
1398 this(valid,valid);
1399 }
1400 public SimpleFactory(boolean evalid, boolean ovalid) {
1401 evenValid = evalid;
1402 oddValid = ovalid;
1403 }
1404 public synchronized void setValid(boolean valid) {
1405 setEvenValid(valid);
1406 setOddValid(valid);
1407 }
1408 public synchronized void setEvenValid(boolean valid) {
1409 evenValid = valid;
1410 }
1411 public synchronized void setOddValid(boolean valid) {
1412 oddValid = valid;
1413 }
1414 public synchronized void setThrowExceptionOnPassivate(boolean bool) {
1415 exceptionOnPassivate = bool;
1416 }
1417 public synchronized void setMaxActive(int maxActive) {
1418 this.maxActive = maxActive;
1419 }
1420 public synchronized void setDestroyLatency(long destroyLatency) {
1421 this.destroyLatency = destroyLatency;
1422 }
1423 public synchronized void setMakeLatency(long makeLatency) {
1424 this.makeLatency = makeLatency;
1425 }
1426 public synchronized void setValidateLatency(long validateLatency) {
1427 this.validateLatency = validateLatency;
1428 }
1429 public Object makeObject() {
1430 final long waitLatency;
1431 synchronized(this) {
1432 activeCount++;
1433 if (activeCount > maxActive) {
1434 throw new IllegalStateException(
1435 "Too many active instances: " + activeCount);
1436 }
1437 waitLatency = makeLatency;
1438 }
1439 if (waitLatency > 0) {
1440 doWait(waitLatency);
1441 }
1442 final int counter;
1443 synchronized(this) {
1444 counter = makeCounter++;
1445 }
1446 return String.valueOf(counter);
1447 }
1448 public void destroyObject(Object obj) throws Exception {
1449 final long waitLatency;
1450 final boolean hurl;
1451 synchronized(this) {
1452 waitLatency = destroyLatency;
1453 hurl = exceptionOnDestroy;
1454 }
1455 if (waitLatency > 0) {
1456 doWait(waitLatency);
1457 }
1458 synchronized(this) {
1459 activeCount--;
1460 }
1461 if (hurl) {
1462 throw new Exception();
1463 }
1464 }
1465 public boolean validateObject(Object obj) {
1466 final boolean validate;
1467 final boolean evenTest;
1468 final boolean oddTest;
1469 final long waitLatency;
1470 final int counter;
1471 synchronized(this) {
1472 validate = enableValidation;
1473 evenTest = evenValid;
1474 oddTest = oddValid;
1475 counter = validateCounter++;
1476 waitLatency = validateLatency;
1477 }
1478 if (waitLatency > 0) {
1479 doWait(waitLatency);
1480 }
1481 if (validate) {
1482 return counter%2 == 0 ? evenTest : oddTest;
1483 }
1484 else {
1485 return true;
1486 }
1487 }
1488 public void activateObject(Object obj) throws Exception {
1489 final boolean hurl;
1490 final boolean evenTest;
1491 final boolean oddTest;
1492 final int counter;
1493 synchronized(this) {
1494 hurl = exceptionOnActivate;
1495 evenTest = evenValid;
1496 oddTest = oddValid;
1497 counter = validateCounter++;
1498 }
1499 if (hurl) {
1500 if (!(counter%2 == 0 ? evenTest : oddTest)) {
1501 throw new Exception();
1502 }
1503 }
1504 }
1505 public void passivateObject(Object obj) throws Exception {
1506 final boolean hurl;
1507 synchronized(this) {
1508 hurl = exceptionOnPassivate;
1509 }
1510 if (hurl) {
1511 throw new Exception();
1512 }
1513 }
1514 int makeCounter = 0;
1515 int validateCounter = 0;
1516 int activeCount = 0;
1517 boolean evenValid = true;
1518 boolean oddValid = true;
1519 boolean exceptionOnPassivate = false;
1520 boolean exceptionOnActivate = false;
1521 boolean exceptionOnDestroy = false;
1522 boolean enableValidation = true;
1523 long destroyLatency = 0;
1524 long makeLatency = 0;
1525 long validateLatency = 0;
1526 int maxActive = Integer.MAX_VALUE;
1527
1528 public synchronized boolean isThrowExceptionOnActivate() {
1529 return exceptionOnActivate;
1530 }
1531
1532 public synchronized void setThrowExceptionOnActivate(boolean b) {
1533 exceptionOnActivate = b;
1534 }
1535
1536 public synchronized void setThrowExceptionOnDestroy(boolean b) {
1537 exceptionOnDestroy = b;
1538 }
1539
1540 public synchronized boolean isValidationEnabled() {
1541 return enableValidation;
1542 }
1543
1544 public synchronized void setValidationEnabled(boolean b) {
1545 enableValidation = b;
1546 }
1547
1548 public synchronized int getMakeCounter() {
1549 return makeCounter;
1550 }
1551
1552 private void doWait(long latency) {
1553 try {
1554 Thread.sleep(latency);
1555 } catch (InterruptedException ex) {
1556
1557 }
1558 }
1559 }
1560 protected boolean isLifo() {
1561 return true;
1562 }
1563
1564 protected boolean isFifo() {
1565 return false;
1566 }
1567
1568
1569
1570
1571
1572
1573 public void testBorrowObjectFairness() {
1574
1575 int numThreads = 30;
1576 int maxActive = 10;
1577
1578 SimpleFactory factory = new SimpleFactory();
1579 factory.setMaxActive(maxActive);
1580 pool.setFactory(factory);
1581 pool.setMaxActive(maxActive);
1582 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
1583 pool.setTimeBetweenEvictionRunsMillis(-1);
1584
1585
1586 TestThread[] threads = new TestThread[numThreads];
1587 for(int i=0;i<numThreads;i++) {
1588 threads[i] = new TestThread(pool, 1, 2000, false, String.valueOf(i % maxActive));
1589 Thread t = new Thread(threads[i]);
1590 t.start();
1591
1592 try {
1593 Thread.sleep(50);
1594 } catch (InterruptedException e) {
1595 fail(e.toString());
1596 }
1597 }
1598
1599
1600 for(int i=0;i<numThreads;i++) {
1601 while(!(threads[i]).complete()) {
1602 try {
1603 Thread.sleep(500L);
1604 } catch(InterruptedException e) {
1605
1606 }
1607 }
1608 if(threads[i].failed()) {
1609 fail("Thread "+i+" failed: "+threads[i]._error.toString());
1610 }
1611 }
1612 }
1613
1614
1615
1616
1617
1618 public void testBrokenFactoryShouldNotBlockPool() {
1619 int maxActive = 1;
1620
1621 SimpleFactory factory = new SimpleFactory();
1622 factory.setMaxActive(maxActive);
1623 pool.setFactory(factory);
1624 pool.setMaxActive(maxActive);
1625 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
1626 pool.setTestOnBorrow(true);
1627
1628
1629
1630 Object obj = null;
1631 Exception ex = null;
1632 factory.setValid(false);
1633 try {
1634 obj = pool.borrowObject();
1635 } catch (Exception e) {
1636 ex = e;
1637 }
1638
1639 assertNotNull(ex);
1640 assertTrue(ex instanceof NoSuchElementException);
1641 assertNull(obj);
1642
1643
1644 factory.setValid(true);
1645
1646
1647 try {
1648 obj = pool.borrowObject();
1649 } catch (Exception e1) {
1650 fail();
1651 }
1652 assertNotNull(obj);
1653 try {
1654 pool.returnObject(obj);
1655 } catch (Exception e) {
1656 fail();
1657 }
1658
1659 }
1660
1661
1662
1663
1664
1665 static class WaitingTestThread extends Thread {
1666 private final GenericObjectPool _pool;
1667 private final long _pause;
1668 private Throwable _thrown;
1669
1670 private long preborrow;
1671 private long postborrow;
1672 private long postreturn;
1673 private long ended;
1674 private String objectId;
1675
1676 public WaitingTestThread(GenericObjectPool pool, long pause) {
1677 _pool = pool;
1678 _pause = pause;
1679 _thrown = null;
1680 }
1681
1682 public void run() {
1683 try {
1684 preborrow = System.currentTimeMillis();
1685 Object obj = _pool.borrowObject();
1686 objectId=obj.toString();
1687 postborrow = System.currentTimeMillis();
1688 Thread.sleep(_pause);
1689 _pool.returnObject(obj);
1690 postreturn = System.currentTimeMillis();
1691 } catch (Exception e) {
1692 _thrown = e;
1693 } finally{
1694 ended = System.currentTimeMillis();
1695 }
1696 }
1697 }
1698
1699 private static final boolean DISPLAY_THREAD_DETAILS=
1700 Boolean.valueOf(System.getProperty("TestGenericObjectPool.display.thread.details", "false")).booleanValue();
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713 public void testMaxWaitMultiThreaded() throws Exception {
1714 final long maxWait = 500;
1715 final long holdTime = 2 * maxWait;
1716 final int threads = 10;
1717 SimpleFactory factory = new SimpleFactory();
1718 GenericObjectPool pool = new GenericObjectPool(factory);
1719 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
1720 pool.setMaxWait(maxWait);
1721 pool.setMaxActive(threads);
1722
1723 WaitingTestThread wtt[] = new WaitingTestThread[threads * 2];
1724 for(int i=0; i < wtt.length; i++){
1725 wtt[i] = new WaitingTestThread(pool,holdTime);
1726 }
1727 long origin = System.currentTimeMillis()-1000;
1728 for(int i=0; i < wtt.length; i++){
1729 wtt[i].start();
1730 }
1731 int failed = 0;
1732 for(int i=0; i < wtt.length; i++){
1733 wtt[i].join();
1734 if (wtt[i]._thrown != null){
1735 failed++;
1736 }
1737 }
1738 if (DISPLAY_THREAD_DETAILS || wtt.length/2 != failed){
1739 System.out.println(
1740 "MaxWait: "+maxWait
1741 +" HoldTime: "+holdTime
1742 + " MaxActive: "+threads
1743 +" Threads: "+wtt.length
1744 +" Failed: "+failed
1745 );
1746 for(int i=0; i < wtt.length; i++){
1747 WaitingTestThread wt = wtt[i];
1748 System.out.println(
1749 "Preborrow: "+(wt.preborrow-origin)
1750 + " Postborrow: "+(wt.postborrow != 0 ? wt.postborrow-origin : -1)
1751 + " BorrowTime: "+(wt.postborrow != 0 ? wt.postborrow-wt.preborrow : -1)
1752 + " PostReturn: "+(wt.postreturn != 0 ? wt.postreturn-origin : -1)
1753 + " Ended: "+(wt.ended-origin)
1754 + " ObjId: "+wt.objectId
1755 );
1756 }
1757 }
1758 assertEquals("Expected half the threads to fail",wtt.length/2,failed);
1759 }
1760
1761
1762
1763
1764
1765
1766
1767
1768 public void testMakeConcurrentWithReturn() throws Exception {
1769 SimpleFactory factory = new SimpleFactory();
1770 GenericObjectPool pool = new GenericObjectPool(factory);
1771 pool.setTestOnBorrow(true);
1772 factory.setValid(true);
1773
1774 WaitingTestThread thread1 = new WaitingTestThread(pool, 200);
1775 thread1.start();
1776 Thread.sleep(50);
1777
1778 factory.setValidateLatency(400);
1779 Object instance = pool.borrowObject();
1780
1781 assertEquals(factory.getMakeCounter(), pool.getNumIdle() + 1);
1782 pool.returnObject(instance);
1783 assertEquals(factory.getMakeCounter(), pool.getNumIdle());
1784 }
1785 }