package org.jboss.cache.mgmt;
import java.util.HashMap;
import java.util.List;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCache;
import org.jboss.cache.interceptors.ActivationInterceptor;
import org.jboss.cache.interceptors.PassivationInterceptor;
import org.jboss.cache.loader.CacheLoader;
import org.jboss.cache.xml.XmlHelper;
import org.w3c.dom.Element;
/**
* Simple functional tests for ActivationInterceptor and PassivationInterceptor statistics
* @author Jerry Gauthier
* @version $Id: PassivationTest.java 1512 2006-04-07 05:15:03Z genman $
*/
public class PassivationTest extends TestCase
{
private static final String CAPITAL = "capital";
private static final String CURRENCY = "currency";
private static final String POPULATION = "population";
private static final String AREA = "area";
private static final String EUROPE_NODE = "Europe";
TreeCache cache = null;
protected void setUp() throws Exception
{
super.setUp();
cache = createCache();
}
protected void tearDown() throws Exception
{
super.tearDown();
if(cache != null)
{
CacheLoader cl = cache.getCacheLoader();
cl.remove(Fqn.fromString(EUROPE_NODE));
cache.stopService();
cache.destroyService();
cache = null;
}
}
public void testPassivationMgmt() throws Exception
{
assertNotNull("Cache is null.", cache);
// note -it's essential to flush any existing test data from the cache loader
// otherwise the loads and misses counts will be incorrect
CacheLoader cl = cache.getCacheLoader();
assertNotNull("CacheLoader is null.", cl);
cl.remove(Fqn.fromString(EUROPE_NODE));
// populate cache with test data
loadCache(cache);
// Note: because these tests are normally executed without a server, the interceptor
// MBeans are usually not available for use in the tests. Consequently it's necessary
// to obtain references to the interceptors and work with them directly.
ActivationInterceptor act = getActivationInterceptor(cache);
assertNotNull("ActivationInterceptor not found.", act);
PassivationInterceptor pass = getPassivationInterceptor(cache);
assertNotNull("PassivationInterceptor not found.", pass);
System.out.println("count of misses " + act.getCacheLoaderMisses());
int miss = 2;
// was 5 in 1.3 (one per attribute)
// now just Europe/Albania and Europe/Hungary were loaded
// verify statistics for entries loaded into cache
assertEquals("CacheLoaderLoads count error: ", new Long(0), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(0), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(0), new Long(pass.getPassivations()));
// now try retrieving a valid attribute and an invalid attribute
Fqn key = Fqn.fromString("Europe/Austria");
assertNotNull("Retrieval error: expected to retrieve " + CAPITAL + " for " + key, cache.get(key, CAPITAL));
assertNull("Retrieval error: did not expect to retrieve " + AREA + " for " + key, cache.get(key, AREA));
// verify statistics after retrieving entries - no change since nodes were already loaded
assertEquals("CacheLoaderLoads count error: ", new Long(0), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(0), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(0), new Long(pass.getPassivations()));
// now try retrieving an attribute for an invalid node
key = Fqn.fromString("Europe/Poland");
assertNull("Retrieval error: did not expect to retrieve " + CAPITAL + " for " + key, cache.get(key, CAPITAL));
// verify statistics after retrieving invalid node - misses should now be incremented
miss++;
assertEquals("CacheLoaderLoads count error: ", new Long(0), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(0), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(0), new Long(pass.getPassivations()));
// now evict Austria and confirm that it's no longer in cache
key = Fqn.fromString("Europe/Austria");
cache.evict(key);
assertFalse("Retrieval error: did not expect to find node " + key + " in cache", cache.exists(key));
// passivations should noe be 1
assertEquals("Passivations count error: ", new Long(1), new Long(pass.getPassivations()));
// now try retrieving the attributes again - first retrieval should trigger a cache load
assertNotNull("Retrieval error: expected to retrieve " + CAPITAL + " for " + key, cache.get(key, CAPITAL));
assertNotNull("Retrieval error: expected to retrieve " + CURRENCY + " for " + key, cache.get(key, CURRENCY));
// verify statistics after retrieving evicted entry - loads and activations should now be 1
assertEquals("CacheLoaderLoads count error: ", new Long(1), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(1), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(1), new Long(pass.getPassivations()));
// now remove Austria and confirm that it's not in cache or loader
cache.remove(key);
assertFalse("Retrieval error: did not expect to find node " + key + " in cache", cache.exists(key));
assertFalse("Retrieval error: did not expect to find node " + key + " in loader", cl.exists(key));
// verify statistics after removing entry - should be unchanged
assertEquals("CacheLoaderLoads count error: ", new Long(1), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(1), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(1), new Long(pass.getPassivations()));
// now try retrieving attributes again - each attempt should fail and cause a miss since node is now removed
assertNull("Retrieval error: did not expect to retrieve " + CAPITAL + " for " + key, cache.get(key, CAPITAL));
assertNull("Retrieval error: did not expect to retrieve " + CURRENCY + " for " + key, cache.get(key, CURRENCY));
// verify statistics after trying to retrieve removed node's attributes - should be two more misses
miss += 2;
assertEquals("CacheLoaderLoads count error: ", new Long(1), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(1), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(1), new Long(pass.getPassivations()));
// add a new node and two attributes - this should cause a miss only
miss++;
cache.put("Europe/Poland", new HashMap());
cache.put("Europe/Poland", CAPITAL, "Warsaw");
cache.put("Europe/Poland", CURRENCY, "Zloty");
assertEquals("CacheLoaderLoads count error: ", new Long(1), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(1), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(1), new Long(pass.getPassivations()));
// evict Poland - this will cause a passivation
key = Fqn.fromString("Europe/Poland");
cache.evict(key);
assertEquals("CacheLoaderLoads count error: ", new Long(1), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(1), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(2), new Long(pass.getPassivations()));
// retrieve a valid attribute - this will cause an activation and a load
assertNotNull("Retrieval error: expected to retrieve " + CURRENCY + " for " + key, cache.get(key, CURRENCY));
assertEquals("CacheLoaderLoads count error: ", new Long(2), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(2), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(2), new Long(pass.getPassivations()));
// evict again - causing another passivation
cache.evict(key);
assertEquals("CacheLoaderLoads count error: ", new Long(2), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(2), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(3), new Long(pass.getPassivations()));
// retrieve an invalid attribute - this will cause an activation and a load
assertNull("Retrieval error: did not expect to retrieve " + AREA + " for " + key, cache.get(key, AREA));
assertEquals("CacheLoaderLoads count error: ", new Long(3), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error: ", new Long(miss), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(3), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(3), new Long(pass.getPassivations()));
// reset statistics
act.resetStatistics();
pass.resetStatistics();
// check the statistics again
assertEquals("CacheLoaderLoads count error after reset: ", new Long(0), new Long(act.getCacheLoaderLoads()));
assertEquals("CacheLoaderMisses count error after reset: ", new Long(0), new Long(act.getCacheLoaderMisses()));
assertEquals("Activations count error: ", new Long(0), new Long(act.getActivations()));
assertEquals("Passivations count error: ", new Long(0), new Long(pass.getPassivations()));
}
private void loadCache(TreeCache cache) throws Exception
{
cache.put(EUROPE_NODE, new HashMap());
cache.put("Europe/Austria", new HashMap());
cache.put("Europe/Austria", CAPITAL, "Vienna");
cache.put("Europe/Austria", CURRENCY, "Euro");
cache.put("Europe/Austria", POPULATION, new Integer(8184691));
cache.put("Europe/England", new HashMap());
cache.put("Europe/England", CAPITAL, "London");
cache.put("Europe/England", CURRENCY, "British Pound");
cache.put("Europe/England", POPULATION, new Integer(60441457));
HashMap albania = new HashMap(4);
albania.put(CAPITAL, "Tirana");
albania.put(CURRENCY, "Lek");
albania.put(POPULATION, new Integer(3563112));
albania.put(AREA, new Integer(28748));
cache.put("Europe/Albania", albania);
HashMap hungary = new HashMap(4);
hungary.put(CAPITAL, "Budapest");
hungary.put(CURRENCY, "Forint");
hungary.put(POPULATION, new Integer(10006835));
hungary.put(AREA, new Integer(93030));
cache.put("Europe/Hungary", hungary);
}
private TreeCache createCache() throws Exception
{
TreeCache cache = new TreeCache();
cache.setCacheMode(TreeCache.LOCAL);
cache.setCacheLoaderConfiguration(getCacheLoaderConfig("location="+getTempDir()));
cache.setUseInterceptorMbeans(true);
cache.createService();
cache.startService();
return cache;
}
private ActivationInterceptor getActivationInterceptor(TreeCache cache)
{
List interceptors = cache.getInterceptors();
if (interceptors.isEmpty())
return null;
for (int i = 0; i < interceptors.size(); i++)
{
Object o = interceptors.get(i);
if (o instanceof ActivationInterceptor)
return (ActivationInterceptor)o;
}
return null;
}
private PassivationInterceptor getPassivationInterceptor(TreeCache cache)
{
List interceptors = cache.getInterceptors();
if (interceptors.isEmpty())
return null;
for (int i = 0; i < interceptors.size(); i++)
{
Object o = interceptors.get(i);
if (o instanceof PassivationInterceptor)
return (PassivationInterceptor)o;
}
return null;
}
private Element getCacheLoaderConfig(String properties) throws Exception
{
String xml = "<config>\n" +
"<passivation>true</passivation>\n" +
"<preload></preload>\n" +
"<shared>false</shared>\n" +
"<cacheloader>\n" +
"<class>org.jboss.cache.loader.FileCacheLoader</class>\n" +
"<properties>" + properties + "</properties>\n" +
"<async>false</async>\n" +
"<fetchPersistentState>false</fetchPersistentState>\n" +
"<ignoreModifications>false</ignoreModifications>\n" +
"</cacheloader>\n" +
"</config>";
return XmlHelper.stringToElement(xml);
}
private String getTempDir()
{
return System.getProperty("java.io.tempdir", "/tmp");
}
public static Test suite()
{
return new TestSuite(PassivationTest.class);
}
}