/*****************************************
* *
* JBoss Portal: The OpenSource Portal *
* *
* Distributable under LGPL license. *
* See terms of license at gnu.org. *
* *
*****************************************/
package org.jboss.cache.aop;
import junit.framework.TestCase;
import org.jboss.cache.aop.PojoCache;
import org.jboss.cache.lock.IsolationLevel;
import org.jboss.cache.TreeCache;
import org.jboss.cache.DummyTransactionManagerLookup;
import org.jboss.cache.AbstractTreeCacheListener;
import org.jboss.cache.Fqn;
import org.jgroups.View;
import javax.transaction.TransactionManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Collections;
import java.util.Map;
/**
* @author Nitzan Niv
* @version
*/
public class PojoCacheListenerTest extends TestCase
{
protected boolean optLocking = false;
public PojoCacheListenerTest(String s)
{
super(s);
}
private PojoCache cache;
protected void setUp() throws Exception
{
super.setUp();
cache = new PojoCache();
cache.setCacheMode(TreeCache.LOCAL);
cache.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
if (optLocking) cache.setNodeLockingScheme("OPTIMISTIC");
cache.setTransactionManagerLookup(new DummyTransactionManagerLookup());
cache.create();
cache.start();
}
protected void tearDown() throws Exception
{
super.tearDown();
cache.stop();
cache.destroy();
}
public void testRemovePropertyWithCommit() throws Exception
{
cache.putObject("/name", "value");
EventLog el = new EventLog();
cache.addTreeCacheListener(el);
TransactionManager tm = cache.getTransactionManager();
tm.begin();
cache.removeObject("/name");
tm.commit();
System.out.println("testRemovePropertyWithCommit:\n" + el.events);
assertEquals(Arrays.asList(new Object[]{
"modify about to modify local /name",
"modified /name",
"modify Modified local /name",
"remove about to remove local /name",
"removed /name",
"remove Removed local /name"}),
el.events);
el.events.clear();
}
public void testNodeCreatedAndModifiedEvent() throws Exception
{
EventLog el = new EventLog(cache);
cache.addTreeCacheListener(el);
cache.putObject("/hello/world", "y");
System.out.println("testNodeCreatedAndModifiedEvent:\n" + el.events);
List expectedChanges = new ArrayList();
expectedChanges.add("created /hello");
expectedChanges.add("created /hello/world");
//TODO: (optLocking)
// all creations are fired as mods since these reflect as modified nodes in the workspace. Opt locking only.
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
assertEquals(expectedChanges, el.events);
el.events.clear();
}
/**
* Not a really good test to debug. No need for it now.
* @throws Exception
*/
public void XtestNodeCreatedAndRemovedMapEvent() throws Exception
{
EventLog el = new EventLog(cache);
cache.addTreeCacheListener(el);
Map data = new HashMap();
data.put("key", "value");
cache.putObject("/hello/world", data);
cache.removeObject("/hello/world");
System.out.println("testNodeCreatedAndModifiedMapEvent:\n" + el.events);
List expectedChanges = new ArrayList();
expectedChanges.add("created /hello");
expectedChanges.add("created /hello/world");
//TODO: (optLocking)
// all creations are fired as mods since these reflect as modified nodes in the workspace. Opt locking only.
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
expectedChanges.add("created /hello/world/key");
expectedChanges.add("modify about to modify local /hello/world/key");
expectedChanges.add("modified /hello/world/key");
expectedChanges.add("modify Modified local /hello/world/key");
expectedChanges.add("modify about to modify local /hello/world/key");
expectedChanges.add("modified /hello/world/key");
expectedChanges.add("modify Modified local /hello/world/key");
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
expectedChanges.add("remove about to remove local /hello/world");
expectedChanges.add("removed /hello/world");
expectedChanges.add("remove Removed local /hello/world");
assertEquals(expectedChanges.size(), el.events.size());
assertEquals(expectedChanges, el.events);
el.events.clear();
}
/**
* Not a really good test to debug. No need for it now.
* @throws Exception
*/
public void XtestNodeCreatedAndRemovedListEvent() throws Exception
{
EventLog el = new EventLog(cache);
cache.addTreeCacheListener(el);
List data = new ArrayList();
data.add("value");
cache.putObject("/hello/world", data);
cache.removeObject("/hello/world");
System.out.println("testNodeCreatedAndRemovedListEvent:\n" + el.events);
List expectedChanges = new ArrayList();
expectedChanges.add("created /hello");
expectedChanges.add("created /hello/world");
//TODO: (optLocking)
// all creations are fired as mods since these reflect as modified nodes in the workspace. Opt locking only.
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
expectedChanges.add("created /hello/world/0");
expectedChanges.add("modify about to modify local /hello/world/0");
expectedChanges.add("modified /hello/world/0");
expectedChanges.add("modify Modified local /hello/world/0");
expectedChanges.add("modify about to modify local /hello/world/0");
expectedChanges.add("modified /hello/world/0");
expectedChanges.add("modify Modified local /hello/world/0");
expectedChanges.add("modify about to modify local /hello/world");
expectedChanges.add("modified /hello/world");
expectedChanges.add("modify Modified local /hello/world");
expectedChanges.add("remove about to remove local /hello/world");
expectedChanges.add("removed /hello/world");
expectedChanges.add("remove Removed local /hello/world");
// assertEquals(expectedChanges.size(), el.events.size());
assertEquals(expectedChanges, el.events);
el.events.clear();
}
public void testRemoveNodeWithRollback() throws Exception
{
cache.putObject("/child", new HashMap());
EventLog el = new EventLog();
cache.addTreeCacheListener(el);
TransactionManager tm = cache.getTransactionManager();
tm.begin();
cache.removeObject("/child");
tm.rollback();
System.out.println("testRemoveNodeWithRollback:\n" + el.events);
if (optLocking)
{
// in opt locking, a rollback will result in nothing having changed in the cache and hence
// no notifications will fire.
assertEquals(Collections.EMPTY_LIST, el.events);
}
else
{
// with pess locking, a rollback consists of modifications + equal and opposite modifications.
assertEquals(Arrays.asList(new Object[]{
"modify about to modify local /child",
"modified /child",
"modify Modified local /child",
"remove about to remove local /child",
"removed /child",
"remove Removed local /child",
"created /child",
"modify about to modify local /child",
"modified /child",
"modify Modified local /child"}),
el.events);
}
el.events.clear();
}
public static class EventLog extends AbstractTreeCacheListener
{
private PojoCache cache;
public EventLog() { };
public EventLog(PojoCache cache) { this.cache = cache; };
public final List events = new ArrayList();
public void nodeCreated(Fqn fqn)
{
events.add("created " + fqn);
}
public void nodeRemove(Fqn fqn, boolean pre, boolean isLocal)
{
events.add("remove "+
(pre? "about to remove " : "Removed ") +
(isLocal? "local " : "remote ") + fqn);
}
public void nodeRemoved(Fqn fqn)
{
events.add("removed " + fqn);
}
public void nodeLoaded(Fqn fqn)
{
throw new UnsupportedOperationException();
}
public void nodeEvicted(Fqn fqn)
{
throw new UnsupportedOperationException();
}
public void nodeModify(Fqn fqn, boolean pre, boolean isLocal)
{
events.add("modify "+
(pre? "about to modify " : "Modified ") +
(isLocal? "local " : "remote ") + fqn);
if(this.cache != null && !pre) {
try
{
cache.getObject(fqn);
}
catch (Exception e)
{
events.add(fqn + ":" + e);
System.err.println("exception on fqn " + fqn);
e.printStackTrace(System.err);
}
}
}
public void nodeModified(Fqn fqn)
{
events.add("modified " + fqn);
}
public void nodeVisited(Fqn fqn)
{
throw new UnsupportedOperationException();
}
public void cacheStarted(TreeCache treeCache)
{
throw new UnsupportedOperationException();
}
public void cacheStopped(TreeCache treeCache)
{
throw new UnsupportedOperationException();
}
public void viewChange(View view)
{
throw new UnsupportedOperationException();
}
}
}