Author: ozeigermann
Date: Sat Aug 18 07:03:52 2007
New Revision: 567274
URL: http://svn.apache.org/viewvc?view=rev&rev=567274
Log:
Base functionality and tests in shape now. Javadocs still lacking completeness.
Modified:
commons/proper/transaction/branches/TRANSACTION_2/project.xml
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/util/FileHelper.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/locking/LockTest.java
Modified: commons/proper/transaction/branches/TRANSACTION_2/project.xml
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/project.xml?view=diff&rev=567274&r1=567273&r2=567274
==============================================================================
--- commons/proper/transaction/branches/TRANSACTION_2/project.xml (original)
+++ commons/proper/transaction/branches/TRANSACTION_2/project.xml Sat Aug 18
07:03:52 2007
@@ -194,15 +194,19 @@
<build>
<nagEmailAddress>[EMAIL PROTECTED]</nagEmailAddress>
<sourceDirectory>src/java</sourceDirectory>
- <!-- unitTestSourceDirectory>src/test</unitTestSourceDirectory-->
+ <unitTestSourceDirectory>src/test</unitTestSourceDirectory>
<integrationUnitTestSourceDirectory/>
<aspectSourceDirectory/>
- <!-- FIXME -->
- <!-- unitTest>
+ <unitTest>
<includes>
- <include>org/apache/commons/collections/TestAllPackages.java</include>
+
<include>org/apache/commons/transaction/DefaultTransactionTest.java</include>
+
<include>org/apache/commons/transaction/file/TxFileResourceManagerTest.java</include>
+ <include>org/apache/commons/transaction/locking/LockTest.java</include>
+
<include>org/apache/commons/transaction/memory/BasicTxMapTest.java</include>
+
<include>org/apache/commons/transaction/memory/OptimisticTxMapTest.java</include>
+
<include>org/apache/commons/transaction/memory/PessimisticTxMapTest.java</include>
</includes>
- </unitTest-->
+ </unitTest>
<resources>
<resource>
<directory>.</directory>
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java?view=diff&rev=567274&r1=567273&r2=567274
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/AbstractLockManager.java
Sat Aug 18 07:03:52 2007
@@ -42,6 +42,7 @@
@Override
public void endWork() {
+ checkIsStarted();
release();
}
@@ -60,6 +61,12 @@
effectiveGlobalTimeouts.put(Thread.currentThread(), effectiveTimeout);
}
+ protected void checkIsStarted() {
+ if (locksForThreads.get(Thread.currentThread()) == null) {
+ throw new IllegalStateException("You need to start work before you
can acquire a lock");
+ }
+ }
+
protected long computeRemainingTime(Thread thread) {
long timeout = effectiveGlobalTimeouts.get(thread);
long now = System.currentTimeMillis();
@@ -73,6 +80,7 @@
@Override
public void lock(M managedResource, K key, boolean exclusive) throws
LockException {
+ checkIsStarted();
long remainingTime = computeRemainingTime(Thread.currentThread());
boolean locked = tryLockInternal(managedResource, key, exclusive,
remainingTime,
@@ -84,6 +92,7 @@
@Override
public boolean tryLock(M managedResource, K key, boolean exclusive) {
+ checkIsStarted();
return tryLockInternal(managedResource, key, exclusive, 0,
TimeUnit.MILLISECONDS);
}
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java?view=diff&rev=567274&r1=567273&r2=567274
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/RWLockManager.java
Sat Aug 18 07:03:52 2007
@@ -18,7 +18,6 @@
import java.util.Collection;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
@@ -27,7 +26,6 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.commons.transaction.locking.AbstractLockManager.KeyEntry;
import org.apache.commons.transaction.locking.LockException.Code;
import org.apache.commons.transaction.locking.locks.ResourceRWLock;
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/util/FileHelper.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/util/FileHelper.java?view=diff&rev=567274&r1=567273&r2=567274
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/util/FileHelper.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/util/FileHelper.java
Sat Aug 18 07:03:52 2007
@@ -31,7 +31,8 @@
*/
public final class FileHelper {
- public static File makeBackup(File file, File backupDirectory, boolean
moveAllowed) throws IOException {
+ public static File makeBackup(File file, File backupDirectory, boolean
moveAllowed)
+ throws IOException {
File copy = File.createTempFile(file.getName(), ".backup",
backupDirectory);
boolean success = false;
if (moveAllowed) {
@@ -42,7 +43,7 @@
}
return copy;
}
-
+
public static byte[] readInto(File file) throws IOException {
long length = file.length();
@@ -194,6 +195,8 @@
}
public static void removeRecursive(File toRemove) {
+ if (!toRemove.exists())
+ return;
if (toRemove.isDirectory()) {
File fileList[] = toRemove.listFiles();
for (int a = 0; a < fileList.length; a++) {
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=567274&r1=567273&r2=567274
==============================================================================
---
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
Sat Aug 18 07:03:52 2007
@@ -34,6 +34,7 @@
import org.junit.Test;
import org.apache.commons.transaction.file.FileResourceManager.FileResource;
+import org.apache.commons.transaction.resource.ResourceException;
import org.apache.commons.transaction.util.FileHelper;
import org.apache.commons.transaction.util.RendezvousBarrier;
@@ -214,6 +215,7 @@
@Test
public void basic() {
+ reset();
TxFileResourceManager manager = new
TxFileResourceManager("TxFileManager", rootPath);
FileResourceUndoManager um;
try {
@@ -236,6 +238,33 @@
}
@Test
+ public void rollback() {
+ reset();
+ TxFileResourceManager manager = new
TxFileResourceManager("TxFileManager", rootPath);
+ FileResourceUndoManager um;
+ try {
+ um = new MemoryUndoManager(tmpDir);
+ manager.setUndoManager(um);
+ manager.startTransaction(60, TimeUnit.SECONDS);
+ FileResource file = manager.getResource(rootPath + "/aha");
+ if (!file.exists()) {
+ file.createAsFile();
+ }
+ OutputStream os = file.writeStream(true);
+ PrintStream ps = new PrintStream(os);
+ ps.print("Huhu");
+ os.close();
+ } catch (Throwable throwable) {
+ System.err.println(throwable);
+ } finally {
+ checkExactlyContains(rootPath, new String[] { "aha" }, new
String[] { "Huhu" });
+ manager.rollbackTransaction();
+ checkIsEmpty(rootPath);
+ }
+
+ }
+
+ @Test
public void global() throws Throwable {
reset();
createInitialFiles();
@@ -245,33 +274,26 @@
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);
+ final RendezvousBarrier startBarrier = new RendezvousBarrier("Start2",
BARRIER_TIMEOUT);
Thread create = new Thread(new Runnable() {
public void run() {
try {
- rm.startTransaction(60, TimeUnit.SECONDS);
-
- shutdownBarrier.call();
- start2Barrier.call();
+ rm.startTransaction(60, TimeUnit.MINUTES);
rm.getResource(rootPath + "/olli/Hubert4").createAsFile();
+ startBarrier.call();
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 });
+ rm.commitTransaction();
+
} catch (Throwable e) {
System.err.println("Error: " + e);
e.printStackTrace();
@@ -281,58 +303,38 @@
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);
+ rm.startTransaction(60, TimeUnit.MINUTES);
- {
- 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();
- }
+ startBarrier.meet();
- shutdownBarrier.call();
+ rm.getResource(rootPath + "/olli/Hubert4").exists();
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();
+ checkExactlyContains(rootPath + "/olli", new String[] {
"Hubert", "Hubert1",
+ "Hubert2", "Hubert3", "Hubert4", "Hubert5",
"Hubert6" });
- 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();
+ boolean failed = false;
+ try {
+ rm.getResource(rootPath +
"/olli/Hubert1").createAsFile();
+ } catch (ResourceException e) {
+ // we must not create a resource that already exists
+ failed = true;
+ }
+ assertTrue(failed);
+ rm.getResource(rootPath + "/olli/Hubert1").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();
-
+
+ checkExactlyContains(rootPath + "/olli", new String[] {
"Hubert6" });
+
rm.commitTransaction();
} catch (Throwable e) {
System.err.println("Error: " + e);
@@ -342,15 +344,13 @@
}, "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();
+ modify.join();
+ create.join();
- checkExactlyContains(rootPath + "/olli", new String[] { "Hubert1",
"Hubert6" },
- new String[] { "", msg });
+ checkExactlyContains(rootPath + "/olli", new String[] { "Hubert6" },
+ new String[] { msg });
}
}
Modified:
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=diff&rev=567274&r1=567273&r2=567274
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/locking/LockTest.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/locking/LockTest.java
Sat Aug 18 07:03:52 2007
@@ -16,18 +16,17 @@
*/
package org.apache.commons.transaction.locking;
-import java.io.PrintWriter;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
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;
+import org.junit.Test;
/**
* Tests for locking.
@@ -43,12 +42,10 @@
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);
+ return new JUnit4TestAdapter(LockTest.class);
}
public static void main(java.lang.String[] args) {
@@ -139,283 +136,6 @@
}
}
- /*
- *
- * 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 {
@@ -692,6 +412,7 @@
Thread reader = 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, false);