001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.pool.impl; 019 020 import java.io.PrintWriter; 021 import java.io.StringWriter; 022 import java.util.HashMap; 023 import java.util.NoSuchElementException; 024 import java.util.Random; 025 026 import org.apache.commons.pool.KeyedObjectPool; 027 import org.apache.commons.pool.KeyedPoolableObjectFactory; 028 import org.apache.commons.pool.TestBaseKeyedObjectPool; 029 import org.apache.commons.pool.VisitTracker; 030 import org.apache.commons.pool.VisitTrackerFactory; 031 import org.apache.commons.pool.WaiterFactory; 032 033 /** 034 * @author Rodney Waldhoff 035 * @version $Revision: 1206483 $ $Date: 2011-11-26 09:37:34 -0700 (Sat, 26 Nov 2011) $ 036 */ 037 public class TestGenericKeyedObjectPool extends TestBaseKeyedObjectPool { 038 public TestGenericKeyedObjectPool(String testName) { 039 super(testName); 040 } 041 042 protected KeyedObjectPool makeEmptyPool(int mincapacity) { 043 GenericKeyedObjectPool pool = new GenericKeyedObjectPool( 044 new KeyedPoolableObjectFactory() { 045 HashMap map = new HashMap(); 046 public Object makeObject(Object key) { 047 int counter = 0; 048 Integer Counter = (Integer)(map.get(key)); 049 if(null != Counter) { 050 counter = Counter.intValue(); 051 } 052 map.put(key,new Integer(counter + 1)); 053 return String.valueOf(key) + String.valueOf(counter); 054 } 055 public void destroyObject(Object key, Object obj) { } 056 public boolean validateObject(Object key, Object obj) { return true; } 057 public void activateObject(Object key, Object obj) { } 058 public void passivateObject(Object key, Object obj) { } 059 } 060 ); 061 pool.setMaxActive(mincapacity); 062 pool.setMaxIdle(mincapacity); 063 return pool; 064 } 065 066 protected KeyedObjectPool makeEmptyPool(KeyedPoolableObjectFactory factory) { 067 return new GenericKeyedObjectPool(factory); 068 } 069 070 protected Object getNthObject(Object key, int n) { 071 return String.valueOf(key) + String.valueOf(n); 072 } 073 074 protected Object makeKey(int n) { 075 return String.valueOf(n); 076 } 077 078 private GenericKeyedObjectPool pool = null; 079 private final Integer zero = new Integer(0); 080 private final Integer one = new Integer(1); 081 private final Integer two = new Integer(2); 082 083 public void setUp() throws Exception { 084 super.setUp(); 085 pool = new GenericKeyedObjectPool(new SimpleFactory()); 086 } 087 088 public void tearDown() throws Exception { 089 super.tearDown(); 090 pool.clear(); 091 pool.close(); 092 pool = null; 093 } 094 095 public void testNegativeMaxActive() throws Exception { 096 pool.setMaxActive(-1); 097 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL); 098 Object obj = pool.borrowObject(""); 099 assertEquals("0",obj); 100 pool.returnObject("",obj); 101 } 102 103 public void testNumActiveNumIdle2() throws Exception { 104 assertEquals(0,pool.getNumActive()); 105 assertEquals(0,pool.getNumIdle()); 106 assertEquals(0,pool.getNumActive("A")); 107 assertEquals(0,pool.getNumIdle("A")); 108 assertEquals(0,pool.getNumActive("B")); 109 assertEquals(0,pool.getNumIdle("B")); 110 111 Object objA0 = pool.borrowObject("A"); 112 Object objB0 = pool.borrowObject("B"); 113 114 assertEquals(2,pool.getNumActive()); 115 assertEquals(0,pool.getNumIdle()); 116 assertEquals(1,pool.getNumActive("A")); 117 assertEquals(0,pool.getNumIdle("A")); 118 assertEquals(1,pool.getNumActive("B")); 119 assertEquals(0,pool.getNumIdle("B")); 120 121 Object objA1 = pool.borrowObject("A"); 122 Object objB1 = pool.borrowObject("B"); 123 124 assertEquals(4,pool.getNumActive()); 125 assertEquals(0,pool.getNumIdle()); 126 assertEquals(2,pool.getNumActive("A")); 127 assertEquals(0,pool.getNumIdle("A")); 128 assertEquals(2,pool.getNumActive("B")); 129 assertEquals(0,pool.getNumIdle("B")); 130 131 pool.returnObject("A",objA0); 132 pool.returnObject("B",objB0); 133 134 assertEquals(2,pool.getNumActive()); 135 assertEquals(2,pool.getNumIdle()); 136 assertEquals(1,pool.getNumActive("A")); 137 assertEquals(1,pool.getNumIdle("A")); 138 assertEquals(1,pool.getNumActive("B")); 139 assertEquals(1,pool.getNumIdle("B")); 140 141 pool.returnObject("A",objA1); 142 pool.returnObject("B",objB1); 143 144 assertEquals(0,pool.getNumActive()); 145 assertEquals(4,pool.getNumIdle()); 146 assertEquals(0,pool.getNumActive("A")); 147 assertEquals(2,pool.getNumIdle("A")); 148 assertEquals(0,pool.getNumActive("B")); 149 assertEquals(2,pool.getNumIdle("B")); 150 } 151 152 public void testMaxIdle() throws Exception { 153 pool.setMaxActive(100); 154 pool.setMaxIdle(8); 155 Object[] active = new Object[100]; 156 for(int i=0;i<100;i++) { 157 active[i] = pool.borrowObject(""); 158 } 159 assertEquals(100,pool.getNumActive("")); 160 assertEquals(0,pool.getNumIdle("")); 161 for(int i=0;i<100;i++) { 162 pool.returnObject("",active[i]); 163 assertEquals(99 - i,pool.getNumActive("")); 164 assertEquals((i < 8 ? i+1 : 8),pool.getNumIdle("")); 165 } 166 167 for(int i=0;i<100;i++) { 168 active[i] = pool.borrowObject("a"); 169 } 170 assertEquals(100,pool.getNumActive("a")); 171 assertEquals(0,pool.getNumIdle("a")); 172 for(int i=0;i<100;i++) { 173 pool.returnObject("a",active[i]); 174 assertEquals(99 - i,pool.getNumActive("a")); 175 assertEquals((i < 8 ? i+1 : 8),pool.getNumIdle("a")); 176 } 177 178 // total number of idle instances is twice maxIdle 179 assertEquals(16, pool.getNumIdle()); 180 // Each pool is at the sup 181 assertEquals(8, pool.getNumIdle("")); 182 assertEquals(8, pool.getNumIdle("a")); 183 184 } 185 186 public void testMaxActive() throws Exception { 187 pool.setMaxActive(3); 188 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL); 189 190 pool.borrowObject(""); 191 pool.borrowObject(""); 192 pool.borrowObject(""); 193 try { 194 pool.borrowObject(""); 195 fail("Expected NoSuchElementException"); 196 } catch(NoSuchElementException e) { 197 // expected 198 } 199 } 200 201 public void testMaxActiveZero() throws Exception { 202 pool.setMaxActive(0); 203 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL); 204 205 try { 206 pool.borrowObject("a"); 207 fail("Expected NoSuchElementException"); 208 } catch(NoSuchElementException e) { 209 // expected 210 } 211 } 212 213 public void testWhenExhaustedGrow() throws Exception { 214 pool.setMaxActive(1); 215 pool.setMaxTotal(1); 216 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW); 217 for (int i = 0; i < 10; i++) { 218 pool.borrowObject("a"); 219 } 220 } 221 222 public void testWhenExhaustedBlockClosePool() throws Exception { 223 pool.setMaxActive(1); 224 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK); 225 pool.setMaxWait(0); 226 Object obj1 = pool.borrowObject("a"); 227 228 // Make sure an object was obtained 229 assertNotNull(obj1); 230 231 // Create a separate thread to try and borrow another object 232 WaitingTestThread wtt = new WaitingTestThread(pool, "a", 200); 233 wtt.start(); 234 // Give wtt time to start 235 Thread.sleep(200); 236 237 // close the pool (Bug POOL-189) 238 pool.close(); 239 240 // Give interrupt time to take effect 241 Thread.sleep(200); 242 243 // Check thread was interrupted 244 assertTrue(wtt._thrown instanceof IllegalStateException); 245 } 246 247 public void testMaxTotal() throws Exception { 248 pool.setMaxActive(2); 249 pool.setMaxTotal(3); 250 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL); 251 252 Object o1 = pool.borrowObject("a"); 253 assertNotNull(o1); 254 Object o2 = pool.borrowObject("a"); 255 assertNotNull(o2); 256 Object o3 = pool.borrowObject("b"); 257 assertNotNull(o3); 258 try { 259 pool.borrowObject("c"); 260 fail("Expected NoSuchElementException"); 261 } catch(NoSuchElementException e) { 262 // expected 263 } 264 265 assertEquals(0, pool.getNumIdle()); 266 267 pool.returnObject("b", o3); 268 assertEquals(1, pool.getNumIdle()); 269 assertEquals(1, pool.getNumIdle("b")); 270 271 Object o4 = pool.borrowObject("b"); 272 assertNotNull(o4); 273 assertEquals(0, pool.getNumIdle()); 274 assertEquals(0, pool.getNumIdle("b")); 275 276 pool.setMaxTotal(4); 277 Object o5 = pool.borrowObject("b"); 278 assertNotNull(o5); 279 280 assertEquals(2, pool.getNumActive("a")); 281 assertEquals(2, pool.getNumActive("b")); 282 assertEquals(pool.getMaxTotal(), 283 pool.getNumActive("b") + pool.getNumActive("b")); 284 assertEquals(pool.getNumActive(), 285 pool.getMaxTotal()); 286 } 287 288 public void testMaxTotalZero() throws Exception { 289 pool.setMaxTotal(0); 290 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL); 291 292 try { 293 pool.borrowObject("a"); 294 fail("Expected NoSuchElementException"); 295 } catch(NoSuchElementException e) { 296 // expected 297 } 298 } 299 300 public void testMaxTotalLRU() throws Exception { 301 pool.setMaxActive(2); 302 pool.setMaxTotal(3); 303 // pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_GROW); 304 305 Object o1 = pool.borrowObject("a"); 306 assertNotNull(o1); 307 pool.returnObject("a", o1); 308 Thread.sleep(25); 309 310 Object o2 = pool.borrowObject("b"); 311 assertNotNull(o2); 312 pool.returnObject("b", o2); 313 Thread.sleep(25); 314 315 Object o3 = pool.borrowObject("c"); 316 assertNotNull(o3); 317 pool.returnObject("c", o3); 318 Thread.sleep(25); 319 320 Object o4 = pool.borrowObject("a"); 321 assertNotNull(o4); 322 pool.returnObject("a", o4); 323 Thread.sleep(25); 324 325 assertSame(o1, o4); 326 327 // this should cause b to be bumped out of the pool 328 Object o5 = pool.borrowObject("d"); 329 assertNotNull(o5); 330 pool.returnObject("d", o5); 331 Thread.sleep(25); 332 333 // now re-request b, we should get a different object because it should 334 // have been expelled from pool (was oldest because a was requested after b) 335 Object o6 = pool.borrowObject("b"); 336 assertNotNull(o6); 337 pool.returnObject("b", o6); 338 339 assertNotSame(o1, o6); 340 341 // second a is still in there 342 Object o7 = pool.borrowObject("a"); 343 assertNotNull(o7); 344 pool.returnObject("a", o7); 345 346 assertSame(o4, o7); 347 } 348 349 public void testSettersAndGetters() throws Exception { 350 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(); 351 { 352 pool.setFactory(new SimpleFactory()); 353 } 354 { 355 pool.setMaxActive(123); 356 assertEquals(123,pool.getMaxActive()); 357 } 358 { 359 pool.setMaxIdle(12); 360 assertEquals(12,pool.getMaxIdle()); 361 } 362 { 363 pool.setMaxWait(1234L); 364 assertEquals(1234L,pool.getMaxWait()); 365 } 366 { 367 pool.setMinEvictableIdleTimeMillis(12345L); 368 assertEquals(12345L,pool.getMinEvictableIdleTimeMillis()); 369 } 370 { 371 pool.setNumTestsPerEvictionRun(11); 372 assertEquals(11,pool.getNumTestsPerEvictionRun()); 373 } 374 { 375 pool.setTestOnBorrow(true); 376 assertTrue(pool.getTestOnBorrow()); 377 pool.setTestOnBorrow(false); 378 assertTrue(!pool.getTestOnBorrow()); 379 } 380 { 381 pool.setTestOnReturn(true); 382 assertTrue(pool.getTestOnReturn()); 383 pool.setTestOnReturn(false); 384 assertTrue(!pool.getTestOnReturn()); 385 } 386 { 387 pool.setTestWhileIdle(true); 388 assertTrue(pool.getTestWhileIdle()); 389 pool.setTestWhileIdle(false); 390 assertTrue(!pool.getTestWhileIdle()); 391 } 392 { 393 pool.setTimeBetweenEvictionRunsMillis(11235L); 394 assertEquals(11235L,pool.getTimeBetweenEvictionRunsMillis()); 395 } 396 { 397 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_BLOCK); 398 assertEquals(GenericObjectPool.WHEN_EXHAUSTED_BLOCK,pool.getWhenExhaustedAction()); 399 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL); 400 assertEquals(GenericObjectPool.WHEN_EXHAUSTED_FAIL,pool.getWhenExhaustedAction()); 401 pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_GROW); 402 assertEquals(GenericObjectPool.WHEN_EXHAUSTED_GROW,pool.getWhenExhaustedAction()); 403 } 404 } 405 406 public void testEviction() throws Exception { 407 pool.setMaxIdle(500); 408 pool.setMaxActive(500); 409 pool.setNumTestsPerEvictionRun(100); 410 pool.setMinEvictableIdleTimeMillis(250L); 411 pool.setTimeBetweenEvictionRunsMillis(500L); 412 413 Object[] active = new Object[500]; 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 for(int i=0;i<500;i++) { 435 active[i] = pool.borrowObject(""); 436 } 437 for(int i=0;i<500;i++) { 438 pool.returnObject("",active[i]); 439 } 440 441 try { Thread.sleep(1000L); } catch(InterruptedException e) { } 442 assertTrue("Should be less than 500 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 500); 443 try { Thread.sleep(600L); } catch(InterruptedException e) { } 444 assertTrue("Should be less than 400 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 400); 445 try { Thread.sleep(600L); } catch(InterruptedException e) { } 446 assertTrue("Should be less than 300 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 300); 447 try { Thread.sleep(600L); } catch(InterruptedException e) { } 448 assertTrue("Should be less than 200 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 200); 449 try { Thread.sleep(600L); } catch(InterruptedException e) { } 450 assertTrue("Should be less than 100 idle, found " + pool.getNumIdle(""),pool.getNumIdle("") < 100); 451 try { Thread.sleep(600L); } catch(InterruptedException e) { } 452 assertEquals("Should be zero idle, found " + pool.getNumIdle(""),0,pool.getNumIdle("")); 453 } 454 455 public void testEviction2() throws Exception { 456 pool.setMaxIdle(500); 457 pool.setMaxActive(500); 458 pool.setNumTestsPerEvictionRun(100); 459 pool.setMinEvictableIdleTimeMillis(500L); 460 pool.setTimeBetweenEvictionRunsMillis(500L); 461 462 Object[] active = new Object[500]; 463 Object[] active2 = new Object[500]; 464 for(int i=0;i<500;i++) { 465 active[i] = pool.borrowObject(""); 466 active2[i] = pool.borrowObject("2"); 467 } 468 for(int i=0;i<500;i++) { 469 pool.returnObject("",active[i]); 470 pool.returnObject("2",active2[i]); 471 } 472 473 try { Thread.sleep(1100L); } catch(InterruptedException e) { } 474 assertTrue("Should be less than 1000 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 1000); 475 try { Thread.sleep(600L); } catch(InterruptedException e) { } 476 assertTrue("Should be less than 900 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 900); 477 try { Thread.sleep(600L); } catch(InterruptedException e) { } 478 assertTrue("Should be less than 800 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 800); 479 try { Thread.sleep(600L); } catch(InterruptedException e) { } 480 assertTrue("Should be less than 700 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 700); 481 try { Thread.sleep(600L); } catch(InterruptedException e) { } 482 assertTrue("Should be less than 600 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 600); 483 try { Thread.sleep(600L); } catch(InterruptedException e) { } 484 assertTrue("Should be less than 500 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 500); 485 try { Thread.sleep(600L); } catch(InterruptedException e) { } 486 assertTrue("Should be less than 400 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 400); 487 try { Thread.sleep(600L); } catch(InterruptedException e) { } 488 assertTrue("Should be less than 300 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 300); 489 try { Thread.sleep(600L); } catch(InterruptedException e) { } 490 assertTrue("Should be less than 200 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 200); 491 try { Thread.sleep(600L); } catch(InterruptedException e) { } 492 assertTrue("Should be less than 100 idle, found " + pool.getNumIdle(),pool.getNumIdle() < 100); 493 try { Thread.sleep(600L); } catch(InterruptedException e) { } 494 assertEquals("Should be zero idle, found " + pool.getNumIdle(),0,pool.getNumIdle()); 495 } 496 497 /** 498 * Kicks off <numThreads> test threads, each of which will go through 499 * <iterations> borrow-return cycles with random delay times <= delay 500 * in between. 501 */ 502 public void runTestThreads(int numThreads, int iterations, int delay) { 503 TestThread[] threads = new TestThread[numThreads]; 504 for(int i=0;i<numThreads;i++) { 505 threads[i] = new TestThread(pool,iterations,delay); 506 Thread t = new Thread(threads[i]); 507 t.start(); 508 } 509 for(int i=0;i<numThreads;i++) { 510 while(!(threads[i]).complete()) { 511 try { 512 Thread.sleep(500L); 513 } catch(InterruptedException e) { 514 // ignored 515 } 516 } 517 if(threads[i].failed()) { 518 fail("Thread failed: "+i+"\n"+getExceptionTrace(threads[i]._exception)); 519 } 520 } 521 } 522 523 public void testThreaded1() throws Exception { 524 pool.setMaxActive(15); 525 pool.setMaxIdle(15); 526 pool.setMaxWait(1000L); 527 runTestThreads(20, 100, 50); 528 } 529 530 /** 531 * Verifies that maxTotal is not exceeded when factory destroyObject 532 * has high latency, testOnReturn is set and there is high incidence of 533 * validation failures. 534 */ 535 public void testMaxTotalInvariant() throws Exception { 536 int maxTotal = 15; 537 SimpleFactory factory = new SimpleFactory(); 538 factory.setEvenValid(false); // Every other validation fails 539 factory.setDestroyLatency(100); // Destroy takes 100 ms 540 factory.setMaxActive(maxTotal); // (makes - destroys) bound 541 factory.setValidationEnabled(true); 542 pool = new GenericKeyedObjectPool(factory); 543 pool.setMaxTotal(maxTotal); 544 pool.setMaxIdle(-1); 545 pool.setTestOnReturn(true); 546 pool.setMaxWait(10000L); 547 runTestThreads(5, 10, 50); 548 } 549 550 public void testMinIdle() throws Exception { 551 pool.setMaxIdle(500); 552 pool.setMinIdle(5); 553 pool.setMaxActive(10); 554 pool.setNumTestsPerEvictionRun(0); 555 pool.setMinEvictableIdleTimeMillis(50L); 556 pool.setTimeBetweenEvictionRunsMillis(100L); 557 pool.setTestWhileIdle(true); 558 559 560 //Generate a random key 561 String key = "A"; 562 563 pool.preparePool(key, true); 564 565 try { Thread.sleep(150L); } catch(InterruptedException e) { } 566 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5); 567 568 Object[] active = new Object[5]; 569 active[0] = pool.borrowObject(key); 570 571 try { Thread.sleep(150L); } catch(InterruptedException e) { } 572 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5); 573 574 for(int i=1 ; i<5 ; i++) { 575 active[i] = pool.borrowObject(key); 576 } 577 578 try { Thread.sleep(150L); } catch(InterruptedException e) { } 579 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5); 580 581 for(int i=0 ; i<5 ; i++) { 582 pool.returnObject(key, active[i]); 583 } 584 585 try { Thread.sleep(150L); } catch(InterruptedException e) { } 586 assertTrue("Should be 10 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 10); 587 } 588 589 public void testMinIdleMaxActive() throws Exception { 590 pool.setMaxIdle(500); 591 pool.setMinIdle(5); 592 pool.setMaxActive(10); 593 pool.setNumTestsPerEvictionRun(0); 594 pool.setMinEvictableIdleTimeMillis(50L); 595 pool.setTimeBetweenEvictionRunsMillis(100L); 596 pool.setTestWhileIdle(true); 597 598 String key = "A"; 599 600 pool.preparePool(key, true); 601 assertTrue("Should be 5 idle, found " + 602 pool.getNumIdle(),pool.getNumIdle() == 5); 603 604 try { Thread.sleep(150L); } catch(InterruptedException e) { } 605 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5); 606 607 Object[] active = new Object[10]; 608 609 try { Thread.sleep(150L); } catch(InterruptedException e) { } 610 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5); 611 612 for(int i=0 ; i<5 ; i++) { 613 active[i] = pool.borrowObject(key); 614 } 615 616 try { Thread.sleep(150L); } catch(InterruptedException e) { } 617 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5); 618 619 for(int i=0 ; i<5 ; i++) { 620 pool.returnObject(key, active[i]); 621 } 622 623 try { Thread.sleep(150L); } catch(InterruptedException e) { } 624 assertTrue("Should be 10 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 10); 625 626 for(int i=0 ; i<10 ; i++) { 627 active[i] = pool.borrowObject(key); 628 } 629 630 try { Thread.sleep(150L); } catch(InterruptedException e) { } 631 assertTrue("Should be 0 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 0); 632 633 for(int i=0 ; i<10 ; i++) { 634 pool.returnObject(key, active[i]); 635 } 636 637 try { Thread.sleep(150L); } catch(InterruptedException e) { } 638 assertTrue("Should be 10 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 10); 639 } 640 641 public void testMinIdleNoPopulateImmediately() throws Exception { 642 pool.setMaxIdle(500); 643 pool.setMinIdle(5); 644 pool.setMaxActive(10); 645 pool.setNumTestsPerEvictionRun(0); 646 pool.setMinEvictableIdleTimeMillis(50L); 647 pool.setTimeBetweenEvictionRunsMillis(1000L); 648 pool.setTestWhileIdle(true); 649 650 651 //Generate a random key 652 String key = "A"; 653 654 pool.preparePool(key, false); 655 656 assertTrue("Should be 0 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 0); 657 658 try { Thread.sleep(1500L); } catch(InterruptedException e) { } 659 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5); 660 } 661 662 public void testMinIdleNoPreparePool() throws Exception { 663 pool.setMaxIdle(500); 664 pool.setMinIdle(5); 665 pool.setMaxActive(10); 666 pool.setNumTestsPerEvictionRun(0); 667 pool.setMinEvictableIdleTimeMillis(50L); 668 pool.setTimeBetweenEvictionRunsMillis(100L); 669 pool.setTestWhileIdle(true); 670 671 672 //Generate a random key 673 String key = "A"; 674 675 try { Thread.sleep(150L); } catch(InterruptedException e) { } 676 assertTrue("Should be 0 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 0); 677 678 Object active = pool.borrowObject(key); 679 assertNotNull(active); 680 681 try { Thread.sleep(150L); } catch(InterruptedException e) { } 682 assertTrue("Should be 5 idle, found " + pool.getNumIdle(),pool.getNumIdle() == 5); 683 } 684 685 public void testFIFO() throws Exception { 686 pool.setLifo(false); 687 final Object key = "key"; 688 pool.addObject(key); // "key0" 689 pool.addObject(key); // "key1" 690 pool.addObject(key); // "key2" 691 assertEquals("Oldest", "key0", pool.borrowObject(key)); 692 assertEquals("Middle", "key1", pool.borrowObject(key)); 693 assertEquals("Youngest", "key2", pool.borrowObject(key)); 694 assertEquals("new-3", "key3", pool.borrowObject(key)); 695 pool.returnObject(key, "r"); 696 assertEquals("returned", "r", pool.borrowObject(key)); 697 assertEquals("new-4", "key4", pool.borrowObject(key)); 698 } 699 700 public void testLIFO() throws Exception { 701 pool.setLifo(true); 702 final Object key = "key"; 703 pool.addObject(key); // "key0" 704 pool.addObject(key); // "key1" 705 pool.addObject(key); // "key2" 706 assertEquals("Youngest", "key2", pool.borrowObject(key)); 707 assertEquals("Middle", "key1", pool.borrowObject(key)); 708 assertEquals("Oldest", "key0", pool.borrowObject(key)); 709 assertEquals("new-3", "key3", pool.borrowObject(key)); 710 pool.returnObject(key, "r"); 711 assertEquals("returned", "r", pool.borrowObject(key)); 712 assertEquals("new-4", "key4", pool.borrowObject(key)); 713 } 714 715 /** 716 * Test to make sure evictor visits least recently used objects first, 717 * regardless of FIFO/LIFO 718 * 719 * JIRA: POOL-86 720 */ 721 public void testEvictionOrder() throws Exception { 722 checkEvictionOrder(false); 723 checkEvictionOrder(true); 724 } 725 726 private void checkEvictionOrder(boolean lifo) throws Exception { 727 SimpleFactory factory = new SimpleFactory(); 728 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory); 729 pool.setNumTestsPerEvictionRun(2); 730 pool.setMinEvictableIdleTimeMillis(100); 731 pool.setLifo(lifo); 732 733 for (int i = 0; i < 3; i ++) { 734 Integer key = new Integer(i); 735 for (int j = 0; j < 5; j++) { 736 pool.addObject(key); 737 } 738 } 739 740 // Make all evictable 741 Thread.sleep(200); 742 743 /* 744 * Initial state (Key, Object) pairs in order of age: 745 * 746 * (0,0), (0,1), (0,2), (0,3), (0,4) 747 * (1,5), (1,6), (1,7), (1,8), (1,9) 748 * (2,10), (2,11), (2,12), (2,13), (2,14) 749 */ 750 751 pool.evict(); // Kill (0,0),(0,1) 752 assertEquals(3, pool.getNumIdle(zero)); 753 Object objZeroA = pool.borrowObject(zero); 754 assertTrue(lifo ? objZeroA.equals("04") : objZeroA.equals("02")); 755 assertEquals(2, pool.getNumIdle(zero)); 756 Object objZeroB = pool.borrowObject(zero); 757 assertTrue(objZeroB.equals("03")); 758 assertEquals(1, pool.getNumIdle(zero)); 759 760 pool.evict(); // Kill remaining 0 survivor and (1,5) 761 assertEquals(0, pool.getNumIdle(zero)); 762 assertEquals(4, pool.getNumIdle(one)); 763 Object objOneA = pool.borrowObject(one); 764 assertTrue(lifo ? objOneA.equals("19") : objOneA.equals("16")); 765 assertEquals(3, pool.getNumIdle(one)); 766 Object objOneB = pool.borrowObject(one); 767 assertTrue(lifo ? objOneB.equals("18") : objOneB.equals("17")); 768 assertEquals(2, pool.getNumIdle(one)); 769 770 pool.evict(); // Kill remaining 1 survivors 771 assertEquals(0, pool.getNumIdle(one)); 772 pool.evict(); // Kill (2,10), (2,11) 773 assertEquals(3, pool.getNumIdle(two)); 774 Object objTwoA = pool.borrowObject(two); 775 assertTrue(lifo ? objTwoA.equals("214") : objTwoA.equals("212")); 776 assertEquals(2, pool.getNumIdle(two)); 777 pool.evict(); // All dead now 778 assertEquals(0, pool.getNumIdle(two)); 779 780 pool.evict(); // Should do nothing - make sure no exception 781 // Currently 2 zero, 2 one and 1 two active. Return them 782 pool.returnObject(zero, objZeroA); 783 pool.returnObject(zero, objZeroB); 784 pool.returnObject(one, objOneA); 785 pool.returnObject(one, objOneB); 786 pool.returnObject(two, objTwoA); 787 // Remove all idle objects 788 pool.clear(); 789 790 // Reload 791 pool.setMinEvictableIdleTimeMillis(500); 792 factory.counter = 0; // Reset counter 793 for (int i = 0; i < 3; i ++) { 794 Integer key = new Integer(i); 795 for (int j = 0; j < 5; j++) { 796 pool.addObject(key); 797 } 798 Thread.sleep(200); 799 } 800 801 // 0's are evictable, others not 802 pool.evict(); // Kill (0,0),(0,1) 803 assertEquals(3, pool.getNumIdle(zero)); 804 pool.evict(); // Kill (0,2),(0,3) 805 assertEquals(1, pool.getNumIdle(zero)); 806 pool.evict(); // Kill (0,4), leave (1,5) 807 assertEquals(0, pool.getNumIdle(zero)); 808 assertEquals(5, pool.getNumIdle(one)); 809 assertEquals(5, pool.getNumIdle(two)); 810 pool.evict(); // (1,6), (1,7) 811 assertEquals(5, pool.getNumIdle(one)); 812 assertEquals(5, pool.getNumIdle(two)); 813 pool.evict(); // (1,8), (1,9) 814 assertEquals(5, pool.getNumIdle(one)); 815 assertEquals(5, pool.getNumIdle(two)); 816 pool.evict(); // (2,10), (2,11) 817 assertEquals(5, pool.getNumIdle(one)); 818 assertEquals(5, pool.getNumIdle(two)); 819 pool.evict(); // (2,12), (2,13) 820 assertEquals(5, pool.getNumIdle(one)); 821 assertEquals(5, pool.getNumIdle(two)); 822 pool.evict(); // (2,14), (1,5) 823 assertEquals(5, pool.getNumIdle(one)); 824 assertEquals(5, pool.getNumIdle(two)); 825 Thread.sleep(200); // Ones now timed out 826 pool.evict(); // kill (1,6), (1,7) - (1,5) missed 827 assertEquals(3, pool.getNumIdle(one)); 828 assertEquals(5, pool.getNumIdle(two)); 829 Object obj = pool.borrowObject(one); 830 if (lifo) { 831 assertEquals("19", obj); 832 } else { 833 assertEquals("15", obj); 834 } 835 } 836 837 838 /** 839 * Verifies that the evictor visits objects in expected order 840 * and frequency. 841 */ 842 public void testEvictorVisiting() throws Exception { 843 checkEvictorVisiting(true); 844 checkEvictorVisiting(false); 845 } 846 847 private void checkEvictorVisiting(boolean lifo) throws Exception { 848 VisitTrackerFactory factory = new VisitTrackerFactory(); 849 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory); 850 pool.setNumTestsPerEvictionRun(2); 851 pool.setMinEvictableIdleTimeMillis(-1); 852 pool.setTestWhileIdle(true); 853 pool.setLifo(lifo); 854 pool.setTestOnReturn(false); 855 pool.setTestOnBorrow(false); 856 for (int i = 0; i < 3; i ++) { 857 factory.resetId(); 858 Integer key = new Integer(i); 859 for (int j = 0; j < 8; j++) { 860 pool.addObject(key); 861 } 862 } 863 pool.evict(); // Visit oldest 2 - 00 and 01 864 Object obj = pool.borrowObject(zero); 865 pool.returnObject(zero, obj); 866 obj = pool.borrowObject(zero); 867 pool.returnObject(zero, obj); 868 // borrow, return, borrow, return 869 // FIFO will move 0 and 1 to end - 2,3,4,5,6,7,0,1 870 // LIFO, 7 out, then in, then out, then in - 7,6,5,4,3,2,1,0 871 pool.evict(); // Should visit 02 and 03 in either case 872 for (int i = 0; i < 8; i++) { 873 VisitTracker tracker = (VisitTracker) pool.borrowObject(zero); 874 if (tracker.getId() >= 4) { 875 assertEquals("Unexpected instance visited " + tracker.getId(), 876 0, tracker.getValidateCount()); 877 } else { 878 assertEquals("Instance " + tracker.getId() + 879 " visited wrong number of times.", 880 1, tracker.getValidateCount()); 881 } 882 } 883 // 0's are all out 884 885 pool.setNumTestsPerEvictionRun(3); 886 887 pool.evict(); // 10, 11, 12 888 pool.evict(); // 13, 14, 15 889 890 obj = pool.borrowObject(one); 891 pool.returnObject(one, obj); 892 obj = pool.borrowObject(one); 893 pool.returnObject(one, obj); 894 obj = pool.borrowObject(one); 895 pool.returnObject(one, obj); 896 // borrow, return, borrow, return 897 // FIFO 3,4,5,^,6,7,0,1,2 898 // LIFO 7,6,^,5,4,3,2,1,0 899 // In either case, pointer should be at 6 900 pool.evict(); 901 // LIFO - 16, 17, 20 902 // FIFO - 16, 17, 10 903 pool.evict(); 904 // LIFO - 21, 22, 23 905 // FIFO - 11, 12, 20 906 pool.evict(); 907 // LIFO - 24, 25, 26 908 // FIFO - 21, 22, 23 909 pool.evict(); 910 // LIFO - 27, skip, 10 911 // FIFO - 24, 25, 26 912 for (int i = 0; i < 8; i++) { 913 VisitTracker tracker = (VisitTracker) pool.borrowObject(one); 914 if ((lifo && tracker.getId() > 0) || 915 (!lifo && tracker.getId() > 2)) { 916 assertEquals("Instance " + tracker.getId() + 917 " visited wrong number of times.", 918 1, tracker.getValidateCount()); 919 } else { 920 assertEquals("Instance " + tracker.getId() + 921 " visited wrong number of times.", 922 2, tracker.getValidateCount()); 923 } 924 } 925 926 // Randomly generate some pools with random numTests 927 // and make sure evictor cycles through elements appropriately 928 int[] smallPrimes = {2, 3, 5, 7}; 929 Random random = new Random(); 930 random.setSeed(System.currentTimeMillis()); 931 pool.setMaxIdle(-1); 932 for (int i = 0; i < smallPrimes.length; i++) { 933 pool.setNumTestsPerEvictionRun(smallPrimes[i]); 934 for (int j = 0; j < 5; j++) {// Try the tests a few times 935 pool.clear(); 936 assertEquals("NumIdle should be zero after clearing the pool",0,pool.getNumIdle()); 937 int zeroLength = 10 + random.nextInt(20); 938 for (int k = 0; k < zeroLength; k++) { 939 pool.addObject(zero); 940 } 941 int oneLength = 10 + random.nextInt(20); 942 for (int k = 0; k < oneLength; k++) { 943 pool.addObject(one); 944 } 945 int twoLength = 10 + random.nextInt(20); 946 for (int k = 0; k < twoLength; k++) { 947 pool.addObject(two); 948 } 949 950 // Choose a random number of evictor runs 951 int runs = 10 + random.nextInt(50); 952 for (int k = 0; k < runs; k++) { 953 pool.evict(); 954 } 955 956 // Total instances in pool 957 int totalInstances = zeroLength + oneLength + twoLength; 958 959 // Number of times evictor should have cycled through pools 960 int cycleCount = (runs * pool.getNumTestsPerEvictionRun()) 961 / totalInstances; 962 963 // Look at elements and make sure they are visited cycleCount 964 // or cycleCount + 1 times 965 VisitTracker tracker = null; 966 int visitCount = 0; 967 for (int k = 0; k < zeroLength; k++) { 968 tracker = (VisitTracker) pool.borrowObject(zero); 969 visitCount = tracker.getValidateCount(); 970 if (visitCount < cycleCount || visitCount > cycleCount + 1){ 971 fail(formatSettings("ZERO", "runs", runs, "lifo", lifo, "i", i, "j", j, 972 "k", k, "visitCount", visitCount, "cycleCount", cycleCount, 973 "totalInstances", totalInstances, zeroLength, oneLength, twoLength)); 974 } 975 } 976 for (int k = 0; k < oneLength; k++) { 977 tracker = (VisitTracker) pool.borrowObject(one); 978 visitCount = tracker.getValidateCount(); 979 if (visitCount < cycleCount || visitCount > cycleCount + 1){ 980 fail(formatSettings("ONE", "runs", runs, "lifo", lifo, "i", i, "j", j, 981 "k", k, "visitCount", visitCount, "cycleCount", cycleCount, 982 "totalInstances", totalInstances, zeroLength, oneLength, twoLength)); 983 } 984 } 985 int visits[] = new int[twoLength]; 986 for (int k = 0; k < twoLength; k++) { 987 tracker = (VisitTracker) pool.borrowObject(two); 988 visitCount = tracker.getValidateCount(); 989 visits[k] = visitCount; 990 if (visitCount < cycleCount || visitCount > cycleCount + 1){ 991 StringBuffer sb = new StringBuffer("Visits:"); 992 for (int l = 0; l <= k; l++){ 993 sb.append(visits[l]).append(' '); 994 } 995 fail(formatSettings("TWO "+sb.toString(), "runs", runs, "lifo", lifo, "i", i, "j", j, 996 "k", k, "visitCount", visitCount, "cycleCount", cycleCount, 997 "totalInstances", totalInstances, zeroLength, oneLength, twoLength)); 998 } 999 } 1000 } 1001 } 1002 } 1003 1004 public void testConstructors() { 1005 1006 // Make constructor arguments all different from defaults 1007 int maxActive = 1; 1008 int maxIdle = 2; 1009 long maxWait = 3; 1010 int minIdle = 4; 1011 int maxTotal = 5; 1012 long minEvictableIdleTimeMillis = 6; 1013 int numTestsPerEvictionRun = 7; 1014 boolean testOnBorrow = true; 1015 boolean testOnReturn = true; 1016 boolean testWhileIdle = true; 1017 long timeBetweenEvictionRunsMillis = 8; 1018 byte whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW; 1019 boolean lifo = false; 1020 1021 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(); 1022 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_ACTIVE, pool.getMaxActive()); 1023 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_IDLE, pool.getMaxIdle()); 1024 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_WAIT, pool.getMaxWait()); 1025 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle()); 1026 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal()); 1027 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, 1028 pool.getMinEvictableIdleTimeMillis()); 1029 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN, 1030 pool.getNumTestsPerEvictionRun()); 1031 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW, 1032 pool.getTestOnBorrow()); 1033 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN, 1034 pool.getTestOnReturn()); 1035 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE, 1036 pool.getTestWhileIdle()); 1037 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, 1038 pool.getTimeBetweenEvictionRunsMillis()); 1039 assertEquals(GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, 1040 pool.getWhenExhaustedAction()); 1041 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo()); 1042 1043 GenericKeyedObjectPool.Config config = new GenericKeyedObjectPool.Config(); 1044 config.lifo = lifo; 1045 config.maxActive = maxActive; 1046 config.maxIdle = maxIdle; 1047 config.minIdle = minIdle; 1048 config.maxTotal = maxTotal; 1049 config.maxWait = maxWait; 1050 config.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; 1051 config.numTestsPerEvictionRun = numTestsPerEvictionRun; 1052 config.testOnBorrow = testOnBorrow; 1053 config.testOnReturn = testOnReturn; 1054 config.testWhileIdle = testWhileIdle; 1055 config.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; 1056 config.whenExhaustedAction = whenExhaustedAction; 1057 pool = new GenericKeyedObjectPool(null, config); 1058 assertEquals(maxActive, pool.getMaxActive()); 1059 assertEquals(maxIdle, pool.getMaxIdle()); 1060 assertEquals(maxWait, pool.getMaxWait()); 1061 assertEquals(minIdle, pool.getMinIdle()); 1062 assertEquals(maxTotal, pool.getMaxTotal()); 1063 assertEquals(minEvictableIdleTimeMillis, 1064 pool.getMinEvictableIdleTimeMillis()); 1065 assertEquals(numTestsPerEvictionRun, pool.getNumTestsPerEvictionRun()); 1066 assertEquals(testOnBorrow,pool.getTestOnBorrow()); 1067 assertEquals(testOnReturn,pool.getTestOnReturn()); 1068 assertEquals(testWhileIdle,pool.getTestWhileIdle()); 1069 assertEquals(timeBetweenEvictionRunsMillis, 1070 pool.getTimeBetweenEvictionRunsMillis()); 1071 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction()); 1072 assertEquals(lifo, pool.getLifo()); 1073 1074 pool = new GenericKeyedObjectPool(null, maxActive); 1075 assertEquals(maxActive, pool.getMaxActive()); 1076 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_IDLE, pool.getMaxIdle()); 1077 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_WAIT, pool.getMaxWait()); 1078 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle()); 1079 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal()); 1080 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, 1081 pool.getMinEvictableIdleTimeMillis()); 1082 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN, 1083 pool.getNumTestsPerEvictionRun()); 1084 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW, 1085 pool.getTestOnBorrow()); 1086 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN, 1087 pool.getTestOnReturn()); 1088 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE, 1089 pool.getTestWhileIdle()); 1090 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, 1091 pool.getTimeBetweenEvictionRunsMillis()); 1092 assertEquals(GenericKeyedObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, 1093 pool.getWhenExhaustedAction()); 1094 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo()); 1095 1096 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction, maxWait); 1097 assertEquals(maxActive, pool.getMaxActive()); 1098 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_IDLE, pool.getMaxIdle()); 1099 assertEquals(maxWait, pool.getMaxWait()); 1100 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle()); 1101 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal()); 1102 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, 1103 pool.getMinEvictableIdleTimeMillis()); 1104 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN, 1105 pool.getNumTestsPerEvictionRun()); 1106 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW, 1107 pool.getTestOnBorrow()); 1108 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN, 1109 pool.getTestOnReturn()); 1110 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE, 1111 pool.getTestWhileIdle()); 1112 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, 1113 pool.getTimeBetweenEvictionRunsMillis()); 1114 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction()); 1115 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo()); 1116 1117 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction, 1118 maxWait, testOnBorrow, testOnReturn); 1119 assertEquals(maxActive, pool.getMaxActive()); 1120 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_IDLE, pool.getMaxIdle()); 1121 assertEquals(maxWait, pool.getMaxWait()); 1122 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle()); 1123 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal()); 1124 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, 1125 pool.getMinEvictableIdleTimeMillis()); 1126 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN, 1127 pool.getNumTestsPerEvictionRun()); 1128 assertEquals(testOnBorrow,pool.getTestOnBorrow()); 1129 assertEquals(testOnReturn,pool.getTestOnReturn()); 1130 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE, 1131 pool.getTestWhileIdle()); 1132 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, 1133 pool.getTimeBetweenEvictionRunsMillis()); 1134 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction()); 1135 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo()); 1136 1137 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction, 1138 maxWait, maxIdle); 1139 assertEquals(maxActive, pool.getMaxActive()); 1140 assertEquals(maxIdle, pool.getMaxIdle()); 1141 assertEquals(maxWait, pool.getMaxWait()); 1142 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle()); 1143 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal()); 1144 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, 1145 pool.getMinEvictableIdleTimeMillis()); 1146 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN, 1147 pool.getNumTestsPerEvictionRun()); 1148 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_BORROW, 1149 pool.getTestOnBorrow()); 1150 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_ON_RETURN, 1151 pool.getTestOnReturn()); 1152 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE, 1153 pool.getTestWhileIdle()); 1154 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, 1155 pool.getTimeBetweenEvictionRunsMillis()); 1156 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction()); 1157 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo()); 1158 1159 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction, 1160 maxWait, maxIdle, testOnBorrow, testOnReturn); 1161 assertEquals(maxActive, pool.getMaxActive()); 1162 assertEquals(maxIdle, pool.getMaxIdle()); 1163 assertEquals(maxWait, pool.getMaxWait()); 1164 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle()); 1165 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal()); 1166 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, 1167 pool.getMinEvictableIdleTimeMillis()); 1168 assertEquals(GenericKeyedObjectPool.DEFAULT_NUM_TESTS_PER_EVICTION_RUN, 1169 pool.getNumTestsPerEvictionRun()); 1170 assertEquals(testOnBorrow, pool.getTestOnBorrow()); 1171 assertEquals(testOnReturn, pool.getTestOnReturn()); 1172 assertEquals(GenericKeyedObjectPool.DEFAULT_TEST_WHILE_IDLE, 1173 pool.getTestWhileIdle()); 1174 assertEquals(GenericKeyedObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, 1175 pool.getTimeBetweenEvictionRunsMillis()); 1176 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction()); 1177 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo()); 1178 1179 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction, 1180 maxWait, maxIdle, testOnBorrow, testOnReturn, 1181 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, 1182 minEvictableIdleTimeMillis, testWhileIdle); 1183 assertEquals(maxActive, pool.getMaxActive()); 1184 assertEquals(maxIdle, pool.getMaxIdle()); 1185 assertEquals(maxWait, pool.getMaxWait()); 1186 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle()); 1187 assertEquals(GenericKeyedObjectPool.DEFAULT_MAX_TOTAL, pool.getMaxTotal()); 1188 assertEquals(minEvictableIdleTimeMillis, 1189 pool.getMinEvictableIdleTimeMillis()); 1190 assertEquals(numTestsPerEvictionRun, 1191 pool.getNumTestsPerEvictionRun()); 1192 assertEquals(testOnBorrow, pool.getTestOnBorrow()); 1193 assertEquals(testOnReturn, pool.getTestOnReturn()); 1194 assertEquals(testWhileIdle, 1195 pool.getTestWhileIdle()); 1196 assertEquals(timeBetweenEvictionRunsMillis, 1197 pool.getTimeBetweenEvictionRunsMillis()); 1198 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction()); 1199 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo()); 1200 1201 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction, 1202 maxWait, maxIdle, maxTotal, testOnBorrow, testOnReturn, 1203 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, 1204 minEvictableIdleTimeMillis, testWhileIdle); 1205 assertEquals(maxActive, pool.getMaxActive()); 1206 assertEquals(maxIdle, pool.getMaxIdle()); 1207 assertEquals(maxWait, pool.getMaxWait()); 1208 assertEquals(GenericKeyedObjectPool.DEFAULT_MIN_IDLE, pool.getMinIdle()); 1209 assertEquals(maxTotal, pool.getMaxTotal()); 1210 assertEquals(minEvictableIdleTimeMillis, 1211 pool.getMinEvictableIdleTimeMillis()); 1212 assertEquals(numTestsPerEvictionRun, 1213 pool.getNumTestsPerEvictionRun()); 1214 assertEquals(testOnBorrow, pool.getTestOnBorrow()); 1215 assertEquals(testOnReturn, pool.getTestOnReturn()); 1216 assertEquals(testWhileIdle, 1217 pool.getTestWhileIdle()); 1218 assertEquals(timeBetweenEvictionRunsMillis, 1219 pool.getTimeBetweenEvictionRunsMillis()); 1220 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction()); 1221 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo()); 1222 1223 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction, 1224 maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn, 1225 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, 1226 minEvictableIdleTimeMillis, testWhileIdle); 1227 assertEquals(maxActive, pool.getMaxActive()); 1228 assertEquals(maxIdle, pool.getMaxIdle()); 1229 assertEquals(maxWait, pool.getMaxWait()); 1230 assertEquals(minIdle, pool.getMinIdle()); 1231 assertEquals(maxTotal, pool.getMaxTotal()); 1232 assertEquals(minEvictableIdleTimeMillis, 1233 pool.getMinEvictableIdleTimeMillis()); 1234 assertEquals(numTestsPerEvictionRun, 1235 pool.getNumTestsPerEvictionRun()); 1236 assertEquals(testOnBorrow, pool.getTestOnBorrow()); 1237 assertEquals(testOnReturn, pool.getTestOnReturn()); 1238 assertEquals(testWhileIdle, 1239 pool.getTestWhileIdle()); 1240 assertEquals(timeBetweenEvictionRunsMillis, 1241 pool.getTimeBetweenEvictionRunsMillis()); 1242 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction()); 1243 assertEquals(GenericKeyedObjectPool.DEFAULT_LIFO, pool.getLifo()); 1244 1245 pool = new GenericKeyedObjectPool(null, maxActive, whenExhaustedAction, 1246 maxWait, maxIdle, maxTotal, minIdle, testOnBorrow, testOnReturn, 1247 timeBetweenEvictionRunsMillis, numTestsPerEvictionRun, 1248 minEvictableIdleTimeMillis, testWhileIdle, lifo); 1249 assertEquals(maxActive, pool.getMaxActive()); 1250 assertEquals(maxIdle, pool.getMaxIdle()); 1251 assertEquals(maxWait, pool.getMaxWait()); 1252 assertEquals(minIdle, pool.getMinIdle()); 1253 assertEquals(maxTotal, pool.getMaxTotal()); 1254 assertEquals(minEvictableIdleTimeMillis, 1255 pool.getMinEvictableIdleTimeMillis()); 1256 assertEquals(numTestsPerEvictionRun, 1257 pool.getNumTestsPerEvictionRun()); 1258 assertEquals(testOnBorrow, pool.getTestOnBorrow()); 1259 assertEquals(testOnReturn, pool.getTestOnReturn()); 1260 assertEquals(testWhileIdle, 1261 pool.getTestWhileIdle()); 1262 assertEquals(timeBetweenEvictionRunsMillis, 1263 pool.getTimeBetweenEvictionRunsMillis()); 1264 assertEquals(whenExhaustedAction,pool.getWhenExhaustedAction()); 1265 assertEquals(lifo, pool.getLifo()); 1266 } 1267 1268 public void testExceptionOnPassivateDuringReturn() throws Exception { 1269 SimpleFactory factory = new SimpleFactory(); 1270 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory); 1271 Object obj = pool.borrowObject("one"); 1272 factory.setThrowExceptionOnPassivate(true); 1273 pool.returnObject("one", obj); 1274 assertEquals(0,pool.getNumIdle()); 1275 pool.close(); 1276 } 1277 1278 public void testExceptionOnDestroyDuringBorrow() throws Exception { 1279 SimpleFactory factory = new SimpleFactory(); 1280 factory.setThrowExceptionOnDestroy(true); 1281 factory.setValidationEnabled(true); 1282 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory); 1283 pool.setTestOnBorrow(true); 1284 pool.borrowObject("one"); 1285 factory.setValid(false); // Make validation fail on next borrow attempt 1286 try { 1287 pool.borrowObject("one"); 1288 fail("Expecting NoSuchElementException"); 1289 } catch (NoSuchElementException ex) { 1290 // expected 1291 } 1292 assertEquals(1, pool.getNumActive("one")); 1293 assertEquals(0, pool.getNumIdle("one")); 1294 assertEquals(1, pool.getNumActive()); 1295 assertEquals(0, pool.getNumIdle()); 1296 } 1297 1298 public void testExceptionOnDestroyDuringReturn() throws Exception { 1299 SimpleFactory factory = new SimpleFactory(); 1300 factory.setThrowExceptionOnDestroy(true); 1301 factory.setValidationEnabled(true); 1302 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory); 1303 pool.setTestOnReturn(true); 1304 Object obj1 = pool.borrowObject("one"); 1305 pool.borrowObject("one"); 1306 factory.setValid(false); // Make validation fail 1307 pool.returnObject("one", obj1); 1308 assertEquals(1, pool.getNumActive("one")); 1309 assertEquals(0, pool.getNumIdle("one")); 1310 assertEquals(1, pool.getNumActive()); 1311 assertEquals(0, pool.getNumIdle()); 1312 } 1313 1314 public void testExceptionOnActivateDuringBorrow() throws Exception { 1315 SimpleFactory factory = new SimpleFactory(); 1316 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory); 1317 Object obj1 = pool.borrowObject("one"); 1318 Object obj2 = pool.borrowObject("one"); 1319 pool.returnObject("one", obj1); 1320 pool.returnObject("one", obj2); 1321 factory.setThrowExceptionOnActivate(true); 1322 factory.setEvenValid(false); 1323 // Activation will now throw every other time 1324 // First attempt throws, but loop continues and second succeeds 1325 Object obj = pool.borrowObject("one"); 1326 assertEquals(1, pool.getNumActive("one")); 1327 assertEquals(0, pool.getNumIdle("one")); 1328 assertEquals(1, pool.getNumActive()); 1329 assertEquals(0, pool.getNumIdle()); 1330 1331 pool.returnObject("one", obj); 1332 factory.setValid(false); 1333 // Validation will now fail on activation when borrowObject returns 1334 // an idle instance, and then when attempting to create a new instance 1335 try { 1336 pool.borrowObject("one"); 1337 fail("Expecting NoSuchElementException"); 1338 } catch (NoSuchElementException ex) { 1339 // expected 1340 } 1341 assertEquals(0, pool.getNumActive("one")); 1342 assertEquals(0, pool.getNumIdle("one")); 1343 assertEquals(0, pool.getNumActive()); 1344 assertEquals(0, pool.getNumIdle()); 1345 } 1346 1347 public void testBlockedKeyDoesNotBlockPool() throws Exception { 1348 SimpleFactory factory = new SimpleFactory(); 1349 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory); 1350 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK); 1351 pool.setMaxWait(5000); 1352 pool.setMaxActive(1); 1353 pool.setMaxTotal(-1); 1354 pool.borrowObject("one"); 1355 long start = System.currentTimeMillis(); 1356 // Needs to be in a separate thread as this will block 1357 Runnable simple = new SimpleTestThread(pool, "one"); 1358 (new Thread(simple)).start(); 1359 // This should be almost instant. If it isn't it means this thread got 1360 // stuck behind the thread created above which is bad. 1361 // Give other thread a chance to start 1362 Thread.sleep(1000); 1363 pool.borrowObject("two"); 1364 long end = System.currentTimeMillis(); 1365 // If it fails it will be more than 4000ms (5000 less the 1000 sleep) 1366 // If it passes it should be almost instant 1367 // Use 3000ms as the threshold - should avoid timing issues on most 1368 // (all? platforms) 1369 assertTrue ("Elapsed time: "+(end-start)+" should be less than 4000",(end-start) < 4000); 1370 1371 } 1372 1373 private static final boolean DISPLAY_THREAD_DETAILS= 1374 Boolean.valueOf(System.getProperty("TestGenericKeyedObjectPool.display.thread.details", "false")).booleanValue(); 1375 // To pass this to a Maven test, use: 1376 // mvn test -DargLine="-DTestGenericKeyedObjectPool.display.thread.details=true" 1377 // @see http://jira.codehaus.org/browse/SUREFIRE-121 1378 1379 /* 1380 * Test multi-threaded pool access. 1381 * Multiple keys, multiple threads, but maxActive only allows half the threads to succeed. 1382 * 1383 * This test was prompted by Continuum build failures in the Commons DBCP test case: 1384 * TestSharedPoolDataSource.testMultipleThreads2() 1385 * Let's see if the this fails on Continuum too! 1386 */ 1387 public void testMaxWaitMultiThreaded() throws Exception { 1388 final long maxWait = 500; // wait for connection 1389 final long holdTime = 2 * maxWait; // how long to hold connection 1390 final int keyCount = 4; // number of different keys 1391 final int threadsPerKey = 5; // number of threads to grab the key initially 1392 SimpleFactory factory = new SimpleFactory(); 1393 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory); 1394 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK); 1395 pool.setMaxWait(maxWait); 1396 pool.setMaxActive(threadsPerKey); 1397 // Create enough threads so half the threads will have to wait 1398 WaitingTestThread wtt[] = new WaitingTestThread[keyCount * threadsPerKey * 2]; 1399 for(int i=0; i < wtt.length; i++){ 1400 wtt[i] = new WaitingTestThread(pool,Integer.toString(i % keyCount),holdTime); 1401 } 1402 long origin = System.currentTimeMillis()-1000; 1403 for(int i=0; i < wtt.length; i++){ 1404 wtt[i].start(); 1405 } 1406 int failed = 0; 1407 for(int i=0; i < wtt.length; i++){ 1408 wtt[i].join(); 1409 if (wtt[i]._thrown != null){ 1410 failed++; 1411 } 1412 } 1413 if (DISPLAY_THREAD_DETAILS || wtt.length/2 != failed){ 1414 System.out.println( 1415 "MaxWait: "+maxWait 1416 +" HoldTime: "+holdTime 1417 +" KeyCount: "+keyCount 1418 +" MaxActive: "+threadsPerKey 1419 +" Threads: "+wtt.length 1420 +" Failed: "+failed 1421 ); 1422 for(int i=0; i < wtt.length; i++){ 1423 WaitingTestThread wt = wtt[i]; 1424 System.out.println( 1425 "Preborrow: "+(wt.preborrow-origin) 1426 + " Postborrow: "+(wt.postborrow != 0 ? wt.postborrow-origin : -1) 1427 + " BorrowTime: "+(wt.postborrow != 0 ? wt.postborrow-wt.preborrow : -1) 1428 + " PostReturn: "+(wt.postreturn != 0 ? wt.postreturn-origin : -1) 1429 + " Ended: "+(wt.ended-origin) 1430 + " Key: "+(wt._key) 1431 + " ObjId: "+wt.objectId 1432 ); 1433 } 1434 } 1435 assertEquals("Expected half the threads to fail",wtt.length/2,failed); 1436 } 1437 1438 /** 1439 * Test case for POOL-180. 1440 */ 1441 public void testMaxActivePerKeyExceeded() { 1442 WaiterFactory factory = new WaiterFactory(0, 20, 0, 0, 0, 0, 8, 5, 0); 1443 pool = new GenericKeyedObjectPool(factory); 1444 pool.setMaxActive(5); 1445 pool.setMaxTotal(8); 1446 pool.setTestOnBorrow(true); 1447 pool.setMaxIdle(5); 1448 pool.setMaxWait(-1); 1449 runTestThreads(20, 300, 250); 1450 } 1451 1452 /** 1453 * POOL-192 1454 * Verify that clear(key) does not leak capacity due to _numInternalProcessing 1455 * not being decremented. 1456 */ 1457 public void testClear() throws Exception { 1458 SimpleFactory factory = new SimpleFactory(); 1459 GenericKeyedObjectPool pool = new GenericKeyedObjectPool(factory); 1460 pool.setMaxTotal(2); 1461 pool.setMaxActive(2); 1462 pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL); 1463 pool.addObject("one"); 1464 pool.addObject("one"); 1465 assertEquals(2, pool.getNumIdle()); 1466 pool.clear("one"); 1467 assertEquals(0, pool.getNumIdle()); 1468 assertEquals(0, pool.getNumIdle("one")); 1469 Object obj1 = pool.borrowObject("one"); 1470 Object obj2 = pool.borrowObject("one"); 1471 pool.returnObject("one", obj1); 1472 pool.returnObject("one", obj2); 1473 pool.clear(); 1474 assertEquals(0, pool.getNumIdle()); 1475 assertEquals(0, pool.getNumIdle("one")); 1476 pool.borrowObject("one"); 1477 pool.borrowObject("one"); 1478 pool.close(); 1479 } 1480 1481 /* 1482 * Very simple test thread that just tries to borrow an object from 1483 * the provided pool with the specified key and returns it 1484 */ 1485 static class SimpleTestThread implements Runnable { 1486 private final KeyedObjectPool _pool; 1487 private final String _key; 1488 1489 public SimpleTestThread(KeyedObjectPool pool, String key) { 1490 _pool = pool; 1491 _key = key; 1492 } 1493 1494 public void run() { 1495 try { 1496 Object obj = _pool.borrowObject(_key); 1497 _pool.returnObject(_key, obj); 1498 } catch (Exception e) { 1499 // Ignore 1500 } 1501 } 1502 } 1503 1504 /* 1505 * Very simple test thread that just tries to borrow an object from 1506 * the provided pool with the specified key and returns it after a wait 1507 */ 1508 static class WaitingTestThread extends Thread { 1509 private final KeyedObjectPool _pool; 1510 private final String _key; 1511 private final long _pause; 1512 private Throwable _thrown; 1513 1514 private long preborrow; // just before borrow 1515 private long postborrow; // borrow returned 1516 private long postreturn; // after object was returned 1517 private long ended; 1518 private String objectId; 1519 1520 public WaitingTestThread(KeyedObjectPool pool, String key, long pause) { 1521 _pool = pool; 1522 _key = key; 1523 _pause = pause; 1524 _thrown = null; 1525 } 1526 1527 public void run() { 1528 try { 1529 preborrow = System.currentTimeMillis(); 1530 Object obj = _pool.borrowObject(_key); 1531 objectId=obj.toString(); 1532 postborrow = System.currentTimeMillis(); 1533 Thread.sleep(_pause); 1534 _pool.returnObject(_key, obj); 1535 postreturn = System.currentTimeMillis(); 1536 } catch (Exception e) { 1537 _thrown = e; 1538 } finally{ 1539 ended = System.currentTimeMillis(); 1540 } 1541 } 1542 } 1543 1544 static class TestThread implements Runnable { 1545 private final java.util.Random _random = new java.util.Random(); 1546 1547 // Thread config items 1548 private final KeyedObjectPool _pool; 1549 private final int _iter; 1550 private final int _delay; 1551 1552 private volatile boolean _complete = false; 1553 private volatile boolean _failed = false; 1554 private volatile Exception _exception; 1555 1556 public TestThread(KeyedObjectPool pool) { 1557 this(pool, 100, 50); 1558 } 1559 1560 public TestThread(KeyedObjectPool pool, int iter) { 1561 this(pool, iter, 50); 1562 } 1563 1564 public TestThread(KeyedObjectPool pool, int iter, int delay) { 1565 _pool = pool; 1566 _iter = iter; 1567 _delay = delay; 1568 } 1569 1570 public boolean complete() { 1571 return _complete; 1572 } 1573 1574 public boolean failed() { 1575 return _failed; 1576 } 1577 1578 public void run() { 1579 for(int i=0;i<_iter;i++) { 1580 String key = String.valueOf(_random.nextInt(3)); 1581 try { 1582 Thread.sleep(_random.nextInt(_delay)); 1583 } catch(InterruptedException e) { 1584 // ignored 1585 } 1586 Object obj = null; 1587 try { 1588 obj = _pool.borrowObject(key); 1589 } catch(Exception e) { 1590 _exception = e; 1591 _failed = true; 1592 _complete = true; 1593 break; 1594 } 1595 1596 try { 1597 Thread.sleep(_random.nextInt(_delay)); 1598 } catch(InterruptedException e) { 1599 // ignored 1600 } 1601 try { 1602 _pool.returnObject(key,obj); 1603 } catch(Exception e) { 1604 _exception = e; 1605 _failed = true; 1606 _complete = true; 1607 break; 1608 } 1609 } 1610 _complete = true; 1611 } 1612 } 1613 1614 static class SimpleFactory implements KeyedPoolableObjectFactory { 1615 public SimpleFactory() { 1616 this(true); 1617 } 1618 public SimpleFactory(boolean valid) { 1619 this.valid = valid; 1620 } 1621 public Object makeObject(Object key) { 1622 synchronized(this) { 1623 activeCount++; 1624 if (activeCount > maxActive) { 1625 throw new IllegalStateException( 1626 "Too many active instances: " + activeCount); 1627 } 1628 } 1629 return String.valueOf(key) + String.valueOf(counter++); 1630 } 1631 public void destroyObject(Object key, Object obj) throws Exception { 1632 doWait(destroyLatency); 1633 synchronized(this) { 1634 activeCount--; 1635 } 1636 if (exceptionOnDestroy) { 1637 throw new Exception(); 1638 } 1639 } 1640 public boolean validateObject(Object key, Object obj) { 1641 if (enableValidation) { 1642 return validateCounter++%2 == 0 ? evenValid : oddValid; 1643 } else { 1644 return valid; 1645 } 1646 } 1647 public void activateObject(Object key, Object obj) throws Exception { 1648 if (exceptionOnActivate) { 1649 if (!(validateCounter++%2 == 0 ? evenValid : oddValid)) { 1650 throw new Exception(); 1651 } 1652 } 1653 } 1654 public void passivateObject(Object key, Object obj) throws Exception { 1655 if (exceptionOnPassivate) { 1656 throw new Exception(); 1657 } 1658 } 1659 1660 public void setMaxActive(int maxActive) { 1661 this.maxActive = maxActive; 1662 } 1663 public void setDestroyLatency(long destroyLatency) { 1664 this.destroyLatency = destroyLatency; 1665 } 1666 public void setValidationEnabled(boolean b) { 1667 enableValidation = b; 1668 } 1669 void setEvenValid(boolean valid) { 1670 evenValid = valid; 1671 } 1672 void setValid(boolean valid) { 1673 evenValid = valid; 1674 oddValid = valid; 1675 } 1676 1677 public void setThrowExceptionOnActivate(boolean b) { 1678 exceptionOnActivate = b; 1679 } 1680 1681 public void setThrowExceptionOnDestroy(boolean b) { 1682 exceptionOnDestroy = b; 1683 } 1684 1685 public void setThrowExceptionOnPassivate(boolean b) { 1686 exceptionOnPassivate = b; 1687 } 1688 1689 int counter = 0; 1690 boolean valid; 1691 1692 int activeCount = 0; 1693 int validateCounter = 0; 1694 boolean evenValid = true; 1695 boolean oddValid = true; 1696 boolean enableValidation = false; 1697 long destroyLatency = 0; 1698 int maxActive = Integer.MAX_VALUE; 1699 boolean exceptionOnPassivate = false; 1700 boolean exceptionOnActivate = false; 1701 boolean exceptionOnDestroy = false; 1702 1703 private void doWait(long latency) { 1704 try { 1705 Thread.sleep(latency); 1706 } catch (InterruptedException ex) { 1707 // ignore 1708 } 1709 } 1710 } 1711 1712 protected boolean isLifo() { 1713 return true; 1714 } 1715 1716 protected boolean isFifo() { 1717 return false; 1718 } 1719 1720 private String getExceptionTrace(Throwable t){ 1721 StringWriter sw = new StringWriter(); 1722 t.printStackTrace(new PrintWriter(sw)); 1723 return sw.toString(); 1724 } 1725 1726 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, 1727 String s4, int i4, String s5, int i5, String s6, int i6, int zeroLength, int oneLength, int twoLength){ 1728 StringBuffer sb = new StringBuffer(80); 1729 sb.append(title).append(' '); 1730 sb.append(s).append('=').append(i).append(' '); 1731 sb.append(s0).append('=').append(b0).append(' '); 1732 sb.append(s1).append('=').append(i1).append(' '); 1733 sb.append(s2).append('=').append(i2).append(' '); 1734 sb.append(s3).append('=').append(i3).append(' '); 1735 sb.append(s4).append('=').append(i4).append(' '); 1736 sb.append(s5).append('=').append(i5).append(' '); 1737 sb.append(s6).append('=').append(i6).append(' '); 1738 sb.append("Lengths=").append(zeroLength).append(',').append(oneLength).append(',').append(twoLength).append(' '); 1739 return sb.toString(); 1740 } 1741 1742 } 1743 1744