KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > transaction > file > FileResourceManagerTest


1 /*
2  * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//transaction/src/test/org/apache/commons/transaction/file/FileResourceManagerTest.java,v 1.3 2005/01/13 01:34:25 ozeigermann Exp $
3 <<<<<<< .mine
4  * $Revision: 1.3 $
5  * $Date: 2005-02-26 14:16:14 +0100 (Sa, 26 Feb 2005) $
6 =======
7  * $Revision$
8  * $Date: 2005-02-26 14:16:14 +0100 (Sa, 26 Feb 2005) $
9 >>>>>>> .r168169
10  *
11  * ====================================================================
12  *
13  * Copyright 1999-2002 The Apache Software Foundation
14  *
15  * Licensed under the Apache License, Version 2.0 (the "License");
16  * you may not use this file except in compliance with the License.
17  * You may obtain a copy of the License at
18  *
19  * http://www.apache.org/licenses/LICENSE-2.0
20  *
21  * Unless required by applicable law or agreed to in writing, software
22  * distributed under the License is distributed on an "AS IS" BASIS,
23  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24  * See the License for the specific language governing permissions and
25  * limitations under the License.
26  *
27  */

28
29 package org.apache.commons.transaction.file;
30
31 import java.io.BufferedReader JavaDoc;
32 import java.io.File JavaDoc;
33 import java.io.FileInputStream JavaDoc;
34 import java.io.FileOutputStream JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.io.InputStream JavaDoc;
37 import java.io.InputStreamReader JavaDoc;
38 import java.io.OutputStream JavaDoc;
39 import java.util.logging.Logger JavaDoc;
40
41 import javax.transaction.Status JavaDoc;
42
43 import junit.framework.Test;
44 import junit.framework.TestCase;
45 import junit.framework.TestSuite;
46
47 import org.apache.commons.transaction.util.FileHelper;
48 import org.apache.commons.transaction.util.Jdk14Logger;
49 import org.apache.commons.transaction.util.LoggerFacade;
50 import org.apache.commons.transaction.util.RendezvousBarrier;
51
52 /**
53  * Tests for FileResourceManager.
54  *
55  * @version $Revision$
56  */

57 public class FileResourceManagerTest extends TestCase {
58
59     private static final Logger JavaDoc logger = Logger.getLogger(FileResourceManagerTest.class.getName());
60     private static final LoggerFacade sLogger = new Jdk14Logger(logger);
61
62     private static final String JavaDoc STORE = "tmp/store";
63     private static final String JavaDoc WORK = "tmp/work";
64     private static final String JavaDoc ENCODING = "ISO-8859-15";
65     // FIXME
66
// XXX INCREASE THIS WHEN DEBUGGING OTHERWISE THE BARRIER WILL TIME OUT AFTER TWO SECONDS
67
// MOST LIKELY CONFUSING YOU COMPLETELY
68
private static final long BARRIER_TIMEOUT = 200000;
69
70     private static final String JavaDoc[] INITIAL_FILES = new String JavaDoc[] { STORE + "/olli/Hubert6", STORE + "/olli/Hubert" };
71
72     private static final String JavaDoc STATUS_COMMITTING_CONTEXT =
73         "8\n10\n2000\n1063099404687\n";
74     private static final String JavaDoc[] STATUS_COMMITTING_CONTEXT_CHANGE_FILES =
75         new String JavaDoc[] { "olli/Hubert40", "olli/Hubert50" };
76     private static final String JavaDoc[] STATUS_COMMITTING_CONTEXT_DELETE_FILES = new String JavaDoc[] { "/olli/Hubert" };
77     private static final String JavaDoc[] STATUS_COMMITTING_CONTEXT_RESULT_FILES =
78         new String JavaDoc[] { "Hubert6", "Hubert50", "Hubert40" };
79
80     private static void initCommittingRecovery() throws Throwable JavaDoc {
81         String JavaDoc txId = "COMMITTING";
82         createTxContextFile(txId, STATUS_COMMITTING_CONTEXT);
83         createTxDeleteFiles(txId, STATUS_COMMITTING_CONTEXT_DELETE_FILES);
84         createTxChangeFiles(txId, STATUS_COMMITTING_CONTEXT_CHANGE_FILES);
85     }
86
87     private static final String JavaDoc STATUS_COMMITTED_CONTEXT =
88         "3\n10\n2000\n1063099404687\n";
89     private static final String JavaDoc[] STATUS_COMMITTED_CONTEXT_CHANGE_FILES =
90         new String JavaDoc[] { "olli/Hubert4", "olli/Hubert5" };
91     private static final String JavaDoc[] STATUS_COMMITTED_CONTEXT_DELETE_FILES = new String JavaDoc[] {
92     };
93     private static final String JavaDoc[] STATUS_COMMITTED_CONTEXT_RESULT_FILES = new String JavaDoc[] { "Hubert6", "Hubert" };
94
95     protected static final long TIMEOUT = Long.MAX_VALUE;
96
97     private static int deadlockCnt = 0;
98
99     private static void initCommittedRecovery() throws Throwable JavaDoc {
100         String JavaDoc txId = "COMMITTED";
101         createTxContextFile(txId, STATUS_COMMITTED_CONTEXT);
102         createTxDeleteFiles(txId, STATUS_COMMITTED_CONTEXT_DELETE_FILES);
103         createTxChangeFiles(txId, STATUS_COMMITTED_CONTEXT_CHANGE_FILES);
104     }
105
106     private static final String JavaDoc STATUS_ROLLING_BACK_CONTEXT =
107         "9\n10\n2000\n1063099404687\n";
108     private static final String JavaDoc[] STATUS_ROLLING_BACK_CONTEXT_CHANGE_FILES =
109         new String JavaDoc[] { "olli/Hubert4", "olli/Hubert5" };
110     private static final String JavaDoc[] STATUS_ROLLING_BACK_CONTEXT_DELETE_FILES = new String JavaDoc[] {
111     };
112     private static final String JavaDoc[] STATUS_ROLLING_BACK_CONTEXT_RESULT_FILES = new String JavaDoc[] { "Hubert6", "Hubert" };
113
114     private static void initRollingBackRecovery() throws Throwable JavaDoc {
115         String JavaDoc txId = "ROLLING_BACK";
116         createTxContextFile(txId, STATUS_ROLLING_BACK_CONTEXT);
117         createTxDeleteFiles(txId, STATUS_ROLLING_BACK_CONTEXT_DELETE_FILES);
118         createTxChangeFiles(txId, STATUS_ROLLING_BACK_CONTEXT_CHANGE_FILES);
119     }
120
121     private static final String JavaDoc STATUS_ROLLEDBACK_CONTEXT =
122         "4\n10\n2000\n1063099404687\n";
123     private static final String JavaDoc[] STATUS_ROLLEDBACK_CONTEXT_CHANGE_FILES =
124         new String JavaDoc[] { "olli/Hubert4", "olli/Hubert5" };
125     private static final String JavaDoc[] STATUS_ROLLEDBACK_CONTEXT_DELETE_FILES = new String JavaDoc[] {
126     };
127     private static final String JavaDoc[] STATUS_ROLLEDBACK_CONTEXT_RESULT_FILES = new String JavaDoc[] { "Hubert6", "Hubert" };
128
129     private static void initRolledBackRecovery() throws Throwable JavaDoc {
130         String JavaDoc txId = "ROLLEDBACK";
131         createTxContextFile(txId, STATUS_ROLLEDBACK_CONTEXT);
132         createTxDeleteFiles(txId, STATUS_ROLLEDBACK_CONTEXT_DELETE_FILES);
133         createTxChangeFiles(txId, STATUS_ROLLEDBACK_CONTEXT_CHANGE_FILES);
134     }
135
136     private static final String JavaDoc STATUS_ACTIVE_CONTEXT = "0\n10\n2000\n1063099404687\n";
137     private static final String JavaDoc[] STATUS_ACTIVE_CONTEXT_CHANGE_FILES = new String JavaDoc[] { "olli/Hubert4", "olli/Hubert5" };
138     private static final String JavaDoc[] STATUS_ACTIVE_CONTEXT_DELETE_FILES = new String JavaDoc[] {
139     };
140     private static final String JavaDoc[] STATUS_ACTIVE_CONTEXT_RESULT_FILES = new String JavaDoc[] { "Hubert6", "Hubert" };
141
142     private static void initActiveRecovery() throws Throwable JavaDoc {
143         String JavaDoc txId = "ACTIVE";
144         createTxContextFile(txId, STATUS_ACTIVE_CONTEXT);
145         createTxDeleteFiles(txId, STATUS_ACTIVE_CONTEXT_DELETE_FILES);
146         createTxChangeFiles(txId, STATUS_ACTIVE_CONTEXT_CHANGE_FILES);
147     }
148
149     private static void removeRec(String JavaDoc dirPath) {
150         FileHelper.removeRec(new File JavaDoc(dirPath));
151     }
152
153     private static final void createFiles(String JavaDoc[] filePaths) {
154         createFiles(filePaths, null, null);
155     }
156
157     private static final void createFiles(String JavaDoc[] filePaths, String JavaDoc dirPath) {
158         createFiles(filePaths, null, dirPath);
159     }
160
161     private static final void createFiles(String JavaDoc[] filePaths, String JavaDoc[] contents) {
162         createFiles(filePaths, contents, null);
163     }
164
165     private static final void createFiles(String JavaDoc[] filePaths, String JavaDoc[] contents, String JavaDoc dirPath) {
166         for (int i = 0; i < filePaths.length; i++) {
167             String JavaDoc filePath = filePaths[i];
168             File JavaDoc file;
169             if (dirPath != null) {
170                 file = new File JavaDoc(new File JavaDoc(dirPath), filePath);
171             } else {
172                 file = new File JavaDoc(filePath);
173             }
174             file.getParentFile().mkdirs();
175             try {
176                 file.delete();
177                 file.createNewFile();
178                 String JavaDoc content = null;
179                 if (contents != null && contents.length > i) {
180                     content = contents[i];
181                 }
182                 if (content != null) {
183                     FileOutputStream JavaDoc stream = new FileOutputStream JavaDoc(file);
184                     stream.write(contents[i].getBytes(ENCODING));
185                     stream.close();
186                 }
187             } catch (IOException JavaDoc e) {
188             }
189         }
190     }
191
192     private static final void deleteInDir(String JavaDoc dirPath, String JavaDoc[] fileNames) {
193         File JavaDoc dir = new File JavaDoc(dirPath);
194
195         if (dir.isDirectory()) {
196             for (int i = 0; i < fileNames.length; i++) {
197                 String JavaDoc fileName = fileNames[i];
198                 File JavaDoc file = new File JavaDoc(dir, fileName);
199                 file.delete();
200             }
201         }
202     }
203
204     private static final void checkIsEmpty(String JavaDoc dirPath) {
205         checkExactlyContains(dirPath, null);
206     }
207     private static final void checkExactlyContains(String JavaDoc dirPath, String JavaDoc[] fileNames) {
208         checkExactlyContains(dirPath, fileNames, null);
209     }
210
211     private static final void checkExactlyContains(String JavaDoc dirPath, String JavaDoc[] fileNames,
212             String JavaDoc[] contents) {
213         File JavaDoc dir = new File JavaDoc(dirPath);
214
215         if (dir.isDirectory()) {
216             File JavaDoc[] files = dir.listFiles();
217             if (fileNames == null) {
218                 if (files.length != 0) {
219                     fail(dirPath + " must be empty");
220                 } else {
221                     return;
222                 }
223             }
224
225             if (files.length != fileNames.length) {
226                 fail(dirPath + " contains " + files.length + " instead of " + fileNames.length
227                         + " files");
228             }
229
230             for (int i = 0; i < fileNames.length; i++) {
231                 String JavaDoc fileName = fileNames[i];
232                 boolean match = false;
233                 File JavaDoc file = null;
234                 for (int j = 0; j < files.length; j++) {
235                     file = files[j];
236                     if (file.getName().equals(fileName)) {
237                         match = true;
238                         break;
239                     }
240                 }
241                 if (!match) {
242                     fail(dirPath + " does not contain required " + fileName);
243                 }
244
245                 String JavaDoc content = null;
246                 if (contents != null && i < contents.length) {
247                     content = contents[i];
248                 }
249                 if (content != null && !compare(file, content)) {
250                     fail("Contents of " + fileName + " in " + dirPath
251                             + " does not contain required content '" + content + "'");
252                 }
253             }
254
255         } else {
256             fail(dirPath + " is not directoy");
257         }
258     }
259
260     private static boolean compare(FileInputStream JavaDoc stream, byte[] bytes) {
261         int read;
262         int count = 0;
263         try {
264             while ((read = stream.read()) != -1) {
265                 if (bytes[count++] != read) {
266                     return false;
267                 }
268             }
269         } catch (IOException JavaDoc e) {
270             return false;
271         }
272         return true;
273     }
274
275     private static boolean compare(File JavaDoc file, String JavaDoc content) {
276         FileInputStream JavaDoc stream = null;
277         try {
278             byte[] bytes = content.getBytes(ENCODING);
279             stream = new FileInputStream JavaDoc(file);
280             return compare(stream, bytes);
281         } catch (Throwable JavaDoc t) {
282             return false;
283         } finally {
284             if (stream != null) {
285                 try {
286                     stream.close();
287                 } catch (IOException JavaDoc e) {
288                 }
289             }
290         }
291     }
292
293     private static String JavaDoc workForTx(Object JavaDoc txId) {
294         return WORK + "/" + txId;
295     }
296
297     private static String JavaDoc changeForTx(Object JavaDoc txId) {
298         return workForTx(txId) + "/change";
299     }
300
301     private static String JavaDoc deleteForTx(Object JavaDoc txId) {
302         return workForTx(txId) + "/delete";
303     }
304
305     private static String JavaDoc logForTx(Object JavaDoc txId) {
306         return workForTx(txId) + "/transaction.log";
307     }
308
309     private static void reset() {
310         removeRec(STORE);
311         removeRec(WORK);
312         new File JavaDoc(STORE).mkdirs();
313         new File JavaDoc(WORK).mkdirs();
314     }
315
316     private static void createInitialFiles() {
317         createFiles(INITIAL_FILES);
318     }
319
320     private static void createTxContextFile(Object JavaDoc txId, String JavaDoc content) {
321         createFiles(new String JavaDoc[] { logForTx(txId)}, new String JavaDoc[] { txId + "\n" + content });
322     }
323
324     private static void createTxDeleteFiles(Object JavaDoc txId, String JavaDoc[] files) {
325         createFiles(files, deleteForTx(txId));
326     }
327
328     private static void createTxChangeFiles(Object JavaDoc txId, String JavaDoc[] files) {
329         createFiles(files, changeForTx(txId));
330     }
331
332     // XXX need this, as JUnit seems to print only part of these strings
333
private static void report(String JavaDoc should, String JavaDoc is) {
334         if (!is.equals(should)) {
335             fail("\nWrong output:\n'" + is + "'\nShould be:\n'" + should + "'\n");
336         }
337     }
338
339     public static FileResourceManager createFRM() {
340         return new FileResourceManager(STORE, WORK, false, sLogger, true);
341     }
342
343     public static Test suite() {
344         TestSuite suite = new TestSuite(FileResourceManagerTest.class);
345         return suite;
346     }
347
348     public static void main(java.lang.String JavaDoc[] args) {
349         junit.textui.TestRunner.run(suite());
350     }
351
352     public FileResourceManagerTest(String JavaDoc testName) {
353         super(testName);
354     }
355
356     public void testGlobal() throws Throwable JavaDoc {
357         reset();
358         createInitialFiles();
359         
360         final FileResourceManager rm = createFRM();
361         
362         rm.start();
363
364         final RendezvousBarrier shutdownBarrier = new RendezvousBarrier("Shutdown", 3, BARRIER_TIMEOUT, sLogger);
365         final RendezvousBarrier start2Barrier = new RendezvousBarrier("Start2", BARRIER_TIMEOUT, sLogger);
366         final RendezvousBarrier commit1Barrier = new RendezvousBarrier("Commit1", BARRIER_TIMEOUT, sLogger);
367
368         final Object JavaDoc txId1 = "Create";
369
370         Thread JavaDoc create = new Thread JavaDoc(new Runnable JavaDoc() {
371             public void run() {
372                 try {
373                     rm.startTransaction(txId1);
374
375                     shutdownBarrier.call();
376                     start2Barrier.call();
377
378                     rm.createResource(txId1, "/olli/Hubert4");
379                     rm.createResource(txId1, "/olli/Hubert5");
380                     String JavaDoc msg = "Greetings from " + txId1 + "\n";
381                     OutputStream JavaDoc out = rm.writeResource(txId1, "/olli/Hubert6");
382                     out.write(msg.getBytes(ENCODING));
383
384                     commit1Barrier.meet();
385
386                     checkExactlyContains(
387                         changeForTx(txId1) + "/olli",
388                         new String JavaDoc[] { "Hubert4", "Hubert5", "Hubert6" },
389                         new String JavaDoc[] { "", "", "Greetings from " + txId1 + "\n" });
390
391                     rm.commitTransaction(txId1);
392
393                     checkExactlyContains(
394                         STORE + "/olli",
395                         new String JavaDoc[] { "Hubert", "Hubert4", "Hubert5", "Hubert6" },
396                         new String JavaDoc[] { "", "", "", "Greetings from " + txId1 + "\n" });
397
398                 } catch (Throwable JavaDoc e) {
399                     System.err.println("Error: " + e);
400                     e.printStackTrace();
401                 }
402             }
403         }, "Create Thread");
404
405         Thread JavaDoc modify = new Thread JavaDoc(new Runnable JavaDoc() {
406             public void run() {
407                 Object JavaDoc txId = null;
408                 try {
409
410                     {
411                         InputStream JavaDoc in = rm.readResource("/olli/Hubert6");
412                         BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in, ENCODING));
413                         String JavaDoc line = reader.readLine();
414                         assertEquals(line, null);
415                         in.close();
416                     }
417
418                     txId = "Modify";
419                     rm.startTransaction(txId);
420                     rm.setIsolationLevel(txId, ResourceManager.ISOLATION_LEVEL_READ_COMMITTED);
421
422                     {
423                         InputStream JavaDoc in = rm.readResource(txId, "/olli/Hubert6");
424                         BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in, ENCODING));
425                         String JavaDoc line = reader.readLine();
426                         assertEquals(line, null);
427                         in.close();
428                     }
429
430                     shutdownBarrier.call();
431
432                     rm.createResource(txId, "/olli/Hubert1");
433                     rm.createResource(txId, "/olli/Hubert2");
434                     rm.createResource(txId, "/olli/Hubert3");
435
436                     // wait until tx commits, so there already are Hubert4 and Hubert5 and
437
// Hubert6 changes
438
commit1Barrier.meet();
439
440                     rm.createResource(txId, "/olli/Hubert4");
441                     rm.createResource(txId, "/olli/Hubert5");
442
443                     rm.createResource(txId, "/olli/Hubert6");
444                     InputStream JavaDoc in = rm.readResource(txId, "/olli/Hubert6");
445                     BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in, ENCODING));
446                     String JavaDoc line = reader.readLine();
447                     // allow for update while in tx as this is READ_COMMITED
448
report("Greetings from " + txId1, line);
449                     in.close();
450
451                     rm.deleteResource(txId, "/olli/Hubert");
452                     rm.deleteResource(txId, "/olli/Hubert2");
453                     rm.deleteResource(txId, "/olli/Hubert3");
454                     rm.deleteResource(txId, "/olli/Hubert4");
455                     rm.deleteResource(txId, "/olli/Hubert5");
456
457                     checkExactlyContains(deleteForTx(txId) + "/olli", new String JavaDoc[] { "Hubert", "Hubert4", "Hubert5" });
458
459                     checkExactlyContains(changeForTx(txId) + "/olli", new String JavaDoc[] { "Hubert1" });
460
461                     rm.commitTransaction(txId);
462                 } catch (Throwable JavaDoc e) {
463                     System.err.println("Error: " + e);
464                     e.printStackTrace();
465                 }
466             }
467         }, "Modify Thread");
468
469         create.start();
470         // be sure first thread is started before trying next
471
start2Barrier.meet();
472         modify.start();
473
474         // let both transaction start before trying to shut down
475
shutdownBarrier.meet();
476
477         assertTrue(rm.stop(ResourceManager.SHUTDOWN_MODE_NORMAL, 5000));
478
479         checkExactlyContains(
480             STORE + "/olli",
481             new String JavaDoc[] { "Hubert1", "Hubert6" },
482             new String JavaDoc[] { "", "Greetings from " + txId1 + "\n" });
483         checkIsEmpty(WORK);
484     }
485
486     public void testCombinedRecovery() throws Throwable JavaDoc {
487         reset();
488         createInitialFiles();
489         initCommittingRecovery();
490         initCommittedRecovery();
491         initActiveRecovery();
492         initRolledBackRecovery();
493         initRollingBackRecovery();
494
495         FileResourceManager rm =createFRM();
496
497         // do nothing, just start and stop to check recovery of tx
498
rm.start();
499         assertTrue(rm.stop(ResourceManager.SHUTDOWN_MODE_NORMAL, 5000));
500
501         // all but committing should be rolled back
502
checkExactlyContains(STORE + "/olli", STATUS_COMMITTING_CONTEXT_RESULT_FILES);
503         checkIsEmpty(WORK);
504     }
505
506     public void testCommittingRecovery() throws Throwable JavaDoc {
507         reset();
508         createInitialFiles();
509         initCommittingRecovery();
510
511         FileResourceManager rm = createFRM();
512
513         // do nothing, just start and stop to check recovery of tx
514
rm.start();
515         assertTrue(rm.stop(ResourceManager.SHUTDOWN_MODE_NORMAL, 5000));
516
517         checkExactlyContains(STORE + "/olli", STATUS_COMMITTING_CONTEXT_RESULT_FILES);
518         checkIsEmpty(WORK);
519     }
520
521     public void testActiveRecovery() throws Throwable JavaDoc {
522         reset();
523         createInitialFiles();
524         initActiveRecovery();
525
526         FileResourceManager rm = createFRM();
527
528         // do nothing, just start and stop to check recovery of tx
529
rm.start();
530         assertTrue(rm.stop(ResourceManager.SHUTDOWN_MODE_NORMAL, 5000));
531
532         checkExactlyContains(STORE + "/olli", STATUS_ACTIVE_CONTEXT_RESULT_FILES);
533         checkIsEmpty(WORK);
534     }
535
536     public void testRolledbackRecovery() throws Throwable JavaDoc {
537         reset();
538         createInitialFiles();
539         initRolledBackRecovery();
540
541         FileResourceManager rm = createFRM();
542
543         // do nothing, just start and stop to check recovery of tx
544
rm.start();
545         assertTrue(rm.stop(ResourceManager.SHUTDOWN_MODE_NORMAL, 5000));
546
547         checkExactlyContains(STORE + "/olli", STATUS_ROLLEDBACK_CONTEXT_RESULT_FILES);
548         checkIsEmpty(WORK);
549     }
550
551     public void testRollingBackRecovery() throws Throwable JavaDoc {
552         reset();
553         createInitialFiles();
554         initRollingBackRecovery();
555
556         FileResourceManager rm = createFRM();
557
558         // do nothing, just start and stop to check recovery of tx
559
rm.start();
560         assertTrue(rm.stop(ResourceManager.SHUTDOWN_MODE_NORMAL, 5000));
561
562         checkExactlyContains(STORE + "/olli", STATUS_ROLLING_BACK_CONTEXT_RESULT_FILES);
563         checkIsEmpty(WORK);
564     }
565
566     public void testCommittedRecovery() throws Throwable JavaDoc {
567         reset();
568         createInitialFiles();
569         initCommittedRecovery();
570
571         FileResourceManager rm = createFRM();
572
573         // do nothing, just start and stop to check recovery of tx
574
rm.start();
575         assertTrue(rm.stop(ResourceManager.SHUTDOWN_MODE_NORMAL, 5000));
576
577         checkExactlyContains(STORE + "/olli", STATUS_COMMITTED_CONTEXT_RESULT_FILES);
578         checkIsEmpty(WORK);
579     }
580
581     public void testInteractiveDirtyRecovery() throws Throwable JavaDoc {
582         reset();
583         createInitialFiles();
584
585         FileResourceManager rm = createFRM();
586
587         rm.start();
588
589         String JavaDoc txId = "DIRTY";
590         rm.startTransaction(txId);
591         rm.createResource(txId, "/olli/Hubert100");
592
593         // fake a failed commit
594
FileResourceManager.TransactionContext context = rm.getContext(txId);
595         // needing synchronization in order not to interfer with shutdown thread
596
synchronized (context) {
597             logger.fine("Committing Tx " + txId);
598
599             context.status = Status.STATUS_COMMITTING;
600             context.saveState();
601             rm.dirty = true;
602             context.finalCleanUp();
603             context.notifyFinish();
604         }
605
606         // should be allowed
607
rm.readResource(txId, "/olli/Hubert");
608
609         // should be disallowed
610
boolean writeDeniedByDirty = false;
611         try {
612             rm.createResource(txId, "/olli/Hubert10");
613         } catch (ResourceManagerSystemException rmse) {
614             writeDeniedByDirty = true;
615         }
616         assertTrue(writeDeniedByDirty);
617
618         // on success (expected) resets dirty flag
619
rm.recover();
620
621         // should all be allowed again
622
txId = "DIRTYTEST";
623         rm.startTransaction(txId);
624         rm.readResource(txId, "/olli/Hubert");
625         rm.createResource(txId, "/olli/Hubert10");
626         rm.commitTransaction(txId);
627
628         assertTrue(rm.stop(ResourceManager.SHUTDOWN_MODE_NORMAL, 5000));
629
630         // tx rolled forward created "/olli/Hubert100", so it should be here as well
631
checkExactlyContains(STORE + "/olli", new String JavaDoc[] { "Hubert", "Hubert100", "Hubert6", "Hubert10" });
632         checkIsEmpty(WORK);
633     }
634
635     public void testConflict() throws Throwable JavaDoc {
636         logger.info("Checking concurrent transaction features");
637
638         reset();
639         createInitialFiles();
640         
641         final FileResourceManager rm = createFRM();
642         
643         rm.start();
644
645         final RendezvousBarrier restart = new RendezvousBarrier("restart",
646                 TIMEOUT, sLogger);
647
648         for (int i = 0; i < 25; i++) {
649
650             final RendezvousBarrier deadlockBarrier1 = new RendezvousBarrier("deadlock" + i,
651                     TIMEOUT, sLogger);
652
653             Thread JavaDoc thread1 = new Thread JavaDoc(new Runnable JavaDoc() {
654                 public void run() {
655                     try {
656                         rm.startTransaction("tx1");
657                         // first both threads get a lock, this one on res2
658
rm.createResource("tx1", "key2");
659                         synchronized (deadlockBarrier1) {
660                             deadlockBarrier1.meet();
661                             deadlockBarrier1.reset();
662                         }
663                         // if I am first, the other thread will be dead, i.e.
664
// exactly one
665
rm.createResource("tx1", "key1");
666                         rm.commitTransaction("tx1");
667                     } catch (InterruptedException JavaDoc ie) {
668                     } catch (ResourceManagerException e) {
669                         assertEquals(e.getStatus(), ResourceManagerException.ERR_DEAD_LOCK);
670                         deadlockCnt++;
671                         try {
672                             rm.rollbackTransaction("tx1");
673                         } catch (ResourceManagerException e1) {
674                             // TODO Auto-generated catch block
675
e1.printStackTrace();
676                         }
677                     } finally {
678                         try {
679                         synchronized (restart) {
680                             restart.meet();
681                             restart.reset();
682                         }
683                         } catch (InterruptedException JavaDoc ie) {}
684
685                     }
686                 }
687             }, "Thread1");
688
689             thread1.start();
690
691             rm.startTransaction("tx2");
692             try {
693                 // first both threads get a lock, this one on res2
694
rm.deleteResource("tx2", "key1");
695                 synchronized (deadlockBarrier1) {
696                     deadlockBarrier1.meet();
697                     deadlockBarrier1.reset();
698                 }
699                 // if I am first, the other thread will be dead, i.e. exactly
700
// one
701
rm.deleteResource("tx2", "key2");
702                 rm.commitTransaction("tx2");
703             } catch (ResourceManagerException e) {
704                 assertEquals(e.getStatus(), ResourceManagerException.ERR_DEAD_LOCK);
705                 deadlockCnt++;
706                 try {
707                     rm.rollbackTransaction("tx2");
708                 } catch (ResourceManagerException e1) {
709                     // TODO Auto-generated catch block
710
e1.printStackTrace();
711                 }
712             } finally {
713                 try {
714                 synchronized (restart) {
715                     restart.meet();
716                     restart.reset();
717                 }
718                 } catch (InterruptedException JavaDoc ie) {}
719
720             }
721
722             // XXX in special scenarios the current implementation might cause both
723
// owners to be deadlock victims
724
if (deadlockCnt != 1) {
725                 sLogger.logWarning("More than one thread was deadlock victim!");
726             }
727             assertTrue(deadlockCnt >= 1);
728             deadlockCnt = 0;
729         }
730     }
731
732 }
733
Popular Tags