/*
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.cache.eviction;

import junit.framework.TestCase;
import org.jboss.cache.PropertyConfigurator;
import org.jboss.cache.TreeCache;
import org.jboss.cache.lock.IsolationLevel;

/**
 * Unit test to test Eviction configuration types.
 *
 * @author Daniel Huang (dhuang@jboss.org)
 * @version $Revision: 1.6 $
 */
public class EvictionConfigurationTest extends TestCase
{
   TreeCache cache;
   RegionManager regionManager;

   public void setUp() throws Exception
   {
      super.setUp();
   }

   public void tearDown() throws Exception
   {
      super.tearDown();
   }

   public void testPolicyPerRegion() throws Exception
   {
      this.setupCache("META-INF/policyPerRegion-eviction-service.xml");
      assertEquals(5, cache.getEvictionThreadWakeupIntervalSeconds());

      Region region = regionManager.getRegion("/org/jboss/data");
      EvictionPolicy policy = region.getEvictionPolicy();
      EvictionConfiguration configuration = region.getEvictionConfiguration();
      assertEquals("/org/jboss/data/", region.getFqn());
      assertTrue(policy instanceof LFUPolicy);
      assertTrue(configuration instanceof LFUConfiguration);
      assertEquals(5000, ((LFUConfiguration) configuration).getMaxNodes());
      assertEquals(1000, ((LFUConfiguration) configuration).getMinNodes());

      region = regionManager.getRegion("/org/jboss/test/data");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/org/jboss/test/data/", region.getFqn());
      assertTrue(policy instanceof FIFOPolicy);
      assertTrue(configuration instanceof FIFOConfiguration);
      assertEquals(5, ((FIFOConfiguration) configuration).getMaxNodes());

      region = regionManager.getRegion("/test");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/test/", region.getFqn());
      assertTrue(policy instanceof MRUPolicy);
      assertTrue(configuration instanceof MRUConfiguration);
      assertEquals(10000, ((MRUConfiguration) configuration).getMaxNodes());

      region = regionManager.getRegion("/maxAgeTest");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/maxAgeTest/", region.getFqn());
      assertTrue(policy instanceof LRUPolicy);
      assertTrue(configuration instanceof LRUConfiguration);
      assertEquals(10000, ((LRUConfiguration) configuration).getMaxNodes());
      assertEquals(8, ((LRUConfiguration) configuration).getTimeToLiveSeconds());
      assertEquals(10, ((LRUConfiguration) configuration).getMaxAgeSeconds());

      // test the default region. use a region name that isn't defined explicitly in conf file.
      region = regionManager.getRegion("/a/b/c");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/_default_/", region.getFqn());
      assertTrue(policy instanceof LRUPolicy);
      assertTrue(configuration instanceof LRUConfiguration);
      assertEquals(5000, ((LRUConfiguration) configuration).getMaxNodes());
      assertEquals(1000, ((LRUConfiguration) configuration).getTimeToLiveSeconds());
      assertEquals(0, ((LRUConfiguration) configuration).getMaxAgeSeconds());

      cache.stopService();
   }

   public void testMixedPolicies() throws Exception
   {
      this.setupCache("META-INF/mixedPolicy-eviction-service.xml");
      assertEquals(5, cache.getEvictionThreadWakeupIntervalSeconds());

      Region region = regionManager.getRegion("/org/jboss/data");
      EvictionPolicy policy = region.getEvictionPolicy();
      EvictionConfiguration configuration = region.getEvictionConfiguration();
      assertEquals("/org/jboss/data/", region.getFqn());
      assertTrue(policy instanceof FIFOPolicy);
      assertTrue(configuration instanceof FIFOConfiguration);
      assertEquals(5000, ((FIFOConfiguration) configuration).getMaxNodes());

      region = regionManager.getRegion("/test");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/test/", region.getFqn());
      assertTrue(policy instanceof MRUPolicy);
      assertTrue(configuration instanceof MRUConfiguration);
      assertEquals(10000, ((MRUConfiguration) configuration).getMaxNodes());

      // test the default region. use a region name that isn't defined explicitly in conf file.
      region = regionManager.getRegion("/a/b/c");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/_default_/", region.getFqn());
      assertTrue(policy instanceof LRUPolicy);
      assertTrue(configuration instanceof LRUConfiguration);
      assertEquals(5000, ((LRUConfiguration) configuration).getMaxNodes());
      assertEquals(1000, ((LRUConfiguration) configuration).getTimeToLiveSeconds());
      assertEquals(0, ((LRUConfiguration) configuration).getMaxAgeSeconds());

      region = regionManager.getRegion("/maxAgeTest");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/maxAgeTest/", region.getFqn());
      assertTrue(policy instanceof LRUPolicy);
      assertTrue(configuration instanceof LRUConfiguration);
      assertEquals(10000, ((LRUConfiguration) configuration).getMaxNodes());
      assertEquals(8, ((LRUConfiguration) configuration).getTimeToLiveSeconds());
      assertEquals(10, ((LRUConfiguration) configuration).getMaxAgeSeconds());

      cache.stopService();
   }

   public void testLegacyPolicyConfiguration() throws Exception
   {
      this.setupCache("META-INF/local-lru-eviction-service.xml");
      assertEquals(5, cache.getEvictionThreadWakeupIntervalSeconds());

      Region region = regionManager.getRegion("/org/jboss/data");
      EvictionPolicy policy = region.getEvictionPolicy();
      EvictionConfiguration configuration = region.getEvictionConfiguration();
      assertEquals("/org/jboss/data/", region.getFqn());
      assertTrue(policy instanceof LRUPolicy);
      assertTrue(configuration instanceof LRUConfiguration);
      assertEquals(5000, ((LRUConfiguration) configuration).getMaxNodes());
      assertEquals(1000, ((LRUConfiguration) configuration).getTimeToLiveSeconds());

      region = regionManager.getRegion("/org/jboss/test/data");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/org/jboss/test/data/", region.getFqn());
      assertTrue(policy instanceof LRUPolicy);
      assertTrue(configuration instanceof LRUConfiguration);
      assertEquals(5, ((LRUConfiguration) configuration).getMaxNodes());
      assertEquals(4, ((LRUConfiguration) configuration).getTimeToLiveSeconds());

      region = regionManager.getRegion("/test");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/test/", region.getFqn());
      assertTrue(policy instanceof LRUPolicy);
      assertTrue(configuration instanceof LRUConfiguration);
      assertEquals(10000, ((LRUConfiguration) configuration).getMaxNodes());
      assertEquals(4, ((LRUConfiguration) configuration).getTimeToLiveSeconds());

      region = regionManager.getRegion("/maxAgeTest");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/maxAgeTest/", region.getFqn());
      assertTrue(policy instanceof LRUPolicy);
      assertTrue(configuration instanceof LRUConfiguration);
      assertEquals(10000, ((LRUConfiguration) configuration).getMaxNodes());
      assertEquals(8, ((LRUConfiguration) configuration).getTimeToLiveSeconds());
      assertEquals(10, ((LRUConfiguration) configuration).getMaxAgeSeconds());

      // test the default region. use a region name that isn't defined explicitly in conf file.
      region = regionManager.getRegion("/a/b/c");
      policy = region.getEvictionPolicy();
      configuration = region.getEvictionConfiguration();
      assertEquals("/_default_/", region.getFqn());
      assertTrue(policy instanceof LRUPolicy);
      assertTrue(configuration instanceof LRUConfiguration);
      assertEquals(5000, ((LRUConfiguration) configuration).getMaxNodes());
      assertEquals(1000, ((LRUConfiguration) configuration).getTimeToLiveSeconds());
      assertEquals(0, ((LRUConfiguration) configuration).getMaxAgeSeconds());

      cache.stopService();

   }

   public void testTwoCacheInstanceConfiguration() throws Exception
   {
      this.setupCache("META-INF/local-lru-eviction-service.xml");
      TreeCache cache1 = cache;
      this.setupCache("META-INF/local-lru-eviction-service.xml");
   }

   public void testNoEviction() throws Exception
   {
      this.setupCache("META-INF/tree-service.xml");
      assertEquals(0, regionManager.getRegions().length);
   }

   private void setupCache(String configurationName) throws Exception
   {
      cache = new TreeCache();
      PropertyConfigurator config = new PropertyConfigurator();
      config.configure(cache, configurationName);
      cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
      cache.setIsolationLevel(IsolationLevel.SERIALIZABLE);
      cache.startService();
      regionManager = cache.getEvictionRegionManager();
   }
}
