Permalink
Browse files

Refactored TransactionSpec to use a better locking mechanism

  • Loading branch information...
orfjackal committed Nov 27, 2008
1 parent 1195261 commit e6ca71c3455b124b061feebe8a4eaf126f6b5bc6
Showing with 49 additions and 57 deletions.
  1. +49 −57 dimdwarf-core/src/test/java/net/orfjackal/dimdwarf/tx/TransactionSpec.java
@@ -31,16 +31,15 @@
package net.orfjackal.dimdwarf.tx;
-import jdave.Block;
-import jdave.Group;
-import jdave.Specification;
+import jdave.*;
import jdave.junit4.JDaveRunner;
import static net.orfjackal.dimdwarf.tx.TransactionStatus.*;
-import org.jmock.Expectations;
-import org.jmock.Sequence;
+import org.jmock.*;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
+import java.util.concurrent.CountDownLatch;
+
/**
* @author Esko Luontola
* @since 15.8.2008
@@ -54,13 +53,27 @@
private TransactionParticipant participant2;
private Logger txLogger;
+ private CountDownLatch testHasEnded = new CountDownLatch(1);
+
public void create() throws Exception {
txLogger = mock(Logger.class);
tx = new TransactionImpl(txLogger);
participant1 = mock(TransactionParticipant.class, "participant1");
participant2 = mock(TransactionParticipant.class, "participant2");
}
+ public void destroy() throws Exception {
+ testHasEnded.countDown();
+ }
+
+ private void waitUntilTestHasEnded() {
+ try {
+ testHasEnded.await();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private Expectations allParticipantsArePrepared() {
try {
return new Expectations() {{
@@ -195,28 +208,29 @@ public void run() throws Throwable {
}, should.raise(IllegalStateException.class));
}
- public void canNotPrepareTwiseConcurrently() {
+ public void canNotPrepareTwiseConcurrently() throws InterruptedException {
checking(allParticipantsArePrepared());
- Blocker blocker = new Blocker() {
+
+ final CountDownLatch prepareIsInProgress = new CountDownLatch(1);
+ tx.join(new DummyTransactionParticipant() {
public void prepare() {
- waitHere();
+ prepareIsInProgress.countDown();
+ waitUntilTestHasEnded();
}
- };
- tx.join(blocker);
-
- Thread t = blocker.waitUntilBlockerBeginsWaiting(new Runnable() {
+ });
+ new Thread(new Runnable() {
public void run() {
tx.prepare();
}
- });
+ }).start();
+ prepareIsInProgress.await();
specify(tx.getStatus(), should.equal(PREPARING));
specify(new Block() {
public void run() throws Throwable {
tx.prepare();
}
}, should.raise(IllegalStateException.class));
- t.interrupt();
}
public void canNotCommitBeforePrepare() {
@@ -285,29 +299,30 @@ public void run() throws Throwable {
}, should.raise(IllegalStateException.class));
}
- public void canNotCommitTwiseConcurrently() {
+ public void canNotCommitTwiseConcurrently() throws InterruptedException {
tx = new TransactionImpl(txLogger);
- Blocker blocker = new Blocker() {
+
+ final CountDownLatch commitIsInProgress = new CountDownLatch(1);
+ tx.join(new DummyTransactionParticipant() {
public void commit() {
- waitHere();
+ commitIsInProgress.countDown();
+ waitUntilTestHasEnded();
}
- };
- tx.join(blocker);
- tx.prepare();
-
- Thread t = blocker.waitUntilBlockerBeginsWaiting(new Runnable() {
+ });
+ new Thread(new Runnable() {
public void run() {
+ tx.prepare();
tx.commit();
}
- });
+ }).start();
+ commitIsInProgress.await();
specify(tx.getStatus(), should.equal(COMMITTING));
specify(new Block() {
public void run() throws Throwable {
tx.commit();
}
}, should.raise(IllegalStateException.class));
- t.interrupt();
}
}
@@ -352,28 +367,29 @@ public void run() throws Throwable {
}, should.raise(IllegalStateException.class));
}
- public void canNotRollbackTwiseConcurrently() {
+ public void canNotRollbackTwiseConcurrently() throws InterruptedException {
checking(allParticipantsAreRolledBack());
- Blocker blocker = new Blocker() {
+
+ final CountDownLatch rollbackIsInProgress = new CountDownLatch(1);
+ tx.join(new DummyTransactionParticipant() {
public void rollback() {
- waitHere();
+ rollbackIsInProgress.countDown();
+ waitUntilTestHasEnded();
}
- };
- tx.join(blocker);
-
- Thread t = blocker.waitUntilBlockerBeginsWaiting(new Runnable() {
+ });
+ new Thread(new Runnable() {
public void run() {
tx.rollback();
}
- });
+ }).start();
+ rollbackIsInProgress.await();
specify(tx.getStatus(), should.equal(ROLLING_BACK));
specify(new Block() {
public void run() throws Throwable {
tx.rollback();
}
}, should.raise(IllegalStateException.class));
- t.interrupt();
}
public void mayRollbackWhenActive() {
@@ -463,30 +479,6 @@ public void run() throws Throwable {
}
- private static class Blocker extends DummyTransactionParticipant {
-
- private volatile boolean isReached = false;
-
- protected void waitHere() {
- isReached = true;
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // ignore; test has ended
- }
- }
-
- public Thread waitUntilBlockerBeginsWaiting(Runnable r) {
- Thread t = new Thread(r);
- t.setDaemon(true);
- t.start();
- while (t.isAlive() && !isReached) {
- Thread.yield();
- }
- return t;
- }
- }
-
private static class DummyTransactionParticipant implements TransactionParticipant {
public void prepare() throws Throwable {

0 comments on commit e6ca71c

Please sign in to comment.