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;
/**