KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > recovery > Recovery2PCTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: Recovery2PCTest.java,v 1.10 2006/10/30 21:14:48 bostic Exp $
7  */

8
9 package com.sleepycat.je.recovery;
10
11 import java.io.IOException JavaDoc;
12 import java.util.Hashtable JavaDoc;
13
14 import javax.transaction.xa.XAException JavaDoc;
15 import javax.transaction.xa.XAResource JavaDoc;
16 import javax.transaction.xa.Xid JavaDoc;
17
18 import junit.framework.Test;
19 import junit.framework.TestSuite;
20
21 import com.sleepycat.je.DatabaseException;
22 import com.sleepycat.je.Transaction;
23 import com.sleepycat.je.XAEnvironment;
24 import com.sleepycat.je.log.LogUtils.XidImpl;
25
26 public class Recovery2PCTest extends RecoveryTestBase {
27     private static final boolean DEBUG = false;
28
29     private boolean explicitTxn;
30     private boolean commit;
31     private boolean recover;
32
33     public static Test suite() {
34         TestSuite allTests = new TestSuite();
35     for (int i = 0; i < 2; i++) {
36         for (int j = 0; j < 2; j++) {
37         for (int k = 0; k < 2; k++) {
38             allTests.addTest
39             (((Recovery2PCTest)
40               (TestSuite.createTest(Recovery2PCTest.class,
41                         "testBasic"))).
42              init(i, j, k));
43         }
44         }
45     }
46
47     /* We only need to test XARecoveryAPI for implicit and explicit. */
48     allTests.addTest
49         (((Recovery2PCTest)
50           (TestSuite.createTest(Recovery2PCTest.class,
51                     "testXARecoverAPI"))).
52          init(0, 0, 0));
53     allTests.addTest
54         (((Recovery2PCTest)
55           (TestSuite.createTest(Recovery2PCTest.class,
56                     "testXARecoverAPI"))).
57          init(1, 0, 0));
58     allTests.addTest
59         (((Recovery2PCTest)
60           (TestSuite.createTest(Recovery2PCTest.class,
61                     "testXARecoverArgCheck"))).
62          init(0, 0, 0));
63         return allTests;
64     }
65
66     public Recovery2PCTest() {
67     super(true);
68     }
69
70     private Recovery2PCTest init(int explicitTxn,
71                  int commit,
72                  int recover) {
73     this.explicitTxn = (explicitTxn == 0);
74     this.commit = (commit == 0);
75     this.recover = (recover == 0);
76     return this;
77     }
78
79     private String JavaDoc opName() {
80     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
81
82     if (explicitTxn) {
83         sb.append("Exp");
84     } else {
85         sb.append("Imp");
86     }
87
88     sb.append("/");
89
90     if (commit) {
91         sb.append("C");
92     } else {
93         sb.append("A");
94     }
95
96     sb.append("/");
97
98     if (recover) {
99         sb.append("Rec");
100     } else {
101         sb.append("No Rec");
102     }
103
104     return sb.toString();
105     }
106
107     public void tearDown()
108     throws IOException JavaDoc, DatabaseException {
109         
110         /* Set test name for reporting; cannot be done in the ctor or setUp. */
111         setName(getName() + ": " + opName());
112     super.tearDown();
113     }
114
115     public void testBasic()
116     throws Throwable JavaDoc {
117
118     createXAEnvAndDbs(1 << 20, false, NUM_DBS);
119     XAEnvironment xaEnv = (XAEnvironment) env;
120         int numRecs = NUM_RECS * 3;
121
122         try {
123             /* Set up an repository of expected data. */
124             Hashtable JavaDoc expectedData = new Hashtable JavaDoc();
125             
126             /* Insert all the data. */
127         XidImpl xid = new XidImpl(1, "TwoPCTest1".getBytes(), null);
128             Transaction txn = null;
129         if (explicitTxn) {
130         txn = env.beginTransaction(null, null);
131         xaEnv.setXATransaction(xid, txn);
132         } else {
133         xaEnv.start(xid, 0);
134         }
135             insertData(txn, 0, numRecs - 1, expectedData, 1, commit, NUM_DBS);
136         if (!explicitTxn) {
137         xaEnv.end(xid, 0);
138         }
139
140         xaEnv.prepare(xid);
141
142         if (recover) {
143         closeEnv();
144         xaRecoverOnly(NUM_DBS);
145         xaEnv = (XAEnvironment) env;
146         }
147
148         if (commit) {
149         xaEnv.commit(xid, false);
150         } else {
151         xaEnv.rollback(xid);
152         }
153
154         if (recover) {
155         verifyData(expectedData, commit, NUM_DBS);
156         forceCloseEnvOnly();
157         } else {
158         closeEnv();
159         }
160             xaRecoverAndVerify(expectedData, NUM_DBS);
161         } catch (Throwable JavaDoc t) {
162             /* Print stacktrace before trying to clean up files. */
163             t.printStackTrace();
164             throw t;
165         }
166     }
167
168     public void testXARecoverAPI()
169     throws Throwable JavaDoc {
170
171     createXAEnvAndDbs(1 << 20, false, NUM_DBS << 1);
172     final XAEnvironment xaEnv = (XAEnvironment) env;
173         final int numRecs = NUM_RECS * 3;
174
175         try {
176             /* Set up an repository of expected data. */
177             final Hashtable JavaDoc expectedData1 = new Hashtable JavaDoc();
178             final Hashtable JavaDoc expectedData2 = new Hashtable JavaDoc();
179             
180             /* Insert all the data. */
181             final Transaction txn1 =
182         (explicitTxn ?
183          env.beginTransaction(null, null) :
184          null);
185             final Transaction txn2 =
186         (explicitTxn ?
187          env.beginTransaction(null, null) :
188          null);
189         final XidImpl xid1 = new XidImpl(1, "TwoPCTest1".getBytes(), null);
190         final XidImpl xid2 = new XidImpl(1, "TwoPCTest2".getBytes(), null);
191
192         Thread JavaDoc thread1 = new Thread JavaDoc() {
193             public void run() {
194             try {
195                 if (explicitTxn) {
196                 xaEnv.setXATransaction(xid1, txn1);
197                 } else {
198                 xaEnv.start(xid1, 0);
199                 }
200                 Thread.yield();
201                 insertData(txn1, 0, numRecs - 1, expectedData1, 1,
202                        true, 0, NUM_DBS);
203                 Thread.yield();
204                 if (!explicitTxn) {
205                 xaEnv.end(xid1, 0);
206                 }
207                 Thread.yield();
208             } catch (Exception JavaDoc E) {
209                 fail("unexpected: " + E);
210             }
211             }
212         };
213
214         Thread JavaDoc thread2 = new Thread JavaDoc() {
215             public void run() {
216             try {
217                 if (explicitTxn) {
218                 xaEnv.setXATransaction(xid2, txn2);
219                 } else {
220                 xaEnv.start(xid2, 0);
221                 }
222                 Thread.yield();
223                 insertData(txn2, numRecs, numRecs << 1,
224                        expectedData2, 1, false, NUM_DBS,
225                        NUM_DBS << 1);
226                 Thread.yield();
227                 if (!explicitTxn) {
228                 xaEnv.end(xid2, 0);
229                 }
230                 Thread.yield();
231             } catch (Exception JavaDoc E) {
232                 fail("unexpected: " + E);
233             }
234             }
235         };
236
237         thread1.start();
238         thread2.start();
239         thread1.join();
240         thread2.join();
241
242         xaEnv.prepare(xid1);
243         try {
244         xaEnv.prepare(xid1);
245         fail("should have thrown XID has already been registered");
246         } catch (XAException JavaDoc XAE) {
247         // xid1 has already been registered.
248
}
249         xaEnv.prepare(xid2);
250
251         XAEnvironment xaEnv2 = xaEnv;
252         Xid JavaDoc[] unfinishedXAXids = xaEnv2.recover(0);
253         assertTrue(unfinishedXAXids.length == 2);
254         boolean sawXid1 = false;
255         boolean sawXid2 = false;
256         for (int i = 0; i < 2; i++) {
257         if (unfinishedXAXids[i].equals(xid1)) {
258             if (sawXid1) {
259             fail("saw Xid1 twice");
260             }
261             sawXid1 = true;
262         }
263         if (unfinishedXAXids[i].equals(xid2)) {
264             if (sawXid2) {
265             fail("saw Xid2 twice");
266             }
267             sawXid2 = true;
268         }
269         }
270         assertTrue(sawXid1 && sawXid2);
271
272             closeEnv();
273         xaEnv2 = (XAEnvironment) env;
274         xaRecoverOnly(NUM_DBS);
275         xaEnv2 = (XAEnvironment) env;
276
277         unfinishedXAXids = xaEnv2.recover(0);
278         assertTrue(unfinishedXAXids.length == 2);
279         sawXid1 = false;
280         sawXid2 = false;
281         for (int i = 0; i < 2; i++) {
282         if (unfinishedXAXids[i].equals(xid1)) {
283             if (sawXid1) {
284             fail("saw Xid1 twice");
285             }
286             sawXid1 = true;
287         }
288         if (unfinishedXAXids[i].equals(xid2)) {
289             if (sawXid2) {
290             fail("saw Xid2 twice");
291             }
292             sawXid2 = true;
293         }
294         }
295         assertTrue(sawXid1 && sawXid2);
296
297         xaEnv2 = (XAEnvironment) env;
298         xaEnv2.getXATransaction(xid1);
299         xaEnv2.getXATransaction(xid2);
300         xaEnv2.commit(xid1, false);
301         xaEnv2.rollback(xid2);
302         verifyData(expectedData1, false, 0, NUM_DBS);
303         verifyData(expectedData2, false, NUM_DBS, NUM_DBS << 1);
304         forceCloseEnvOnly();
305         xaRecoverOnly(NUM_DBS);
306         verifyData(expectedData1, false, 0, NUM_DBS);
307         verifyData(expectedData2, false, NUM_DBS, NUM_DBS << 1);
308         } catch (Throwable JavaDoc t) {
309             /* Print stacktrace before trying to clean up files. */
310             t.printStackTrace();
311             throw t;
312         }
313     }
314
315     public void testXARecoverArgCheck()
316     throws Throwable JavaDoc {
317
318     createXAEnvAndDbs(1 << 20, false, NUM_DBS);
319     XAEnvironment xaEnv = (XAEnvironment) env;
320
321         try {
322         XidImpl xid = new XidImpl(1, "TwoPCTest1".getBytes(), null);
323
324         /* Check that only one of TMJOIN and TMRESUME can be set. */
325         try {
326         xaEnv.start(xid, XAResource.TMJOIN | XAResource.TMRESUME);
327         fail("Expected XAException(XAException.XAER_INVAL)");
328         } catch (XAException JavaDoc XAE) {
329         /* Expect this. */
330         assertTrue(XAE.errorCode == XAException.XAER_INVAL);
331         }
332
333         /*
334          * Check that only one of TMJOIN and TMRESUME can be set by passing
335          * a bogus flag value (TMSUSPEND).
336          */

337         try {
338         xaEnv.start(xid, XAResource.TMSUSPEND);
339         fail("Expected XAException(XAException.XAER_INVAL)");
340         } catch (XAException JavaDoc XAE) {
341         /* Expect this. */
342         assertTrue(XAE.errorCode == XAException.XAER_INVAL);
343         }
344
345         xaEnv.start(xid, XAResource.TMNOFLAGS);
346         try {
347         xaEnv.start(xid, XAResource.TMNOFLAGS);
348         fail("Expected XAER_DUPID");
349         } catch (XAException JavaDoc XAE) {
350         /* Expect this. */
351         assertTrue(XAE.errorCode == XAException.XAER_DUPID);
352         }
353         xaEnv.end(xid, XAResource.TMNOFLAGS);
354
355         /*
356          * Check that JOIN with a non-existant association throws NOTA.
357          */

358         try {
359         xid = new XidImpl(1, "TwoPCTest2".getBytes(), null);
360         xaEnv.start(xid, XAResource.TMJOIN);
361         fail("Expected XAER_NOTA");
362         } catch (XAException JavaDoc XAE) {
363         /* Expect this. */
364         assertTrue(XAE.errorCode == XAException.XAER_NOTA);
365         }
366
367         /*
368          * Check that RESUME with a non-existant association throws NOTA.
369          */

370         try {
371         xaEnv.start(xid, XAResource.TMRESUME);
372         fail("Expected XAER_NOTA");
373         } catch (XAException JavaDoc XAE) {
374         /* Expect this. */
375         assertTrue(XAE.errorCode == XAException.XAER_NOTA);
376         }
377
378         /*
379          * Check that start(JOIN) from a thread that is already associated
380          * throws XAER_PROTO.
381          */

382         Xid JavaDoc xid2 = new XidImpl(1, "TwoPCTest3".getBytes(), null);
383         xaEnv.start(xid2, XAResource.TMNOFLAGS);
384         xaEnv.end(xid2, XAResource.TMNOFLAGS);
385         xid = new XidImpl(1, "TwoPCTest2".getBytes(), null);
386         xaEnv.start(xid, XAResource.TMNOFLAGS);
387         try {
388         xaEnv.start(xid2, XAResource.TMJOIN);
389         fail("Expected XAER_PROTO");
390         } catch (XAException JavaDoc XAE) {
391         /* Expect this. */
392         assertTrue(XAE.errorCode == XAException.XAER_PROTO);
393         }
394
395         /*
396          * Check that start(RESUME) for an xid that is not suspended throws
397          * XAER_PROTO.
398          */

399         try {
400         xid = new XidImpl(1, "TwoPCTest2".getBytes(), null);
401         xaEnv.start(xid, XAResource.TMRESUME);
402         fail("Expected XAER_PROTO");
403         } catch (XAException JavaDoc XAE) {
404         /* Expect this. */
405         assertTrue(XAE.errorCode == XAException.XAER_PROTO);
406         }
407
408         /*
409          * Check that end(TMFAIL | TMSUCCESS) throws XAER_INVAL.
410          */

411         try {
412         xid = new XidImpl(1, "TwoPCTest2".getBytes(), null);
413         xaEnv.end(xid, XAResource.TMFAIL | XAResource.TMSUCCESS);
414         fail("Expected XAER_INVAL");
415         } catch (XAException JavaDoc XAE) {
416         /* Expect this. */
417         assertTrue(XAE.errorCode == XAException.XAER_INVAL);
418         }
419
420         /*
421          * Check that end(TMFAIL | TMSUSPEND) throws XAER_INVAL.
422          */

423         try {
424         xid = new XidImpl(1, "TwoPCTest2".getBytes(), null);
425         xaEnv.end(xid, XAResource.TMFAIL | XAResource.TMSUSPEND);
426         fail("Expected XAER_INVAL");
427         } catch (XAException JavaDoc XAE) {
428         /* Expect this. */
429         assertTrue(XAE.errorCode == XAException.XAER_INVAL);
430         }
431
432         /*
433          * Check that end(TMSUCCESS | TMSUSPEND) throws XAER_INVAL.
434          */

435         try {
436         xid = new XidImpl(1, "TwoPCTest2".getBytes(), null);
437         xaEnv.end(xid, XAResource.TMSUCCESS | XAResource.TMSUSPEND);
438         fail("Expected XAER_INVAL");
439         } catch (XAException JavaDoc XAE) {
440         /* Expect this. */
441         assertTrue(XAE.errorCode == XAException.XAER_INVAL);
442         }
443
444         /*
445          * Check that end(TMSUSPEND) actually works.
446          */

447         Xid JavaDoc xid4 = new XidImpl(1, "TwoPCTest4".getBytes(), null);
448         xaEnv.start(xid4, XAResource.TMNOFLAGS);
449         Transaction txn4 = xaEnv.getThreadTransaction();
450         assertTrue(txn4 != null);
451         xaEnv.end(xid4, XAResource.TMSUSPEND);
452         assertTrue(xaEnv.getThreadTransaction() == null);
453         Xid JavaDoc xid5 = new XidImpl(1, "TwoPCTest5".getBytes(), null);
454         xaEnv.start(xid5, XAResource.TMNOFLAGS);
455         Transaction txn5 = xaEnv.getThreadTransaction();
456         xaEnv.end(xid5, XAResource.TMSUSPEND);
457         assertTrue(xaEnv.getThreadTransaction() == null);
458         xaEnv.start(xid4, XAResource.TMRESUME);
459         assertTrue(xaEnv.getThreadTransaction().equals(txn4));
460         xaEnv.end(xid4, XAResource.TMNOFLAGS);
461         xaEnv.start(xid5, XAResource.TMRESUME);
462         assertTrue(xaEnv.getThreadTransaction().equals(txn5));
463         xaEnv.end(xid5, XAResource.TMNOFLAGS);
464
465         /*
466          * Check TMFAIL.
467          */

468         try {
469         xid = new XidImpl(1, "TwoPCTest6".getBytes(), null);
470         xaEnv.start(xid, XAResource.TMNOFLAGS);
471         xaEnv.end(xid, XAResource.TMFAIL);
472         xaEnv.commit(xid, false);
473         } catch (XAException JavaDoc XAE) {
474         /* Expect this. */
475         assertTrue(XAE.errorCode == XAException.XA_RBROLLBACK);
476         }
477         xaEnv.rollback(xid);
478
479         /*
480          * Check TMSUCCESS.
481          */

482         xid = new XidImpl(1, "TwoPCTest6".getBytes(), null);
483         xaEnv.start(xid, XAResource.TMNOFLAGS);
484         xaEnv.end(xid, XAResource.TMSUCCESS);
485         xaEnv.commit(xid, false);
486
487         /*
488          * Check start(); end(SUSPEND); end(SUCCESS). This is a case that
489          * JBoss causes to happen. It should succeed.
490          */

491         xid = new XidImpl(1, "TwoPCTest7".getBytes(), null);
492         xaEnv.start(xid, XAResource.TMNOFLAGS);
493         xaEnv.end(xid, XAResource.TMSUSPEND);
494         xaEnv.end(xid, XAResource.TMSUCCESS);
495         xaEnv.commit(xid, false);
496
497         /*
498          * Check end(SUSPEND); end(SUCCESS) [with no start() call.].
499          * This should fail.
500          */

501         try {
502         xid = new XidImpl(1, "TwoPCTest8".getBytes(), null);
503         xaEnv.end(xid, XAResource.TMFAIL);
504         xaEnv.commit(xid, false);
505         } catch (XAException JavaDoc XAE) {
506         /* Expect this. */
507         assertTrue(XAE.errorCode == XAException.XAER_NOTA);
508         }
509     } catch (Throwable JavaDoc t) {
510         t.printStackTrace();
511         throw t;
512     }
513     }
514 }
515
Popular Tags