1 18 package org.objectweb.perseus.pool; 19 20 import junit.framework.TestCase; 21 import org.objectweb.util.monolog.api.Logger; 22 import org.objectweb.util.monolog.api.LoggerFactory; 23 import org.objectweb.util.monolog.api.BasicLevel; 24 import org.objectweb.util.monolog.Monolog; 25 import org.objectweb.perseus.pool.api.Pool; 26 import org.objectweb.perseus.pool.api.PoolAttributes; 27 import org.objectweb.perseus.pool.api.PoolMatchFactory; 28 import org.objectweb.perseus.pool.api.PoolException; 29 import org.objectweb.perseus.pool.lib.ArrayListPool; 30 import org.objectweb.perseus.dependency.api.DependencyGraph; 31 import org.objectweb.perseus.dependency.api.DeadLockException; 32 import org.objectweb.perseus.dependency.lib.BasicDependencyGraph; 33 import org.objectweb.fractal.api.control.BindingController; 34 35 39 public class TestPool extends TestCase implements PoolMatchFactory { 40 41 static Logger logger; 42 static Logger poolLogger; 43 static LoggerFactory loggerFactory; 44 45 private int resourceCpt = 0; 46 public TestPool(String s) { 47 super(s); 48 if (logger == null) { 49 synchronized(Monolog.class) { 50 if (logger == null) { 51 loggerFactory = Monolog.initialize(); 52 logger = loggerFactory.getLogger(getClass().getName()); 53 poolLogger = loggerFactory.getLogger( 54 instanciatePool().getClass().getName()); 55 } 56 } 57 } 58 } 59 60 protected void tearDown() throws Exception { 61 resourceCpt = 0; 62 } 63 64 70 public Object createResource(Object hints) throws PoolException { 71 resourceCpt ++; 72 return (hints == null ? new Integer (resourceCpt) : hints); 73 } 74 75 85 public boolean matchResource(Object resource, Object hints) { 86 return true; 87 } 88 89 95 public void destroyResource(Object resource) { 96 } 97 98 protected Pool instanciatePool() { 99 return new ArrayListPool(); 100 } 101 private Pool getPool(int min, int max, long inactivettl, long ttl, long timeout, DependencyGraph dg) { 102 Pool pool = instanciatePool(); 103 try { 104 BindingController bc = (BindingController) pool; 105 bc.bindFc("logger", poolLogger); 106 bc.bindFc("monolog-factory", loggerFactory); 107 bc.bindFc("dependency-graph", dg); 108 bc.bindFc("pool-match-factory", this); 109 PoolAttributes pa = (PoolAttributes) pool; 110 pa.setMinSize(min); 111 pa.setMaxSize(max); 112 pa.setTTL(ttl); 113 pa.setInactiveTTL(inactivettl); 114 pa.setTimeout(timeout); 115 } catch (Exception e) { 116 String msg = "Initialisation error: "; 117 logger.log(BasicLevel.ERROR, msg, e); 118 fail(msg + e.getMessage()); 119 } 120 return pool; 121 } 122 public void testNoWait() throws PoolException { 123 Pool pool = getPool(0, 1, 0, -1, 0, null); 124 pool.getResource(new Integer (0)); 125 try { 126 pool.getResource(new Integer (3)); 127 fail(""); 128 } catch (PoolException e) { 129 } 130 } 131 public void testWaitUntilRelease() throws PoolException { 132 final Pool pool = getPool(0, 1, 0, -1, -1, null); 133 Object r = pool.getResource(new Integer (0)); 134 final Boolean [] b = new Boolean [1]; 135 b[0] = Boolean.FALSE; 136 Thread t = new Thread (new Runnable () { 137 public void run () { 138 try { 139 pool.getResource(new Integer (3)); 140 if (!b[0].booleanValue()) { 141 fail("Resource obtained"); 142 } 143 } catch (PoolException e) { 144 String msg = "Allocation error: "; 145 logger.log(BasicLevel.ERROR, msg, e); 146 fail(msg + e.getMessage()); 147 } 148 }}); 149 t.start(); 150 Thread.yield(); 151 try { 152 t.join(500); 153 } catch (InterruptedException e) { 154 } 155 assertTrue("Thread not blocked", t.isAlive()); 156 b[0] = Boolean.TRUE; 157 pool.releaseResource(r); 158 try { 159 t.join(500); 160 } catch (InterruptedException e) { 161 } 162 assertTrue("Thread blocked", !t.isAlive()); 163 164 } 165 166 public void testMinSize() throws PoolException { 167 Pool pool = getPool(5, 10, 0, -1, 500, null); 168 pool.getResource(new Integer (2)); 169 assertEquals("Bad min", 5, resourceCpt); 170 } 171 public void testWait500() throws PoolException { 172 final Pool pool = getPool(0, 1, 0, -1, 500, null); 173 pool.getResource(new Integer (0)); 174 Thread t = new Thread (new Runnable () { 175 public void run () { 176 try { 177 pool.getResource(new Integer (3)); 178 fail("Resource obtained"); 179 } catch (PoolException e) { 180 } 181 }}); 182 t.start(); 183 try { 184 t.join(600); 185 } catch (InterruptedException e) { 186 } 187 assertTrue("Thread blocked", !t.isAlive()); 188 } 189 190 protected DependencyGraph instanciateDependencyGraph() { 191 return new BasicDependencyGraph(); 192 } 193 protected DependencyGraph getDependencyGraph() { 194 DependencyGraph dg = instanciateDependencyGraph(); 195 try { 196 BindingController bc = (BindingController) dg; 197 bc.bindFc("logger", poolLogger); 198 bc.bindFc("monolog-factory", loggerFactory); 199 } catch (Exception e) { 200 String msg = "DG Initialisation error: "; 201 logger.log(BasicLevel.ERROR, msg, e); 202 fail(msg + e.getMessage()); 203 } 204 return dg; 205 } 206 public void testDG() throws PoolException, DeadLockException { 207 final Pool pool = getPool(0, 2, 0, -1, -1, getDependencyGraph()); 208 final String [] users = new String [] {"user1", "user2"}; 209 final Object [] resources = new Object [] {"res1", "res2"}; 210 pool.getResource(resources[0], users[0]); 211 pool.getResource(resources[1], users[1]); 212 Thread t = new Thread (new Runnable () { 213 public void run () { 214 try { 215 pool.getResource(resources[1], users[0]); 216 } catch (Exception e) { 217 } 218 }}); 219 t.start(); 220 Thread.yield(); 221 try { 222 t.join(100); 223 } catch (InterruptedException e) { 224 } 225 try { 226 pool.getResource(resources[0], users[1]); 227 fail("No DeadLockException"); 228 } catch (DeadLockException e) { 229 } 230 pool.releaseResource(resources[0]); 231 pool.releaseResource(resources[1]); 232 try { 233 t.join(200); 234 } catch (InterruptedException e) { 235 } 236 assertTrue("Thread blocked", !t.isAlive()); 237 } 238 239 public void testInactiveTTL() throws PoolException, DeadLockException { 240 final int InactiveTTL = 5 * 1000; logger.log(BasicLevel.INFO, "testInactiveTTL(" + InactiveTTL + ")"); 242 Pool pool = getPool(5, 10, InactiveTTL, -1, 500, null); 243 pool.releaseResource(pool.getResource(null)); 245 246 Object r1 = pool.getResource(new Integer (2)); 248 pool.releaseResource(r1); 249 250 Object r2 = pool.getResource(new Integer (2)); 253 assertTrue("Resources are different, r1=" + r1 + ", r2=" + r2, r1 == r2); 254 pool.releaseResource(r2); 255 256 try { 258 Thread.sleep(2 * InactiveTTL); 259 } catch (InterruptedException e) { 260 fail(e.getMessage()); 261 } 262 263 r2 = pool.getResource(new Integer (2)); 266 assertTrue("Same resource, r1=" + r1 + ", r2=" + r2, r1 != r2); 267 } 268 269 public void testTTL1() throws PoolException, DeadLockException { 270 final int TTL = 5 * 1000; 271 logger.log(BasicLevel.INFO, "testTTL1(" + TTL + ")"); 272 Pool pool = getPool(5, 10, -1, TTL, 500, null); 273 pool.releaseResource(pool.getResource(null)); 275 276 Object r1 = pool.getResource(new Integer (2)); 278 pool.releaseResource(r1); 279 280 Object r2 = pool.getResource(new Integer (2)); 283 assertTrue("Resources are different, r1=" + r1 + ", r2=" + r2, r1 == r2); 284 pool.releaseResource(r2); 285 286 try { 287 Thread.sleep(2 * TTL); 288 } catch (InterruptedException e) { 289 fail(e.getMessage()); 290 } 291 292 r2 = pool.getResource(new Integer (2)); 295 assertTrue("Same resource, r1=" + r1 + ", r2=" + r2, r1 != r2); 296 } 297 298 public void testTTL2() throws PoolException, DeadLockException { 299 final int TTL = 5 * 1000; 300 logger.log(BasicLevel.INFO, "testTTL2(" + TTL + ")"); 301 Pool pool = getPool(3, 10, -1, TTL, 500, null); 302 pool.releaseResource(pool.getResource(null)); 304 305 Object r1 = pool.getResource(new Integer (2)); 307 pool.releaseResource(r1); 308 309 Object r2 = pool.getResource(new Integer (2)); 312 assertTrue("Resources are different, r1=" + r1 + ", r2=" + r2, r1 == r2); 313 314 try { 315 Thread.sleep(2 * TTL); 316 } catch (InterruptedException e) { 317 fail(e.getMessage()); 318 } 319 pool.releaseResource(r2); 320 321 r2 = pool.getResource(new Integer (2)); 324 assertTrue("Same resource, r1=" + r1 + ", r2=" + r2, r1 != r2); 325 } 326 327 protected void setUp() throws Exception { 328 allocTime = 0; 329 nballoc = 0; 330 } 331 332 private long allocTime = 0; 333 private long nballoc = 0; 334 public void testStress(final int nbThread, 335 final int poolMaxSize, 336 final int nbAllocResource, 337 final int sleep 338 ) { 339 logger.log(BasicLevel.INFO, "* testStress: nbThread=" + nbThread 340 + ", poolMaxSize=" + poolMaxSize 341 + ", nbAllocResource=" + nbAllocResource 342 + ", sleep=" + sleep); 343 final Pool pool = getPool(0, poolMaxSize, 0, -1, -1, null); 344 final Thread [] t = new Thread [nbThread]; 345 for(int i=0; i<nbThread; i++) { 346 final int threadId = i; 347 t[threadId] = new Thread (new Runnable () { 348 public void run () { 349 for(int j=0; j<nbAllocResource; j++) { 350 try { 351 long exectime = System.currentTimeMillis(); 352 Object r = pool.getResource(new Integer (3)); 353 if (sleep > 0) { 354 Thread.sleep(sleep); 355 } 356 pool.releaseResource(r); 357 exectime = System.currentTimeMillis() - exectime; 358 synchronized(t) { 359 nballoc ++; 360 allocTime += exectime; 361 } 362 } catch (PoolException e) { 363 String msg = "Thread=" + threadId + ", alloc=" + j + " error: "; 364 logger.log(BasicLevel.ERROR, msg, e); 365 fail(msg + e.getMessage()); 366 } catch (InterruptedException e) { 367 } 368 } 369 }}); 370 } 371 long exectime = System.currentTimeMillis(); 372 for(int threadId=0; threadId<nbThread; threadId++) { 373 t[threadId].start(); 374 } 375 for(int threadId=0; threadId<nbThread; threadId++) { 376 try { 377 t[threadId].join(100000); 378 } catch (InterruptedException e) { 379 } 380 } 381 exectime = System.currentTimeMillis() - exectime; 382 for(int threadId=0; threadId<nbThread; threadId++) { 383 assertTrue("Thread blocked", !t[threadId].isAlive()); 384 } 385 assertTrue("Bad pool size", pool.getSize() <= poolMaxSize); 386 int nbAllAllocation = nbThread * nbAllocResource; 387 logger.log(BasicLevel.INFO, "\tExecution time: " + exectime 388 + "ms, nb allocation: " + nbAllAllocation); 389 logger.log(BasicLevel.INFO, "\tAverage Allocation time: " + 390 (allocTime / nballoc) + "ms (sleep=" + sleep + "), rate: " 391 + ((nbAllAllocation * 1000) /exectime) + " alloc/s"); 392 } 393 394 public void testStressTh20Max20Alloc100Sleep10() { 395 testStress(20, 20, 100, 10); 396 } 397 public void testStressTh20Max20Alloc100Sleep100() { 398 testStress(20, 20, 100, 100); 399 } 400 public void testStressTh20Max10Alloc100Sleep100() { 401 testStress(20, 10, 100, 100); 402 } 403 public void testStressTh200Max100Alloc500Sleep50() { 404 testStress(200, 100, 500, 50); 405 } 406 public void testStressTh100Max100Alloc5000Sleep0() { 407 testStress(100, 100, 5000, 0); 408 } 409 } 410 | Popular Tags |