package org.jboss.cache.eviction;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
import org.jboss.cache.CacheException;
import org.jboss.cache.DummyTransactionManagerLookup;
import org.jboss.cache.Fqn;
import org.jboss.cache.PropertyConfigurator;
import org.jboss.cache.TreeCache;
import org.jboss.cache.interceptors.EvictionInterceptor;
import org.jboss.cache.misc.TestingUtil;
import javax.transaction.TransactionManager;
import java.util.List;
import java.util.Iterator;
/**
* Tests the eviction and the possible lack of locking nodes.
* The configuration is with an aggressive eviction policy, 100 objects 2 seconds interval.
* <p/>
* It is possible that the number needs to be changed a little, depending on the machine speed.
*
* @author fhenning
*/
public class OptimisticEvictionTest extends TestCase
{
//Maximum number of runs 2^20
private static final int NUMBER_OF_RUNS = (1 << 20);
//Initial number of nodes
private static final int NUMBER_NODES = 256;
private Fqn region = Fqn.fromString("testingRegion");
private TransactionManager txManager;
private TreeCache cache;
protected void setUp() throws Exception
{
super.setUp();
txManager = new DummyTransactionManagerLookup().getTransactionManager();
cache = new TreeCache();
PropertyConfigurator config = new PropertyConfigurator();
config.configure(this.cache, "META-INF/optimistic-eviction.xml");
cache.startService();
}
protected void tearDown() throws Exception
{
if (cache != null)
{
cache.stopService();
cache = null;
}
super.tearDown();
}
public void testEvictionError() throws CacheException
{
//Initialize the cache via a map
for (int i = 0; i < NUMBER_NODES; i++)
{
cache.put(new Fqn(region, new Integer(i)), new Integer(i), new Integer(i));
}
for (int i = 0; i < NUMBER_OF_RUNS; i++)
{
try
{
txManager.begin();
cache.get(region, new Integer(i % NUMBER_NODES));
txManager.commit();
}
catch (Exception e)
{
fail("Exception caught after run: " + i + ". Cause was " + e.getCause());
}
}
}
public void testEvictionOccurence() throws Exception
{
cache.put("/timeBased/test", "key", "value");
assertTrue(cache.exists("/timeBased/test"));
// wait for it to be evicted.
TestingUtil.sleepThread(3000);
assertTrue(!cache.exists("/timeBased/test"));
}
public void testMultEvictionOccurences() throws Exception
{
for (int i=0; i<50; i++)
{
cache.put("/testingRegion/test/" + i, "key", "value");
}
// allow some time for the eviction thread to finish it's work
TestingUtil.sleepThread(1000);
assertEquals(12, cache.getNumberOfNodes()); // root + base + num nodes in region
}
public void testInterceptorChain() throws Exception
{
List interceptors = cache.getInterceptors();
System.out.println(interceptors);
Iterator i = interceptors.iterator();
boolean found = false;
while (i.hasNext())
{
Object o = i.next();
if (o instanceof EvictionInterceptor)
{
found = true;
}
}
assertTrue("Eviction interceptor should be in interceptor chain.", found);
}
public void testCompleteRemoval() throws Exception
{
String rootStr = "/timeBased/";
// Add a parent, then a child. LRU will evict the parent,
// then the child, leaving behind an empty parent
Fqn parent = Fqn.fromString(rootStr + "parent");
cache.put(parent, "key", "value");
cache.put(new Fqn(parent, "child"), "key", "value");
// Give eviction time to run a few times, then confirm parent
// is completely gone
TestingUtil.sleepThread(5500);
assertFalse("Parent completely removed", cache.exists(parent));
}
public static void main(String[] args)
{
TestRunner.run(new TestSuite(OptimisticEvictionTest.class));
}
}