KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > jca > test > MultiThreadedTxUnitTestCase


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.jca.test;
23
24 import javax.management.ObjectName JavaDoc;
25 import javax.transaction.RollbackException JavaDoc;
26
27 import junit.framework.Test;
28
29 import org.jboss.test.JBossTestCase;
30 import org.jboss.test.jca.mbean.MTOperation;
31
32 /**
33  * Multithreaded Tx JCA tests
34  *
35  * @author <a HREF="dimitris@jboss.org">Dimitris Andreadis</a>
36  * @version $Revision: 37406 $
37  */

38 public class MultiThreadedTxUnitTestCase extends JBossTestCase
39 {
40    static String JavaDoc[] SIG = new String JavaDoc[] { String JavaDoc.class.getName(), new MTOperation[0][0].getClass().getName() };
41
42    ObjectName JavaDoc mtMBean;
43
44    public MultiThreadedTxUnitTestCase(String JavaDoc name)
45    {
46       super(name);
47
48       try
49       {
50          mtMBean = new ObjectName JavaDoc("jboss.test:test=MultiThreadedTxUnitTestCase");
51       }
52       catch (Exception JavaDoc e)
53       {
54          throw new RuntimeException JavaDoc(e.toString());
55       }
56    }
57
58    public void runTest(MTOperation[][] ops) throws Exception JavaDoc
59    {
60       getServer().invoke(mtMBean, "testMTOperations", new Object JavaDoc[] { getName(), ops }, SIG);
61    }
62
63    public static Test suite() throws Exception JavaDoc
64    {
65       Test t1 = getDeploySetup(MultiThreadedTxUnitTestCase.class, "mtjcatest.sar");
66       Test t2 = getDeploySetup(t1, "mttestadapter-ds.xml");
67       return getDeploySetup(t2, "jbosstestadapter.rar");
68    }
69
70    /**
71     * Have thread0 control the tx and thread1 joining the tx.
72     * Both threads get/enlist a connection and close it and
73     * thread1 suspends the tx. Thread0 commits.
74     */

75    public void testEnlistConnsInSameTxButDifferentThreads() throws Exception JavaDoc
76    {
77       runTest(new MTOperation[][]
78       {
79             {
80                // thread 0
81
new MTOperation(MTOperation.CF_LOOKUP),
82                new MTOperation(MTOperation.TM_BEGIN, 10),
83                new MTOperation(MTOperation.CF_GET_CONN, 1),
84                new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, 999),
85                new MTOperation(MTOperation.CN_CLOSE_CONN, 1),
86                new MTOperation(MTOperation.TM_COMMIT)
87             }
88             ,
89             {
90                // thread 1
91
new MTOperation(MTOperation.CF_LOOKUP),
92                new MTOperation(MTOperation.XX_WAIT_FOR_TX, 10),
93                new MTOperation(MTOperation.TM_RESUME, 10),
94                new MTOperation(MTOperation.CF_GET_CONN, 2),
95                new MTOperation(MTOperation.CN_CLOSE_CONN, 2),
96                new MTOperation(MTOperation.TM_SUSPEND),
97                new MTOperation(MTOperation.XX_POST_SIGNAL, 999)
98             }
99       });
100    }
101
102    /**
103     * Same like testEnlistConnsInSameTxButDifferentThreads()
104     * but use a TrackByTx connection factory.
105     */

106    public void testEnlistConnsInSameTxButDifferentThreadsTrackByTx() throws Exception JavaDoc
107    {
108       runTest(new MTOperation[][]
109       {
110             {
111                // thread 0
112
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
113                new MTOperation(MTOperation.TM_BEGIN, 10),
114                new MTOperation(MTOperation.CF_GET_CONN, 1),
115                new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, 999),
116                new MTOperation(MTOperation.CN_CLOSE_CONN, 1),
117                new MTOperation(MTOperation.TM_COMMIT)
118             }
119             ,
120             {
121                // thread 1
122
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
123                new MTOperation(MTOperation.XX_WAIT_FOR_TX, 10),
124                new MTOperation(MTOperation.TM_RESUME, 10),
125                new MTOperation(MTOperation.CF_GET_CONN, 2),
126                new MTOperation(MTOperation.CN_CLOSE_CONN, 2),
127                new MTOperation(MTOperation.TM_SUSPEND),
128                new MTOperation(MTOperation.XX_POST_SIGNAL, 999)
129             }
130       });
131    }
132
133    /**
134     * Same like testEnlistConnsInSameTxButDifferentThreadsTrackByTx()
135     * but don't suspend in the second thread. It the transaction
136     * reconsiliation policy of allowing only one associated thread
137     * at commit time is active, we should get an exception.
138     */

139    public void testEnlistConnsInSameTxButDifferentThreadsTrackByTxDontSuspend() throws Exception JavaDoc
140    {
141       Boolean JavaDoc txSyncActive = new Boolean JavaDoc(false);
142       try
143       {
144          ObjectName JavaDoc target = new ObjectName JavaDoc("jboss:service=TransactionSynchronization");
145          txSyncActive = (Boolean JavaDoc)getServer().getAttribute(target, "EnforceOneThreadActiveAtCommit");
146       }
147       catch (Exception JavaDoc e)
148       {
149          // ignore
150
}
151       
152       if (txSyncActive.booleanValue() == true)
153       {
154          runTest(new MTOperation[][]
155          {
156             {
157                // thread 0
158
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
159                new MTOperation(MTOperation.TM_BEGIN, 10),
160                new MTOperation(MTOperation.CF_GET_CONN, 1),
161                new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, 999),
162                new MTOperation(MTOperation.CN_CLOSE_CONN, 1),
163                new MTOperation(MTOperation.TM_COMMIT, -1, new RollbackException JavaDoc())
164             }
165             ,
166             {
167                // thread 1
168
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
169                new MTOperation(MTOperation.XX_WAIT_FOR_TX, 10),
170                new MTOperation(MTOperation.TM_RESUME, 10),
171                new MTOperation(MTOperation.CF_GET_CONN, 2),
172                new MTOperation(MTOperation.CN_CLOSE_CONN, 2),
173                new MTOperation(MTOperation.XX_POST_SIGNAL, 999)
174             }
175          });
176       }
177       else
178       {
179          runTest(new MTOperation[][]
180          {
181             {
182                // thread 0
183
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
184                new MTOperation(MTOperation.TM_BEGIN, 10),
185                new MTOperation(MTOperation.CF_GET_CONN, 1),
186                new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, 999),
187                new MTOperation(MTOperation.CN_CLOSE_CONN, 1),
188                new MTOperation(MTOperation.TM_COMMIT)
189             }
190             ,
191             {
192                // thread 1
193
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
194                new MTOperation(MTOperation.XX_WAIT_FOR_TX, 10),
195                new MTOperation(MTOperation.TM_RESUME, 10),
196                new MTOperation(MTOperation.CF_GET_CONN, 2),
197                new MTOperation(MTOperation.CN_CLOSE_CONN, 2),
198                new MTOperation(MTOperation.XX_POST_SIGNAL, 999)
199             }
200          });
201       }
202    }
203    
204    /**
205     * Have 3 threads getting connection both in the same
206     * and in different transactions, or not tx.
207     */

208    public void testEnlistInSameOrDifferentOrNoTx() throws Exception JavaDoc
209    {
210       runTest(new MTOperation[][]
211       {
212          {
213             // thread 0
214
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
215             new MTOperation(MTOperation.TM_BEGIN, 10),
216             new MTOperation(MTOperation.CF_GET_CONN, 1),
217             new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, 888),
218             new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, 999),
219             new MTOperation(MTOperation.TM_COMMIT)
220          }
221          ,
222          {
223             // thread 1
224
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
225             new MTOperation(MTOperation.XX_WAIT_FOR_TX, 10),
226             new MTOperation(MTOperation.TM_RESUME, 10),
227             new MTOperation(MTOperation.CF_GET_CONN, 2),
228             new MTOperation(MTOperation.CN_CLOSE_CONN, 2),
229             new MTOperation(MTOperation.TM_SUSPEND, 10),
230             new MTOperation(MTOperation.TM_BEGIN, 20),
231             new MTOperation(MTOperation.CF_GET_CONN, 3),
232             new MTOperation(MTOperation.CN_CLOSE_CONN, 3),
233             new MTOperation(MTOperation.TM_COMMIT),
234             new MTOperation(MTOperation.XX_POST_SIGNAL, 888)
235          }
236          ,
237          {
238             // thread 2
239
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
240             new MTOperation(MTOperation.XX_WAIT_FOR_TX, 10),
241             new MTOperation(MTOperation.TM_RESUME, 10),
242             new MTOperation(MTOperation.CF_GET_CONN, 4),
243             new MTOperation(MTOperation.CN_CLOSE_CONN, 4),
244             new MTOperation(MTOperation.TM_SUSPEND, 10),
245             new MTOperation(MTOperation.CF_GET_CONN, 5),
246             new MTOperation(MTOperation.CN_CLOSE_CONN, 5),
247             new MTOperation(MTOperation.XX_POST_SIGNAL, 999)
248          }
249       });
250    }
251    
252    /**
253     * Enlist the first connection (which is tracked by tx)
254     * in a different thread from the one that originally
255     * started the transaction.
256     */

257    public void testEnlistConnInOtherThreadThanTxBegun() throws Exception JavaDoc
258    {
259       runTest(new MTOperation[][]
260       {
261             {
262                // thread 0
263
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
264                new MTOperation(MTOperation.TM_BEGIN, 10),
265                new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, 888),
266                new MTOperation(MTOperation.CF_GET_CONN, 2),
267                new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, 999),
268                new MTOperation(MTOperation.CN_CLOSE_CONN, 2),
269                new MTOperation(MTOperation.TM_COMMIT)
270             }
271             ,
272             {
273                // thread 1
274
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
275                new MTOperation(MTOperation.XX_WAIT_FOR_TX, 10),
276                new MTOperation(MTOperation.TM_RESUME, 10),
277                new MTOperation(MTOperation.CF_GET_CONN, 1),
278                new MTOperation(MTOperation.XX_POST_SIGNAL, 888),
279                new MTOperation(MTOperation.CN_CLOSE_CONN, 1),
280                new MTOperation(MTOperation.TM_SUSPEND, 10),
281                new MTOperation(MTOperation.XX_POST_SIGNAL, 999)
282             }
283       });
284    }
285
286    /**
287     * Simple test to just show in the logs how connections
288     * are reused when track-by-tx is true
289     */

290    public void testShowConnReuseTrackByTx() throws Exception JavaDoc
291    {
292       runTest(new MTOperation[][]
293       {
294          {
295             // thread 0
296
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
297             new MTOperation(MTOperation.TM_BEGIN, 10),
298             new MTOperation(MTOperation.CF_GET_CONN, 1),
299             new MTOperation(MTOperation.CN_CLOSE_CONN, 1),
300             new MTOperation(MTOperation.CF_GET_CONN, 2),
301             new MTOperation(MTOperation.CN_CLOSE_CONN, 2),
302             new MTOperation(MTOperation.CF_GET_CONN, 3),
303             new MTOperation(MTOperation.CN_CLOSE_CONN, 3),
304             new MTOperation(MTOperation.CF_GET_CONN, 4),
305             new MTOperation(MTOperation.CF_GET_CONN, 5),
306             new MTOperation(MTOperation.CF_GET_CONN, 6),
307             new MTOperation(MTOperation.CN_CLOSE_CONN, 6),
308             new MTOperation(MTOperation.CN_CLOSE_CONN, 5),
309             new MTOperation(MTOperation.CN_CLOSE_CONN, 4),
310             new MTOperation(MTOperation.CF_GET_CONN, 7),
311             new MTOperation(MTOperation.CF_GET_CONN, 8),
312             new MTOperation(MTOperation.CF_GET_CONN, 9),
313             new MTOperation(MTOperation.CN_CLOSE_CONN, 7),
314             new MTOperation(MTOperation.CN_CLOSE_CONN, 8),
315             new MTOperation(MTOperation.CN_CLOSE_CONN, 9),
316             new MTOperation(MTOperation.TM_COMMIT)
317          }
318       });
319    }
320    
321    /**
322     * Simple test to just show in the logs how connections
323     * are reused when track-by-tx is false
324     */

325    public void testShowConnReuse() throws Exception JavaDoc
326    {
327       runTest(new MTOperation[][]
328       {
329          {
330             // thread 0
331
new MTOperation(MTOperation.CF_LOOKUP),
332             new MTOperation(MTOperation.TM_BEGIN, 10),
333             new MTOperation(MTOperation.CF_GET_CONN, 1),
334             new MTOperation(MTOperation.CN_CLOSE_CONN, 1),
335             new MTOperation(MTOperation.CF_GET_CONN, 2),
336             new MTOperation(MTOperation.CN_CLOSE_CONN, 2),
337             new MTOperation(MTOperation.CF_GET_CONN, 3),
338             new MTOperation(MTOperation.CN_CLOSE_CONN, 3),
339             new MTOperation(MTOperation.CF_GET_CONN, 4),
340             new MTOperation(MTOperation.CF_GET_CONN, 5),
341             new MTOperation(MTOperation.CF_GET_CONN, 6),
342             new MTOperation(MTOperation.CN_CLOSE_CONN, 6),
343             new MTOperation(MTOperation.CN_CLOSE_CONN, 5),
344             new MTOperation(MTOperation.CN_CLOSE_CONN, 4),
345             new MTOperation(MTOperation.CF_GET_CONN, 7),
346             new MTOperation(MTOperation.CF_GET_CONN, 8),
347             new MTOperation(MTOperation.CF_GET_CONN, 9),
348             new MTOperation(MTOperation.CN_CLOSE_CONN, 7),
349             new MTOperation(MTOperation.CN_CLOSE_CONN, 8),
350             new MTOperation(MTOperation.CN_CLOSE_CONN, 9),
351             new MTOperation(MTOperation.TM_COMMIT)
352          }
353       });
354    }
355    
356    /**
357     * Close the connection inside a different transaction
358     */

359    public void testCloseConnectionInDifferentTx() throws Exception JavaDoc
360    {
361       runTest(new MTOperation[][]
362       {
363          {
364             // thread 0
365
new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
366             new MTOperation(MTOperation.TM_BEGIN, 10),
367             new MTOperation(MTOperation.CF_GET_CONN, 1),
368             new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, 999),
369             new MTOperation(MTOperation.TM_COMMIT)
370          }
371          ,
372          {
373             // thread 1
374
new MTOperation(MTOperation.TM_BEGIN, 20),
375             new MTOperation(MTOperation.XX_WAIT_FOR_CONN, 1),
376             new MTOperation(MTOperation.CN_CLOSE_CONN, 1),
377             new MTOperation(MTOperation.XX_POST_SIGNAL, 999),
378             new MTOperation(MTOperation.TM_COMMIT)
379          }
380       });
381    }
382    
383    /**
384     * Thread0 begins a tx, creates a connection and waits.
385     * N Threads resume thead0 tx and create and destroy 3
386     * connections each. Thread0 waits for them and commits the tx.
387     */

388    public void testStressConnsMultipleThreadsInSameTx() throws Exception JavaDoc
389    {
390       final int numThreads = 60;
391       
392       MTOperation[][] stressTest = new MTOperation[numThreads + 1][];
393
394       // thread 0
395
MTOperation[] thread0 = new MTOperation[5 + numThreads];
396       thread0[0] = new MTOperation(MTOperation.CF_BY_TX_LOOKUP);
397       thread0[1] = new MTOperation(MTOperation.TM_BEGIN, 10);
398       thread0[2] = new MTOperation(MTOperation.CF_GET_CONN, 0);
399       for (int i = 0; i < numThreads; i++)
400       {
401          thread0[3+i] = new MTOperation(MTOperation.XX_WAIT_FOR_SIGNAL, i+1);
402       }
403       thread0[3 + numThreads] = new MTOperation(MTOperation.CN_CLOSE_CONN, 0);
404       thread0[4 + numThreads] = new MTOperation(MTOperation.TM_COMMIT);
405
406       stressTest[0] = thread0;
407       
408       // threads 1 -> numThreads
409
for (int i = 1; i <= numThreads; i++)
410       {
411          stressTest[i] = new MTOperation[] {
412             new MTOperation(MTOperation.CF_BY_TX_LOOKUP),
413             new MTOperation(MTOperation.XX_WAIT_FOR_TX, 10),
414             new MTOperation(MTOperation.TM_RESUME, 10),
415             new MTOperation(MTOperation.CF_GET_CONN, 1000+i),
416             new MTOperation(MTOperation.XX_SLEEP_RANDOM),
417             new MTOperation(MTOperation.CF_GET_CONN, 2000+i),
418             new MTOperation(MTOperation.XX_SLEEP_RANDOM),
419             new MTOperation(MTOperation.CF_GET_CONN, 3000+i),
420             new MTOperation(MTOperation.XX_SLEEP_RANDOM),
421             new MTOperation(MTOperation.CN_CLOSE_CONN, 3000+i),
422             new MTOperation(MTOperation.XX_SLEEP_RANDOM),
423             new MTOperation(MTOperation.CN_CLOSE_CONN, 2000+i),
424             new MTOperation(MTOperation.XX_SLEEP_RANDOM),
425             new MTOperation(MTOperation.CN_CLOSE_CONN, 1000+i),
426             new MTOperation(MTOperation.TM_SUSPEND, 10),
427             new MTOperation(MTOperation.XX_POST_SIGNAL, i)
428          };
429       }
430       runTest(stressTest);
431    }
432    
433    /**
434     * Create multiple threads that get and close connections
435     * within different transactions.
436     */

437    public void testStressMultipleThreadsDifferentTx() throws Exception JavaDoc
438    {
439       final int numThreads = 60;
440       
441       MTOperation[][] stressTest = new MTOperation[numThreads][];
442
443       // threads 0 -> numThreads
444
for (int i = 0; i < numThreads; i++)
445       {
446          stressTest[i] = new MTOperation[] {
447                new MTOperation(MTOperation.CF_LOOKUP),
448                new MTOperation(MTOperation.TM_BEGIN, 500+i),
449                new MTOperation(MTOperation.CF_GET_CONN, 1000+i),
450                new MTOperation(MTOperation.XX_SLEEP_RANDOM),
451                // Uncomment to following to run out of connections!
452
// new MTOperation(MTOperation.CF_GET_CONN, 2000+i),
453
// new MTOperation(MTOperation.XX_SLEEP_RANDOM),
454
// new MTOperation(MTOperation.CN_CLOSE_CONN, 2000+i),
455
// new MTOperation(MTOperation.XX_SLEEP_RANDOM),
456
new MTOperation(MTOperation.CN_CLOSE_CONN, 1000+i),
457                new MTOperation(MTOperation.TM_COMMIT)
458          };
459       }
460       runTest(stressTest);
461    }
462 }
463
Popular Tags