package org.jboss.cache.passivation;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.CacheException;
import org.jboss.cache.DataNode;
import org.jboss.cache.Fqn;
import org.jboss.cache.Modification;
import org.jboss.cache.TreeCache;
import org.jboss.cache.loader.CacheLoader;
import org.jboss.cache.loader.SamplePojo;
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.cache.transaction.DummyTransactionManager;
import org.jboss.cache.xml.XmlHelper;
import org.w3c.dom.Element;
import javax.transaction.NotSupportedException;
import javax.transaction.Transaction;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Base tests for passivation using any of the cache loaders
*
* @author <a href="mailto:{hmesha@novell.com}">{Hany Mesha}</a>
* @version $Id: PassivationTestsBase.java 3090 2006-12-05 15:27:52Z msurtani $
*/
abstract public class PassivationTestsBase extends TestCase {
Log log = LogFactory.getLog(getClass());
//Cache Loader fields
TreeCache cache;
CacheLoader loader=null;
Transaction tx=null;
static final Fqn FQN = new Fqn("key");
protected Element getCacheLoaderConfig(String preload, String cacheloaderClass, String properties, boolean async, boolean fetchPersistentState) throws Exception
{
String xml = "<config>\n" +
"<passivation>true</passivation>\n" +
"<preload>" + preload + "</preload>\n" +
"<cacheloader>\n" +
"<class>" + cacheloaderClass + "</class>\n" +
"<properties>" + properties + "</properties>\n" +
"<async>" + async + "</async>\n" +
"<fetchPersistentState>" + fetchPersistentState + "</fetchPersistentState>\n" +
"</cacheloader>\n" +
"</config>";
return XmlHelper.stringToElement(xml);
}
protected void setUp() throws Exception {
super.setUp();
log.debug("Testing " + getName());
log.debug("");
cache=new TreeCache();
cache.setCacheMode("local");
configureCache();
// cache.setCacheLoaderPreload("/1/2/3/4/5/d");
cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
cache.setIsolationLevel(IsolationLevel.SERIALIZABLE);
cache.createService();
cache.startService();
loader=cache.getCacheLoader();
}
abstract protected void configureCache() throws Exception;
protected void tearDown() throws Exception {
super.tearDown();
if(tx != null) {
try {
tx.commit();
}
catch(Throwable e) {
e.printStackTrace();
}
}
cache.remove("/");
loader.remove(Fqn.fromString("/"));
cache.stopService();
cache.destroyService();
}
protected void addDelay()
{
; // returns immediately in this case. Subclasses may override where a delay is needed.
}
public void testPrintPassivation() throws Exception {
final Fqn NODE=Fqn.fromString("/test");
final String KEY="key";
loader.remove(NODE);
cache.put(NODE, KEY, new Integer(10));
cache.evict(NODE);
assertTrue(loader.exists(NODE));
addDelay();
log.info("print node " + NODE);
String ret=cache.print(NODE);
assertNotNull(ret);
log.info("loader exists " + NODE);
assertTrue(!loader.exists(NODE));
cache.get(NODE, KEY);
assertFalse(loader.exists(NODE));
}
public void testPutPassivation() throws Exception {
final String NODE="/test";
final String KEY="key";
Object retval=null;
cache.remove(NODE); // nothing to remove
addDelay();
retval=cache.put(NODE, KEY, new Integer(10)); // put in memory
assertNull(retval);
retval=cache.put(NODE, KEY, new Integer(20)); // put in memory
addDelay();
assertEquals(new Integer(10), retval); // get from memory
cache.evict(Fqn.fromString(NODE)); // passivate node
addDelay();
log.debug("______________");
retval=cache.put(NODE, KEY, new Integer(30)); // activate node then does put in memory
assertFalse(loader.exists(Fqn.fromString(NODE)));
assertEquals(new Integer(20), retval);
}
public void testPut2Passivation() throws CacheException {
final String NODE="/a/b/c";
final String KEY="key";
Object retval=null;
cache.remove(NODE); // nothing to remove
addDelay();
retval=cache.put(NODE, KEY, new Integer(10)); // put in memory
assertNull(retval);
addDelay();
retval=cache.put(NODE, KEY, new Integer(20)); // put in memory
assertEquals(new Integer(10), retval);
cache.evict(Fqn.fromString(NODE)); // passivate node
cache.evict(Fqn.fromString("/a/b")); // passivate parent node
cache.evict(Fqn.fromString("/a")); // passivate parent node
addDelay();
try{
assertTrue(loader.exists(Fqn.fromString("/a/b/c")));
}
catch(Exception e){
fail(e.toString());
}
retval=cache.put(NODE, KEY, new Integer(30)); // activate node, put in memory new value
try{
assertFalse(loader.exists(Fqn.fromString(NODE)));
}
catch(Exception e){
fail(e.toString());
}
assertEquals(new Integer(20), retval);
}
public void testSerializationPassivation() throws CacheException {
SamplePojo pojo=new SamplePojo(39, "Hany");
pojo.getHobbies().add("Running");
pojo.getHobbies().add("Beerathlon");
pojo.getHobbies().add("Triathlon");
cache.put("/mypojo", new Integer(322649), pojo); // put in memory
addDelay();
assertNotNull(cache.get("/mypojo", new Integer(322649))); // get from memory
cache.evict(Fqn.fromString("/mypojo")); // passivate node
try{
assertTrue(loader.exists(Fqn.fromString("/mypojo")));
}
catch(Exception e) {
fail(e.toString());
}
SamplePojo pojo2=(SamplePojo)cache.get("/mypojo", new Integer(322649)); // activate node
try{
assertFalse(loader.exists(Fqn.fromString("/mypojo")));
}
catch(Exception e) {
fail(e.toString());
}
assertNotNull(pojo2);
assertEquals(39, pojo2.getAge());
assertEquals("Hany", pojo2.getName());
assertEquals(3, pojo2.getHobbies().size());
}
/** Just adds some data that wil be later retrieved. This test has to be run first */
public void testPopulate() {
try {
Map m=new HashMap();
for(int i=0; i < 10; i++)
m.put("key" + i, "val" + i);
cache.put("/a/b/c", m);
cache.load("/1/2/3/4/5");
cache.put("/1/2/3/4/5", null);
cache.put("/1/2/3/4/5/a", null);
cache.put("/1/2/3/4/5/b", null);
cache.put("/1/2/3/4/5/c", null);
cache.put("/1/2/3/4/5/d", null);
cache.put("/1/2/3/4/5/e", null);
cache.put("/1/2/3/4/5/d/one", null);
cache.put("/1/2/3/4/5/d/two", null);
cache.put("/1/2/3/4/5/d/three", null);
// cache.put("/a/b/c", "newKey", "newValue");
System.out.println("cache: " + cache);
assertTrue(cache.exists("/1/2/3/4"));
assertTrue(cache.exists("/a/b/c"));
assertFalse(cache.exists("/a/b/c/d"));
}
catch(Exception e) {
fail(e.toString());
}
}
public void testPreloadingPassivation() throws Exception {
cache.remove("/"); // remove nothing
cache.put("1/2/3/4/5/d", "key", "val"); // put in memory
cache.evict(Fqn.fromString("1/2/3/4/5/d")); // passivate node
System.out.println("-- checking for 1/2/3/4/5/d");
addDelay();
try{
assertTrue(loader.exists(Fqn.fromString("1/2/3/4/5/d")));
}
catch(Exception e) {
fail(e.toString());
}
cache.get("1/2/3/4/5/d"); // get from loader but doesn't load attributes
assertEquals(false, loader.exists(Fqn.fromString("1/2/3/4/5/d")));
assertTrue(cache.exists("1/2/3/4/5/d"));
System.out.println("-- 1/2/3/4/5/d exists");
cache.get("1/2/3/4/5/d", "key"); // activate node
assertEquals(false, loader.exists(Fqn.fromString("1/2/3/4/5/d")));
}
public void testCacheLoading2() throws CacheException {
Set keys=null;
cache.put("/a/b/c", "key", "val");
try {
keys=cache.getKeys("/a/b/c");
assertNotNull(keys);
assertEquals(1, keys.size());
}
catch(Exception e) {
fail(e.toString());
}
try {
keys.add("myKey");
}
catch(UnsupportedOperationException ex) {
fail("unsupported operation: " + ex);
}
}
public void testExists() throws Exception {
cache.put("/eins/zwei/drei", "key1", "val1");
assertTrue(cache.exists("/eins/zwei/drei"));
assertTrue(cache.exists("/eins/zwei/drei", "key1"));
assertFalse(cache.exists("/eins/zwei/drei", "key2"));
assertFalse(cache.exists("/uno/due/tre"));
assertFalse(cache.exists("/une/due/tre", "key1"));
}
public void testGetChildren() throws Exception {
cache.put("/d/one", (Map)null);
cache.put("/d/two", (Map)null);
cache.put("/d/three", (Map)null);
cache.get("/d");
Set children=cache.getChildrenNames("/d");
assertNotNull(children);
assertEquals(3, children.size());
assertTrue(children.contains("one"));
assertTrue(children.contains("two"));
assertTrue(children.contains("three"));
}
public void testGetChildrenWithEvictionPassivation() throws CacheException {
cache.put("/a/b/c/1", null);
cache.put("/a/b/c/2", null);
cache.put("/a/b/c/3", null);
cache.evict(Fqn.fromString("/a/b/c/1")); // passivate node
cache.evict(Fqn.fromString("/a/b/c/2")); // passivate node
cache.evict(Fqn.fromString("/a/b/c/3")); // passivate node
cache.evict(Fqn.fromString("/a/b/c")); // passivate node
cache.evict(Fqn.fromString("/a/b")); // passivate node
cache.evict(Fqn.fromString("/a")); // passivate node
cache.evict(Fqn.fromString("/")); // passivate node
addDelay();
Set children=cache.getChildrenNames("/a/b/c"); // load node children names
assertNotNull(children);
assertEquals(3, children.size());
assertTrue(children.contains("1"));
assertTrue(children.contains("2"));
assertTrue(children.contains("3"));
try{
assertTrue(loader.exists(Fqn.fromString("/a/b/c")));
}
catch(Exception e) {
fail(e.toString());
}
cache.get("/a/b/c/1", "test"); // load child
cache.get("/a/b/c/2", "test"); // load child
cache.get("/a/b/c/3", "test"); // load child
cache.get("/a/b/c", "test"); // load attributes
try{
assertFalse(loader.exists(Fqn.fromString("/a/b/c/1")));
assertFalse(loader.exists(Fqn.fromString("/a/b/c/2")));
assertFalse(loader.exists(Fqn.fromString("/a/b/c/3")));
assertFalse(loader.exists(Fqn.fromString("/a/b/c")));
}
catch(Exception e) {
fail(e.toString());
}
}
public void testGetChildren2() {
try {
cache.put("/1", null);
cache.put("a", null);
Set children=cache.getChildrenNames("/"); // get root node children names
assertNotNull(children);
assertEquals(2, children.size());
assertTrue(children.contains("1"));
assertTrue(children.contains("a"));
}
catch(Exception e) {
fail(e.toString());
}
}
public void testGetChildren3() {
try {
cache.put("/1", null);
cache.put("a", null);
Set children=cache.getChildrenNames(""); // get children from root node
assertNotNull(children);
assertEquals(2, children.size());
assertTrue(children.contains("1"));
assertTrue(children.contains("a"));
}
catch(Exception e) {
fail(e.toString());
}
}
public void testGetChildren4() {
try {
if(!cache.exists("/a/b/c"))
cache.put("/a/b/c", null);
Set children=cache.getChildrenNames((Fqn)null); // get "null* node children names
assertNull(children);
}
catch(Exception e) {
fail(e.toString());
}
}
public void testGetChildren5() {
try {
cache.put("/a/1", null);
cache.put("/a/2", null);
cache.put("/a/3", null);
System.out.println("cache is " + cache.printLockInfo());
DataNode n=cache.get("/a");
assertNotNull(n);
Set children=cache.getChildrenNames("/a");
assertNotNull(children);
assertEquals(3, children.size());
}
catch(Exception e) {
fail(e.toString());
}
}
public void testGetChildren6Passivation() {
try {
cache.put("/a/1", null); // put node in memory
cache.put("/a/2", null); // put node in memory
cache.put("/a/3", null); // put node in memory
System.out.println("cache is " + cache.printLockInfo());
cache.evict(Fqn.fromString("/a/1")); // passivate node
cache.evict(Fqn.fromString("/a/2")); // passivate node
cache.evict(Fqn.fromString("/a/3")); // passivate node
cache.evict(Fqn.fromString("/a")); // passivate node
assertTrue(loader.exists(Fqn.fromString("/a")));
System.out.println("cache is " + cache.printLockInfo());
addDelay();
assertNotNull(cache.get("/a")); // load node
assertTrue(loader.exists(Fqn.fromString("/a"))); // children haven't been loaded
Set children=cache.getChildrenNames("/a");
assertNotNull("No children were loaded", children);
System.out.println("children: " + children);
assertEquals("3 children weren't loaded", 3, children.size());
cache.get("/a/1", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/1")));
cache.get("/a/2", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/2")));
cache.get("/a/3", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/3")));
cache.get("/a", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a")));
}
catch(Exception e) {
fail(e.toString());
}
}
public void testGetChildren7Passivation() {
try {
cache.put("/a/1", null);
cache.put("/a/2", null);
cache.put("/a/3", null);
cache.put("/a", "test", "test");
System.out.println("cache is " + cache.printLockInfo());
cache.evict(Fqn.fromString("/a/1")); // passivate node
cache.evict(Fqn.fromString("/a/2")); // passivate node
cache.evict(Fqn.fromString("/a/3")); // passivate node
cache.evict(Fqn.fromString("/a")); // passivate node
assertTrue(loader.exists(Fqn.fromString("/a")));
System.out.println("cache is " + cache.printLockInfo());
addDelay();
Object val=cache.get("/a", "test"); // load node's attributes but not children
assertEquals("attributes weren't loaded", "test", val);
Set children=cache.getChildrenNames("/a"); // get node's children names
assertNotNull("No children were loaded", children);
System.out.println("children: " + children);
assertEquals("3 children weren't loaded", 3, children.size());
cache.get("/a/1", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/1")));
cache.get("/a/2", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/2")));
cache.get("/a/3", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/3")));
assertTrue(loader.exists(Fqn.fromString("/a")));
}
catch(Exception e) {
fail(e.toString());
}
}
public void testGetChildren8Passivation() {
try {
cache.put("/a/1", null);
cache.put("/a/2", null);
cache.put("/a/3", null);
System.out.println("cache is " + cache.printLockInfo());
cache.evict(Fqn.fromString("/a/1")); // passivate node
cache.evict(Fqn.fromString("/a/2")); // passivate node
cache.evict(Fqn.fromString("/a/3")); // passivate node
cache.evict(Fqn.fromString("/a")); // passivate node
System.out.println("cache is " + cache.printLockInfo());
addDelay();
assertNull(cache.get("/a", "test")); // load attributes only
assertTrue(loader.exists(Fqn.fromString("/a"))); // loaded attibutes but not children
assertNull(cache.get("/a/1", "test")); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/1"))); // loaded attributes and has no children
Set children=cache.getChildrenNames("/a"); // load children names
assertNotNull("No children were loaded", children);
System.out.println("children: " + children);
assertEquals("3 children weren't loaded", 3, children.size());
assertTrue(loader.exists(Fqn.fromString("/a"))); //loaded children but didn't initalizae them
}
catch(Exception e) {
fail(e.toString());
}
}
public void testGetChildren9Passivation() {
try {
cache.put("/a/1", null);
cache.put("/a/2", null);
cache.put("/a/3", null);
System.out.println("cache is " + cache.printLockInfo());
cache.evict(Fqn.fromString("/a/1")); // passivate node
cache.evict(Fqn.fromString("/a/2")); // passivate node
cache.evict(Fqn.fromString("/a/3")); // passivate node
cache.evict(Fqn.fromString("/a")); // passivate node
assertTrue(loader.exists(Fqn.fromString("/a")));
System.out.println("cache is " + cache.printLockInfo());
addDelay();
cache.get("/a/1", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/1")));
cache.get("/a/2", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/2")));
cache.get("/a/3", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/3")));
Set children=cache.getChildrenNames("/a"); // get node's children names
assertNotNull("No children were loaded", children);
System.out.println("children: " + children);
assertEquals("3 children weren't loaded", 3, children.size());
assertNull(cache.get("/a", "test")); // load attributes and has no children by now, activation
assertFalse(loader.exists(Fqn.fromString("/a")));
cache.evict(Fqn.fromString("/a/1")); // passivate node
cache.evict(Fqn.fromString("/a/2")); // passivate node
cache.evict(Fqn.fromString("/a/3")); // passivate node
cache.evict(Fqn.fromString("/a")); // passivate node
System.out.println("cache is " + cache.printLockInfo());
assertTrue(loader.exists(Fqn.fromString("/a")));
cache.get("/a/1", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/1")));
cache.get("/a/2", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/2")));
cache.get("/a/3", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/3")));
children=cache.getChildrenNames("/a"); // get children names
assertNotNull("No children were loaded", children);
System.out.println("children: " + children);
assertEquals("3 children weren't loaded", 3, children.size());
assertNull(cache.get("/a", "test")); // load attributes and has no children by now, activation
assertFalse(loader.exists(Fqn.fromString("/a")));
}
catch(Exception e) {
fail(e.toString());
}
}
public void testGetChildren10Passivation() {
try {
cache.put("/a/1", null);
cache.put("/a/2", null);
cache.put("/a/3", null);
System.out.println("cache is " + cache.printLockInfo());
cache.evict(Fqn.fromString("/a/1")); // passivate node
cache.evict(Fqn.fromString("/a/2")); // passivate node
cache.evict(Fqn.fromString("/a/3")); // passivate node
cache.evict(Fqn.fromString("/a")); // passivate node
System.out.println("cache is " + cache.printLockInfo());
addDelay();
assertTrue(loader.exists(Fqn.fromString("/a")));
assertNull(cache.get("/a", "test")); // load attributes from loader
cache.get("/a/1", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/1")));
cache.get("/a/2", "test"); // activate node
assertFalse(loader.exists(Fqn.fromString("/a/2")));
cache.get("/a/3", "test"); // passivate node
assertFalse(loader.exists(Fqn.fromString("/a/3")));
Set children=cache.getChildrenNames("/a");
assertNotNull("No children were loaded", children);
System.out.println("children: " + children);
assertEquals("3 children weren't loaded", 3, children.size());
assertNull(cache.get("/a", "test")); // activate node
assertFalse(loader.exists(Fqn.fromString("/a")));
}
catch(Exception e) {
fail(e.toString());
}
}
public void testRemoveData() throws Exception {
String key="/x/y/z/";
cache.put(key, "keyA", "valA");
cache.put(key, "keyB", "valB");
cache.put(key, "keyC", "valC");
assertEquals(3, cache.getKeys(key).size());
cache.removeData(key);
Set keys=cache.getKeys(key);
assertEquals(0, keys.size());
cache.remove("/x");
Object val=cache.get(key, "keyA");
assertNull(val);
}
public void testRemoveData2Passivation() throws Exception {
Set keys;
Fqn key=Fqn.fromString("/x/y/z/");
cache.put(key, "keyA", "valA");
cache.put(key, "keyB", "valB");
cache.put(key, "keyC", "valC");
addDelay();
keys=cache.getKeys(key);
assertEquals(3, keys.size());
cache.removeData(key);
cache.evict(key); // passivate node
addDelay();
keys=cache.getKeys(key); // activate node
try{
assertFalse(loader.exists(key));
}
catch(Exception e) {
fail(e.toString());
}
assertEquals(0, keys.size());
}
public void testRemoveData3Passivation() throws Exception {
Set keys;
Fqn key=Fqn.fromString("/x/y/z/");
cache.put(key, "keyA", "valA");
cache.put(key, "keyB", "valB");
cache.put(key, "keyC", "valC");
keys=cache.getKeys(key);
assertEquals(3, keys.size());
cache.evict(key); // passivate node
assertTrue(loader.exists(key));
cache.removeData(key);
keys=cache.getKeys(key); // activate node
assertFalse(loader.exists(key));
assertEquals(0, keys.size());
}
public void testRemoveKey() throws Exception {
String key="/x/y/z/";
cache.put(key, "keyA", "valA");
cache.put(key, "keyB", "valB");
cache.put(key, "keyC", "valC");
cache.remove(key, "keyA");
assertEquals(2, cache.getKeys(key).size());
cache.remove("/x");
}
public void testRemoveKey2() throws CacheException {
final String NODE="/test";
final String KEY="key";
Object retval=null;
cache.remove(NODE);
retval=cache.put(NODE, KEY, new Integer(10));
assertNull(retval);
addDelay();
retval=cache.remove(NODE, KEY);
assertEquals(new Integer(10), retval);
addDelay();
retval=cache.remove(NODE, KEY);
assertNull(retval);
}
public void testRemoveKey3Passivation() throws CacheException {
final String NODE="/test";
final String KEY="key";
Object retval=null;
cache.remove(NODE);
retval=cache.put(NODE, KEY, new Integer(10));
assertNull(retval);
cache.evict(Fqn.fromString(NODE)); // passivate node
addDelay();
try{
assertTrue(loader.exists(Fqn.fromString(NODE)));
assertEquals(new Integer(10), loader.get(Fqn.fromString(NODE)).get(KEY));
}
catch(Exception e) {
fail(e.toString());
}
retval=cache.remove(NODE, KEY); // activate node
assertEquals(new Integer(10), retval);
try{
assertFalse(loader.exists(Fqn.fromString(NODE)));
}
catch(Exception e) {
fail(e.toString());
}
cache.evict(Fqn.fromString(NODE)); // passiave node
addDelay();
retval=cache.remove(NODE, KEY); // activate node
try{
assertFalse(loader.exists(Fqn.fromString(NODE)));
}
catch(Exception e) {
fail(e.toString());
}
assertNull(retval);
}
public void testRemove() throws Exception {
String key="/x/y/z/";
cache.put(key, "keyA", "valA");
cache.put(key, "keyB", "valB");
cache.put(key, "keyC", "valC");
cache.remove("/x");
assertNull(cache.get(key, "keyA"));
addDelay();
Set keys=cache.getKeys(key);
assertNull(keys);
cache.remove("/x");
}
public void testRemoveRoot() throws Exception {
assertEquals(0, cache.getKeys("/").size());
cache.put("/1/2/3/4/5", null);
cache.put("uno/due/tre", null);
cache.put("1/2/3/a", null);
cache.put("/eins/zwei/drei", null);
cache.put("/one/two/three", null);
cache.remove("/");
assertEquals(0, cache.getKeys("/").size());
}
public void testEvictionWithCacheLoaderPassivation() throws Exception {
cache.put("/first/second", "key1", "val1");
cache.put("/first/second/third", "key2", "val2");
cache.evict(Fqn.fromString("/first/second")); // pasivate node to cache loader
addDelay();
assertTrue(loader.exists(Fqn.fromString("/first/second")));
assertTrue(cache.exists("/first"));
String val=(String)cache.get("/first/second", "key1"); // loads attributes only
assertTrue(loader.exists(Fqn.fromString("/first/second")));
assertEquals("val1", val);
String val2=(String)cache.get("/first/second/third", "key2"); // activate node
assertFalse(loader.exists(Fqn.fromString("/first/second/third")));
assertEquals("val2", val2);
assertTrue(cache.exists("/first/second/third"));
assertTrue(cache.exists("/first/second"));
assertTrue(cache.exists("/first"));
}
public void testEvictionWithCacheLoaderPassivation2() throws Exception {
cache.put("/first/second/third", "key1", "val1"); // stored in cache loader
cache.evict(Fqn.fromString("/first/second/third")); // passivate node, note: it has no children
addDelay();
try{
assertTrue(loader.exists(Fqn.fromString("/first/second/third")));
}
catch(Exception e){
fail(e.toString());
}
assertTrue(cache.exists("/first/second"));
assertTrue(cache.exists("/first"));
String val=(String)cache.get("/first/second/third", "key1"); // activate node
try{
assertFalse(loader.exists(Fqn.fromString("/first/second/third")));
}
catch(Exception e){
fail(e.toString());
}
assertEquals("val1", val);
assertTrue(cache.exists("/first/second/third"));
assertTrue(cache.exists("/first/second"));
assertTrue(cache.exists("/first"));
}
public void testEvictionWithGetChildrenNamesPassivation() throws Exception {
cache.put("/a/1", null);
cache.put("/a/2", null);
cache.put("/a/3", null);
cache.evict(Fqn.fromString("/a/1")); // passivate node
assertTrue(loader.exists(Fqn.fromString("/a/1")));
cache.evict(Fqn.fromString("/a/2")); // passivate node
assertTrue(loader.exists(Fqn.fromString("/a/2")));
cache.evict(Fqn.fromString("/a/3")); // passivate node
assertTrue(loader.exists(Fqn.fromString("/a/3")));
cache.evict(Fqn.fromString("/a")); // passivate node
assertTrue(loader.exists(Fqn.fromString("/a")));
addDelay();
DummyTransactionManager mgr=DummyTransactionManager.getInstance();
mgr.begin();
tx=mgr.getTransaction();
Set children=cache.getChildrenNames("/a");
assertEquals(3, children.size());
assertTrue(children.contains("1"));
assertTrue(children.contains("2"));
assertTrue(children.contains("3"));
assertEquals(5, cache.getNumberOfLocksHeld());
tx.commit();
}
public void testTxPutCommit() throws Exception, NotSupportedException {
DummyTransactionManager mgr=DummyTransactionManager.getInstance();
mgr.begin();
tx=mgr.getTransaction();
cache.put("/one/two/three", "key1", "val1");
cache.put("/one/two/three/four", "key2", "val2");
tx.commit();
assertNotNull(cache.getKeys("/one/two/three"));
assertEquals("val1", cache.get(Fqn.fromString("/one/two/three"), "key1"));
mgr.begin();
tx=mgr.getTransaction();
cache.evict(Fqn.fromString("/one/two/three"));
cache.evict(Fqn.fromString("/one/two/three/four"));
tx.commit();
assertTrue(loader.exists(Fqn.fromString("/one/two/three")));
assertTrue(loader.exists(Fqn.fromString("/one/two/three/four")));
assertNotNull(cache.getKeys("/one/two/three"));
Set children=cache.getChildrenNames("/one");
assertEquals(1, children.size());
cache.remove("/");
}
public void testTxPutRollback() throws Exception, NotSupportedException {
DummyTransactionManager mgr=DummyTransactionManager.getInstance();
cache.remove("/one");
addDelay();
mgr.begin();
tx=mgr.getTransaction();
cache.put("/one/two/three", "key1", "val1");
cache.put("/one/two/three/four", "key2", "val2");
tx.rollback();
addDelay();
assertNull(cache.getKeys("/one/two/three"));
Set children=cache.getChildrenNames("/one");
assertNull(children);
assertFalse(loader.exists(Fqn.fromString("/one/two/three")));
assertFalse(loader.exists(Fqn.fromString("/one/two/three/four")));
}
public void testPassivationAndActivation() throws Exception {
Object val, val2;
Fqn NODE=Fqn.fromString("/test");
loader.remove(Fqn.fromString("/"));
cache.put(NODE, "key", "val");
//val=loader.get(NODE).get("key");
assertNull("value cannot be passivated yet (only on eviction)", loader.get(NODE));
cache.evict(NODE);
assertEquals(0, cache.getNumberOfNodes());
assertEquals(0, cache.getNumberOfAttributes());
val=loader.get(NODE).get("key");
assertNotNull("value must have been passivated on evict()", val);
assertEquals(val, "val");
val2=cache.get(NODE, "key");
assertNotNull(val2);
assertEquals(val, val2);
// val=loader.get(NODE).get("key");
assertNull("value should have been deleted from store on activation", loader.get(NODE));
}
/**
* Tests basic operations without a transaction.
*/
public void testBasicOperations()
throws Exception {
doTestBasicOperations();
}
/**
* Tests basic operations with a transaction.
*/
public void testBasicOperationsTransactional()
throws Exception {
DummyTransactionManager mgr=DummyTransactionManager.getInstance();
mgr.begin();
tx=mgr.getTransaction();
doTestBasicOperations();
tx.commit();
}
/**
* Tests basic operations.
*/
private void doTestBasicOperations() throws Exception {
/* One FQN only. */
doPutTests(new Fqn("key"));
doRemoveTests(new Fqn("key"));
// assertEquals(0, loader.loadEntireState().length);
/* Add three FQNs, middle FQN last. */
doPutTests(new Fqn("key1"));
doPutTests(new Fqn("key3"));
doPutTests(new Fqn("key2"));
assertEquals(4, loader.get(new Fqn("key1")).size());
assertEquals(4, loader.get(new Fqn("key2")).size());
assertEquals(4, loader.get(new Fqn("key3")).size());
/* Remove middle FQN first, then the others. */
doRemoveTests(new Fqn("key2"));
doRemoveTests(new Fqn("key3"));
doRemoveTests(new Fqn("key1"));
assertEquals(null, loader.get(new Fqn("key1")));
assertEquals(null, loader.get(new Fqn("key2")));
assertEquals(null, loader.get(new Fqn("key3")));
// assertEquals(0, loader.loadEntireState().length);
}
/**
* Do basic put tests for a given FQN.
*/
private void doPutTests(Fqn fqn)
throws Exception {
assertTrue(!loader.exists(fqn));
/* put(Fqn,Object,Object) and get(Fqn,Object) */
Object oldVal;
oldVal = loader.put(fqn, "one", "two");
assertNull(oldVal);
addDelay();
oldVal = loader.put(fqn, "three", "four");
assertNull(oldVal);
addDelay();
assertEquals("two", loader.get(fqn).get("one"));
assertEquals("four", loader.get(fqn).get("three"));
addDelay();
oldVal = loader.put(fqn, "one", "xxx");
assertEquals("two", oldVal);
addDelay();
oldVal = loader.put(fqn, "one", "two");
assertEquals("xxx", oldVal);
/* get(Fqn) */
addDelay();
Map map = loader.get(fqn);
assertEquals(2, map.size());
assertEquals("two", map.get("one"));
assertEquals("four", map.get("three"));
/* put(Fqn,Map) */
map.put("five", "six");
map.put("seven", "eight");
loader.put(fqn, map);
addDelay();
assertEquals("six", loader.get(fqn).get("five"));
assertEquals("eight", loader.get(fqn).get("seven"));
assertEquals(map, loader.get(fqn));
assertEquals(4, map.size());
assertTrue(loader.exists(fqn));
}
/**
* Do basic remove tests for a given FQN.
*/
private void doRemoveTests(Fqn fqn)
throws Exception {
/* remove(Fqn,Object) */
Object oldVal;
oldVal = loader.remove(fqn, "one");
assertEquals("two", oldVal);
addDelay();
oldVal = loader.remove(fqn, "five");
assertEquals("six", oldVal);
addDelay();
assertEquals(null, loader.get(fqn).get("one"));
assertEquals(null, loader.get(fqn).get("five"));
assertEquals("four", loader.get(fqn).get("three"));
assertEquals("eight", loader.get(fqn).get("seven"));
Map map = loader.get(fqn);
assertEquals(2, map.size());
assertEquals("four", map.get("three"));
assertEquals("eight", map.get("seven"));
/* remove(Fqn) */
assertTrue(loader.exists(fqn));
loader.remove(fqn);
addDelay();
assertNull(loader.get(fqn));
assertTrue(!loader.exists(fqn));
}
/**
* Tests creating implicit intermediate nodes when a leaf node is created,
* and tests removing subtrees.
*/
public void testMultiLevelTree()
throws Exception {
/* Create top level node implicitly. */
assertTrue(!loader.exists(new Fqn("key0")));
loader.put(Fqn.fromString("/key0/level1/level2"), null);
addDelay();
assertTrue(loader.exists(Fqn.fromString("/key0/level1/level2")));
assertTrue(loader.exists(Fqn.fromString("/key0/level1")));
assertTrue(loader.exists(new Fqn("key0")));
/* Remove leaf, leaving implicitly created middle level. */
loader.put(Fqn.fromString("/key0/x/y"), null);
addDelay();
assertTrue(loader.exists(Fqn.fromString("/key0/x/y")));
assertTrue(loader.exists(Fqn.fromString("/key0/x")));
loader.remove(Fqn.fromString("/key0/x/y"));
addDelay();
assertTrue(!loader.exists(Fqn.fromString("/key0/x/y")));
assertTrue(loader.exists(Fqn.fromString("/key0/x")));
/* Delete top level to delete everything. */
loader.remove(new Fqn("key0"));
addDelay();
assertTrue(!loader.exists(new Fqn("key0")));
assertTrue(!loader.exists(Fqn.fromString("/key0/level1/level2")));
assertTrue(!loader.exists(Fqn.fromString("/key0/level1")));
assertTrue(!loader.exists(Fqn.fromString("/key0/x")));
/* Add three top level nodes as context. */
loader.put(new Fqn("key1"), null);
loader.put(new Fqn("key2"), null);
loader.put(new Fqn("key3"), null);
addDelay();
assertTrue(loader.exists(new Fqn("key1")));
assertTrue(loader.exists(new Fqn("key2")));
assertTrue(loader.exists(new Fqn("key3")));
/* Put /key3/level1/level2. level1 should be implicitly created. */
assertTrue(!loader.exists(Fqn.fromString("/key3/level1")));
assertTrue(!loader.exists(Fqn.fromString("/key3/level1/level2")));
loader.put(Fqn.fromString("/key3/level1/level2"), null);
addDelay();
assertTrue(loader.exists(Fqn.fromString("/key3/level1/level2")));
assertTrue(loader.exists(Fqn.fromString("/key3/level1")));
/* Context nodes should still be intact. */
assertTrue(loader.exists(new Fqn("key1")));
assertTrue(loader.exists(new Fqn("key2")));
assertTrue(loader.exists(new Fqn("key3")));
/* Remove middle level only. */
loader.remove(Fqn.fromString("/key3/level1"));
addDelay();
assertTrue(!loader.exists(Fqn.fromString("/key3/level1/level2")));
assertTrue(!loader.exists(Fqn.fromString("/key3/level1")));
/* Context nodes should still be intact. */
assertTrue(loader.exists(new Fqn("key1")));
assertTrue(loader.exists(new Fqn("key2")));
assertTrue(loader.exists(new Fqn("key3")));
/* Delete first root, leaving other roots. */
loader.remove(new Fqn("key1"));
addDelay();
assertTrue(!loader.exists(new Fqn("key1")));
assertTrue(loader.exists(new Fqn("key2")));
assertTrue(loader.exists(new Fqn("key3")));
/* Delete last root, leaving other roots. */
loader.remove(new Fqn("key3"));
addDelay();
assertTrue(loader.exists(new Fqn("key2")));
assertTrue(!loader.exists(new Fqn("key3")));
/* Delete final root, leaving none. */
loader.remove(new Fqn("key2"));
addDelay();
assertTrue(!loader.exists(new Fqn("key0")));
assertTrue(!loader.exists(new Fqn("key1")));
assertTrue(!loader.exists(new Fqn("key2")));
assertTrue(!loader.exists(new Fqn("key3")));
/* Repeat all tests above using put(Fqn,Object,Object) and get(Fqn) */
assertNull(loader.get(new Fqn("key0")));
loader.put(Fqn.fromString("/key0/level1/level2"), "a", "b");
addDelay();
assertNotNull(loader.get(Fqn.fromString("/key0/level1/level2")));
assertNotNull(loader.get(Fqn.fromString("/key0/level1")));
assertTrue(loader.get(Fqn.fromString("/key0/level1")).isEmpty());
assertNotNull(loader.get(new Fqn("key0")));
assertTrue(loader.get(Fqn.fromString("/key0")).isEmpty());
loader.put(Fqn.fromString("/key0/x/y"), "a", "b");
addDelay();
assertNotNull(loader.get(Fqn.fromString("/key0/x/y")));
assertNotNull(loader.get(Fqn.fromString("/key0/x")));
assertTrue(loader.get(Fqn.fromString("/key0/x")).isEmpty());
loader.remove(Fqn.fromString("/key0/x/y"));
addDelay();
assertNull(loader.get(Fqn.fromString("/key0/x/y")));
assertNotNull(loader.get(Fqn.fromString("/key0/x")));
assertTrue(loader.get(Fqn.fromString("/key0/x")).isEmpty());
loader.remove(new Fqn("key0"));
addDelay();
assertNull(loader.get(new Fqn("key0")));
assertNull(loader.get(Fqn.fromString("/key0/level1/level2")));
assertNull(loader.get(Fqn.fromString("/key0/level1")));
assertNull(loader.get(Fqn.fromString("/key0/x")));
loader.put(new Fqn("key1"), "a", "b");
loader.put(new Fqn("key2"), "a", "b");
loader.put(new Fqn("key3"), "a", "b");
addDelay();
assertNotNull(loader.get(new Fqn("key1")));
assertNotNull(loader.get(new Fqn("key2")));
assertNotNull(loader.get(new Fqn("key3")));
assertNull(loader.get(Fqn.fromString("/key3/level1")));
assertNull(loader.get(Fqn.fromString("/key3/level1/level2")));
loader.put(Fqn.fromString("/key3/level1/level2"), "a", "b");
addDelay();
assertNotNull(loader.get(Fqn.fromString("/key3/level1/level2")));
assertNotNull(loader.get(Fqn.fromString("/key3/level1")));
assertTrue(loader.get(Fqn.fromString("/key3/level1")).isEmpty());
assertNotNull(loader.get(new Fqn("key1")));
assertNotNull(loader.get(new Fqn("key2")));
assertNotNull(loader.get(new Fqn("key3")));
loader.remove(Fqn.fromString("/key3/level1"));
addDelay();
assertNull(loader.get(Fqn.fromString("/key3/level1/level2")));
assertNull(loader.get(Fqn.fromString("/key3/level1")));
assertNotNull(loader.get(new Fqn("key1")));
assertNotNull(loader.get(new Fqn("key2")));
assertNotNull(loader.get(new Fqn("key3")));
loader.remove(new Fqn("key1"));
addDelay();
assertNull(loader.get(new Fqn("key1")));
assertNotNull(loader.get(new Fqn("key2")));
assertNotNull(loader.get(new Fqn("key3")));
loader.remove(new Fqn("key3"));
addDelay();
assertNotNull(loader.get(new Fqn("key2")));
assertNull(loader.get(new Fqn("key3")));
loader.remove(new Fqn("key2"));
addDelay();
assertNull(loader.get(new Fqn("key0")));
assertNull(loader.get(new Fqn("key1")));
assertNull(loader.get(new Fqn("key2")));
assertNull(loader.get(new Fqn("key3")));
}
/**
* Tests the getChildrenNames() method.
*/
public void testGetChildrenNames()
throws Exception {
checkChildren(new Fqn(), null);
checkChildren(Fqn.fromString("/key0"), null);
loader.put(Fqn.fromString("/key0"), null);
addDelay();
checkChildren(new Fqn(), new String[] { "key0" });
loader.put(Fqn.fromString("/key1/x"), null);
addDelay();
checkChildren(new Fqn(), new String[] { "key0", "key1" });
checkChildren(Fqn.fromString("/key1"), new String[] { "x" });
loader.remove(Fqn.fromString("/key1/x"));
addDelay();
checkChildren(new Fqn(), new String[] { "key0", "key1" });
checkChildren(Fqn.fromString("/key0"), null);
checkChildren(Fqn.fromString("/key1"), null);
loader.put(Fqn.fromString("/key0/a"), null);
loader.put(Fqn.fromString("/key0/ab"), null);
loader.put(Fqn.fromString("/key0/abc"), null);
addDelay();
checkChildren(Fqn.fromString("/key0"),
new String[] { "a", "ab", "abc" });
loader.put(Fqn.fromString("/key0/xxx"), null);
loader.put(Fqn.fromString("/key0/xx"), null);
loader.put(Fqn.fromString("/key0/x"), null);
addDelay();
checkChildren(Fqn.fromString("/key0"),
new String[] { "a", "ab", "abc", "x", "xx", "xxx" });
loader.put(Fqn.fromString("/key0/a/1"), null);
loader.put(Fqn.fromString("/key0/a/2"), null);
loader.put(Fqn.fromString("/key0/a/2/1"), null);
addDelay();
checkChildren(Fqn.fromString("/key0/a/2"), new String[] { "1" });
checkChildren(Fqn.fromString("/key0/a"), new String[] { "1", "2" });
checkChildren(Fqn.fromString("/key0"),
new String[] { "a", "ab", "abc", "x", "xx", "xxx" });
//
// loader.put(Fqn.fromString("/key0/\u0000"), null);
// loader.put(Fqn.fromString("/key0/\u0001"), null);
// checkChildren(Fqn.fromString("/key0"),
// new String[] { "a", "ab", "abc", "x", "xx", "xxx",
// "\u0000", "\u0001"});
//
// loader.put(Fqn.fromString("/\u0001"), null);
// checkChildren(new Fqn(), new String[] { "key0", "key1", "\u0001" });
//
// loader.put(Fqn.fromString("/\u0001/\u0001"), null);
// checkChildren(Fqn.fromString("/\u0001"), new String[] { "\u0001" });
//
// loader.put(Fqn.fromString("/\u0001/\uFFFF"), null);
// checkChildren(Fqn.fromString("/\u0001"),
// new String[] { "\u0001", "\uFFFF" });
//
// loader.put(Fqn.fromString("/\u0001/\uFFFF/\u0001"), null);
// checkChildren(Fqn.fromString("/\u0001/\uFFFF"),
// new String[] { "\u0001" });
}
/**
* Checks that the given list of children part names is returned.
*/
private void checkChildren(Fqn fqn, String[] names)
throws Exception {
Set set = loader.getChildrenNames(fqn);
if (names != null) {
assertEquals(names.length, set.size());
for (int i = 0; i < names.length; i += 1) {
assertTrue(set.contains(names[i]));
}
} else {
assertNull(set);
}
}
/**
* Tests basic operations without a transaction.
*/
public void testModifications()
throws Exception {
doTestModifications();
}
/**
* Tests basic operations with a transaction.
*/
public void testModificationsTransactional()
throws Exception {
DummyTransactionManager mgr=DummyTransactionManager.getInstance();
mgr.begin();
tx=mgr.getTransaction();
doTestModifications();
tx.commit();
}
/**
* Tests modifications.
*/
private void doTestModifications()
throws Exception {
/* PUT_KEY_VALUE, PUT_DATA */
List list = createUpdates();
loader.put(list);
addDelay();
checkModifications(list);
/* REMOVE_KEY_VALUE */
list = new ArrayList();
Modification mod = new Modification();
mod.setType(Modification.REMOVE_KEY_VALUE);
mod.setFqn(FQN);
mod.setKey("one");
list.add(mod);
loader.put(list);
addDelay();
checkModifications(list);
/* REMOVE_NODE */
list = new ArrayList();
mod = new Modification();
mod.setType(Modification.REMOVE_NODE);
mod.setFqn(FQN);
list.add(mod);
loader.put(list);
addDelay();
checkModifications(list);
assertEquals(null, loader.get(FQN));
/* REMOVE_DATA */
loader.put(FQN, "one", "two");
list = new ArrayList();
mod = new Modification();
mod.setType(Modification.REMOVE_DATA);
mod.setFqn(FQN);
list.add(mod);
loader.put(list);
addDelay();
checkModifications(list);
}
/**
* Tests a one-phase transaction.
*/
public void testOnePhaseTransaction()
throws Exception {
List mods = createUpdates();
loader.prepare(null, mods, true);
checkModifications(mods);
}
/**
* Tests a two-phase transaction.
*/
public void testTwoPhaseTransactionPassivation()
throws Exception {
Object txnKey = new Object();
List mods = createUpdates();
loader.prepare(txnKey, mods, false);
// try {
// checkModifications(mods);
// // fail("Expected lock timeout");
// } catch (DeadlockException expected) {}
loader.commit(txnKey);
addDelay();
checkModifications(mods);
}
/**
* Tests rollback of a two-phase transaction.
*/
public void testTransactionRollbackPassivation()
throws Exception {
loader.remove(Fqn.fromString("/"));
int num=loader.loadEntireState().length;
Object txnKey = new Object();
List mods = createUpdates();
loader.prepare(txnKey, mods, false);
loader.rollback(txnKey);
assertEquals(num, loader.loadEntireState().length);
}
/**
* Creates a set of update (PUT_KEY_VALUE, PUT_DATA) modifications.
*/
private List createUpdates() {
List list = new ArrayList();
Modification mod = new Modification();
mod.setType(Modification.PUT_KEY_VALUE);
mod.setFqn(FQN);
mod.setKey("one");
mod.setValue("two");
list.add(mod);
mod = new Modification();
mod.setType(Modification.PUT_KEY_VALUE);
mod.setFqn(FQN);
mod.setKey("three");
mod.setValue("four");
list.add(mod);
Map map = new HashMap();
map.put("five", "six");
map.put("seven", "eight");
mod = new Modification();
mod.setType(Modification.PUT_DATA);
mod.setFqn(FQN);
mod.setData(map);
list.add(mod);
return list;
}
/**
* Checks that a list of modifications was applied.
*/
private void checkModifications(List list)
throws Exception {
for (int i = 0; i < list.size(); i += 1) {
Modification mod = (Modification) list.get(i);
Fqn fqn = mod.getFqn();
switch (mod.getType()) {
case Modification.PUT_KEY_VALUE:
assertEquals(mod.getValue(), loader.get(fqn).get(mod.getKey()));
break;
case Modification.PUT_DATA:
Map map = mod.getData();
for (Iterator iter = map.keySet().iterator(); iter.hasNext();) {
Object key = iter.next();
assertEquals(map.get(key), loader.get(fqn).get(key));
}
break;
case Modification.REMOVE_KEY_VALUE:
assertEquals(null, loader.get(fqn).get(mod.getKey()));
break;
case Modification.REMOVE_DATA:
map = loader.get(fqn);
assertNotNull(map);
assertTrue(map.isEmpty());
break;
case Modification.REMOVE_NODE:
assertEquals(null, loader.get(fqn));
break;
default:
fail("unknown type: " + mod);
break;
}
}
}
/**
* Tests that null keys and values work as for a standard Java Map.
*/
public void testNullKeysAndValues()
throws Exception {
loader.put(FQN, null, "x");
addDelay();
assertEquals("x", loader.get(FQN).get(null));
Map map = loader.get(FQN);
assertEquals(1, map.size());
assertEquals("x", map.get(null));
loader.put(FQN, "y", null);
addDelay();
assertEquals(null, loader.get(FQN).get("y"));
map = loader.get(FQN);
assertEquals(2, map.size());
assertEquals("x", map.get(null));
assertEquals(null, map.get("y"));
loader.remove(FQN, null);
addDelay();
assertEquals(null, loader.get(FQN).get(null));
assertEquals(1, loader.get(FQN).size());
loader.remove(FQN, "y");
addDelay();
assertNotNull(loader.get(FQN));
assertNull(loader.get(FQN).get("y"));
assertEquals(0, loader.get(FQN).size());
map = new HashMap();
map.put(null, null);
loader.put(FQN, map);
addDelay();
assertEquals(map, loader.get(FQN));
loader.remove(FQN);
addDelay();
assertNull(loader.get(FQN));
map = new HashMap();
map.put("xyz", null);
map.put(null, "abc");
loader.put(FQN, map);
addDelay();
assertEquals(map, loader.get(FQN));
loader.remove(FQN);
addDelay();
assertNull(loader.get(FQN));
}
/**
* Test non-default database name.
*/
public void testDatabaseNamePassivation()
throws Exception {
loader.put(FQN, "one", "two");
addDelay();
assertEquals("two", loader.get(FQN).get("one"));
}
/**
* Test load/store state.
*/
public void testLoadAndStore()
throws Exception {
/* Empty state. */
loader.remove(Fqn.fromString("/"));
// assertEquals(0, loader.loadEntireState().length);
// loader.storeEntireState(new byte[0]);
// assertEquals(0, loader.loadEntireState().length);
// loader.storeEntireState(null);
// assertEquals(0, loader.loadEntireState().length);
// assertEquals(null, loader.get(FQN));
/* Use a complex object to ensure that the class catalog is used. */
Complex c1 = new Complex();
Complex c2 = new Complex(c1);
/* Add objects. */
loader.put(FQN, new Integer(1), c1);
loader.put(FQN, new Integer(2), c2);
addDelay();
assertEquals(c1, loader.get(FQN).get(new Integer(1)));
assertEquals(c2, loader.get(FQN).get(new Integer(2)));
assertEquals(2, loader.get(FQN).size());
/* Save state. */
byte[] state = loader.loadEntireState();
assertTrue(state.length > 0);
/* Restore state. */
loader.storeEntireState(state);
addDelay();
assertEquals(c1, loader.get(FQN).get(new Integer(1)));
assertEquals(c2, loader.get(FQN).get(new Integer(2)));
assertEquals(2, loader.get(FQN).size());
}
/**
* Complex object whose class description is stored in the class catalog.
*/
private static class Complex implements Serializable {
Complex nested;
Complex() {
this(null);
}
Complex(Complex nested) {
this.nested = nested;
}
public boolean equals(Object o) {
try {
Complex x = (Complex) o;
return (nested != null) ? nested.equals(x.nested)
: (x.nested == null);
} catch (ClassCastException e) {
return false;
}
}
public int hashCode() {
if(nested == null)
return super.hashCode();
else
return 13 + nested.hashCode();
}
}
public static Test suite() {
return new TestSuite(PassivationTestsBase.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
}