/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.cache.options;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.jboss.cache.Fqn;
import org.jboss.cache.OptimisticTreeNode;
import org.jboss.cache.TreeCache;
import org.jboss.cache.config.Option;
import org.jboss.cache.optimistic.DataVersion;
import org.jboss.cache.optimistic.DefaultDataVersion;
import javax.transaction.TransactionManager;
/**
* Tests the passing in of explicit {@see DataVersion} instances when using optimistic locking.
*
* @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
*/
public class ExplicitVersionsTest extends TestCase
{
private TreeCache cache;
private Fqn fqn = Fqn.fromString("/a");
private String key = "key";
private Option option = new Option();
protected void setUp() throws Exception
{
if (cache != null) tearDown();
cache = new TreeCache();
cache.setCacheMode( TreeCache.LOCAL );
cache.setNodeLockingScheme("OPTIMISTIC");
cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
cache.startService();
}
protected void tearDown()
{
if (cache != null)
{
cache.stopService();
cache = null;
}
}
public void testSimplePut() throws Exception
{
DataVersion version = new TestVersion("99");
option.setDataVersion( version );
cache.put(fqn, key, "value", option);
//now retrieve the data from the cache.
Assert.assertEquals("value", cache.get(fqn,key));
// get a hold of the node
OptimisticTreeNode node = (OptimisticTreeNode) cache.get(fqn);
DataVersion versionFromCache = node.getVersion();
Assert.assertEquals(TestVersion.class, versionFromCache.getClass());
Assert.assertEquals("99", ((TestVersion) versionFromCache).getInternalVersion());
}
public void testFailingPut() throws Exception
{
DataVersion version = new TestVersion("99");
option.setDataVersion(version);
cache.put(fqn, key, "value", option);
version = new TestVersion("25");
option.setDataVersion(version);
TransactionManager mgr = cache.getTransactionManager();
mgr.begin();
cache.put(fqn, key, "value2", option);
try
{
mgr.commit();
Assert.assertTrue("expected to fail", false);
}
catch (Exception e)
{
// should fail.
Assert.assertTrue("expected to fail", true);
}
}
public void testIncompatibleVersionTypes() throws Exception
{
DataVersion version = new TestVersion("99");
option.setDataVersion(version);
cache.put(fqn, key, "value", option);
TransactionManager mgr = cache.getTransactionManager();
mgr.begin();
option.setDataVersion(new DefaultDataVersion(777));
cache.put(fqn, key, "value2", option);
try
{
// this call will use implicit versioning and will hence fail.
mgr.commit();
Assert.assertTrue("expected to fail", false);
}
catch (Exception e)
{
// should fail.
Assert.assertTrue("expected to fail", true);
}
}
public void testExplicitVersionOnLeaf() throws Exception
{
cache.put("/org/domain/Entity", null);
assertEquals(1, ((DefaultDataVersion)((OptimisticTreeNode)cache.get("/org/domain/Entity")).getVersion()).getRawVersion());
TestVersion v = new TestVersion("Arse");
Option o = new Option();
o.setDataVersion(v);
cache.put(Fqn.fromString("/org/domain/Entity/EntityInstance#1"), "k", "v", o);
assertEquals(1, ((DefaultDataVersion)((OptimisticTreeNode)cache.get("/org/domain/Entity")).getVersion()).getRawVersion());
assertEquals(v, ((OptimisticTreeNode)cache.get("/org/domain/Entity/EntityInstance#1")).getVersion());
}
public void testExplicitVersionOnLeafImplicitParentCreation() throws Exception
{
TestVersion v = new TestVersion("Arse");
Option o = new Option();
o.setDataVersion(v);
cache.put(Fqn.fromString("/org/domain/Entity/EntityInstance#1"), "k", "v", o);
assertEquals(1, ((DefaultDataVersion)((OptimisticTreeNode)cache.get("/org/domain/Entity")).getVersion()).getRawVersion());
assertEquals(v, ((OptimisticTreeNode)cache.get("/org/domain/Entity/EntityInstance#1")).getVersion());
}
public void testExplicitVersionOnParentAndChild() throws Exception
{
TestVersion vParent = new TestVersion("Parent-Version");
Option o = new Option();
o.setDataVersion(vParent);
cache.getTransactionManager().begin();
cache.put(Fqn.fromString("/parent"), "k", "v", o);
cache.getTransactionManager().commit();
assertEquals(0, ((DefaultDataVersion)((OptimisticTreeNode)cache.get("/")).getVersion()).getRawVersion());
assertEquals(vParent, ((OptimisticTreeNode)cache.get("/parent")).getVersion());
TestVersion vChild = new TestVersion("Child-Version");
o = new Option();
o.setDataVersion(vChild);
cache.getTransactionManager().begin();
cache.put(Fqn.fromString("/parent/child"), "k", "v", o);
cache.getTransactionManager().commit();
assertEquals(0, ((DefaultDataVersion)((OptimisticTreeNode)cache.get("/")).getVersion()).getRawVersion());
assertEquals(vParent, ((OptimisticTreeNode)cache.get("/parent")).getVersion());
assertEquals(vChild, ((OptimisticTreeNode)cache.get("/parent/child")).getVersion());
}
}
/**
* Note that this uses STRING comparisons!!
*/
class TestVersion implements DataVersion
{
private String myVersion;
public TestVersion(String version)
{
myVersion = version;
}
public String getInternalVersion()
{
return myVersion;
}
public void setInternalVersion(String version)
{
myVersion = version;
}
public boolean newerThan(DataVersion other)
{
if (other instanceof TestVersion)
{
return myVersion.compareTo(((TestVersion) other).getInternalVersion()) > 0;
}
else throw new IllegalArgumentException("version type mismatch");
}
public String toString()
{
return "TestVersion-" + myVersion;
}
public boolean equals(Object other)
{
if (other instanceof TestVersion)
{
TestVersion oVersion = (TestVersion) other;
if (oVersion.myVersion == null && myVersion == null) return true;
if (myVersion != null) return myVersion.equals(oVersion.myVersion);
}
return false;
}
}