KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > util > test > ThreadPoolRunnableUnitTestCase


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.test.util.test;
23
24 import java.util.Arrays JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.ArrayList JavaDoc;
28
29 import org.jboss.util.threadpool.BasicThreadPool;
30 import org.jboss.util.threadpool.ThreadPoolFullException;
31 import org.jboss.util.threadpool.BlockingMode;
32 import org.jboss.logging.Logger;
33 import junit.framework.TestCase;
34
35 /**
36  * Tests of thread pool with Runnables added to the pool
37  *
38  * @see org.jboss.util.threadpool.ThreadPool
39  * @author <a HREF="adrian@jboss.org">Adrian.Brock</a>
40  * @author Scott.Stark@jboss.org
41  * @version $Revision: 58115 $
42  */

43 public class ThreadPoolRunnableUnitTestCase extends TestCase
44 {
45    private static Logger log = Logger.getLogger(ThreadPoolRunnableUnitTestCase.class);
46
47    /** Basic test */
48    static final int BASIC = 0;
49
50    /** Hold the thread after start */
51    static final int HOLD_START = 1;
52
53    /** The started runnables */
54    HashSet JavaDoc startedRunnables = new HashSet JavaDoc();
55
56    /** The started releases */
57    HashSet JavaDoc startedReleases = new HashSet JavaDoc();
58
59    /** The finished runnables */
60    HashSet JavaDoc finishedRunnables = new HashSet JavaDoc();
61
62    /** The thread names */
63    HashMap JavaDoc threadNames = new HashMap JavaDoc();
64
65    /**
66     * Create a new ThreadPoolRunnableUnitTestCase
67     *
68     * @param name the test to run
69     */

70    public ThreadPoolRunnableUnitTestCase(String JavaDoc name)
71    {
72       super(name);
73    }
74
75    /**
76     * Basic test
77     */

78    public void testBasic() throws Exception JavaDoc
79    {
80       BasicThreadPool pool = new BasicThreadPool();
81       try
82       {
83          pool.run(new TestRunnable(BASIC, "test"));
84          waitFinished(1);
85          HashSet JavaDoc expected = makeExpected(new Object JavaDoc[] {"test"});
86          assertEquals(expected, finishedRunnables);
87       }
88       finally
89       {
90          pool.stop(true);
91       }
92    }
93
94    /**
95     * Multiple Basic test
96     */

97    public void testMultipleBasic() throws Exception JavaDoc
98    {
99       BasicThreadPool pool = new BasicThreadPool();
100       try
101       {
102          pool.run(new TestRunnable(BASIC, "test1"));
103          pool.run(new TestRunnable(BASIC, "test2"));
104          pool.run(new TestRunnable(BASIC, "test3"));
105          waitFinished(3);
106          HashSet JavaDoc expected = makeExpected(new Object JavaDoc[] {"test1", "test2", "test3"});
107          assertEquals(expected, finishedRunnables);
108       }
109       finally
110       {
111          pool.stop(true);
112       }
113    }
114
115    /**
116     * Test pooling
117     */

118    public void testSimplePooling() throws Exception JavaDoc
119    {
120       BasicThreadPool pool = new BasicThreadPool();
121       pool.setMaximumPoolSize(1);
122       try
123       {
124          pool.run(new TestRunnable(BASIC, "test1"));
125          waitFinished(1);
126          pool.run(new TestRunnable(BASIC, "test2"));
127          waitFinished(2);
128          assertEquals(threadNames.get("test1"), threadNames.get("test2"));
129       }
130       finally
131       {
132          pool.stop(true);
133       }
134    }
135
136    /**
137     * Test multiple pooling
138     */

139    public void testMultiplePooling() throws Exception JavaDoc
140    {
141       BasicThreadPool pool = new BasicThreadPool();
142       try
143       {
144          pool.run(new TestRunnable(HOLD_START, "test1"));
145          waitStarted(1);
146          pool.run(new TestRunnable(BASIC, "test2"));
147          waitFinished(1);
148          releaseStarted("test1");
149          waitFinished(2);
150          assertTrue("Shouldn't run on the same thread", threadNames.get("test1").equals(threadNames.get("test2")) == false);
151       }
152       finally
153       {
154          pool.stop(true);
155       }
156    }
157
158    /**
159     * Test maximum pool
160     */

161    public void testMaximumPool() throws Exception JavaDoc
162    {
163       BasicThreadPool pool = new BasicThreadPool();
164       pool.setMaximumPoolSize(1);
165       try
166       {
167          pool.run(new TestRunnable(HOLD_START, "test1"));
168          waitStarted(1);
169          pool.run(new TestRunnable(BASIC, "test2"));
170          Thread.sleep(1000);
171          assertEquals(0, finishedRunnables.size());
172          releaseStarted("test1");
173          waitFinished(2);
174          assertEquals(makeExpected(new Object JavaDoc[] {"test1", "test2"}), finishedRunnables);
175       }
176       finally
177       {
178          pool.stop(true);
179       }
180    }
181
182    /**
183     * Test maximum cache
184     */

185    public void testMaximumQueue() throws Exception JavaDoc
186    {
187       BasicThreadPool pool = new BasicThreadPool();
188       pool.setMaximumQueueSize(1);
189       pool.setMaximumPoolSize(1);
190       try
191       {
192          pool.run(new TestRunnable(HOLD_START, "test1"));
193          waitStarted(1);
194          pool.run(new TestRunnable(BASIC, "test2"));
195
196          boolean caught = false;
197          try
198          {
199             pool.run(new TestRunnable(BASIC, "test3"));
200          }
201          catch (ThreadPoolFullException expected)
202          {
203             caught = true;
204          }
205          assertTrue("Expected ThreadPoolFullException", caught);
206
207          releaseStarted("test1");
208          waitFinished(2);
209          assertEquals(makeExpected(new Object JavaDoc[] {"test1", "test2"}), finishedRunnables);
210       }
211       finally
212       {
213          pool.stop(true);
214       }
215    }
216
217    /**
218     * Test runnable timeouts
219     */

220    public void testRunnableTimeout() throws Exception JavaDoc
221    {
222       BasicThreadPool pool = new BasicThreadPool();
223       pool.setMaximumQueueSize(1);
224       pool.setMaximumPoolSize(1);
225       try
226       {
227          TestRunnable test = new TestRunnable(HOLD_START, "test1", 12*1000);
228          pool.run(test, 0, 10*1000);
229          waitStarted(1);
230          releaseStarted("test1");
231          waitFinished(1);
232          assertEquals(makeExpected(new Object JavaDoc[] {"test1"}), finishedRunnables);
233       }
234       finally
235       {
236          pool.stop(true);
237       }
238    }
239
240    /**
241     * Test runnable timeouts
242     */

243    public void testRunnableTimeoutWithSpinLoop() throws Exception JavaDoc
244    {
245       BasicThreadPool pool = new BasicThreadPool();
246       pool.setMaximumQueueSize(1);
247       pool.setMaximumPoolSize(1);
248       try
249       {
250          TestRunnable test = new TestRunnable(HOLD_START, "test1", Long.MAX_VALUE);
251          pool.run(test, 0, 10*1000);
252          waitStarted(1);
253          releaseStarted("test1");
254          Thread.sleep(11*1000);
255          // Run another task to validate the previous thread has been cleared
256
pool.run(new TestRunnable(BASIC, "test2"));
257          waitStarted(1);
258          releaseStarted("test2");
259          waitFinished(1);
260          assertEquals(makeExpected(new Object JavaDoc[] {"test2"}), finishedRunnables);
261       }
262       finally
263       {
264          pool.stop(true);
265       }
266    }
267
268    /**
269     * Test runnable timeouts
270     */

271    public void testRunnableTimeoutWithSpinLoop2() throws Exception JavaDoc
272    {
273       BasicThreadPool pool = new BasicThreadPool();
274       pool.setMaximumQueueSize(1);
275       pool.setMaximumPoolSize(1);
276       pool.setBlockingMode(BlockingMode.RUN);
277       try
278       {
279          TestRunnable test = new TestRunnable(BASIC, "testx", Long.MAX_VALUE);
280          pool.run(test, 0, 1*1000);
281          // Run another task to validate the previous thread has been cleared
282
ArrayList JavaDoc tmp = new ArrayList JavaDoc();
283          for(int n = 0; n < 10; n ++)
284          {
285             String JavaDoc name = "test"+n;
286             pool.run(new TestRunnable(BASIC, name));
287             tmp.add(name);
288          }
289          Thread.sleep(3000);
290          assertEquals(makeExpected(tmp.toArray()), finishedRunnables);
291       }
292       finally
293       {
294          pool.stop(true);
295       }
296    }
297
298    /**
299     * Save the thread name
300     *
301     * @param data the test data
302     * @param name the thread name
303     */

304    public synchronized void saveRunnableThreadName(String JavaDoc data, String JavaDoc name)
305    {
306       threadNames.put(data, name);
307    }
308
309    /**
310     * Wait for expected starts
311     */

312    public synchronized void waitStarted(int target)
313       throws InterruptedException JavaDoc
314    {
315       log.info("waitStarted, target="+target);
316       while (startedRunnables.size() < target)
317          wait();
318    }
319
320    /**
321     * Release in waiting for start
322     *
323     * @param data the thread to start
324     */

325    public synchronized void releaseStarted(String JavaDoc data)
326    {
327       log.info("releaseStarted, data="+data);
328       startedReleases.add(data);
329       notifyAll();
330    }
331
332    /**
333     * Wait for release started
334     */

335    public synchronized void waitForReleaseStarted(String JavaDoc data)
336    {
337       try
338       {
339          log.info("waitForReleaseStarted, data="+data);
340          while (startedReleases.contains(data) == false)
341             wait();
342       }
343       catch (InterruptedException JavaDoc ignored)
344       {
345       }
346    }
347
348    /**
349     * Notify started
350     */

351    public synchronized void notifyStarted(String JavaDoc data)
352    {
353       log.info("notifyStarted, data="+data);
354       startedRunnables.add(data);
355       notifyAll();
356    }
357
358    /**
359     * Clear started
360     */

361    public synchronized void clearStarted()
362    {
363       log.info("clearStarted");
364       startedRunnables.clear();
365    }
366
367    /**
368     * Wait for expected finishes
369     */

370    public synchronized void waitFinished(int target)
371       throws InterruptedException JavaDoc
372    {
373       log.info("waitFinished, target="+target);
374       while (finishedRunnables.size() < target)
375          wait();
376    }
377
378    /**
379     * Notify finished
380     */

381    public synchronized void notifyFinished(String JavaDoc data)
382    {
383       log.info("notifyFinished, data="+data);
384       finishedRunnables.add(data);
385       notifyAll();
386    }
387
388    /**
389     * Clear finished
390     */

391    public synchronized void clearFinished()
392    {
393       log.info("clearFinished");
394       finishedRunnables.clear();
395    }
396
397    /**
398     * Make the expected result
399     *
400     * @param expected the results as an object array
401     * @return the expected result
402     */

403    public HashSet JavaDoc makeExpected(Object JavaDoc[] expected)
404    {
405       return new HashSet JavaDoc(Arrays.asList(expected));
406    }
407
408    /**
409     * Test runnable
410     */

411    public class TestRunnable implements Runnable JavaDoc
412    {
413       /** The test to run */
414       private int test;
415       /** The data for the test */
416       private String JavaDoc data;
417       private long runSleepTime;
418
419       /**
420        * Create a new TestRunnable
421        *
422        * @param test the test
423        * @param data the test data
424        */

425       public TestRunnable(int test, String JavaDoc data)
426       {
427          this(test, data, 0);
428       }
429       public TestRunnable(int test, String JavaDoc data, long runSleepTime)
430       {
431          this.test = test;
432          this.data = data;
433          this.runSleepTime = runSleepTime;
434       }
435
436       /**
437        * Runnable implementation
438        */

439       public void run()
440       {
441          log.info("Begin run");
442          saveThreadName();
443          started();
444          if( runSleepTime > 0 )
445          {
446             log.info("Begin spin loop");
447             if( runSleepTime == Long.MAX_VALUE )
448             {
449                while( true )
450                   ;
451             }
452             else
453             {
454                log.info("Begin sleep");
455                try
456                {
457                   Thread.sleep(runSleepTime);
458                }
459                catch(InterruptedException JavaDoc e)
460                {
461                }
462             }
463          }
464          finished();
465          log.info("End run");
466       }
467
468       /**
469        * Save the thread
470        */

471       public void saveThreadName()
472       {
473          saveRunnableThreadName(data, Thread.currentThread().getName());
474       }
475
476       /**
477        * The test is finished
478        */

479       public void started()
480       {
481          notifyStarted(data);
482          if (test == HOLD_START)
483             waitForReleaseStarted(data);
484       }
485
486       /**
487        * The test is finished
488        */

489       public void finished()
490       {
491          notifyFinished(data);
492       }
493    }
494 }
495
Popular Tags