[jboss-cvs] JBossCache/tests/functional/org/jboss/cache/api/pfer ...
Manik Surtani
manik at jboss.org
Mon Mar 19 15:03:34 EDT 2007
User: msurtani
Date: 07/03/19 15:03:34
Modified: tests/functional/org/jboss/cache/api/pfer
PutForExternalReadTestBase.java
Log:
JBCACHE-848 - putForExternalRead()
Revision Changes Path
1.2 +101 -42 JBossCache/tests/functional/org/jboss/cache/api/pfer/PutForExternalReadTestBase.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: PutForExternalReadTestBase.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/tests/functional/org/jboss/cache/api/pfer/PutForExternalReadTestBase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- PutForExternalReadTestBase.java 16 Mar 2007 17:48:17 -0000 1.1
+++ PutForExternalReadTestBase.java 19 Mar 2007 19:03:34 -0000 1.2
@@ -2,6 +2,7 @@
import org.jboss.cache.Cache;
import org.jboss.cache.CacheImpl;
+import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
import org.jboss.cache.NodeSPI;
import org.jboss.cache.RPCManager;
@@ -10,17 +11,21 @@
import org.jboss.cache.factories.UnitTestCacheFactory;
import org.jboss.cache.lock.NodeLock;
import org.jboss.cache.misc.TestingUtil;
+import org.jboss.cache.optimistic.TransactionWorkspace;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jboss.cache.transaction.OptimisticTransactionEntry;
import org.jgroups.Address;
import org.jmock.Mock;
import org.jmock.MockObjectTestCase;
import org.jmock.core.Constraint;
+import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import java.lang.reflect.Method;
import java.util.List;
-public class PutForExternalReadTestBase extends MockObjectTestCase
+public abstract class PutForExternalReadTestBase extends MockObjectTestCase
{
protected Cache<String, String> cache1, cache2;
@@ -96,17 +101,31 @@
* Locks could only occur on the parent node is write locked since if the child node exists it is a no-op anyway.
* If the parent node is read locked as well, there is no issue.
*/
- public void testNoOpWhenLocked() throws Exception
+ public void testNoOpWhenLockedAnd0msTimeout() throws Exception
{
- tm1.begin();
+ // create the parent node first ...
cache1.put(parentFqn, key, value);
- NodeSPI parentNode = (NodeSPI) cache1.getRoot().getChild(parentFqn);
+
+ tm1.begin();
+ cache1.put(parentFqn, key, value2);
+ NodeSPI parentNode = null;
+ TransactionWorkspace workspace = null;
+
+ if (optimistic)
+ workspace = extractTransactionWorkspace(cache1);
+ else
+ parentNode = (NodeSPI) cache1.getRoot().getChild(parentFqn);
+
Transaction t = tm1.suspend();
- assertLocked(parentNode, true);
+ assertLocked(parentFqn, parentNode, workspace, true);
// parentFqn should be write-locked.
+ long startTime = System.currentTimeMillis();
cache1.putForExternalRead(fqn, key, value);
+
+ // crappy way to test that pFER does not block, but it is effective.
+ assertTrue("Should not wait for lock timeout, should attempt to acquite lock with 0ms!", System.currentTimeMillis() - startTime < cache1.getConfiguration().getLockAcquisitionTimeout());
// should not block.
tm1.resume(t);
@@ -114,12 +133,16 @@
asyncWait();
- assertEquals("Parent node write should have succeeded", value, cache1.get(parentFqn, key));
- assertEquals("Parent node write should have replicated", value, cache2.get(parentFqn, key));
+ assertEquals("Parent node write should have succeeded", value2, cache1.get(parentFqn, key));
+ assertEquals("Parent node write should have replicated", value2, cache2.get(parentFqn, key));
+ if (!optimistic)
+ {
+ // doesn't apply with optimistic locking since both txs will succeed here.
assertNull("PFER should have been a no-op", cache1.get(fqn, key));
assertNull("PFER should have been a no-op", cache2.get(fqn, key));
}
+ }
public void testNoOpWhenNodePresent()
{
@@ -149,46 +172,45 @@
public void testAsyncForce()
{
Mock mockRpcManager = mock(RPCManager.class);
+ CacheImpl cache1Impl = (CacheImpl) cache1;
+ RPCManager originalRpcManager = cache1Impl.getRPCManager();
// inject a mock RPC manager so that we can test whether calls made are sync or async.
- ((CacheImpl) cache1).setRpcManager((RPCManager) mockRpcManager.proxy());
+ cache1Impl.setRpcManager((RPCManager) mockRpcManager.proxy());
// specify what we expect called on the mock Rpc Manager. For params we don't care about, just use ANYTHING.
// setting the mock object to expect the "sync" param to be false.
+ mockRpcManager.expects(once()).method("getReplicationQueue").withNoArguments();
mockRpcManager.expects(once()).method("callRemoteMethods").with(new Constraint[]{ANYTHING, ANYTHING, ANYTHING, eq(false), ANYTHING, ANYTHING});
// now try a simple replication. Since the RPCManager is a mock object it will not actually replicate anything.
cache1.putForExternalRead(fqn, key, value);
// cleanup
+ cache1Impl.setRpcManager(originalRpcManager);
cache1.removeNode(fqn);
-
- // now for a negative test.
- // now set the mock object to expect sync = true
- mockRpcManager.expects(once()).method("callRemoteMethods").with(new Constraint[]{ANYTHING, ANYTHING, ANYTHING, eq(true), ANYTHING, ANYTHING});
-
- try
- {
- cache1.putForExternalRead(fqn, key, value);
- fail("Should have barfed");
- }
- catch (Exception e)
- {
- // expected
- }
}
public void testTxSuspension() throws Exception
{
+ // create parent node first
+ cache1.put(parentFqn, key, value);
+
// start a tx and do some stuff.
tm1.begin();
- cache1.put(parentFqn, key, value);
+ cache1.get(parentFqn, key);
+ NodeSPI parentNode = null;
+ TransactionWorkspace workspace = null;
+ if (optimistic)
+ workspace = extractTransactionWorkspace(cache1);
+ else
+ parentNode = (NodeSPI) cache1.getRoot().getChild(parentFqn);
+
cache1.putForExternalRead(fqn, key, value); // should have happened in a separate tx and have committed already.
Transaction t = tm1.suspend();
asyncWait();
- assertNull("parent fqn transaction has not completed", cache1.get(parentFqn, key));
- assertNull("parent fqn transaction has not completed", cache2.get(parentFqn, key));
+ assertLocked(parentFqn, parentNode, workspace, false);
assertEquals("PFER should have completed", value, cache1.get(fqn, key));
assertEquals("PFER should have completed", value, cache2.get(fqn, key));
@@ -212,32 +234,51 @@
}
};
+ barfingRpcManager.setCache((CacheSPI) cache1);
((CacheImpl) cache1).setRpcManager(barfingRpcManager);
try
{
cache1.put(fqn, key, value);
+ if (!optimistic) fail("Should have barfed");
+ }
+ catch (RuntimeException re)
+ {
+ }
+
+ if (optimistic)
+ {
+ // proves that the put did, in fact, barf.
+ assertNull(cache1.get(fqn, key));
+ }
+ else
+ {
+ // clean up any indeterminate state left over
+ try
+ {
+ cache1.removeNode(fqn);
fail("Should have barfed");
}
catch (RuntimeException re)
{
- // expected.
}
+ }
+
+ assertNull("Should have cleaned up", cache1.get(fqn, key));
- assertNull("State should not have been applied", cache1.get(fqn, key));
// should not barf
cache1.putForExternalRead(fqn, key, value);
-
- // but should not apply state either
- assertNull("State should not have been applied", cache1.get(fqn, key));
}
- public void test0msForce()
+ protected void assertLocked(Fqn fqn, NodeSPI n, TransactionWorkspace workspace, boolean write_locked) throws Exception
{
- fail("Implement me");
+ // this needs to cater for "optimistically locked" nodes as well.
+ if (workspace != null)
+ {
+ // scan workspaces for this node
+ assertNotNull("node " + fqn + " should be in transaction workspace", workspace.getNode(fqn));
}
-
- protected void assertLocked(NodeSPI n, boolean write_locked) throws Exception
+ else
{
NodeLock lock = n.getLock();
assertTrue("node " + fqn + " is not locked", lock.isLocked());
@@ -250,6 +291,24 @@
assertTrue("node " + fqn + " is not read-locked" + (lock.isWriteLocked() ? " but is write-locked instead!" : "!"), lock.isReadLocked());
}
}
+ }
+
+ protected TransactionWorkspace extractTransactionWorkspace(Cache c)
+ {
+ CacheSPI cs = (CacheSPI) c;
+ try
+ {
+ GlobalTransaction gtx = cs.getTransactionTable().get(cs.getTransactionManager().getTransaction());
+ OptimisticTransactionEntry entry = (OptimisticTransactionEntry) cs.getTransactionTable().get(gtx);
+ return entry.getTransactionWorkSpace();
+ }
+ catch (SystemException e)
+ {
+ e.printStackTrace();
+ fail("Unable to extract transaction workspace from cache");
+ }
+ return null;
+ }
protected void asyncWait()
{
More information about the jboss-cvs-commits
mailing list