/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.cache.eviction;
import org.jboss.cache.Cache;
import org.jboss.cache.CacheFactory;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
import org.jboss.cache.config.*;
import org.jboss.cache.misc.TestingUtil;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.fail;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.Properties;
import java.util.List;
import java.util.ArrayList;
import java.io.IOException;
/**
* Tests cache behavior in the presence of concurrent passivation.
*
* @author Brian Stansberry
* @version $Revision: 5238 $
*/
@Test(groups = {"functional"})
public class ConcurrentEvictionTest
{
private Cache<Integer, String> cache_;
private int wakeupIntervalMillis_ = 0;
private String tmpDir = System.getProperty("java.io.tmpdir", "/tmp");
private String cacheLoaderDir = "/JBossCacheFileCacheLoader";
@BeforeMethod(alwaysRun = true)
public void setUp() throws Exception
{
initCaches();
wakeupIntervalMillis_ = cache_.getConfiguration().getEvictionConfig().getWakeupIntervalSeconds() * 1000;
if (wakeupIntervalMillis_ < 0)
{
fail("testEviction(): eviction thread wake up interval is illegal " + wakeupIntervalMillis_);
}
}
void initCaches() throws Exception
{
TestingUtil.recursiveFileRemove(tmpDir + cacheLoaderDir);
CacheFactory<Integer, String> factory = new DefaultCacheFactory();
Configuration conf = UnitTestCacheConfigurationFactory.createConfiguration(Configuration.CacheMode.LOCAL, true);
conf.setEvictionConfig(buildEvictionConfig());
conf.setCacheLoaderConfig(buildCacheLoaderConfig());
conf.setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
cache_ = factory.createCache(conf, true);// read in generic local xml
}
private CacheLoaderConfig buildCacheLoaderConfig()
throws IOException
{
CacheLoaderConfig cacheLoaderConfig = new CacheLoaderConfig();
cacheLoaderConfig.setPassivation(false);
cacheLoaderConfig.setPreload("/");
cacheLoaderConfig.setShared(false);
CacheLoaderConfig.IndividualCacheLoaderConfig iclc = new CacheLoaderConfig.IndividualCacheLoaderConfig();
iclc.setClassName("org.jboss.cache.loader.FileCacheLoader");
Properties p = new Properties();
p.put("location", tmpDir + cacheLoaderDir);
iclc.setProperties(p);
iclc.setAsync(false);
iclc.setFetchPersistentState(true);
iclc.setIgnoreModifications(false);
cacheLoaderConfig.addIndividualCacheLoaderConfig(iclc);
return cacheLoaderConfig;
}
private EvictionConfig buildEvictionConfig()
{
EvictionConfig ec = new EvictionConfig("org.jboss.cache.eviction.LRUPolicy");
ec.setDefaultEvictionPolicyClass("org.jboss.cache.eviction.LRUPolicy");
ec.setWakeupIntervalSeconds(5);
EvictionRegionConfig erc = UnitTestCacheConfigurationFactory.buildLruEvictionRegionConfig("_default_", 5000, 1000);
List<EvictionRegionConfig> erConfigs = new ArrayList<EvictionRegionConfig>();
erConfigs.add(erc);
ec.setEvictionRegionConfigs(erConfigs);
return ec;
}
@AfterMethod(alwaysRun = true)
public void tearDown() throws Exception
{
TestingUtil.recursiveFileRemove(tmpDir + cacheLoaderDir);
cache_.stop();
cache_ = null;
}
public void testConcurrentEviction() throws Exception
{
Fqn<String> base = Fqn.fromString("/org/jboss/test/data/concurrent/eviction");
// Create a bunch of nodes; more than the /org/jboss/test/data
// region's maxNodes so we know eviction will kick in
for (int i = 0; i < 1000; i++)
{
cache_.put(new Fqn<Object>(base, i / 100), i, "value");
}
// Loop for long enough to have 5 runs of the eviction thread
long loopDone = System.currentTimeMillis() + (5 * wakeupIntervalMillis_);
while (System.currentTimeMillis() < loopDone)
{
// If any get returns null, that's a failure
for (int i = 0; i < 1000; i++)
{
Fqn<Object> fqn = new Fqn<Object>(base, i / 100);
Integer key = i;
assertNotNull("found value under Fqn " + fqn + " and key " + key,
cache_.get(fqn, key));
}
}
}
}