package org.jboss.cache.api.pfer;
import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
import org.jboss.cache.lock.NodeLock;
import static org.testng.AssertJUnit.*;
import javax.transaction.Transaction;
public abstract class PFERPessimisticTestBase extends PutForExternalReadTestBase
{
protected PFERPessimisticTestBase()
{
nodeLockingScheme = NodeLockingScheme.PESSIMISTIC;
}
@Override
protected void assertLocked(Fqn fqn, CacheSPI cache, boolean writeLocked)
{
NodeLock lock = cache.peek(fqn, true, true).getLock();
assertTrue("node " + fqn + " is not locked", lock.isLocked());
if (writeLocked)
{
assertTrue("node " + fqn + " is not write-locked" + (lock.isReadLocked() ? " but is read-locked instead!" : "!"), lock.isWriteLocked());
}
else
{
assertTrue("node " + fqn + " is not read-locked" + (lock.isWriteLocked() ? " but is write-locked instead!" : "!"), lock.isReadLocked());
}
}
/**
* 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 testNoOpWhenLockedAnd0msTimeout() throws Exception
{
PutForExternalReadTestBaseTL threadCfg = threadLocal.get();
// create the parent node first ...
threadCfg.cache1.put(parentFqn, key, value);
threadCfg.tm1.begin();
threadCfg.cache1.put(parentFqn, key, value2);
Transaction t = threadCfg.tm1.suspend();
assertLocked(parentFqn, threadCfg.cache1, true);
// parentFqn should be write-locked.
long startTime = System.currentTimeMillis();
threadCfg.cache1.putForExternalRead(fqn, key, value);
long waited = System.currentTimeMillis() - startTime;
// crappy way to test that pFER does not block, but it is effective.
assertTrue("Should not wait " + waited + " millis for lock timeout, should attempt to acquire lock with 0ms!", waited < threadCfg.cache1.getConfiguration().getLockAcquisitionTimeout());
// should not block.
threadCfg.tm1.resume(t);
threadCfg.tm1.commit();
asyncWait();
assertEquals("Parent node write should have succeeded", value2, threadCfg.cache1.get(parentFqn, key));
if (isUsingInvalidation())
assertNull("Parent node write should have invalidated", threadCfg.cache2.get(parentFqn, key));
else
assertEquals("Parent node write should have replicated", value2, threadCfg.cache2.get(parentFqn, key));
assertNull("PFER should have been a no-op", threadCfg.cache1.get(fqn, key));
assertNull("PFER should have been a no-op", threadCfg.cache2.get(fqn, key));
}
}