KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > perseus > pool > TestPool


1 /**
2  * Copyright (C) 2001-2003 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

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 /**
36  *
37  * @author S.Chassande-Barrioz
38  */

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 JavaDoc 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 JavaDoc {
61         resourceCpt = 0;
62     }
63
64     /**
65      * <b>createResource</b> creates a new PoolResource.
66      * @param hints The "properties" that the created PoolResource should
67      * conform to.
68      * @return The created PoolResource.
69      */

70     public Object JavaDoc createResource(Object JavaDoc hints) throws PoolException {
71         resourceCpt ++;
72         return (hints == null ? new Integer JavaDoc(resourceCpt) : hints);
73     }
74
75     /**
76      * <b>matchResource</b> tests if a given resource of a Pool matches with
77      * the hints passed with the Pool getResource method.
78      * @param resource The PoolResource to test its matching with some
79      * "properties" specified by hints.
80      * @param hints The "properties" that the PoolResource specified by pr
81      * should match.
82      * @return <b>true</b> if the pr PoolResource matches the hints
83      * "properties".
84      */

85     public boolean matchResource(Object JavaDoc resource, Object JavaDoc hints) {
86         return true;
87     }
88
89     /**
90      * is called when a resource is going to be destroyed. This method permits
91      * to close physical resource for example.
92      *
93      * @param resource to initialize.
94      */

95     public void destroyResource(Object JavaDoc 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 JavaDoc e) {
116             String JavaDoc 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 JavaDoc(0));
125         try {
126             pool.getResource(new Integer JavaDoc(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 JavaDoc r = pool.getResource(new Integer JavaDoc(0));
134         final Boolean JavaDoc[] b = new Boolean JavaDoc[1];
135         b[0] = Boolean.FALSE;
136         Thread JavaDoc t = new Thread JavaDoc(new Runnable JavaDoc () {
137             public void run () {
138                 try {
139                     pool.getResource(new Integer JavaDoc(3));
140                     if (!b[0].booleanValue()) {
141                         fail("Resource obtained");
142                     }
143                 } catch (PoolException e) {
144                     String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc(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 JavaDoc(0));
174         Thread JavaDoc t = new Thread JavaDoc(new Runnable JavaDoc () {
175             public void run () {
176                 try {
177                     pool.getResource(new Integer JavaDoc(3));
178                     fail("Resource obtained");
179                 } catch (PoolException e) {
180                 }
181             }});
182         t.start();
183         try {
184             t.join(600);
185         } catch (InterruptedException JavaDoc 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 JavaDoc e) {
200             String JavaDoc 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 JavaDoc[] users = new String JavaDoc[] {"user1", "user2"};
209         final Object JavaDoc[] resources = new Object JavaDoc[] {"res1", "res2"};
210         pool.getResource(resources[0], users[0]);
211         pool.getResource(resources[1], users[1]);
212         Thread JavaDoc t = new Thread JavaDoc(new Runnable JavaDoc () {
213             public void run () {
214                 try {
215                      pool.getResource(resources[1], users[0]);
216                 } catch (Exception JavaDoc e) {
217                 }
218             }});
219         t.start();
220         Thread.yield();
221         try {
222             t.join(100);
223         } catch (InterruptedException JavaDoc 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 JavaDoc e) {
235         }
236         assertTrue("Thread blocked", !t.isAlive());
237     }
238
239     public void testInactiveTTL() throws PoolException, DeadLockException {
240         final int InactiveTTL = 5 * 1000; //10s
241
logger.log(BasicLevel.INFO, "testInactiveTTL(" + InactiveTTL + ")");
242         Pool pool = getPool(5, 10, InactiveTTL, -1, 500, null);
243         //init resource from the pool
244
pool.releaseResource(pool.getResource(null));
245         
246         //fetch a resource reference
247
Object JavaDoc r1 = pool.getResource(new Integer JavaDoc(2));
248         pool.releaseResource(r1);
249         
250         //fetch again the resource: the inactivettl should not be expired
251
//Then the resouce should be the same
252
Object JavaDoc r2 = pool.getResource(new Integer JavaDoc(2));
253         assertTrue("Resources are different, r1=" + r1 + ", r2=" + r2, r1 == r2);
254         pool.releaseResource(r2);
255         
256         //Wait 2 InactiveTTL
257
try {
258             Thread.sleep(2 * InactiveTTL);
259         } catch (InterruptedException JavaDoc e) {
260             fail(e.getMessage());
261         }
262
263         //fetch again the resource: the inactivettl should be expired
264
//Then the resouce should be different
265
r2 = pool.getResource(new Integer JavaDoc(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         //init resource from the pool
274
pool.releaseResource(pool.getResource(null));
275
276         //fetch a resource reference
277
Object JavaDoc r1 = pool.getResource(new Integer JavaDoc(2));
278         pool.releaseResource(r1);
279         
280         //fetch again the resource: the ttl should not be expired
281
//Then the resouce should be the same
282
Object JavaDoc r2 = pool.getResource(new Integer JavaDoc(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 JavaDoc e) {
289             fail(e.getMessage());
290         }
291
292         //fetch again the resource: the ttl should be expired
293
//Then the resouce should be different
294
r2 = pool.getResource(new Integer JavaDoc(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         //init resource from the pool
303
pool.releaseResource(pool.getResource(null));
304
305         //fetch a resource reference
306
Object JavaDoc r1 = pool.getResource(new Integer JavaDoc(2));
307         pool.releaseResource(r1);
308         
309         //fetch again the resource: the ttl should not be expired
310
//Then the resouce should be the same
311
Object JavaDoc r2 = pool.getResource(new Integer JavaDoc(2));
312         assertTrue("Resources are different, r1=" + r1 + ", r2=" + r2, r1 == r2);
313
314         try {
315             Thread.sleep(2 * TTL);
316         } catch (InterruptedException JavaDoc e) {
317             fail(e.getMessage());
318         }
319         pool.releaseResource(r2);
320
321         //fetch again the resource: the ttl should be expired
322
//Then the resouce should be different
323
r2 = pool.getResource(new Integer JavaDoc(2));
324         assertTrue("Same resource, r1=" + r1 + ", r2=" + r2, r1 != r2);
325     }
326
327     protected void setUp() throws Exception JavaDoc {
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 JavaDoc[] t = new Thread JavaDoc[nbThread];
345         for(int i=0; i<nbThread; i++) {
346             final int threadId = i;
347             t[threadId] = new Thread JavaDoc(new Runnable JavaDoc () {
348             public void run () {
349                 for(int j=0; j<nbAllocResource; j++) {
350                     try {
351                         long exectime = System.currentTimeMillis();
352                         Object JavaDoc r = pool.getResource(new Integer JavaDoc(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 JavaDoc msg = "Thread=" + threadId + ", alloc=" + j + " error: ";
364                         logger.log(BasicLevel.ERROR, msg, e);
365                         fail(msg + e.getMessage());
366                     } catch (InterruptedException JavaDoc 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 JavaDoc 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