package org.jboss.cache.aop;
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.aop.PojoCache;
import org.jboss.cache.aop.test.Address;
import org.jboss.cache.aop.test.Person;
import org.jboss.cache.aop.test.Link;
import org.jboss.cache.aop.test.NodeManager;
import org.jboss.cache.PropertyConfigurator;
import org.jboss.cache.DataNode;
import java.util.*;
/**
* Test object graph handling in aop, e.g., circular reference, multiple reference, link, etc.
* @author Ben Wang
*/
public class ObjectGraphAopTest extends TestCase
{
Log log=LogFactory.getLog(ObjectGraphAopTest.class);
PojoCache cache_;
public ObjectGraphAopTest(String name)
{
super(name);
}
protected void setUp() throws Exception
{
super.setUp();
log.info("setUp() ....");
// String configFile = "META-INF/local-service.xml";
String configFile = "META-INF/local-service.xml";
cache_ = new PojoCache();
PropertyConfigurator config = new PropertyConfigurator();
config.configure(cache_, configFile); // read in generic replSync xml
cache_.start();
}
protected void tearDown() throws Exception
{
super.tearDown();
cache_.stop();
}
// public void testDummy() {}
protected Person createPerson(String name, int age)
{
Person p = new Person();
p.setName(name);
p.setAge(age);
return p;
}
/**
* Test shared sub-object. In diagram, it is a forest
* where the sub-object is connected by two tree parents.
*/
public void testMultipleReference() throws Exception
{
log.info("testMultipleReference() ...");
cache_.putObject("/person/joe", createPerson("Joe Black", 31));
Person joe = (Person) cache_.getObject("/person/joe");
cache_.putObject("/person/ben", createPerson("Ben Hogan", 51));
Person ben = (Person) cache_.getObject("/person/ben");
Address addr = new Address();
addr.setStreet("123 Albert Ave.");
addr.setCity("Sunnyvale");
addr.setZip(94087);
// They share the sub-object: address
log.info("testMultipleReference(): set Joe address");
joe.setAddress(addr);
log.info("testMultipleReference(): set Ben address");
ben.setAddress(addr);
log.info("testMultipleReference(): verify");
Address add1 = (Address) ((Person)cache_.getObject("/person/joe")).getAddress();
Address add2 = (Address) ((Person)cache_.getObject("/person/ben")).getAddress();
assertEquals(add1.getCity(), add2.getCity());
addr.setCity("Santa Clara");
assertEquals(add1.getCity(), add2.getCity());
}
public void testRefCount() throws Exception
{
// try {Thread.sleep(10000); } catch (Exception e) {};
log.info("testRefCount() ...");
stage1();
stage2();
cache_.removeObject("/person/ben");
}
private void stage1() throws Exception
{
Person joe = createPerson("Joe Black", 31);
Person ben = createPerson("Ben Hogan", 51);
cache_.putObject("/person/joe", joe);
cache_.putObject("/person/ben", ben);
Address addr = new Address();
addr.setStreet("123 Albert Ave.");
addr.setCity("Sunnyvale");
addr.setZip(94087);
joe.setAddress(addr);
ben.setAddress(addr);
// They share the sub-object: address
Address add1 = (Address) ((Person)cache_.getObject("/person/joe")).getAddress();
Address add2 = (Address) ((Person)cache_.getObject("/person/ben")).getAddress();
assertEquals("Joe's address should still be valid ", "Sunnyvale", add1.getCity());
assertEquals("Ben's address should still be valid ", "Sunnyvale", add2.getCity());
}
private void stage2() throws Exception
{
//
cache_.removeObject("/person/joe");
Person ben = (Person) cache_.getObject("/person/ben");
Address addr = ben.getAddress();
assertEquals("Ben's address should still be valid ", "Sunnyvale", addr.getCity());
addr.setCity("Santa Clara");
assertEquals("Ben's address should be changed ", "Santa Clara", addr.getCity());
}
/**
* Pure parent child relationsip
* @throws Exception
*/
public void testCircularReference() throws Exception
{
// try {Thread.sleep(10000); } catch (Exception e) {};
log.info("testCircularReference() ...");
Link parent = new Link("parent");
Link child = new Link("child");
parent.setLink(child);
child.setLink(parent);
cache_.putObject("/link/parent", parent);
assertEquals("parent", ((Link) cache_.getObject("/link/parent")).getName());
assertEquals("child", ((Link) cache_.getObject("/link/parent")).getLink().getName());
// Would fail if uncoment becuase of internal mapping is non-canonical.
// child.setLink(parent);
parent.setLink(child);
}
/**
* Pure parent child relationsip
* @throws Exception
*/
public void testCircularReference1() throws Exception
{
// try {Thread.sleep(10000); } catch (Exception e) {};
log.info("testCircularReference1() ...");
Link parent = new Link("parent");
Link child = new Link("child");
parent.setLink(child);
child.setLink(parent);
cache_.putObject("/link/parent", parent);
assertEquals("parent", ((Link) cache_.getObject("/link/parent")).getName());
assertEquals("child", ((Link) cache_.getObject("/link/parent")).getLink().getName());
Link link = (Link)cache_.removeObject("/link/parent");
assertEquals("child", link.getLink().getName());
assertNull("Cache should be null ", ((DataNode)cache_.get("/parent")));
}
/**
* cache managed first before put in the relationsip.
* @throws Exception
*/
public void testCircularReference2() throws Exception
{
// try {Thread.sleep(10000); } catch (Exception e) {};
log.info("testCircularReference2() ...");
Link parent = new Link("parent");
Link child = new Link("child");
cache_.putObject("/link/parent", parent);
parent.setLink(child);
child.setLink(parent);
assertEquals("parent", ((Link) cache_.getObject("/link/parent")).getName());
assertEquals("child", ((Link) cache_.getObject("/link/parent")).getLink().getName());
Link link = (Link)cache_.removeObject("/link/parent");
assertEquals("child", link.getLink().getName());
assertNull("Cache should be null ", ((DataNode)cache_.get("/parent")));
}
/**
* Put first before settting the relationship
* @throws Exception
*/
public void testCircularReference3() throws Exception
{
// try {Thread.sleep(10000); } catch (Exception e) {};
log.info("testCircularReference3() ...");
Link parent = new Link("parent");
Link child = new Link("child");
cache_.putObject("/link/parent", parent);
cache_.putObject("/link/child", child);
parent.setLink(child);
child.setLink(parent);
assertEquals("parent", ((Link) cache_.getObject("/link/parent")).getName());
assertEquals("child", ((Link) cache_.getObject("/link/parent")).getLink().getName());
assertEquals("child", ((Link) cache_.getObject("/link/child")).getName());
assertEquals("parent", ((Link) cache_.getObject("/link/child")).getLink().getName());
Link link = (Link)cache_.removeObject("/link/parent");
assertEquals("child", link.getLink().getName());
assertNull("Cache should be null ", ((DataNode)cache_.get("/parent")));
}
/**
* Setting the circular relationship and also as a shared object.
* @throws Exception
*/
public void testCircularReference4() throws Exception
{
// try {Thread.sleep(10000); } catch (Exception e) {};
log.info("testCircularReference3() ...");
Link parent = new Link("parent");
Link child = new Link("child");
parent.setLink(child);
child.setLink(parent);
List list = new ArrayList();
list.add(parent);
cache_.putObject("/list", list);
cache_.putObject("/alias", list);
List list1 = (List)cache_.getObject("/list");
List list2 = (List)cache_.getObject("/alias");
assertEquals("parent", ((Link) list1.get(0)).getName());
assertEquals("child", ((Link) list2.get(0)).getLink().getName());
}
public void testCircularAndSharedReferences() throws Exception
{
log.info("testCircularAndSharedReferences() ...");
NodeManager pm_ = new NodeManager();
pm_.setRootNode("root");
pm_.addNode("root", "kanto");
pm_.addNode("root.kanto", "tokyo");
pm_.addNode("root.kanto", "kanagawa");
assertEquals("kanagawa", pm_.findNode("root.kanto.kanagawa").getNodeRDN());
cache_.putObject("/propagation", pm_);
pm_.addNode("root.kanto.tokyo", "hadanshita");
assertEquals("hadanshita", pm_.findNode("root.kanto.tokyo.hadanshita").getNodeRDN());
List list = pm_.findNode("root").getChildren();
assertEquals("Root should have children of ", 1, list.size());
/*
System.out.println("\n\n");
System.out.println("---------------------------------------------");
System.out.println("Initial cache content");
System.out.println(cache_.printDetails());
System.out.println("---------------------------------------------");
System.out.println("\n\n");
System.out.println("---------------------------------------------");
System.out.println("Initial pm state");
System.out.println("---------------------------------------------");
*/
pm_.printNodes();
}
public void testRemoveObject1() throws Exception
{
log.info("testRemoveObject1() ...");
cache_.putObject("/person/joe", createPerson("Joe Black", 31));
Person joe = (Person) cache_.getObject("/person/joe");
cache_.putObject("/person/ben", createPerson("Ben Hogan", 51));
Person ben = (Person) cache_.getObject("/person/ben");
Address addr = new Address();
addr.setStreet("123 Albert Ave.");
addr.setCity("Sunnyvale");
addr.setZip(94087);
// They share the sub-object: address
log.info("testMultipleReference(): set Joe address");
joe.setAddress(addr);
log.info("testMultipleReference(): set Ben address");
ben.setAddress(addr);
Address add1 = (Address) ((Person)cache_.getObject("/person/joe")).getAddress();
Address add2 = (Address) ((Person)cache_.getObject("/person/ben")).getAddress();
assertEquals(add1.getCity(), add2.getCity());
addr.setCity("Santa Clara");
assertEquals(add1.getCity(), add2.getCity());
// Remove pojo joe will relocate the address field to ben's
cache_.removeObject("/person/joe");
add2 = (Address) ((Person)cache_.getObject("/person/ben")).getAddress();
assertEquals("City ", "Santa Clara", add2.getCity());
}
public void testRemoveObject2() throws Exception
{
log.info("testRemoveObject2() ...");
cache_.putObject("/person/joe", createPerson("Joe Black", 31));
Person joe = (Person) cache_.getObject("/person/joe");
cache_.putObject("/person/ben", createPerson("Ben Hogan", 51));
Person ben = (Person) cache_.getObject("/person/ben");
cache_.putObject("/person/john", createPerson("John Daly", 41));
Person john = (Person) cache_.getObject("/person/john");
Address addr = new Address();
addr.setStreet("123 Albert Ave.");
addr.setCity("Sunnyvale");
addr.setZip(94087);
Address addr1 = new Address();
addr1.setStreet("123 Albert Ave.");
addr1.setCity("San Jose");
addr1.setZip(94087);
// They share the sub-object: address
log.info("testMultipleReference(): set Joe address");
joe.setAddress(addr);
log.info("testMultipleReference(): set Ben address");
ben.setAddress(addr);
log.info("testMultipleReference(): set John address");
john.setAddress(addr);
Address add1 = (Address) ((Person)cache_.getObject("/person/joe")).getAddress();
Address add2 = (Address) ((Person)cache_.getObject("/person/ben")).getAddress();
assertEquals(add1.getCity(), add2.getCity());
addr.setCity("Santa Clara");
assertEquals(add1.getCity(), add2.getCity());
// Remove pojo joe will relocate the address field to ben's
joe.setAddress(addr1);
add2 = (Address) ((Person)cache_.getObject("/person/joe")).getAddress();
assertEquals("City ", "San Jose", add2.getCity());
add2 = (Address) ((Person)cache_.getObject("/person/ben")).getAddress();
assertEquals("City ", "Santa Clara", add2.getCity());
add2 = (Address) ((Person)cache_.getObject("/person/john")).getAddress();
assertEquals("City ", "Santa Clara", add2.getCity());
}
public void XtestObjectIdentity() throws Exception
{
}
public static Test suite() throws Exception
{
return new TestSuite(ObjectGraphAopTest.class);
}
public static void main(String[] args) throws Exception
{
junit.textui.TestRunner.run(suite());
}
}