[jbosscache-commits] JBoss Cache SVN: r4826 - in core/branches/1.4.X: tests/functional/org/jboss/cache/optimistic and 1 other directory.
jbosscache-commits at lists.jboss.org
jbosscache-commits at lists.jboss.org
Tue Dec 11 11:41:18 EST 2007
Author: manik.surtani at jboss.com
Date: 2007-12-11 11:41:18 -0500 (Tue, 11 Dec 2007)
New Revision: 4826
Added:
core/branches/1.4.X/tests/functional/org/jboss/cache/optimistic/OptimisticLockInterceptorTest.java
Removed:
core/branches/1.4.X/tests/functional/org/jboss/cache/optimistic/OpLockingInterceptorTest.java
Modified:
core/branches/1.4.X/src/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java
core/branches/1.4.X/src/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
Log:
JBCACHE-1228 - optimistic locking interceptor always acquired write locks
Modified: core/branches/1.4.X/src/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java 2007-12-10 23:47:41 UTC (rev 4825)
+++ core/branches/1.4.X/src/org/jboss/cache/interceptors/OptimisticLockingInterceptor.java 2007-12-11 16:41:18 UTC (rev 4826)
@@ -8,6 +8,7 @@
import org.jboss.cache.CacheException;
import org.jboss.cache.DataNode;
+import org.jboss.cache.Fqn;
import org.jboss.cache.GlobalTransaction;
import org.jboss.cache.InvocationContext;
import org.jboss.cache.TransactionEntry;
@@ -20,7 +21,10 @@
import java.lang.reflect.Method;
import java.util.Collection;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
/**
* Locks nodes during transaction boundaries
@@ -137,9 +141,10 @@
}
- private Object lockNodes(GlobalTransaction gtx) throws Exception
+ private void lockNodes(GlobalTransaction gtx) throws Exception
{
TransactionWorkspace workspace = getTransactionWorkspace(gtx);
+ TransactionEntry te = cache.getTransactionTable().get(gtx);
log.debug("locking nodes");
// should be an ordered list
@@ -150,20 +155,19 @@
WorkspaceNode workspaceNode = (WorkspaceNode) it.next();
DataNode node = workspaceNode.getNode();
- boolean acquired = node.acquire(gtx, lockAcquisitionTimeout, DataNode.LOCK_TYPE_WRITE);
+ boolean writeLock = workspaceNode.isDirty() || workspaceNode.isCreated() || workspaceNode.isDeleted() || (workspaceNode.isChildrenModified() && cache.getLockParentForChildInsertRemove());
+
+ boolean acquired = node.acquire(gtx, lockAcquisitionTimeout, writeLock ? DataNode.LOCK_TYPE_WRITE : DataNode.LOCK_TYPE_READ);
if (acquired)
{
if (log.isTraceEnabled()) log.trace("acquired lock on node " + node.getName());
- cache.getTransactionTable().addLock(gtx, node.getLock());
+ te.addLock(node.getLock());
}
else
{
throw new CacheException("unable to acquire lock on node " + node.getName());
}
-
}
- return null;
-
}
Modified: core/branches/1.4.X/src/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
===================================================================
--- core/branches/1.4.X/src/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java 2007-12-10 23:47:41 UTC (rev 4825)
+++ core/branches/1.4.X/src/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java 2007-12-11 16:41:18 UTC (rev 4826)
@@ -366,13 +366,16 @@
DataNode node = cache.peek(fqn);
if (node == null)
{
- return null; // seems to happen quite a bit
+ workspaceNode = null; // seems to happen quite a bit
}
- workspaceNode = NodeFactory.getInstance().createWorkspaceNode(node, workspace);
- workspace.addNode(workspaceNode);
+ else
+ {
+ workspaceNode = NodeFactory.getInstance().createWorkspaceNode(node, workspace);
+ workspace.addNode(workspaceNode);
+ }
}
// the node has been deleted dude!
- if (workspaceNode.isDeleted())
+ if (workspaceNode != null && workspaceNode.isDeleted())
{
if (log.isDebugEnabled()) log.debug("Node " + fqn + " has been deleted in the workspace.");
if (undeleteIfNecessary)
@@ -393,6 +396,13 @@
log.trace("Setting versioning to explicit");
workspaceNode.setVersioningImplicit(false);
}
+
+ // now make sure all parents are in the wsp as well
+ if (workspaceNode != null)
+ {
+ if (!fqn.isRoot()) getOrCreateWorkspaceNode(fqn.getParent(), workspace, false);
+ }
+
return workspaceNode;
}
}
Deleted: core/branches/1.4.X/tests/functional/org/jboss/cache/optimistic/OpLockingInterceptorTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/optimistic/OpLockingInterceptorTest.java 2007-12-10 23:47:41 UTC (rev 4825)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/optimistic/OpLockingInterceptorTest.java 2007-12-11 16:41:18 UTC (rev 4826)
@@ -1,366 +0,0 @@
-/*
- * Created on 17-Feb-2005
- *
- *
- *
- */
-package org.jboss.cache.optimistic;
-
-import org.jboss.cache.*;
-import org.jboss.cache.interceptors.Interceptor;
-import org.jboss.cache.interceptors.OptimisticCreateIfNotExistsInterceptor;
-import org.jboss.cache.interceptors.OptimisticLockingInterceptor;
-import org.jboss.cache.interceptors.OptimisticNodeInterceptor;
-import org.jboss.cache.loader.SamplePojo;
-import org.jboss.cache.lock.IdentityLock;
-import org.jboss.cache.marshall.MethodCallFactory;
-import org.jboss.cache.marshall.MethodDeclarations;
-import org.jboss.cache.transaction.DummyTransactionManager;
-import org.jgroups.blocks.MethodCall;
-
-import javax.transaction.Transaction;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * @author xenephon
- */
-public class OpLockingInterceptorTest extends AbstractOptimisticTestCase
-{
-
-
- /**
- * @param name
- */
- public OpLockingInterceptorTest(String name)
- {
- super(name);
-
- }
-
- public void testTransactionPrepareMethod() throws Exception
- {
-
- TestListener listener = new TestListener();
- final TreeCache cache = createCacheWithListener(listener);
-
- Interceptor lockingInterceptor = new OptimisticLockingInterceptor();
- lockingInterceptor.setCache(cache);
- Interceptor interceptor = new OptimisticCreateIfNotExistsInterceptor();
- interceptor.setCache(cache);
- Interceptor nodeInterceptor = new OptimisticNodeInterceptor();
- nodeInterceptor.setCache(cache);
- MockInterceptor dummy = new MockInterceptor();
- dummy.setCache(cache);
- lockingInterceptor.setNext(interceptor);
- interceptor.setNext(nodeInterceptor);
- nodeInterceptor.setNext(dummy);
-
- cache.setInterceptorChain(lockingInterceptor);
-
-// first set up a node with a pojo
- DummyTransactionManager mgr = DummyTransactionManager.getInstance();
- mgr.begin();
- Transaction tx = mgr.getTransaction();
-
- // inject InvocationContext
- cache.getInvocationContext().setTransaction(tx);
- cache.getInvocationContext().setGlobalTransaction(cache.getCurrentTransaction(tx));
-
- SamplePojo pojo = new SamplePojo(21, "test");
- Map temp = new HashMap();
- temp.put("key1", pojo);
- cache.put("/one/two", temp);
-
- assertEquals(null, dummy.getCalled());
- TransactionTable table = cache.getTransactionTable();
-
- GlobalTransaction gtx = table.get(tx);
-
- OptimisticTransactionEntry entry = (OptimisticTransactionEntry) table.get(gtx);
-
- TransactionWorkspace workspace = entry.getTransactionWorkSpace();
-
- /*GlobalTransaction.class,
- List.class,
- Address.class,
- boolean.class*/
-
- assertEquals(3, workspace.getNodes().size());
- assertNotNull(workspace.getNode(Fqn.fromString("/one/two")));
- assertEquals(pojo, workspace.getNode(Fqn.fromString("/one/two")).get("key1"));
- assertEquals(1, workspace.getNode(Fqn.fromString("/one/two")).getMergedData().size());
- assertTrue(entry.getLocks().isEmpty());
- assertEquals(1, entry.getModifications().size());
- assertTrue(!cache.exists("/one/two"));
- assertEquals(null, dummy.getCalled());
-
- //now let us do a prepare
- MethodCall prepareMethod = MethodCallFactory.create(MethodDeclarations.optimisticPrepareMethod, new Object[]{gtx, entry.getModifications(), gtx.getAddress(), Boolean.FALSE});
- try
- {
- cache._replicate(prepareMethod);
- }
- catch (Throwable t)
- {
-
- }
-
-
- assertEquals(3, workspace.getNodes().size());
- assertNotNull(workspace.getNode(Fqn.fromString("/one/two")));
- assertEquals(pojo, workspace.getNode(Fqn.fromString("/one/two")).get("key1"));
- assertEquals(1, workspace.getNode(Fqn.fromString("/one/two")).getMergedData().size());
- assertEquals(3, entry.getLocks().size());
- for (Iterator it = entry.getLocks().iterator(); it.hasNext();)
- {
- IdentityLock lock = (IdentityLock) it.next();
- assertTrue(lock.isWriteLocked());
- assertEquals(gtx, lock.getWriterOwner());
- }
- assertEquals(1, entry.getModifications().size());
- assertTrue(!cache.exists("/one/two"));
- //assertEquals(null,dummy.getCalled());
-
-
- mgr.commit();
-
- cache.stopService();
-
- }
-
- public void testTransactionCommitMethod() throws Exception
- {
-
- TestListener listener = new TestListener();
- final TreeCache cache = createCacheWithListener(listener);
-
- Interceptor lockingInterceptor = new OptimisticLockingInterceptor();
- lockingInterceptor.setCache(cache);
- Interceptor interceptor = new OptimisticCreateIfNotExistsInterceptor();
- interceptor.setCache(cache);
- Interceptor nodeInterceptor = new OptimisticNodeInterceptor();
- nodeInterceptor.setCache(cache);
- MockInterceptor dummy = new MockInterceptor();
- dummy.setCache(cache);
- lockingInterceptor.setNext(interceptor);
- interceptor.setNext(nodeInterceptor);
- nodeInterceptor.setNext(dummy);
-
- cache.setInterceptorChain(lockingInterceptor);
-
-// first set up a node with a pojo
- DummyTransactionManager mgr = DummyTransactionManager.getInstance();
- mgr.begin();
- Transaction tx = mgr.getTransaction();
-
- // inject InvocationContext
- cache.getInvocationContext().setTransaction(tx);
- cache.getInvocationContext().setGlobalTransaction(cache.getCurrentTransaction(tx));
-
- SamplePojo pojo = new SamplePojo(21, "test");
- Map temp = new HashMap();
- temp.put("key1", pojo);
- cache.put("/one/two", temp);
-
- assertEquals(null, dummy.getCalled());
- TransactionTable table = cache.getTransactionTable();
-
- GlobalTransaction gtx = table.get(tx);
-
- OptimisticTransactionEntry entry = (OptimisticTransactionEntry) table.get(gtx);
-
- TransactionWorkspace workspace = entry.getTransactionWorkSpace();
-
- /*GlobalTransaction.class,
- List.class,
- Address.class,
- boolean.class*/
-
- assertEquals(3, workspace.getNodes().size());
- assertNotNull(workspace.getNode(Fqn.fromString("/one/two")));
- assertEquals(pojo, workspace.getNode(Fqn.fromString("/one/two")).get("key1"));
- assertEquals(1, workspace.getNode(Fqn.fromString("/one/two")).getMergedData().size());
- assertTrue(entry.getLocks().isEmpty());
- assertEquals(1, entry.getModifications().size());
- assertTrue(!cache.exists("/one/two"));
- assertEquals(null, dummy.getCalled());
-
- //now let us do a prepare
- MethodCall prepareMethod = MethodCallFactory.create(MethodDeclarations.optimisticPrepareMethod, new Object[]{gtx, entry.getModifications(), gtx.getAddress(), Boolean.FALSE});
- try
- {
- cache._replicate(prepareMethod);
- }
- catch (Throwable t)
- {
-
- }
-
-
- assertEquals(3, workspace.getNodes().size());
- assertNotNull(workspace.getNode(Fqn.fromString("/one/two")));
- assertEquals(pojo, workspace.getNode(Fqn.fromString("/one/two")).get("key1"));
- assertEquals(1, workspace.getNode(Fqn.fromString("/one/two")).getMergedData().size());
- assertEquals(3, entry.getLocks().size());
- for (Iterator it = entry.getLocks().iterator(); it.hasNext();)
- {
- IdentityLock lock = (IdentityLock) it.next();
- assertTrue(lock.isWriteLocked());
- assertEquals(gtx, lock.getWriterOwner());
- }
- assertEquals(1, entry.getModifications().size());
- assertTrue(!cache.exists("/one/two"));
- //assertEquals(null,dummy.getCalled());
- assertEquals(MethodDeclarations.optimisticPrepareMethod, dummy.getCalled());
-
-
- MethodCall commitMethod = MethodCallFactory.create(MethodDeclarations.commitMethod, new Object[]{gtx});
- try
- {
- cache._replicate(commitMethod);
- }
- catch (Throwable t)
- {
- fail();
- }
- assertEquals(3, entry.getLocks().size());
- for (Iterator it = entry.getLocks().iterator(); it.hasNext();)
- {
- IdentityLock lock = (IdentityLock) it.next();
- assertEquals(false, lock.isLocked());
-
- }
- //make sure the nodes and locks are the same order
- int i = 0;
- for (Iterator it = workspace.getNodes().values().iterator(); it.hasNext();)
- {
- DataNode node = ((WorkspaceNode) it.next()).getNode();
- assertEquals(node.getLock(), entry.getLocks().get(i));
- i++;
- }
- assertEquals(MethodDeclarations.commitMethod, dummy.getCalled());
- mgr.commit();
-
- cache.stopService();
-
- }
-
- public void testTransactionRollbackMethod() throws Exception
- {
-
- TestListener listener = new TestListener();
- final TreeCache cache = createCacheWithListener(listener);
-
- Interceptor lockingInterceptor = new OptimisticLockingInterceptor();
- lockingInterceptor.setCache(cache);
- Interceptor interceptor = new OptimisticCreateIfNotExistsInterceptor();
- interceptor.setCache(cache);
- Interceptor nodeInterceptor = new OptimisticNodeInterceptor();
- nodeInterceptor.setCache(cache);
- MockInterceptor dummy = new MockInterceptor();
- dummy.setCache(cache);
- lockingInterceptor.setNext(interceptor);
- interceptor.setNext(nodeInterceptor);
- nodeInterceptor.setNext(dummy);
-
- cache.setInterceptorChain(lockingInterceptor);
-
-// first set up a node with a pojo
- DummyTransactionManager mgr = DummyTransactionManager.getInstance();
- mgr.begin();
- Transaction tx = mgr.getTransaction();
-
- // inject InvocationContext
- cache.getInvocationContext().setTransaction(tx);
- cache.getInvocationContext().setGlobalTransaction(cache.getCurrentTransaction(tx));
-
- SamplePojo pojo = new SamplePojo(21, "test");
- Map temp = new HashMap();
- temp.put("key1", pojo);
- cache.put("/one/two", temp);
-
- assertEquals(null, dummy.getCalled());
- TransactionTable table = cache.getTransactionTable();
-
- GlobalTransaction gtx = table.get(tx);
-
- OptimisticTransactionEntry entry = (OptimisticTransactionEntry) table.get(gtx);
-
- TransactionWorkspace workspace = entry.getTransactionWorkSpace();
-
- /*GlobalTransaction.class,
- List.class,
- Address.class,
- boolean.class*/
-
- assertEquals(3, workspace.getNodes().size());
- assertNotNull(workspace.getNode(Fqn.fromString("/one/two")));
- assertEquals(pojo, workspace.getNode(Fqn.fromString("/one/two")).get("key1"));
- assertEquals(1, workspace.getNode(Fqn.fromString("/one/two")).getMergedData().size());
- assertTrue(entry.getLocks().isEmpty());
- assertEquals(1, entry.getModifications().size());
- assertTrue(!cache.exists("/one/two"));
- assertEquals(null, dummy.getCalled());
-
- //now let us do a prepare
- MethodCall prepareMethod = MethodCallFactory.create(MethodDeclarations.optimisticPrepareMethod, new Object[]{gtx, entry.getModifications(), gtx.getAddress(), Boolean.FALSE});
- try
- {
- cache._replicate(prepareMethod);
- }
- catch (Throwable t)
- {
-
- }
-
-
- assertEquals(3, workspace.getNodes().size());
- assertNotNull(workspace.getNode(Fqn.fromString("/one/two")));
- assertEquals(pojo, workspace.getNode(Fqn.fromString("/one/two")).get("key1"));
- assertEquals(1, workspace.getNode(Fqn.fromString("/one/two")).getMergedData().size());
- assertEquals(3, entry.getLocks().size());
- for (Iterator it = entry.getLocks().iterator(); it.hasNext();)
- {
- IdentityLock lock = (IdentityLock) it.next();
- assertTrue(lock.isWriteLocked());
- assertEquals(gtx, lock.getWriterOwner());
- }
- assertEquals(1, entry.getModifications().size());
- assertTrue(!cache.exists("/one/two"));
- assertEquals(MethodDeclarations.optimisticPrepareMethod, dummy.getCalled());
-
-
- MethodCall rollbackMethod = MethodCallFactory.create(MethodDeclarations.rollbackMethod, new Object[]{gtx});
- try
- {
- cache._replicate(rollbackMethod);
- }
- catch (Throwable t)
- {
- fail();
- }
- assertEquals(3, entry.getLocks().size());
- for (Iterator it = entry.getLocks().iterator(); it.hasNext();)
- {
- IdentityLock lock = (IdentityLock) it.next();
- assertEquals(false, lock.isLocked());
-
- }
- //make sure the nodes and locks are the same order
- int i = 0;
- for (Iterator it = workspace.getNodes().values().iterator(); it.hasNext();)
- {
- DataNode node = ((WorkspaceNode) it.next()).getNode();
- assertEquals(node.getLock(), entry.getLocks().get(i));
- i++;
- }
- assertEquals(MethodDeclarations.rollbackMethod, dummy.getCalled());
- mgr.commit();
-
- cache.stopService();
-
- }
-
-}
Added: core/branches/1.4.X/tests/functional/org/jboss/cache/optimistic/OptimisticLockInterceptorTest.java
===================================================================
--- core/branches/1.4.X/tests/functional/org/jboss/cache/optimistic/OptimisticLockInterceptorTest.java (rev 0)
+++ core/branches/1.4.X/tests/functional/org/jboss/cache/optimistic/OptimisticLockInterceptorTest.java 2007-12-11 16:41:18 UTC (rev 4826)
@@ -0,0 +1,245 @@
+package org.jboss.cache.optimistic;
+
+import junit.framework.Assert;
+import org.jboss.cache.DataNode;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.TreeCache;
+import org.jboss.cache.interceptors.Interceptor;
+import org.jboss.cache.interceptors.OptimisticCreateIfNotExistsInterceptor;
+import org.jboss.cache.interceptors.OptimisticInterceptor;
+import org.jboss.cache.interceptors.OptimisticLockingInterceptor;
+import org.jboss.cache.lock.IdentityLock;
+import org.jgroups.blocks.MethodCall;
+
+import javax.transaction.TransactionManager;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * // Test for JBCACHE-1228
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ */
+public class OptimisticLockInterceptorTest extends AbstractOptimisticTestCase
+{
+ private TreeCache cache;
+ private LockReportInterceptor lri;
+ private Fqn parent = Fqn.fromString("/parent");
+ private Fqn child = Fqn.fromString("/parent/child");
+ private TransactionManager tm;
+
+ public OptimisticLockInterceptorTest(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ cache = createCache();
+ lri = new LockReportInterceptor();
+ lri.setCache(cache);
+
+ Interceptor i = (Interceptor) cache.getInterceptors().get(0);
+ Interceptor lockInterceptor = i;
+ // find the OptimisticLockInterceptor and insert LockReportInterceptor after that.
+ while (!(lockInterceptor instanceof OptimisticLockingInterceptor)) lockInterceptor = lockInterceptor.getNext();
+ Interceptor next = lockInterceptor.getNext();
+
+ lockInterceptor.setNext(lri);
+ lri.setNext(next);
+
+ cache.setInterceptorChain(i);
+
+ cache.put(child, "key", "value");
+
+ tm = cache.getTransactionManager();
+ }
+
+ protected void tearDown()
+ {
+ cache.stop();
+ }
+
+ public void testPut() throws Exception
+ {
+ tm.begin();
+ cache.put(child, "key2", "value2");
+ lri.reset();
+ lri.expectsReadLock(Fqn.ROOT);
+ lri.expectsReadLock(parent);
+ lri.expectsWriteLock(child);
+ tm.commit();
+ lri.assertReceivedExpectedLocks();
+
+ assertNoStaleLocks();
+ }
+
+ public void testGet() throws Exception
+ {
+ tm.begin();
+ cache.get(child, "key2");
+ lri.reset();
+ // nothing is stale, expecting nothing here.
+ tm.commit();
+ lri.assertReceivedExpectedLocks();
+
+ assertNoStaleLocks();
+ }
+
+ public void testRemove() throws Exception
+ {
+ tm.begin();
+ cache.remove(child, "key2");
+ lri.reset();
+ lri.expectsReadLock(Fqn.ROOT);
+ lri.expectsReadLock(parent);
+ lri.expectsWriteLock(child);
+ tm.commit();
+ lri.assertReceivedExpectedLocks();
+
+ assertNoStaleLocks();
+ }
+
+ public void testPutLockParentForCIR() throws Exception
+ {
+ cache.setLockParentForChildInsertRemove(true);
+ cache.remove(parent);
+ cache.put(parent, "k", "v");
+
+ tm.begin();
+ cache.put(child, "key2", "value2");
+ lri.reset();
+ lri.expectsReadLock(Fqn.ROOT);
+ lri.expectsWriteLock(parent);
+ lri.expectsWriteLock(child);
+ tm.commit();
+ lri.assertReceivedExpectedLocks();
+
+ assertNoStaleLocks();
+ }
+
+ public void testGetLockParentForCIR() throws Exception
+ {
+ cache.setLockParentForChildInsertRemove(true);
+ tm.begin();
+ cache.get(child, "key2");
+ lri.reset();
+ // nothing is stale, expecting nothing here.
+ tm.commit();
+ lri.assertReceivedExpectedLocks();
+
+ assertNoStaleLocks();
+ }
+
+ public void testRemoveLockParentForCIR() throws Exception
+ {
+ cache.setLockParentForChildInsertRemove(true);
+ tm.begin();
+ cache.remove(child);
+ lri.reset();
+ lri.expectsReadLock(Fqn.ROOT);
+ lri.expectsWriteLock(parent);
+ lri.expectsWriteLock(child);
+ tm.commit();
+ lri.assertReceivedExpectedLocks();
+
+ assertNoStaleLocks();
+ }
+
+
+ public void testPutNodeNotExists() throws Exception
+ {
+ cache.remove(Fqn.ROOT);
+ tm.begin();
+ cache.put(child, "key2", "value2");
+ lri.reset();
+ lri.expectsReadLock(Fqn.ROOT);
+ lri.expectsWriteLock(parent);
+ lri.expectsWriteLock(child);
+ tm.commit();
+ lri.assertReceivedExpectedLocks();
+
+ assertNoStaleLocks();
+ }
+
+ public void testGetNodeNotExists() throws Exception
+ {
+ cache.remove(Fqn.ROOT);
+ tm.begin();
+ cache.get(child, "key2");
+ lri.reset();
+ // nothing is stale, expecting nothing here.
+ tm.commit();
+ lri.assertReceivedExpectedLocks();
+
+ assertNoStaleLocks();
+ }
+
+ public void testRemoveNodeNotExists() throws Exception
+ {
+ cache.remove(Fqn.ROOT);
+ tm.begin();
+ cache.remove(child, "key2");
+ lri.reset();
+ // nothing is stale, expecting nothing here.
+ tm.commit();
+ lri.assertReceivedExpectedLocks();
+
+ assertNoStaleLocks();
+ }
+
+ private void assertNoStaleLocks()
+ {
+ assertEquals(cache.getNumberOfLocksHeld(), 0);
+ }
+}
+
+class LockReportInterceptor extends OptimisticInterceptor
+{
+ private Object READ = "READ";
+ private Object WRITE = "WRITE";
+ private Map expected = new HashMap();
+ private Map actual = new HashMap();
+
+ void reset()
+ {
+ expected.clear();
+ actual.clear();
+ }
+
+ void assertReceivedExpectedLocks()
+ {
+ Assert.assertEquals(expected, actual);
+ }
+
+ void expectsReadLock(Fqn f)
+ {
+ expected.put(f, READ);
+ }
+
+ void expectsWriteLock(Fqn f)
+ {
+ expected.put(f, WRITE);
+ }
+
+ public Object invoke(MethodCall call) throws Throwable
+ {
+ TransactionWorkspace w = getTransactionWorkspace(getInvocationContext().getGlobalTransaction());
+ Map nodeMap = w.getNodes();
+ for (Iterator i = nodeMap.keySet().iterator(); i.hasNext();)
+ {
+ WorkspaceNode wn = (WorkspaceNode) nodeMap.get(i.next());
+ DataNode n = wn.getNode();
+ IdentityLock lock = n.getLock();
+ if (lock.isLocked())
+ {
+ actual.put(n.getFqn(), lock.isReadLocked() ? READ : WRITE);
+ }
+ }
+
+ return super.invoke(call);
+ }
+
+
+}
More information about the jbosscache-commits
mailing list