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 junit.framework.Test;
21 import junit.framework.TestSuite;
22 import org.apache.commons.pool.KeyedObjectPool;
23 import org.apache.commons.pool.KeyedPoolableObjectFactory;
24 import org.apache.commons.pool.TestBaseKeyedObjectPool;
25 import org.apache.commons.pool.VisitTracker;
26 import org.apache.commons.pool.VisitTrackerFactory;
27
28 import java.io.PrintWriter;
29 import java.io.StringWriter;
30 import java.util.HashMap;
31 import java.util.NoSuchElementException;
32 import java.util.Random;
33
34
35
36
37
38 public class TestGenericKeyedObjectPool extends TestBaseKeyedObjectPool {
39 public TestGenericKeyedObjectPool(String testName) {
40 super(testName);
41 }
42
43 public static Test suite() {
44 return new TestSuite(TestGenericKeyedObjectPool.class);
45 }
46
47 protected KeyedObjectPool makeEmptyPool(int mincapacity) {
48 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(
49 new KeyedPoolableObjectFactory() {
50 HashMap map = new HashMap();
51 public Object makeObject(Object key) {
52 int counter = 0;
53 Integer Counter = (Integer)(map.get(key));
54 if(null != Counter) {
55 counter = Counter.intValue();
56 }
57 map.put(key,new Integer(counter + 1));
58 return String.valueOf(key) + String.valueOf(counter);
59 }
60 public void destroyObject(Object key, Object obj) { }
61 public boolean validateObject(Object key, Object obj) { return true; }
62 public void activateObject(Object key, Object obj) { }
63 public void passivateObject(Object key, Object obj) { }
64 }
65 );
66 pool.setMaxActive(mincapacity);
67 pool.setMaxIdle(mincapacity);
68 return pool;
69 }
70
71 protected KeyedObjectPool makeEmptyPool(KeyedPoolableObjectFactory factory) {
72 return new GenericKeyedObjectPool(factory);
73 }
74
75 protected Object getNthObject(Object key, int n) {
76 return String.valueOf(key) + String.valueOf(n);
77 }
78
79 protected Object makeKey(int n) {
80 return String.valueOf(n);
81 }
82
83 private GenericKeyedObjectPool pool = null;
84 private final Integer zero = new Integer(0);
85 private final Integer one = new Integer(1);
86 private final Integer two = new Integer(2);
87
88 public void setUp() throws Exception {
89 super.setUp();
90 pool = new GenericKeyedObjectPool(new SimpleFactory());
91 }
92
93 public void tearDown() throws Exception {
94 super.tearDown();
95 pool.clear();
96 pool.close();
97 pool = null;
98 }
99
100 public void testNegativeMaxActive() throws Exception {
101 pool.setMaxActive(-1);
102 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL);
103 Object obj = pool.borrowObject("");
104 assertEquals("0",obj);
105 pool.returnObject("",obj);
106 }
107
108 public void testNumActiveNumIdle2() throws Exception {
109 assertEquals(0,pool.getNumActive());
110 assertEquals(0,pool.getNumIdle());
111 assertEquals(0,pool.getNumActive("A"));
112 assertEquals(0,pool.getNumIdle("A"));
113 assertEquals(0,pool.getNumActive("B"));
114 assertEquals(0,pool.getNumIdle("B"));
115
116 Object objA0 = pool.borrowObject("A");
117 Object objB0 = pool.borrowObject("B");
118
119 assertEquals(2,pool.getNumActive());
120 assertEquals(0,pool.getNumIdle());
121 assertEquals(1,pool.getNumActive("A"));
122 assertEquals(0,pool.getNumIdle("A"));
123 assertEquals(1,pool.getNumActive("B"));
124 assertEquals(0,pool.getNumIdle("B"));
125
126 Object objA1 = pool.borrowObject("A");
127 Object objB1 = pool.borrowObject("B");
128
129 assertEquals(4,pool.getNumActive());
130 assertEquals(0,pool.getNumIdle());
131 assertEquals(2,pool.getNumActive("A"));
132 assertEquals(0,pool.getNumIdle("A"));
133 assertEquals(2,pool.getNumActive("B"));
134 assertEquals(0,pool.getNumIdle("B"));
135
136 pool.returnObject("A",objA0);
137 pool.returnObject("B",objB0);
138
139 assertEquals(2,pool.getNumActive());
140 assertEquals(2,pool.getNumIdle());
141 assertEquals(1,pool.getNumActive("A"));
142 assertEquals(1,pool.getNumIdle("A"));
143 assertEquals(1,pool.getNumActive("B"));
144 assertEquals(1,pool.getNumIdle("B"));
145
146 pool.returnObject("A",objA1);
147 pool.returnObject("B",objB1);
148
149 assertEquals(0,pool.getNumActive());
150 assertEquals(4,pool.getNumIdle());
151 assertEquals(0,pool.getNumActive("A"));
152 assertEquals(2,pool.getNumIdle("A"));
153 assertEquals(0,pool.getNumActive("B"));
154 assertEquals(2,pool.getNumIdle("B"));
155 }
156
157 public void testMaxIdle() throws Exception {
158 pool.setMaxActive(100);
159 pool.setMaxIdle(8);
160 Object[] active = new Object[100];
161 for(int i=0;i<100;i++) {
162 active[i] = pool.borrowObject("");
163 }
164 assertEquals(100,pool.getNumActive(""));
165 assertEquals(0,pool.getNumIdle(""));
166 for(int i=0;i<100;i++) {
167 pool.returnObject("",active[i]);
168 assertEquals(99 - i,pool.getNumActive(""));
169 assertEquals((i < 8 ? i+1 : 8),pool.getNumIdle(""));
170 }
171
172 for(int i=0;i<100;i++) {
173 active[i] = pool.borrowObject("a");
174 }
175 assertEquals(100,pool.getNumActive("a"));
176 assertEquals(0,pool.getNumIdle("a"));
177 for(int i=0;i<100;i++) {
178 pool.returnObject("a",active[i]);
179 assertEquals(99 - i,pool.getNumActive("a"));
180 assertEquals((i < 8 ? i+1 : 8),pool.getNumIdle("a"));
181 }
182
183
184 assertEquals(16, pool.getNumIdle());
185
186 assertEquals(8, pool.getNumIdle(""));
187 assertEquals(8, pool.getNumIdle("a"));
188
189 }
190
191 public void testMaxActive() throws Exception {
192 pool.setMaxActive(3);
193 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL);
194
195 pool.borrowObject("");
196 pool.borrowObject("");
197 pool.borrowObject("");
198 try {
199 pool.borrowObject("");
200 fail("Expected NoSuchElementException");
201 } catch(NoSuchElementException e) {
202
203 }
204 }
205
206 public void testMaxActiveZero() throws Exception {
207 pool.setMaxActive(0);
208 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
209
210 try {
211 pool.borrowObject("a");
212 fail("Expected NoSuchElementException");
213 } catch(NoSuchElementException e) {
214
215 }
216 }
217
218 public void testWhenExhaustedGrow() throws Exception {
219 pool.setMaxActive(1);
220 pool.setMaxTotal(1);
221 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);
222 for (int i = 0; i < 10; i++) {
223 pool.borrowObject("a");
224 }
225 }
226
227 public void testMaxTotal() throws Exception {
228 pool.setMaxActive(2);
229 pool.setMaxTotal(3);
230 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL);
231
232 Object o1 = pool.borrowObject("a");
233 assertNotNull(o1);
234 Object o2 = pool.borrowObject("a");
235 assertNotNull(o2);
236 Object o3 = pool.borrowObject("b");
237 assertNotNull(o3);
238 try {
239 pool.borrowObject("c");
240 fail("Expected NoSuchElementException");
241 } catch(NoSuchElementException e) {
242
243 }
244
245 assertEquals(0, pool.getNumIdle());
246
247 pool.returnObject("b", o3);
248 assertEquals(1, pool.getNumIdle());
249 assertEquals(1, pool.getNumIdle("b"));
250
251 Object o4 = pool.borrowObject("b");
252 assertNotNull(o4);
253 assertEquals(0, pool.getNumIdle());
254 assertEquals(0, pool.getNumIdle("b"));
255
256 pool.setMaxTotal(4);
257 Object o5 = pool.borrowObject("b");
258 assertNotNull(o5);
259
260 assertEquals(2, pool.getNumActive("a"));
261 assertEquals(2, pool.getNumActive("b"));
262 assertEquals(pool.getMaxTotal(),
263 pool.getNumActive("b") + pool.getNumActive("b"));
264 assertEquals(pool.getNumActive(),
265 pool.getMaxTotal());
266 }
267
268 public void testMaxTotalZero() throws Exception {
269 pool.setMaxTotal(0);
270 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
271
272 try {
273 pool.borrowObject("a");
274 fail("Expected NoSuchElementException");
275 } catch(NoSuchElementException e) {
276
277 }
278 }
279
280 public void testMaxTotalLRU() throws Exception {
281 pool.setMaxActive(2);
282 pool.setMaxTotal(3);
283
284
285 Object o1 = pool.borrowObject("a");
286 assertNotNull(o1);
287 pool.returnObject("a", o1);
288 Thread.sleep(25);
289
290 Object o2 = pool.borrowObject("b");
291 assertNotNull(o2);
292 pool.returnObject("b", o2);
293 Thread.sleep(25);
294
295 Object o3 = pool.borrowObject("c");
296 assertNotNull(o3);
297 pool.returnObject("c", o3);
298 Thread.sleep(25);
299
300 Object o4 = pool.borrowObject("a");
301 assertNotNull(o4);
302 pool.returnObject("a", o4);
303 Thread.sleep(25);
304
305 assertSame(o1, o4);
306
307
308 Object o5 = pool.borrowObject("d");
309 assertNotNull(o5);
310 pool.returnObject("d", o5);
311 Thread.sleep(25);
312
313
314
315 Object o6 = pool.borrowObject("b");
316 assertNotNull(o6);
317 pool.returnObject("b", o6);
318
319 assertNotSame(o1, o6);
320
321
322 Object o7 = pool.borrowObject("a");
323 assertNotNull(o7);
324 pool.returnObject("a", o7);
325
326 assertSame(o4, o7);
327 }
328
329 public void testSettersAndGetters() throws Exception {
330 GenericKeyedObjectPool pool = new GenericKeyedObjectPool();
331 {
332 pool.setFactory(new SimpleFactory());
333 }
334 {
335 pool.setMaxActive(123);
336 assertEquals(123,pool.getMaxActive());
337 }
338 {
339 pool.setMaxIdle(12);
340 assertEquals(12,pool.getMaxIdle());
341 }
342 {
343 pool.setMaxWait(1234L);
344 assertEquals(1234L,pool.getMaxWait());
345 }
346 {
347 pool.setMinEvictableIdleTimeMillis(12345L);
348 assertEquals(12345L,pool.getMinEvictableIdleTimeMillis());
349 }
350 {
351 pool.setNumTestsPerEvictionRun(11);
352 assertEquals(11,pool.getNumTestsPerEvictionRun());
353 }
354 {
355 pool.setTestOnBorrow(true);
356 assertTrue(pool.getTestOnBorrow());
357 pool.setTestOnBorrow(false);
358 assertTrue(!pool.getTestOnBorrow());
359 }
360 {
361 pool.setTestOnReturn(true);
362 assertTrue(pool.getTestOnReturn());
363 pool.setTestOnReturn(false);
364 assertTrue(!pool.getTestOnReturn());
365 }
366 {
367 pool.setTestWhileIdle(true);
368 assertTrue(pool.getTestWhileIdle());
369 pool.setTestWhileIdle(false);
370 assertTrue(!pool.getTestWhileIdle());
371 }
372 {
373 pool.setTimeBetweenEvictionRunsMillis(11235L);
374 assertEquals(11235L,pool.getTimeBetweenEvictionRunsMillis());
375 }
376 {
377 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_BLOCK);
378 assertEquals(GenericObjectPool.WHEN_EXHAUSTED_BLOCK,pool.getWhenExhaustedAction());
379 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL);
380 assertEquals(GenericObjectPool.WHEN_EXHAUSTED_FAIL,pool.getWhenExhaustedAction());
381 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_GROW);
382 assertEquals(GenericObjectPool.WHEN_EXHAUSTED_GROW,pool.getWhenExhaustedAction());
383 }
384 }
385
386 public void testEviction() throws Exception {
387 pool.setMaxIdle(500);
388 pool.setMaxActive(500);
389 pool.setNumTestsPerEvictionRun(100);
390 pool.setMinEvictableIdleTimeMillis(250L);
391 pool.setTimeBetweenEvictionRunsMillis(500L);
392
393 Object[] active = new Object[500];
394 for(int i=0;i<500;i++) {
395 active[i] = pool.borrowObject("");
396 }
397 for(int i=0;i<500;i++) {
398 pool.returnObject("",active[i]);
399 }
400
401 try { Thread.sleep(1000L); } catch(InterruptedException e) { }
402 assertTrue("Should be less than 500 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 500);
403 try { Thread.sleep(600L); } catch(InterruptedException e) { }
404 assertTrue("Should be less than 400 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 400);
405 try { Thread.sleep(600L); } catch(InterruptedException e) { }
406 assertTrue("Should be less than 300 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 300);
407 try { Thread.sleep(600L); } catch(InterruptedException e) { }
408 assertTrue("Should be less than 200 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 200);
409 try { Thread.sleep(600L); } catch(InterruptedException e) { }
410 assertTrue("Should be less than 100 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 100);
411 try { Thread.sleep(600L); } catch(InterruptedException e) { }
412 assertEquals("Should be zero idle, found " + pool.getNumIdle(""),0,pool.getNumIdle(""));
413
414 for(int i=0;i<500;i++) {
415 active[i] = pool.borrowObject("");
416 }
417 for(int i=0;i<500;i++) {
418 pool.returnObject("",active[i]);
419 }
420
421 try { Thread.sleep(1000L); } catch(InterruptedException e) { }
422 assertTrue("Should be less than 500 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 500);
423 try { Thread.sleep(600L); } catch(InterruptedException e) { }
424 assertTrue("Should be less than 400 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 400);
425 try { Thread.sleep(600L); } catch(InterruptedException e) { }
426 assertTrue("Should be less than 300 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 300);
427 try { Thread.sleep(600L); } catch(InterruptedException e) { }
428 assertTrue("Should be less than 200 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 200);
429 try { Thread.sleep(600L); } catch(InterruptedException e) { }
430 assertTrue("Should be less than 100 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 100);
431 try { Thread.sleep(600L); } catch(InterruptedException e) { }
432 assertEquals("Should be zero idle, found " + pool.getNumIdle(""),0,pool.getNumIdle(""));
433 }
434
435 public void testEviction2() throws Exception {
436 pool.setMaxIdle(500);
437 pool.setMaxActive(500);
438 pool.setNumTestsPerEvictionRun(100);
439 pool.setMinEvictableIdleTimeMillis(500L);
440 pool.setTimeBetweenEvictionRunsMillis(500L);
441
442 Object[] active = new Object[500];
443 Object[] active2 = new Object[500];
444 for(int i=0;i<500;i++) {
445 active[i] = pool.borrowObject("");
446 active2[i] = pool.borrowObject("2");
447 }
448 for(int i=0;i<500;i++) {
449 pool.returnObject("",active[i]);
450 pool.returnObject("2",active2[i]);
451 }
452
453 try { Thread.sleep(1100L); } catch(InterruptedException e) { }
454 assertTrue("Should be less than 1000 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 1000);
455 try { Thread.sleep(600L); } catch(InterruptedException e) { }
456 assertTrue("Should be less than 900 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 900);
457 try { Thread.sleep(600L); } catch(InterruptedException e) { }
458 assertTrue("Should be less than 800 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 800);
459 try { Thread.sleep(600L); } catch(InterruptedException e) { }
460 assertTrue("Should be less than 700 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 700);
461 try { Thread.sleep(600L); } catch(InterruptedException e) { }
462 assertTrue("Should be less than 600 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 600);
463 try { Thread.sleep(600L); } catch(InterruptedException e) { }
464 assertTrue("Should be less than 500 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 500);
465 try { Thread.sleep(600L); } catch(InterruptedException e) { }
466 assertTrue("Should be less than 400 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 400);
467 try { Thread.sleep(600L); } catch(InterruptedException e) { }
468 assertTrue("Should be less than 300 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 300);
469 try { Thread.sleep(600L); } catch(InterruptedException e) { }
470 assertTrue("Should be less than 200 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 200);
471 try { Thread.sleep(600L); } catch(InterruptedException e) { }
472 assertTrue("Should be less than 100 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 100);
473 try { Thread.sleep(600L); } catch(InterruptedException e) { }
474 assertEquals("Should be zero idle, found " + pool.getNumIdle(),0,pool.getNumIdle());
475 }
476
477
478
479
480
481
482 public void runTestThreads(int numThreads, int iterations, int delay) {
483 TestThread[] threads = new TestThread[numThreads];
484 for(int i=0;i<numThreads;i++) {
485 threads[i] = new TestThread(pool,iterations,delay);
486 Thread t = new Thread(threads[i]);
487 t.start();
488 }
489 for(int i=0;i<numThreads;i++) {
490 while(!(threads[i]).complete()) {
491 try {
492 Thread.sleep(500L);
493 } catch(InterruptedException e) {
494
495 }
496 }
497 if(threads[i].failed()) {
498 fail("Thread failed: "+i+"\n"+getExceptionTrace(threads[i]._exception));
499 }
500 }
501 }
502
503 public void testThreaded1() throws Exception {
504 pool.setMaxActive(15);
505 pool.setMaxIdle(15);
506 pool.setMaxWait(1000L);
507 runTestThreads(20, 100, 50);
508 }
509
510
511
512
513
514
515 public void testMaxTotalInvariant() throws Exception {
516 int maxTotal = 15;
517 SimpleFactory factory = new SimpleFactory();
518 factory.setEvenValid(false);
519 factory.setDestroyLatency(100);
520 factory.setMaxActive(maxTotal);
521 factory.setValidationEnabled(true);
522 pool = new GenericKeyedObjectPool(factory);
523 pool.setMaxTotal(maxTotal);
524 pool.setMaxIdle(-1);
525 pool.setTestOnReturn(true);
526 pool.setMaxWait(10000L);
527 runTestThreads(5, 10, 50);
528 }
529
530 public void testMinIdle() throws Exception {
531 pool.setMaxIdle(500);
532 pool.setMinIdle(5);
533 pool.setMaxActive(10);
534 pool.setNumTestsPerEvictionRun(0);
535 pool.setMinEvictableIdleTimeMillis(50L);
536 pool.setTimeBetweenEvictionRunsMillis(100L);
537 pool.setTestWhileIdle(true);
538
539
540
541 String key = "A";
542
543 pool.preparePool(key, true);
544
545 try { Thread.sleep(150L); } catch(InterruptedException e) { }
546 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
547
548 Object[] active = new Object[5];
549 active[0] = pool.borrowObject(key);
550
551 try { Thread.sleep(150L); } catch(InterruptedException e) { }
552 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
553
554 for(int i=1 ; i<5 ; i++) {
555 active[i] = pool.borrowObject(key);
556 }
557
558 try { Thread.sleep(150L); } catch(InterruptedException e) { }
559 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
560
561 for(int i=0 ; i<5 ; i++) {
562 pool.returnObject(key, active[i]);
563 }
564
565 try { Thread.sleep(150L); } catch(InterruptedException e) { }
566 assertTrue("Should be 10 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 10);
567 }
568
569 public void testMinIdleMaxActive() throws Exception {
570 pool.setMaxIdle(500);
571 pool.setMinIdle(5);
572 pool.setMaxActive(10);
573 pool.setNumTestsPerEvictionRun(0);
574 pool.setMinEvictableIdleTimeMillis(50L);
575 pool.setTimeBetweenEvictionRunsMillis(100L);
576 pool.setTestWhileIdle(true);
577
578 String key = "A";
579
580 pool.preparePool(key, true);
581 assertTrue("Should be 5 idle, found " +
582 pool.getNumIdle(),pool.getNumIdle() == 5);
583
584 try { Thread.sleep(150L); } catch(InterruptedException e) { }
585 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
586
587 Object[] active = new Object[10];
588
589 try { Thread.sleep(150L); } catch(InterruptedException e) { }
590 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
591
592 for(int i=0 ; i<5 ; i++) {
593 active[i] = pool.borrowObject(key);
594 }
595
596 try { Thread.sleep(150L); } catch(InterruptedException e) { }
597 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
598
599 for(int i=0 ; i<5 ; i++) {
600 pool.returnObject(key, active[i]);
601 }
602
603 try { Thread.sleep(150L); } catch(InterruptedException e) { }
604 assertTrue("Should be 10 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 10);
605
606 for(int i=0 ; i<10 ; i++) {
607 active[i] = pool.borrowObject(key);
608 }
609
610 try { Thread.sleep(150L); } catch(InterruptedException e) { }
611 assertTrue("Should be 0 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 0);
612
613 for(int i=0 ; i<10 ; i++) {
614 pool.returnObject(key, active[i]);
615 }
616
617 try { Thread.sleep(150L); } catch(InterruptedException e) { }
618 assertTrue("Should be 10 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 10);
619 }
620
621 public void testMinIdleNoPopulateImmediately() throws Exception {
622 pool.setMaxIdle(500);
623 pool.setMinIdle(5);
624 pool.setMaxActive(10);
625 pool.setNumTestsPerEvictionRun(0);
626 pool.setMinEvictableIdleTimeMillis(50L);
627 pool.setTimeBetweenEvictionRunsMillis(1000L);
628 pool.setTestWhileIdle(true);
629
630
631
632 String key = "A";
633
634 pool.preparePool(key, false);
635
636 assertTrue("Should be 0 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 0);
637
638 try { Thread.sleep(1500L); } catch(InterruptedException e) { }
639 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
640 }
641
642 public void testMinIdleNoPreparePool() throws Exception {
643 pool.setMaxIdle(500);
644 pool.setMinIdle(5);
645 pool.setMaxActive(10);
646 pool.setNumTestsPerEvictionRun(0);
647 pool.setMinEvictableIdleTimeMillis(50L);
648 pool.setTimeBetweenEvictionRunsMillis(100L);
649 pool.setTestWhileIdle(true);
650
651
652
653 String key = "A";
654
655 try { Thread.sleep(150L); } catch(InterruptedException e) { }
656 assertTrue("Should be 0 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 0);
657
658 Object active = pool.borrowObject(key);
659 assertNotNull(active);
660
661 try { Thread.sleep(150L); } catch(InterruptedException e) { }
662 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5);
663 }
664
665 public void testFIFO() throws Exception {
666 pool.setLifo(false);
667 final Object key = "key";
668 pool.addObject(key);
669 pool.addObject(key);
670 pool.addObject(key);
671 assertEquals("Oldest", "key0", pool.borrowObject(key));
672 assertEquals("Middle", "key1", pool.borrowObject(key));
673 assertEquals("Youngest", "key2", pool.borrowObject(key));
674 assertEquals("new-3", "key3", pool.borrowObject(key));
675 pool.returnObject(key, "r");
676 assertEquals("returned", "r", pool.borrowObject(key));
677 assertEquals("new-4", "key4", pool.borrowObject(key));
678 }
679
680 public void testLIFO() throws Exception {
681 pool.setLifo(true);
682 final Object key = "key";
683 pool.addObject(key);
684 pool.addObject(key);
685 pool.addObject(key);
686 assertEquals("Youngest", "key2", pool.borrowObject(key));
687 assertEquals("Middle", "key1", pool.borrowObject(key));
688 assertEquals("Oldest", "key0", pool.borrowObject(key));
689 assertEquals("new-3", "key3", pool.borrowObject(key));
690 pool.returnObject(key, "r");
691 assertEquals("returned", "r", pool.borrowObject(key));
692 assertEquals("new-4", "key4", pool.borrowObject(key));
693 }
694
695
696
697
698
699
700
701 public void testEvictionOrder() throws Exception {
702 checkEvictionOrder(false);
703 checkEvictionOrder(true);
704 }
705
706 private void checkEvictionOrder(boolean lifo) throws Exception {
707 SimpleFactory factory = new SimpleFactory();
708 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory);
709 pool.setNumTestsPerEvictionRun(2);
710 pool.setMinEvictableIdleTimeMillis(100);
711 pool.setLifo(lifo);
712
713 for (int i = 0; i < 3; i ++) {
714 Integer key = new Integer(i);
715 for (int j = 0; j < 5; j++) {
716 pool.addObject(key);
717 }
718 }
719
720
721 Thread.sleep(200);
722
723
724
725
726
727
728
729
730
731 pool.evict();
732 assertEquals(3, pool.getNumIdle(zero));
733 Object obj = pool.borrowObject(zero);
734 assertTrue(lifo ? obj.equals("04") : obj.equals("02"));
735 assertEquals(2, pool.getNumIdle(zero));
736 obj = pool.borrowObject(zero);
737 assertTrue(obj.equals("03"));
738 assertEquals(1, pool.getNumIdle(zero));
739
740 pool.evict();
741 assertEquals(0, pool.getNumIdle(zero));
742 assertEquals(4, pool.getNumIdle(one));
743 obj = pool.borrowObject(one);
744 assertTrue(lifo ? obj.equals("19") : obj.equals("16"));
745 assertEquals(3, pool.getNumIdle(one));
746 obj = pool.borrowObject(one);
747 assertTrue(lifo ? obj.equals("18") : obj.equals("17"));
748 assertEquals(2, pool.getNumIdle(one));
749
750 pool.evict();
751 assertEquals(0, pool.getNumIdle(one));
752 pool.evict();
753 assertEquals(3, pool.getNumIdle(two));
754 obj = pool.borrowObject(two);
755 assertTrue(lifo ? obj.equals("214") : obj.equals("212"));
756 assertEquals(2, pool.getNumIdle(two));
757 pool.evict();
758 assertEquals(0, pool.getNumIdle(two));
759
760 pool.evict();
761 pool.evict();
762
763
764 pool.setMinEvictableIdleTimeMillis(500);
765 factory.counter = 0;
766 for (int i = 0; i < 3; i ++) {
767 Integer key = new Integer(i);
768 for (int j = 0; j < 5; j++) {
769 pool.addObject(key);
770 }
771 Thread.sleep(200);
772 }
773
774
775 pool.evict();
776 assertEquals(3, pool.getNumIdle(zero));
777 pool.evict();
778 assertEquals(1, pool.getNumIdle(zero));
779 pool.evict();
780 assertEquals(0, pool.getNumIdle(zero));
781 assertEquals(5, pool.getNumIdle(one));
782 assertEquals(5, pool.getNumIdle(two));
783 pool.evict();
784 assertEquals(5, pool.getNumIdle(one));
785 assertEquals(5, pool.getNumIdle(two));
786 pool.evict();
787 assertEquals(5, pool.getNumIdle(one));
788 assertEquals(5, pool.getNumIdle(two));
789 pool.evict();
790 assertEquals(5, pool.getNumIdle(one));
791 assertEquals(5, pool.getNumIdle(two));
792 pool.evict();
793 assertEquals(5, pool.getNumIdle(one));
794 assertEquals(5, pool.getNumIdle(two));
795 pool.evict();
796 assertEquals(5, pool.getNumIdle(one));
797 assertEquals(5, pool.getNumIdle(two));
798 Thread.sleep(200);
799 pool.evict();
800 assertEquals(3, pool.getNumIdle(one));
801 assertEquals(5, pool.getNumIdle(two));
802 obj = pool.borrowObject(one);
803 assertTrue(lifo ? obj.equals("19") : obj.equals("15"));
804 }
805
806
807
808
809
810
811 public void testEvictorVisiting() throws Exception {
812 checkEvictorVisiting(true);
813 checkEvictorVisiting(false);
814 }
815
816 private void checkEvictorVisiting(boolean lifo) throws Exception {
817 VisitTrackerFactory factory = new VisitTrackerFactory();
818 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory);
819 pool.setNumTestsPerEvictionRun(2);
820 pool.setMinEvictableIdleTimeMillis(-1);
821 pool.setTestWhileIdle(true);
822 pool.setLifo(lifo);
823 pool.setTestOnReturn(false);
824 pool.setTestOnBorrow(false);
825 for (int i = 0; i < 3; i ++) {
826 factory.resetId();
827 Integer key = new Integer(i);
828 for (int j = 0; j < 8; j++) {
829 pool.addObject(key);
830 }
831 }
832 pool.evict();
833 Object obj = pool.borrowObject(zero);
834 pool.returnObject(zero, obj);
835 obj = pool.borrowObject(zero);
836 pool.returnObject(zero, obj);
837
838
839
840 pool.evict();
841 for (int i = 0; i < 8; i++) {
842 VisitTracker tracker = (VisitTracker) pool.borrowObject(zero);
843 if (tracker.getId() >= 4) {
844 assertEquals("Unexpected instance visited " + tracker.getId(),
845 0, tracker.getValidateCount());
846 } else {
847 assertEquals("Instance " + tracker.getId() +
848 " visited wrong number of times.",
849 1, tracker.getValidateCount());
850 }
851 }
852
853
854 pool.setNumTestsPerEvictionRun(3);
855
856 pool.evict();
857 pool.evict();
858
859 obj = pool.borrowObject(one);
860 pool.returnObject(one, obj);
861 obj = pool.borrowObject(one);
862 pool.returnObject(one, obj);
863 obj = pool.borrowObject(one);
864 pool.returnObject(one, obj);
865
866
867
868
869 pool.evict();
870
871
872 pool.evict();
873
874
875 pool.evict();
876
877
878 pool.evict();
879
880
881 for (int i = 0; i < 8; i++) {
882 VisitTracker tracker = (VisitTracker) pool.borrowObject(one);
883 if ((lifo && tracker.getId() > 0) ||
884 (!lifo && tracker.getId() > 2)) {
885 assertEquals("Instance " + tracker.getId() +
886 " visited wrong number of times.",
887 1, tracker.getValidateCount());
888 } else {
889 assertEquals("Instance " + tracker.getId() +
890 " visited wrong number of times.",
891 2, tracker.getValidateCount());
892 }
893 }
894
895
896
897 int[] smallPrimes = {2, 3, 5, 7};
898 Random random = new Random();
899 random.setSeed(System.currentTimeMillis());
900 pool.setMaxIdle(-1);
901 for (int i = 0; i < smallPrimes.length; i++) {
902 pool.setNumTestsPerEvictionRun(smallPrimes[i]);
903 for (int j = 0; j < 5; j++) {
904 pool.clear();
905 assertEquals("NumIdle should be zero after clearing the pool",0,pool.getNumIdle());
906 int zeroLength = 10 + random.nextInt(20);
907 for (int k = 0; k < zeroLength; k++) {
908 pool.addObject(zero);
909 }
910 int oneLength = 10 + random.nextInt(20);
911 for (int k = 0; k < oneLength; k++) {
912 pool.addObject(one);
913 }
914 int twoLength = 10 + random.nextInt(20);
915 for (int k = 0; k < twoLength; k++) {
916 pool.addObject(two);
917 }
918
919
920 int runs = 10 + random.nextInt(50);
921 for (int k = 0; k < runs; k++) {
922 pool.evict();
923 }
924
925
926 int totalInstances = zeroLength + oneLength + twoLength;
927
928
929 int cycleCount = (runs * pool.getNumTestsPerEvictionRun())
930 / totalInstances;
931
932
933
934 VisitTracker tracker = null;
935 int visitCount = 0;
936 for (int k = 0; k < zeroLength; k++) {
937 tracker = (VisitTracker) pool.borrowObject(zero);
938 visitCount = tracker.getValidateCount();
939 if (visitCount < cycleCount || visitCount > cycleCount + 1){
940 fail(formatSettings("ZERO", "runs", runs, "lifo", lifo, "i", i, "j", j,
941 "k", k, "visitCount", visitCount, "cycleCount", cycleCount,
942 "totalInstances", totalInstances, zeroLength, oneLength, twoLength));
943 }
944 }
945 for (int k = 0; k < oneLength; k++) {
946 tracker = (VisitTracker) pool.borrowObject(one);
947 visitCount = tracker.getValidateCount();
948 if (visitCount < cycleCount || visitCount > cycleCount + 1){
949 fail(formatSettings("ONE", "runs", runs, "lifo", lifo, "i", i, "j", j,
950 "k", k, "visitCount", visitCount, "cycleCount", cycleCount,
951 "totalInstances", totalInstances, zeroLength, oneLength, twoLength));
952 }
953 }
954 int visits[] = new int[twoLength];
955 for (int k = 0; k < twoLength; k++) {
956 tracker = (VisitTracker) pool.borrowObject(two);
957 visitCount = tracker.getValidateCount();
958 visits[k] = visitCount;
959 if (visitCount < cycleCount || visitCount > cycleCount + 1){
960 StringBuffer sb = new StringBuffer("Visits:");
961 for (int l = 0; l <= k; l++){
962 sb.append(visits[l]).append(' ');
963 }
964 fail(formatSettings("TWO "+sb.toString(), "runs", runs, "lifo", lifo, "i", i, "j", j,
965 "k", k, "visitCount", visitCount, "cycleCount", cycleCount,
966 "totalInstances", totalInstances, zeroLength, oneLength, twoLength));
967 }
968 }
969 }
970 }
971 }
972
973 public void testConstructors() {
974
975
976 int maxActive = 1;
977 int maxIdle = 2;
978 long maxWait = 3;
979 int minIdle = 4;
980 int maxTotal = 5;
981 long minEvictableIdleTimeMillis = 6;
982 int numTestsPerEvictionRun = 7;
983 boolean testOnBorrow = true;
984 boolean testOnReturn = true;
985 boolean testWhileIdle = true;
986 long timeBetweenEvictionRunsMillis = 8;
987 byte whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW;
988 boolean lifo = false;
989
990 GenericKeyedObjectPool pool = new GenericKeyedObjectPool();
991 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE, pool.getMaxActive());
992 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_IDLE, pool.getMaxIdle());
993 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_WAIT, pool.getMaxWait());
994 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle());
995 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal());
996 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
997 pool.getMinEvictableIdleTimeMillis());
998 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
999 pool.getNumTestsPerEvictionRun());
1000 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,
1001 pool.getTestOnBorrow());
1002 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,
1003 pool.getTestOnReturn());
1004 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE,
1005 pool.getTestWhileIdle());
1006 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
1007 pool.getTimeBetweenEvictionRunsMillis());
1008 assertEquals(GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
1009 pool.getWhenExhaustedAction());
1010 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo());
1011
1012 GenericKeyedObjectPool.Config config = new GenericKeyedObjectPool.Config();
1013 config.lifo = lifo;
1014 config.maxActive = maxActive;
1015 config.maxIdle = maxIdle;
1016 config.minIdle = minIdle;
1017 config.maxTotal = maxTotal;
1018 config.maxWait = maxWait;
1019 config.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
1020 config.numTestsPerEvictionRun = numTestsPerEvictionRun;
1021 config.testOnBorrow = testOnBorrow;
1022 config.testOnReturn = testOnReturn;
1023 config.testWhileIdle = testWhileIdle;
1024 config.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
1025 config.whenExhaustedAction = whenExhaustedAction;
1026 pool = new GenericKeyedObjectPool(null, config);
1027 assertEquals(maxActive, pool.getMaxActive());
1028 assertEquals(maxIdle, pool.getMaxIdle());
1029 assertEquals(maxWait, pool.getMaxWait());
1030 assertEquals(minIdle, pool.getMinIdle());
1031 assertEquals(maxTotal, pool.getMaxTotal());
1032 assertEquals(minEvictableIdleTimeMillis,
1033 pool.getMinEvictableIdleTimeMillis());
1034 assertEquals(numTestsPerEvictionRun, pool.getNumTestsPerEvictionRun());
1035 assertEquals(testOnBorrow,pool.getTestOnBorrow());
1036 assertEquals(testOnReturn,pool.getTestOnReturn());
1037 assertEquals(testWhileIdle,pool.getTestWhileIdle());
1038 assertEquals(timeBetweenEvictionRunsMillis,
1039 pool.getTimeBetweenEvictionRunsMillis());
1040 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction());
1041 assertEquals(lifo, pool.getLifo());
1042
1043 pool = new GenericKeyedObjectPool(null, maxActive);
1044 assertEquals(maxActive, pool.getMaxActive());
1045 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_IDLE, pool.getMaxIdle());
1046 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_WAIT, pool.getMaxWait());
1047 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle());
1048 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal());
1049 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
1050 pool.getMinEvictableIdleTimeMillis());
1051 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
1052 pool.getNumTestsPerEvictionRun());
1053 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,
1054 pool.getTestOnBorrow());
1055 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,
1056 pool.getTestOnReturn());
1057 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE,
1058 pool.getTestWhileIdle());
1059 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
1060 pool.getTimeBetweenEvictionRunsMillis());
1061 assertEquals(GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION,
1062 pool.getWhenExhaustedAction());
1063 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo());
1064
1065 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction, maxWait);
1066 assertEquals(maxActive, pool.getMaxActive());
1067 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_IDLE, pool.getMaxIdle());
1068 assertEquals(maxWait, pool.getMaxWait());
1069 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle());
1070 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal());
1071 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
1072 pool.getMinEvictableIdleTimeMillis());
1073 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
1074 pool.getNumTestsPerEvictionRun());
1075 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,
1076 pool.getTestOnBorrow());
1077 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,
1078 pool.getTestOnReturn());
1079 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE,
1080 pool.getTestWhileIdle());
1081 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
1082 pool.getTimeBetweenEvictionRunsMillis());
1083 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction());
1084 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo());
1085
1086 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction,
1087 maxWait, testOnBorrow, testOnReturn);
1088 assertEquals(maxActive, pool.getMaxActive());
1089 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_IDLE, pool.getMaxIdle());
1090 assertEquals(maxWait, pool.getMaxWait());
1091 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle());
1092 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal());
1093 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
1094 pool.getMinEvictableIdleTimeMillis());
1095 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
1096 pool.getNumTestsPerEvictionRun());
1097 assertEquals(testOnBorrow,pool.getTestOnBorrow());
1098 assertEquals(testOnReturn,pool.getTestOnReturn());
1099 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE,
1100 pool.getTestWhileIdle());
1101 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
1102 pool.getTimeBetweenEvictionRunsMillis());
1103 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction());
1104 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo());
1105
1106 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction,
1107 maxWait, maxIdle);
1108 assertEquals(maxActive, pool.getMaxActive());
1109 assertEquals(maxIdle, pool.getMaxIdle());
1110 assertEquals(maxWait, pool.getMaxWait());
1111 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle());
1112 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal());
1113 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
1114 pool.getMinEvictableIdleTimeMillis());
1115 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
1116 pool.getNumTestsPerEvictionRun());
1117 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW,
1118 pool.getTestOnBorrow());
1119 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN,
1120 pool.getTestOnReturn());
1121 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE,
1122 pool.getTestWhileIdle());
1123 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
1124 pool.getTimeBetweenEvictionRunsMillis());
1125 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction());
1126 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo());
1127
1128 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction,
1129 maxWait, maxIdle, testOnBorrow, testOnReturn);
1130 assertEquals(maxActive, pool.getMaxActive());
1131 assertEquals(maxIdle, pool.getMaxIdle());
1132 assertEquals(maxWait, pool.getMaxWait());
1133 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle());
1134 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal());
1135 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
1136 pool.getMinEvictableIdleTimeMillis());
1137 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN,
1138 pool.getNumTestsPerEvictionRun());
1139 assertEquals(testOnBorrow, pool.getTestOnBorrow());
1140 assertEquals(testOnReturn, pool.getTestOnReturn());
1141 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE,
1142 pool.getTestWhileIdle());
1143 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
1144 pool.getTimeBetweenEvictionRunsMillis());
1145 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction());
1146 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo());
1147
1148 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction,
1149 maxWait, maxIdle, testOnBorrow, testOnReturn,
1150 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
1151 minEvictableIdleTimeMillis, testWhileIdle);
1152 assertEquals(maxActive, pool.getMaxActive());
1153 assertEquals(maxIdle, pool.getMaxIdle());
1154 assertEquals(maxWait, pool.getMaxWait());
1155 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle());
1156 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal());
1157 assertEquals(minEvictableIdleTimeMillis,
1158 pool.getMinEvictableIdleTimeMillis());
1159 assertEquals(numTestsPerEvictionRun,
1160 pool.getNumTestsPerEvictionRun());
1161 assertEquals(testOnBorrow, pool.getTestOnBorrow());
1162 assertEquals(testOnReturn, pool.getTestOnReturn());
1163 assertEquals(testWhileIdle,
1164 pool.getTestWhileIdle());
1165 assertEquals(timeBetweenEvictionRunsMillis,
1166 pool.getTimeBetweenEvictionRunsMillis());
1167 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction());
1168 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo());
1169
1170 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction,
1171 maxWait, maxIdle, maxTotal, testOnBorrow, testOnReturn,
1172 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
1173 minEvictableIdleTimeMillis, testWhileIdle);
1174 assertEquals(maxActive, pool.getMaxActive());
1175 assertEquals(maxIdle, pool.getMaxIdle());
1176 assertEquals(maxWait, pool.getMaxWait());
1177 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle());
1178 assertEquals(maxTotal, pool.getMaxTotal());
1179 assertEquals(minEvictableIdleTimeMillis,
1180 pool.getMinEvictableIdleTimeMillis());
1181 assertEquals(numTestsPerEvictionRun,
1182 pool.getNumTestsPerEvictionRun());
1183 assertEquals(testOnBorrow, pool.getTestOnBorrow());
1184 assertEquals(testOnReturn, pool.getTestOnReturn());
1185 assertEquals(testWhileIdle,
1186 pool.getTestWhileIdle());
1187 assertEquals(timeBetweenEvictionRunsMillis,
1188 pool.getTimeBetweenEvictionRunsMillis());
1189 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction());
1190 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo());
1191
1192 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction,
1193 maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn,
1194 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
1195 minEvictableIdleTimeMillis, testWhileIdle);
1196 assertEquals(maxActive, pool.getMaxActive());
1197 assertEquals(maxIdle, pool.getMaxIdle());
1198 assertEquals(maxWait, pool.getMaxWait());
1199 assertEquals(minIdle, pool.getMinIdle());
1200 assertEquals(maxTotal, pool.getMaxTotal());
1201 assertEquals(minEvictableIdleTimeMillis,
1202 pool.getMinEvictableIdleTimeMillis());
1203 assertEquals(numTestsPerEvictionRun,
1204 pool.getNumTestsPerEvictionRun());
1205 assertEquals(testOnBorrow, pool.getTestOnBorrow());
1206 assertEquals(testOnReturn, pool.getTestOnReturn());
1207 assertEquals(testWhileIdle,
1208 pool.getTestWhileIdle());
1209 assertEquals(timeBetweenEvictionRunsMillis,
1210 pool.getTimeBetweenEvictionRunsMillis());
1211 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction());
1212 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo());
1213
1214 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction,
1215 maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn,
1216 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun,
1217 minEvictableIdleTimeMillis, testWhileIdle, lifo);
1218 assertEquals(maxActive, pool.getMaxActive());
1219 assertEquals(maxIdle, pool.getMaxIdle());
1220 assertEquals(maxWait, pool.getMaxWait());
1221 assertEquals(minIdle, pool.getMinIdle());
1222 assertEquals(maxTotal, pool.getMaxTotal());
1223 assertEquals(minEvictableIdleTimeMillis,
1224 pool.getMinEvictableIdleTimeMillis());
1225 assertEquals(numTestsPerEvictionRun,
1226 pool.getNumTestsPerEvictionRun());
1227 assertEquals(testOnBorrow, pool.getTestOnBorrow());
1228 assertEquals(testOnReturn, pool.getTestOnReturn());
1229 assertEquals(testWhileIdle,
1230 pool.getTestWhileIdle());
1231 assertEquals(timeBetweenEvictionRunsMillis,
1232 pool.getTimeBetweenEvictionRunsMillis());
1233 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction());
1234 assertEquals(lifo, pool.getLifo());
1235 }
1236
1237 public void testExceptionOnPassivateDuringReturn() throws Exception {
1238 SimpleFactory factory = new SimpleFactory();
1239 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory);
1240 Object obj = pool.borrowObject("one");
1241 factory.setThrowExceptionOnPassivate(true);
1242 pool.returnObject("one", obj);
1243 assertEquals(0,pool.getNumIdle());
1244 pool.close();
1245 }
1246
1247 public void testExceptionOnDestroyDuringBorrow() throws Exception {
1248 SimpleFactory factory = new SimpleFactory();
1249 factory.setThrowExceptionOnDestroy(true);
1250 factory.setValidationEnabled(true);
1251 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory);
1252 pool.setTestOnBorrow(true);
1253 pool.borrowObject("one");
1254 factory.setValid(false);
1255 try {
1256 pool.borrowObject("one");
1257 fail("Expecting NoSuchElementException");
1258 } catch (NoSuchElementException ex) {
1259
1260 }
1261 assertEquals(1, pool.getNumActive("one"));
1262 assertEquals(0, pool.getNumIdle("one"));
1263 assertEquals(1, pool.getNumActive());
1264 assertEquals(0, pool.getNumIdle());
1265 }
1266
1267 public void testExceptionOnDestroyDuringReturn() throws Exception {
1268 SimpleFactory factory = new SimpleFactory();
1269 factory.setThrowExceptionOnDestroy(true);
1270 factory.setValidationEnabled(true);
1271 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory);
1272 pool.setTestOnReturn(true);
1273 Object obj1 = pool.borrowObject("one");
1274 pool.borrowObject("one");
1275 factory.setValid(false);
1276 pool.returnObject("one", obj1);
1277 assertEquals(1, pool.getNumActive("one"));
1278 assertEquals(0, pool.getNumIdle("one"));
1279 assertEquals(1, pool.getNumActive());
1280 assertEquals(0, pool.getNumIdle());
1281 }
1282
1283 public void testExceptionOnActivateDuringBorrow() throws Exception {
1284 SimpleFactory factory = new SimpleFactory();
1285 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory);
1286 Object obj1 = pool.borrowObject("one");
1287 Object obj2 = pool.borrowObject("one");
1288 pool.returnObject("one", obj1);
1289 pool.returnObject("one", obj2);
1290 factory.setThrowExceptionOnActivate(true);
1291 factory.setEvenValid(false);
1292
1293
1294 Object obj = pool.borrowObject("one");
1295 assertEquals(1, pool.getNumActive("one"));
1296 assertEquals(0, pool.getNumIdle("one"));
1297 assertEquals(1, pool.getNumActive());
1298 assertEquals(0, pool.getNumIdle());
1299
1300 pool.returnObject("one", obj);
1301 factory.setValid(false);
1302
1303
1304 try {
1305 pool.borrowObject("one");
1306 fail("Expecting NoSuchElementException");
1307 } catch (NoSuchElementException ex) {
1308
1309 }
1310 assertEquals(0, pool.getNumActive("one"));
1311 assertEquals(0, pool.getNumIdle("one"));
1312 assertEquals(0, pool.getNumActive());
1313 assertEquals(0, pool.getNumIdle());
1314 }
1315
1316 public void testBlockedKeyDoesNotBlockPool() throws Exception {
1317 SimpleFactory factory = new SimpleFactory();
1318 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory);
1319 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK);
1320 pool.setMaxWait(5000);
1321 pool.setMaxActive(1);
1322 pool.setMaxTotal(-1);
1323 pool.borrowObject("one");
1324 long start = System.currentTimeMillis();
1325
1326 Runnable simple = new SimpleTestThread(pool, "one");
1327 (new Thread(simple)).start();
1328
1329
1330
1331 Thread.sleep(1000);
1332 pool.borrowObject("two");
1333 long end = System.currentTimeMillis();
1334
1335
1336
1337
1338 assertTrue ((end-start) < 4000);
1339
1340 }
1341
1342
1343
1344
1345
1346 static class SimpleTestThread implements Runnable {
1347 private final KeyedObjectPool _pool;
1348 private final String _key;
1349
1350 public SimpleTestThread(KeyedObjectPool pool, String key) {
1351 _pool = pool;
1352 _key = key;
1353 }
1354
1355 public void run() {
1356 try {
1357 Object obj = _pool.borrowObject(_key);
1358 _pool.returnObject(_key, obj);
1359 } catch (Exception e) {
1360
1361 }
1362 }
1363 }
1364
1365 static class TestThread implements Runnable {
1366 private final java.util.Random _random = new java.util.Random();
1367
1368
1369 private final KeyedObjectPool _pool;
1370 private final int _iter;
1371 private final int _delay;
1372
1373 private volatile boolean _complete = false;
1374 private volatile boolean _failed = false;
1375 private volatile Exception _exception;
1376
1377 public TestThread(KeyedObjectPool pool) {
1378 this(pool, 100, 50);
1379 }
1380
1381 public TestThread(KeyedObjectPool pool, int iter) {
1382 this(pool, iter, 50);
1383 }
1384
1385 public TestThread(KeyedObjectPool pool, int iter, int delay) {
1386 _pool = pool;
1387 _iter = iter;
1388 _delay = delay;
1389 }
1390
1391 public boolean complete() {
1392 return _complete;
1393 }
1394
1395 public boolean failed() {
1396 return _failed;
1397 }
1398
1399 public void run() {
1400 for(int i=0;i<_iter;i++) {
1401 String key = String.valueOf(_random.nextInt(3));
1402 try {
1403 Thread.sleep(_random.nextInt(_delay));
1404 } catch(InterruptedException e) {
1405
1406 }
1407 Object obj = null;
1408 try {
1409 obj = _pool.borrowObject(key);
1410 } catch(Exception e) {
1411 _exception = e;
1412 _failed = true;
1413 _complete = true;
1414 break;
1415 }
1416
1417 try {
1418 Thread.sleep(_random.nextInt(_delay));
1419 } catch(InterruptedException e) {
1420
1421 }
1422 try {
1423 _pool.returnObject(key,obj);
1424 } catch(Exception e) {
1425 _exception = e;
1426 _failed = true;
1427 _complete = true;
1428 break;
1429 }
1430 }
1431 _complete = true;
1432 }
1433 }
1434
1435 static class SimpleFactory implements KeyedPoolableObjectFactory {
1436 public SimpleFactory() {
1437 this(true);
1438 }
1439 public SimpleFactory(boolean valid) {
1440 this.valid = valid;
1441 }
1442 public Object makeObject(Object key) {
1443 synchronized(this) {
1444 activeCount++;
1445 if (activeCount > maxActive) {
1446 throw new IllegalStateException(
1447 "Too many active instances: " + activeCount);
1448 }
1449 }
1450 return String.valueOf(key) + String.valueOf(counter++);
1451 }
1452 public void destroyObject(Object key, Object obj) throws Exception {
1453 doWait(destroyLatency);
1454 synchronized(this) {
1455 activeCount--;
1456 }
1457 if (exceptionOnDestroy) {
1458 throw new Exception();
1459 }
1460 }
1461 public boolean validateObject(Object key, Object obj) {
1462 if (enableValidation) {
1463 return validateCounter++%2 == 0 ? evenValid : oddValid;
1464 } else {
1465 return valid;
1466 }
1467 }
1468 public void activateObject(Object key, Object obj) throws Exception {
1469 if (exceptionOnActivate) {
1470 if (!(validateCounter++%2 == 0 ? evenValid : oddValid)) {
1471 throw new Exception();
1472 }
1473 }
1474 }
1475 public void passivateObject(Object key, Object obj) throws Exception {
1476 if (exceptionOnPassivate) {
1477 throw new Exception();
1478 }
1479 }
1480
1481 public void setMaxActive(int maxActive) {
1482 this.maxActive = maxActive;
1483 }
1484 public void setDestroyLatency(long destroyLatency) {
1485 this.destroyLatency = destroyLatency;
1486 }
1487 public void setValidationEnabled(boolean b) {
1488 enableValidation = b;
1489 }
1490 void setEvenValid(boolean valid) {
1491 evenValid = valid;
1492 }
1493 void setValid(boolean valid) {
1494 evenValid = valid;
1495 oddValid = valid;
1496 }
1497
1498 public void setThrowExceptionOnActivate(boolean b) {
1499 exceptionOnActivate = b;
1500 }
1501
1502 public void setThrowExceptionOnDestroy(boolean b) {
1503 exceptionOnDestroy = b;
1504 }
1505
1506 public void setThrowExceptionOnPassivate(boolean b) {
1507 exceptionOnPassivate = b;
1508 }
1509
1510 int counter = 0;
1511 boolean valid;
1512
1513 int activeCount = 0;
1514 int validateCounter = 0;
1515 boolean evenValid = true;
1516 boolean oddValid = true;
1517 boolean enableValidation = false;
1518 long destroyLatency = 0;
1519 int maxActive = Integer.MAX_VALUE;
1520 boolean exceptionOnPassivate = false;
1521 boolean exceptionOnActivate = false;
1522 boolean exceptionOnDestroy = false;
1523
1524 private void doWait(long latency) {
1525 try {
1526 Thread.sleep(latency);
1527 } catch (InterruptedException ex) {
1528
1529 }
1530 }
1531 }
1532
1533 protected boolean isLifo() {
1534 return true;
1535 }
1536
1537 protected boolean isFifo() {
1538 return false;
1539 }
1540
1541 private String getExceptionTrace(Throwable t){
1542 StringWriter sw = new StringWriter();
1543 t.printStackTrace(new PrintWriter(sw));
1544 return sw.toString();
1545 }
1546
1547 private String formatSettings(String title, String s, int i, String s0, boolean b0, String s1, int i1, String s2, int i2, String s3, int i3,
1548 String s4, int i4, String s5, int i5, String s6, int i6, int zeroLength, int oneLength, int twoLength){
1549 StringBuffer sb = new StringBuffer(80);
1550 sb.append(title).append(' ');
1551 sb.append(s).append('=').append(i).append(' ');
1552 sb.append(s0).append('=').append(b0).append(' ');
1553 sb.append(s1).append('=').append(i1).append(' ');
1554 sb.append(s2).append('=').append(i2).append(' ');
1555 sb.append(s3).append('=').append(i3).append(' ');
1556 sb.append(s4).append('=').append(i4).append(' ');
1557 sb.append(s5).append('=').append(i5).append(' ');
1558 sb.append(s6).append('=').append(i6).append(' ');
1559 sb.append("Lengths=").append(zeroLength).append(',').append(oneLength).append(',').append(twoLength).append(' ');
1560 return sb.toString();
1561 }
1562
1563 }
1564
1565