You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oz...@apache.org on 2007/08/18 03:37:47 UTC

svn commit: r567198 - in /commons/proper/transaction/branches/TRANSACTION_2/src: java/org/apache/commons/transaction/file/ test/org/apache/commons/transaction/file/ test/org/apache/commons/transaction/locking/ test/org/apache/commons/transaction/memory/

Author: ozeigermann
Date: Fri Aug 17 18:37:46 2007
New Revision: 567198

URL: http://svn.apache.org/viewvc?view=rev&rev=567198
Log:
Completed initial tests (not all complete successfully, yet)

Added:
    commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/locking/
    commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/locking/LockTest.java
Modified:
    commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
    commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java
    commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/memory/BasicTxMapTest.java

Modified: commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
URL: http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java?view=diff&rev=567198&r1=567197&r2=567198
==============================================================================
--- commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java (original)
+++ commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java Fri Aug 17 18:37:46 2007
@@ -22,7 +22,7 @@
  */
 public class MemoryUndoManager implements FileResourceUndoManager {
 
-    private Log logger = LogFactory.getLog(getClass());
+    private Log log = LogFactory.getLog(getClass());
 
     protected ThreadLocal<List<UndoRecord>> localRecords = new ThreadLocal<List<UndoRecord>>();
 
@@ -68,7 +68,7 @@
                     moveAllowed));
         } catch (IOException e) {
             // FIXME: This really is fatal: How to signal?
-            logger.fatal("Can not record content update", e);
+            log.fatal("Can not record content update", e);
         }
     }
 
@@ -124,7 +124,7 @@
                     FileHelper.move(updatedFile, file);
                 } catch (IOException e) {
                     // FIXME: This really is fatal: How to signal?
-                    logger.fatal("Can not undo content update", e);
+                    log.fatal("Can not undo content update", e);
                 }
                 break;
             }

Modified: commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java?view=diff&rev=567198&r1=567197&r2=567198
==============================================================================
--- commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java (original)
+++ commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java Fri Aug 17 18:37:46 2007
@@ -18,23 +18,56 @@
 
 import static junit.framework.Assert.fail;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.util.concurrent.TimeUnit;
 
 import junit.framework.JUnit4TestAdapter;
+import static junit.framework.Assert.*;
+import org.junit.Test;
 
 import org.apache.commons.transaction.file.FileResourceManager.FileResource;
-import org.junit.Test;
+import org.apache.commons.transaction.util.FileHelper;
+import org.apache.commons.transaction.util.RendezvousBarrier;
 
 public class TxFileResourceManagerTest {
-    
+
     private static final String ENCODING = "ISO-8859-15";
 
+    // XXX INCREASE THIS WHEN DEBUGGING OTHERWISE THE BARRIER WILL TIME OUT
+    // AFTER TWO SECONDS
+    // MOST LIKELY CONFUSING YOU COMPLETELY
+    private static final long BARRIER_TIMEOUT = 200000;
+
+    private static final String rootPath = "d:/tmp/content";
+
+    private static final String tmpDir = "d:/tmp/txlogs";
+
+    private static String msg;
+
+    private static void reset() {
+        removeRec(rootPath);
+        removeRec(tmpDir);
+    }
+
+    private static final String[] INITIAL_FILES = new String[] { rootPath + "/olli/Hubert6",
+            rootPath + "/olli/Hubert" };
+
+    private static void removeRec(String dirPath) {
+        FileHelper.removeRecursive(new File(dirPath));
+    }
+
+    private static void createInitialFiles() {
+        createFiles(INITIAL_FILES);
+    }
+
     public static junit.framework.Test suite() {
         return new JUnit4TestAdapter(TxFileResourceManagerTest.class);
     }
@@ -43,6 +76,13 @@
         junit.textui.TestRunner.run(suite());
     }
 
+    // XXX need this, as JUnit seems to print only part of these strings
+    private static void report(String should, String is) {
+        if (!is.equals(should)) {
+            fail("\nWrong output:\n'" + is + "'\nShould be:\n'" + should + "'\n");
+        }
+    }
+
     private static final void createFiles(String[] filePaths) {
         createFiles(filePaths, null, null);
     }
@@ -85,6 +125,7 @@
     private static final void checkIsEmpty(String dirPath) {
         checkExactlyContains(dirPath, null);
     }
+
     private static final void checkExactlyContains(String dirPath, String[] fileNames) {
         checkExactlyContains(dirPath, fileNames, null);
     }
@@ -173,13 +214,13 @@
 
     @Test
     public void basic() {
-        TxFileResourceManager manager = new TxFileResourceManager("TxFileManager", "d:/tmp/content");
+        TxFileResourceManager manager = new TxFileResourceManager("TxFileManager", rootPath);
         FileResourceUndoManager um;
         try {
-            um = new MemoryUndoManager("d:/tmp/txlogs");
+            um = new MemoryUndoManager(tmpDir);
             manager.setUndoManager(um);
             manager.startTransaction(60, TimeUnit.SECONDS);
-            FileResource file = manager.getResource("d:/tmp/content/aha");
+            FileResource file = manager.getResource(rootPath + "/aha");
             if (!file.exists()) {
                 file.createAsFile();
             }
@@ -193,5 +234,123 @@
         }
 
     }
-    
+
+    @Test
+    public void global() throws Throwable {
+        reset();
+        createInitialFiles();
+
+        final TxFileResourceManager rm = new TxFileResourceManager("TxFileManager", rootPath);
+        FileResourceUndoManager um;
+        um = new MemoryUndoManager(tmpDir);
+        rm.setUndoManager(um);
+
+        final RendezvousBarrier shutdownBarrier = new RendezvousBarrier("Shutdown", 3,
+                BARRIER_TIMEOUT);
+        final RendezvousBarrier start2Barrier = new RendezvousBarrier("Start2", BARRIER_TIMEOUT);
+        final RendezvousBarrier commit1Barrier = new RendezvousBarrier("Commit1", BARRIER_TIMEOUT);
+
+        Thread create = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    rm.startTransaction(60, TimeUnit.SECONDS);
+
+                    shutdownBarrier.call();
+                    start2Barrier.call();
+
+                    rm.getResource(rootPath + "/olli/Hubert4").createAsFile();
+                    rm.getResource(rootPath + "/olli/Hubert5").createAsFile();
+                    msg = "Greetings from " + Thread.currentThread().getName() + "\n";
+                    OutputStream out = rm.getResource(rootPath + "/olli/Hubert6")
+                            .writeStream(false);
+                    out.write(msg.getBytes(ENCODING));
+
+                    commit1Barrier.meet();
+
+                    rm.commitTransaction();
+
+                    checkExactlyContains(rootPath + "/olli", new String[] { "Hubert", "Hubert4",
+                            "Hubert5", "Hubert6" }, new String[] { "", "", "", msg });
+
+                } catch (Throwable e) {
+                    System.err.println("Error: " + e);
+                    e.printStackTrace();
+                }
+            }
+        }, "Create Thread");
+
+        Thread modify = new Thread(new Runnable() {
+            public void run() {
+                Object txId = null;
+                try {
+
+                    {
+                        InputStream in = rm.getResource(rootPath + "/olli/Hubert6").readStream();
+                        BufferedReader reader = new BufferedReader(new InputStreamReader(in,
+                                ENCODING));
+                        String line = reader.readLine();
+                        assertEquals(line, null);
+                        in.close();
+                    }
+
+                    txId = "Modify";
+                    rm.startTransaction(60, TimeUnit.SECONDS);
+
+                    {
+                        InputStream in = rm.getResource(rootPath + "/olli/Hubert6").readStream();
+                        BufferedReader reader = new BufferedReader(new InputStreamReader(in,
+                                ENCODING));
+                        String line = reader.readLine();
+                        assertEquals(line, null);
+                        in.close();
+                    }
+
+                    shutdownBarrier.call();
+
+                    rm.getResource(rootPath + "/olli/Hubert1").createAsFile();
+                    rm.getResource(rootPath + "/olli/Hubert2").createAsFile();
+                    rm.getResource(rootPath + "/olli/Hubert3").createAsFile();
+
+                    // wait until tx commits, so there already are Hubert4 and
+                    // Hubert5 and
+                    // Hubert6 changes
+                    commit1Barrier.meet();
+
+                    rm.getResource(rootPath + "/olli/Hubert4").createAsFile();
+                    rm.getResource(rootPath + "/olli/Hubert5").createAsFile();
+                    rm.getResource(rootPath + "/olli/Hubert6").createAsFile();
+                    InputStream in = rm.getResource(rootPath + "/olli/Hubert6").readStream();
+                    BufferedReader reader = new BufferedReader(new InputStreamReader(in, ENCODING));
+                    String line = reader.readLine();
+                    // allow for update while in tx as this is READ_COMMITED
+                    report(msg, line);
+                    in.close();
+
+                    
+                    rm.getResource(rootPath + "/olli/Hubert").delete();
+                    rm.getResource(rootPath + "/olli/Hubert2").delete();
+                    rm.getResource(rootPath + "/olli/Hubert3").delete();
+                    rm.getResource(rootPath + "/olli/Hubert4").delete();
+                    rm.getResource(rootPath + "/olli/Hubert5").delete();
+                    
+                    rm.commitTransaction();
+                } catch (Throwable e) {
+                    System.err.println("Error: " + e);
+                    e.printStackTrace();
+                }
+            }
+        }, "Modify Thread");
+
+        create.start();
+        // be sure first thread is started before trying next
+        start2Barrier.meet();
+        modify.start();
+
+        // let both transaction start before trying to shut down
+        shutdownBarrier.meet();
+
+        checkExactlyContains(rootPath + "/olli", new String[] { "Hubert1", "Hubert6" },
+                new String[] { "", msg });
+    }
+
 }

Added: commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/locking/LockTest.java
URL: http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/locking/LockTest.java?view=auto&rev=567198
==============================================================================
--- commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/locking/LockTest.java (added)
+++ commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/locking/LockTest.java Fri Aug 17 18:37:46 2007
@@ -0,0 +1,719 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.transaction.locking;
+
+import java.io.PrintWriter;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.JUnit4TestAdapter;
+import static junit.framework.Assert.*;
+import org.junit.Test;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.transaction.file.TxFileResourceManagerTest;
+import org.apache.commons.transaction.util.RendezvousBarrier;
+import org.apache.commons.transaction.util.TurnBarrier;
+
+/**
+ * Tests for locking.
+ * 
+ */
+public class LockTest {
+
+    private Log log = LogFactory.getLog(getClass());
+
+    private static final int CONCURRENT_TESTS = 25;
+
+    protected static final long TIMEOUT = 1000000;
+
+    private static int deadlockCnt = 0;
+
+    private static String first = null;
+
+    private static String defaultResource = "resource";
+
+    public static junit.framework.Test suite() {
+        return new JUnit4TestAdapter(TxFileResourceManagerTest.class);
+    }
+
+    public static void main(java.lang.String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    @Test
+    public void deadlock() throws Throwable {
+
+        log.info("\n\nChecking deadlock detection\n\n");
+
+        final String res1 = "res1";
+        final String res2 = "res2";
+
+        final RWLockManager<Object, Object> manager = new RWLockManager<Object, Object>();
+
+        final RendezvousBarrier restart = new RendezvousBarrier("restart", TIMEOUT);
+
+        for (int i = 0; i < CONCURRENT_TESTS; i++) {
+
+            System.out.print(".");
+
+            final RendezvousBarrier deadlockBarrier1 = new RendezvousBarrier("deadlock1" + i,
+                    TIMEOUT);
+
+            Thread deadlock = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10, TimeUnit.SECONDS);
+                        // first both threads get a lock, this one on res2
+                        manager.lock(defaultResource, res2, true);
+                        synchronized (deadlockBarrier1) {
+                            deadlockBarrier1.meet();
+                            deadlockBarrier1.reset();
+                        }
+                        // if I am first, the other thread will be dead, i.e.
+                        // exactly one
+                        manager.lock(defaultResource, res1, true);
+                    } catch (LockException le) {
+                        assertEquals(le.getCode(), LockException.Code.WOULD_DEADLOCK);
+                        deadlockCnt++;
+                    } catch (InterruptedException ie) {
+                    } finally {
+                        manager.endWork();
+                        try {
+                            synchronized (restart) {
+                                restart.meet();
+                                restart.reset();
+                            }
+                        } catch (InterruptedException ie) {
+                        }
+                    }
+                }
+            }, "Deadlock Thread");
+
+            deadlock.start();
+
+            try {
+                manager.startWork(10, TimeUnit.SECONDS);
+                // first both threads get a lock, this one on res2
+                manager.lock(defaultResource, res1, false);
+                synchronized (deadlockBarrier1) {
+                    deadlockBarrier1.meet();
+                    deadlockBarrier1.reset();
+                }
+                // if I am first, the other thread will be dead, i.e. exactly
+                // one
+                manager.lock(defaultResource, res2, true);
+            } catch (LockException le) {
+                assertEquals(le.getCode(), LockException.Code.WOULD_DEADLOCK);
+                deadlockCnt++;
+            } finally {
+                manager.endWork();
+                synchronized (restart) {
+                    restart.meet();
+                    restart.reset();
+                }
+            }
+
+            // XXX in special scenarios the current implementation might cause
+            // both
+            // owners to be deadlock victims
+            if (deadlockCnt != 1) {
+                log.warn("More than one thread was deadlock victim!");
+            }
+            assertTrue(deadlockCnt >= 1);
+            deadlockCnt = 0;
+        }
+    }
+
+    /*
+     * 
+     * Test detection of an indirect deadlock:
+     * 
+     * Owner Owner Owner Step #1 #2 #3 1 read res1 (ok) 2 read res2 (ok) 3 read
+     * res3 (ok) 4 write res2 (blocked because of #2) 5 write res1 (blocked
+     * because of #1) 6 write res3 (blocked because #3) - Thread#1 waits for
+     * Thread#3 on res3 - Thread#2 waits for Thread#1 on res1 - Thread#3 waits
+     * for Thread#2 on res2
+     * 
+     * This needs recursion of the deadlock detection algorithm
+     * 
+     */
+    @Test
+    public void indirectDeadlock() throws Throwable {
+
+        log.info("\n\nChecking detection of indirect deadlock \n\n");
+
+        final String res1 = "res1";
+        final String res2 = "res2";
+        final String res3 = "res3";
+
+        final RWLockManager<Object, Object> manager = new RWLockManager<Object, Object>();
+
+        final RendezvousBarrier restart = new RendezvousBarrier("restart", 5, TIMEOUT);
+
+        final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, 1);
+
+        for (int i = 0; i < CONCURRENT_TESTS; i++) {
+
+            System.out.print(".");
+
+            // thread that accesses lock of res1 just to cause interference and
+            // possibly detect concurrency problems
+            Thread jamThread1 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        for (int i = 0; i < 10; i++) {
+                            manager.startWork(10, TimeUnit.SECONDS);
+                            manager.lock(defaultResource, res1, false);
+                            Thread.sleep(10);
+                            manager.endWork();
+                            Thread.sleep(10);
+                            manager.startWork(10, TimeUnit.SECONDS);
+                            manager.lock(defaultResource, res1, true);
+                            Thread.sleep(10);
+                            manager.endWork();
+                            Thread.sleep(10);
+                        }
+                    } catch (LockException le) {
+                        fail("Jam Thread should not fail");
+                    } catch (InterruptedException ie) {
+                    } finally {
+                        manager.endWork();
+                        synchronized (restart) {
+                            try {
+                                synchronized (restart) {
+                                    restart.meet();
+                                    restart.reset();
+                                }
+                            } catch (InterruptedException ie) {
+                            }
+                        }
+                    }
+                }
+            }, "Jam Thread #1");
+
+            jamThread1.start();
+
+            // thread that accesses lock of res1 just to cause interference and
+            // possibly detect concurrency problems
+            Thread jamThread2 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        for (int i = 0; i < 10; i++) {
+                            manager.startWork(10, TimeUnit.SECONDS);
+                            manager.lock(defaultResource, res1, true);
+                            Thread.sleep(10);
+                            manager.endWork();
+                            manager.startWork(10, TimeUnit.SECONDS);
+                            Thread.sleep(10);
+                            manager.lock(defaultResource, res1, false);
+                            Thread.sleep(10);
+                            manager.endWork();
+                            Thread.sleep(10);
+                        }
+                    } catch (LockException le) {
+                        fail("Jam Thread should not fail");
+                    } catch (InterruptedException ie) {
+                    } finally {
+                        manager.endWork();
+                        synchronized (restart) {
+                            try {
+                                synchronized (restart) {
+                                    restart.meet();
+                                    restart.reset();
+                                }
+                            } catch (InterruptedException ie) {
+                            }
+                        }
+                    }
+                }
+            }, "Jam Thread #2");
+
+            jamThread2.start();
+
+            Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10, TimeUnit.SECONDS);
+                        cb.waitForTurn(2);
+                        manager.lock(defaultResource, res2, false);
+                        cb.signalTurn(3);
+                        cb.waitForTurn(5);
+                        synchronized (cb) {
+                            cb.signalTurn(6);
+                            manager.lock(defaultResource, res1, true);
+                        }
+                    } catch (LockException le) {
+                        assertEquals(le.getCode(), LockException.Code.WOULD_DEADLOCK);
+                        deadlockCnt++;
+                    } catch (InterruptedException ie) {
+                    } finally {
+                        manager.endWork();
+                        synchronized (restart) {
+                            try {
+                                synchronized (restart) {
+                                    restart.meet();
+                                    restart.reset();
+                                }
+                            } catch (InterruptedException ie) {
+                            }
+                        }
+                    }
+                }
+            }, "Thread #1");
+
+            t1.start();
+
+            Thread t2 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10, TimeUnit.SECONDS);
+                        cb.waitForTurn(3);
+                        manager.lock(defaultResource, res3, false);
+                        synchronized (cb) {
+                            cb.signalTurn(5);
+                            manager.lock(defaultResource, res2, true);
+                        }
+                    } catch (LockException le) {
+                        assertEquals(le.getCode(), LockException.Code.WOULD_DEADLOCK);
+                        deadlockCnt++;
+                    } catch (InterruptedException ie) {
+                    } finally {
+                        manager.endWork();
+                        synchronized (restart) {
+                            try {
+                                synchronized (restart) {
+                                    restart.meet();
+                                    restart.reset();
+                                }
+                            } catch (InterruptedException ie) {
+                            }
+                        }
+                    }
+                }
+            }, "Thread #2");
+
+            t2.start();
+
+            try {
+                manager.startWork(10, TimeUnit.SECONDS);
+                cb.waitForTurn(1);
+                manager.lock(defaultResource, res1, false);
+                cb.signalTurn(2);
+                cb.waitForTurn(6);
+                manager.lock(defaultResource, res3, true);
+            } catch (LockException le) {
+                assertEquals(le.getCode(), LockException.Code.WOULD_DEADLOCK);
+                deadlockCnt++;
+            } catch (InterruptedException ie) {
+            } finally {
+                manager.endWork();
+                synchronized (restart) {
+                    try {
+                        synchronized (restart) {
+                            restart.meet();
+                            restart.reset();
+                        }
+                    } catch (InterruptedException ie) {
+                    }
+                }
+            }
+
+            // XXX in special scenarios the current implementation might cause
+            // more than one
+            // owner to be a deadlock victim
+            if (deadlockCnt != 1) {
+                log.warn("\nMore than one thread was deadlock victim!\n");
+            }
+            assertTrue(deadlockCnt >= 1);
+            deadlockCnt = 0;
+            cb.reset();
+        }
+    }
+
+    @Test
+    public void globalTimeout() throws Throwable {
+
+        log.info("\n\nChecking global timeouts\n\n");
+
+        final String owner1 = "owner1";
+        final String owner2 = "owner2";
+
+        final String res1 = "res1";
+
+        final RWLockManager<Object, Object> manager = new RWLockManager<Object, Object>();
+
+        final RendezvousBarrier restart = new RendezvousBarrier("restart", 2, TIMEOUT);
+
+        final TurnBarrier cb = new TurnBarrier("cb1", TIMEOUT, 1);
+
+        for (int i = 0; i < CONCURRENT_TESTS; i++) {
+
+            System.out.print(".");
+
+            Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10, TimeUnit.SECONDS);
+                        cb.waitForTurn(2);
+                        manager.lock(defaultResource, res1, false);
+                        cb.signalTurn(3);
+                        manager.endWork();
+                        synchronized (restart) {
+                            restart.meet();
+                            restart.reset();
+                        }
+                    } catch (InterruptedException ie) {
+                    }
+                }
+            }, "Thread #1");
+
+            t1.start();
+
+            cb.waitForTurn(1);
+            manager.startWork(10, TimeUnit.SECONDS);
+            manager.lock(defaultResource, res1, false);
+            cb.signalTurn(2);
+            cb.waitForTurn(3);
+            boolean failed = false;
+            try {
+                manager.tryLock(defaultResource, res1, false);
+            } catch (LockException le) {
+                failed = true;
+            }
+            assertTrue(failed);
+            manager.endWork();
+            failed = false;
+            manager.startWork(10, TimeUnit.SECONDS);
+            try {
+                manager.tryLock(defaultResource, res1, false);
+            } catch (LockException le) {
+                failed = true;
+            }
+            assertFalse(failed);
+            manager.endWork();
+            synchronized (restart) {
+                restart.meet();
+                restart.reset();
+            }
+
+            cb.reset();
+        }
+
+    }
+
+    @Test
+    public void stress() throws Throwable {
+
+        log.info("\n\nStress checking locks\n\n");
+
+        final String res1 = "res1";
+        final String res2 = "res2";
+        final String res3 = "res3";
+
+        final RWLockManager<Object, Object> manager = new RWLockManager<Object, Object>();
+
+        final RendezvousBarrier restart = new RendezvousBarrier("restart", 5, TIMEOUT);
+        final RendezvousBarrier start = new RendezvousBarrier("start", 5, TIMEOUT);
+
+        for (int i = 0; i < CONCURRENT_TESTS; i++) {
+
+            System.out.print(".");
+
+            Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        try {
+                            synchronized (start) {
+                                start.meet();
+                                start.reset();
+                            }
+                            manager.startWork(10, TimeUnit.SECONDS);
+                            manager.lock(defaultResource, res1, false);
+                            manager.lock(defaultResource, res2, false);
+                            manager.lock(defaultResource, res3, true);
+                        } catch (LockException ie) {
+                        } finally {
+                            manager.endWork();
+                            synchronized (restart) {
+                                restart.meet();
+                                restart.reset();
+                            }
+                        }
+                    } catch (InterruptedException ie) {
+                    }
+                }
+            }, "Thread #1");
+            t1.start();
+
+            Thread t2 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        try {
+                            synchronized (start) {
+                                start.meet();
+                                start.reset();
+                            }
+                            manager.startWork(10, TimeUnit.SECONDS);
+                            manager.lock(defaultResource, res1, false);
+                            manager.lock(defaultResource, res2, false);
+                            manager.lock(defaultResource, res3, true);
+                        } catch (LockException ie) {
+                        } finally {
+                            manager.endWork();
+                            synchronized (restart) {
+                                restart.meet();
+                                restart.reset();
+                            }
+                        }
+                    } catch (InterruptedException ie) {
+                    }
+                }
+            }, "Thread #2");
+            t2.start();
+
+            Thread t3 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        try {
+                            synchronized (start) {
+                                start.meet();
+                                start.reset();
+                            }
+                            manager.startWork(10, TimeUnit.SECONDS);
+                            manager.lock(defaultResource, res1, false);
+                            manager.lock(defaultResource, res2, false);
+                            manager.lock(defaultResource, res3, true);
+                        } catch (LockException ie) {
+                        } finally {
+                            manager.endWork();
+                            synchronized (restart) {
+                                restart.meet();
+                                restart.reset();
+                            }
+                        }
+                    } catch (InterruptedException ie) {
+                    }
+                }
+            }, "Thread #3");
+            t3.start();
+
+            Thread t4 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        try {
+                            synchronized (start) {
+                                start.meet();
+                                start.reset();
+                            }
+                            manager.startWork(10, TimeUnit.SECONDS);
+                            manager.lock(defaultResource, res1, false);
+                            manager.lock(defaultResource, res2, false);
+                            manager.lock(defaultResource, res3, true);
+                        } catch (LockException ie) {
+                        } finally {
+                            manager.endWork();
+                            synchronized (restart) {
+                                restart.meet();
+                                restart.reset();
+                            }
+                        }
+                    } catch (InterruptedException ie) {
+                    }
+                }
+            }, "Thread #4");
+            t4.start();
+
+            try {
+                try {
+                    synchronized (start) {
+                        start.meet();
+                        start.reset();
+                    }
+                    manager.startWork(10, TimeUnit.SECONDS);
+                    manager.lock(defaultResource, res1, false);
+                    manager.lock(defaultResource, res2, false);
+                    manager.lock(defaultResource, res3, false);
+                } catch (LockException ie) {
+                } finally {
+                    manager.endWork();
+                    try {
+                        synchronized (restart) {
+                            restart.meet();
+                            restart.reset();
+                        }
+                    } catch (InterruptedException ie) {
+                    }
+                }
+            } catch (InterruptedException ie) {
+            }
+        }
+
+    }
+
+    @Test
+    public void choas() throws Throwable {
+
+        log.info("\n\nChaos testing locks for internal deadlocks resp. concurrent mods\n\n");
+
+        final String res1 = "res1";
+        final String res2 = "res2";
+        final String res3 = "res3";
+
+        final RWLockManager<Object, Object> manager = new RWLockManager<Object, Object>();
+
+        int concurrentThreads = 7;
+        int threads = CONCURRENT_TESTS * concurrentThreads;
+
+        final RendezvousBarrier end = new RendezvousBarrier("end", threads + 1, TIMEOUT);
+
+        log.info("\n\nStarting " + threads + " threads\n\n");
+
+        for (int i = 0; i < CONCURRENT_TESTS; i++) {
+
+            final int cnt = i;
+
+            System.out.print(".");
+
+            Thread t1 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10, TimeUnit.SECONDS);
+                        manager.lock(defaultResource, res1, false);
+                        manager.lock(defaultResource, res2, false);
+                        manager.lock(defaultResource, res3, true);
+                    } catch (LockException ie) {
+                        System.out.print("-");
+                    } finally {
+                        manager.endWork();
+                        end.call();
+                    }
+                }
+            }, "Thread #1");
+
+            Thread t2 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10, TimeUnit.SECONDS);
+                        manager.lock(defaultResource, res1, false);
+                        manager.lock(defaultResource, res2, false);
+                        manager.lock(defaultResource, res3, true);
+                    } catch (LockException ie) {
+                        System.out.print("-");
+                    } finally {
+                        manager.endWork();
+                        end.call();
+                    }
+                }
+            }, "Thread #2");
+
+            Thread t3 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10 + cnt, TimeUnit.SECONDS);
+                        manager.lock(defaultResource, res1, false);
+                        manager.lock(defaultResource, res2, false);
+                        manager.lock(defaultResource, res3, true);
+                    } catch (LockException le) {
+                        if (le.getCode() == LockException.Code.TIMED_OUT) {
+                            System.out.print("*");
+                        } else {
+                            System.out.print("-");
+                        }
+                    } finally {
+                        manager.endWork();
+                        end.call();
+                    }
+                }
+            }, "Thread #3");
+
+            Thread t4 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10, TimeUnit.SECONDS);
+                        manager.lock(defaultResource, res1, false);
+                        manager.lock(defaultResource, res2, false);
+                        manager.lock(defaultResource, res3, true);
+                    } catch (LockException le) {
+                        System.out.print("-");
+                    } finally {
+                        manager.endWork();
+                        end.call();
+                    }
+                }
+            }, "Thread #4");
+
+            Thread deadlock1 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10, TimeUnit.SECONDS);
+                        manager.lock(defaultResource, res2, true);
+                        manager.lock(defaultResource, res1, true);
+                    } catch (LockException le) {
+                        assertEquals(le.getCode(), LockException.Code.WOULD_DEADLOCK);
+                        System.out.print("-");
+                    } finally {
+                        manager.endWork();
+                        end.call();
+                    }
+                }
+            }, "Deadlock1 Thread");
+
+            Thread deadlock2 = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.startWork(10, TimeUnit.SECONDS);
+                        manager.lock(defaultResource, res1, false);
+                        manager.lock(defaultResource, res2, false);
+                    } catch (LockException le) {
+                        assertEquals(le.getCode(), LockException.Code.WOULD_DEADLOCK);
+                        System.out.print("-");
+                    } finally {
+                        manager.endWork();
+                        end.call();
+                    }
+                }
+            }, "Deadlock1 Thread");
+
+            Thread reader = new Thread(new Runnable() {
+                public void run() {
+                    try {
+                        manager.lock(defaultResource, res1, false);
+                        manager.lock(defaultResource, res2, false);
+                        manager.lock(defaultResource, res3, false);
+                    } catch (LockException ie) {
+                        System.out.print("-");
+                    } finally {
+                        manager.endWork();
+                        end.call();
+                    }
+                }
+            }, "Reader Thread");
+
+            t4.start();
+            t3.start();
+            reader.start();
+            t1.start();
+            deadlock2.start();
+            t2.start();
+            deadlock1.start();
+        }
+        // wait until all threads have really terminated
+        end.meet();
+
+    }
+}

Modified: commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/memory/BasicTxMapTest.java
URL: http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/memory/BasicTxMapTest.java?view=diff&rev=567198&r1=567197&r2=567198
==============================================================================
--- commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/memory/BasicTxMapTest.java (original)
+++ commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/memory/BasicTxMapTest.java Fri Aug 17 18:37:46 2007
@@ -33,7 +33,6 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.commons.transaction.locking.LockManager;
 import org.apache.commons.transaction.util.RendezvousBarrier;
 
 /**