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