[jbosscache-commits] JBoss Cache SVN: r5831 - in core/trunk/src: main/java/org/jboss/cache/eviction and 6 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Mon May 12 13:20:48 EDT 2008


Author: mircea.markus
Date: 2008-05-12 13:20:48 -0400 (Mon, 12 May 2008)
New Revision: 5831

Added:
   core/trunk/src/test/java/org/jboss/cache/util/internals/
   core/trunk/src/test/java/org/jboss/cache/util/internals/EvictionController.java
   core/trunk/src/test/java/org/jboss/cache/util/internals/ReplicationQueueNotifier.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/config/EvictionConfig.java
   core/trunk/src/main/java/org/jboss/cache/eviction/BaseEvictionAlgorithm.java
   core/trunk/src/main/java/org/jboss/cache/eviction/EvictionTimerTask.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorChain.java
   core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java
   core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java
   core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java
Log:
fixed finding of start/stop methods

Modified: core/trunk/src/main/java/org/jboss/cache/config/EvictionConfig.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/config/EvictionConfig.java	2008-05-12 16:45:25 UTC (rev 5830)
+++ core/trunk/src/main/java/org/jboss/cache/config/EvictionConfig.java	2008-05-12 17:20:48 UTC (rev 5831)
@@ -22,6 +22,7 @@
 package org.jboss.cache.config;
 
 import org.jboss.cache.RegionManager;
+import org.jboss.cache.Fqn;
 import org.jboss.cache.eviction.EvictionPolicy;
 import org.jboss.cache.util.Util;
 
@@ -211,4 +212,20 @@
    }
 
 
+   /**
+    * Returns the <code>EvictionRegionConfig</code> coresponding to given region fqn, or <code>null</code> if no
+    * match is found.
+    */
+   public EvictionRegionConfig getEvictionRegionConfig(String region)
+   {
+      Fqn<String> fqn = Fqn.fromString(region);
+      for (EvictionRegionConfig evConfig : getEvictionRegionConfigs())
+      {
+         if (evConfig.getRegionFqn().equals(fqn))
+         {
+            return evConfig;
+         }
+      }
+      return null;
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/eviction/BaseEvictionAlgorithm.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/eviction/BaseEvictionAlgorithm.java	2008-05-12 16:45:25 UTC (rev 5830)
+++ core/trunk/src/main/java/org/jboss/cache/eviction/BaseEvictionAlgorithm.java	2008-05-12 17:20:48 UTC (rev 5831)
@@ -417,7 +417,7 @@
       // if a collection is only guaranteed sort order by adding to the collection,
       // this implementation will not guarantee sort order.
       ne.setNumberOfNodeVisits(ne.getNumberOfNodeVisits() + 1);
-      ne.setModifiedTimeStamp(System.currentTimeMillis());
+      ne.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
    }
 
    protected void processRemovedElement(EvictedEventNode evictedEventNode) throws EvictionException
@@ -438,7 +438,7 @@
       ne.setNumberOfElements(ne.getNumberOfElements() - 1);
       // also treat it as a node visit.
       ne.setNumberOfNodeVisits(ne.getNumberOfNodeVisits() + 1);
-      ne.setModifiedTimeStamp(System.currentTimeMillis());
+      ne.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
    }
 
    protected void processAddedElement(EvictedEventNode evictedEventNode) throws EvictionException
@@ -459,7 +459,7 @@
 
       // also treat it as a node visit.
       ne.setNumberOfNodeVisits(ne.getNumberOfNodeVisits() + 1);
-      ne.setModifiedTimeStamp(System.currentTimeMillis());
+      ne.setModifiedTimeStamp(evictedEventNode.getCreationTimestamp());
 //      log.error ("*** Processing nodeAdded for fqn " + fqn + " NodeEntry's hashcode is " + ne.hashCode());
    }
 

Modified: core/trunk/src/main/java/org/jboss/cache/eviction/EvictionTimerTask.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/eviction/EvictionTimerTask.java	2008-05-12 16:45:25 UTC (rev 5830)
+++ core/trunk/src/main/java/org/jboss/cache/eviction/EvictionTimerTask.java	2008-05-12 17:20:48 UTC (rev 5831)
@@ -74,6 +74,11 @@
       return processedRegions.contains(region);
    }
 
+   public Set<Region> getProcessedRegions()
+   {
+      return processedRegions;
+   }
+
    public void stop()
    {
       log.debug("Stopping eviction timer");
@@ -98,36 +103,44 @@
           */
          public void run()
          {
-            synchronized (processedRegions)
-            {
-               log.trace("***** eviction kicks in");
-               for (Region region : processedRegions)
-               {
-                  final EvictionPolicy policy = region.getEvictionPolicy();
-
-                  synchronized (region)
-                  {
-                     final EvictionAlgorithm algo = policy.getEvictionAlgorithm();
-                     if (algo == null)
-                        throw new NullPointerException("algorithm null");
-                     try
-                     {
-                        algo.process(region);
-                     }
-                     catch (EvictionException e)
-                     {
-                        log.error("run(): error processing eviction with exception: " + e.toString()
-                                + " will reset the eviction queue list.");
-                        region.resetEvictionQueues();
-                        log.debug("trace", e);
-                     }
-                  }
-               }
-            }
+            processRegions();
          }
       };
       evictionThread.schedule(tt, wakeupIntervalSeconds * 1000, wakeupIntervalSeconds * 1000);
    }
+
+   private void processRegions()
+   {
+      synchronized (processedRegions)
+      {
+         for (Region region : processedRegions)
+         {
+            handleRegion(region);
+         }
+      }
+   }
+
+   private void handleRegion(Region region)
+   {
+      synchronized (region)
+      {
+         final EvictionPolicy policy = region.getEvictionPolicy();
+         final EvictionAlgorithm algo = policy.getEvictionAlgorithm();
+         if (algo == null)
+            throw new NullPointerException("algorithm null");
+         try
+         {
+            algo.process(region);
+         }
+         catch (EvictionException e)
+         {
+            log.error("run(): error processing eviction with exception: " + e.toString()
+                  + " will reset the eviction queue list.");
+            region.resetEvictionQueues();
+            log.debug("trace", e);
+         }
+      }
+   }
 }
 
 

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorChain.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorChain.java	2008-05-12 16:45:25 UTC (rev 5830)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/InterceptorChain.java	2008-05-12 17:20:48 UTC (rev 5831)
@@ -14,6 +14,7 @@
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.ArrayList;
 
 /**
  * Knows how to build and manage an chain of interceptors. Also in charge with invoking methods on the chain.
@@ -271,6 +272,22 @@
       return invocationContextContainer.get();
    }
 
+   /**
+    * Returns all interceptors which extend the given command interceptor.
+    */
+   public List<CommandInterceptor> getInterceptorsWhichExtend(Class<? extends CommandInterceptor> interceptorClass)
+   {
+      List<CommandInterceptor> result = new ArrayList<CommandInterceptor>();
+      for (CommandInterceptor interceptor : asList())
+      {
+         boolean isSubclass = interceptorClass.isAssignableFrom(interceptor.getClass());
+         if (isSubclass)
+         {
+            result.add(interceptor);
+         }
+      }
+      return result;
+   }
 
    public String toString()
    {

Modified: core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java	2008-05-12 16:45:25 UTC (rev 5830)
+++ core/trunk/src/test/java/org/jboss/cache/invocation/InterceptorChainTest.java	2008-05-12 17:20:48 UTC (rev 5831)
@@ -126,6 +126,18 @@
       assert txInterceptor.getNext().equals(invalidationInterceptor);
    }
 
+   public void testGetInterceptorsWhichExtend()
+   {
+      InvocationContextInterceptor ic2 = (InvocationContextInterceptor) create(InvocationContextInterceptor.class);
+      chain.appendIntereceptor(ic2);
+      List<CommandInterceptor> result = chain.getInterceptorsWhichExtend(InvocationContextInterceptor.class);
+      assert result.contains(icInterceptor);
+      assert result.contains(ic2);
+      assert result.size() == 2;
+      result = chain.getInterceptorsWhichExtend(CommandInterceptor.class);
+      assert result.size() == chain.asList().size();
+   }
+
    public void removeInterceptorWithtType()
    {
       chain.addInterceptor(txInterceptor, 1);

Modified: core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java	2008-05-12 16:45:25 UTC (rev 5830)
+++ core/trunk/src/test/java/org/jboss/cache/misc/TestingUtil.java	2008-05-12 17:20:48 UTC (rev 5831)
@@ -50,11 +50,26 @@
       return extractField(target.getClass(), target, fieldName);
    }
 
-   private static Object extractField(Class type, Object target, String fieldName)
+   public static void replaceField(Object newValue, String fieldName, Object owner, Class baseType)
    {
       Field field;
       try
       {
+         field = baseType.getDeclaredField(fieldName);
+         field.setAccessible(true);
+         field.set(owner, newValue);
+      } catch (Exception e)
+      {
+         throw new RuntimeException(e);//just to simplify exception handeling
+      }
+   }
+
+
+   public static Object extractField(Class type, Object target, String fieldName)
+   {
+      Field field;
+      try
+      {
          field = type.getDeclaredField(fieldName);
          field.setAccessible(true);
          return field.get(target);
@@ -65,8 +80,7 @@
          {
             e.printStackTrace();
             return null;
-         }
-         else
+         } else
          {
             // try with superclass!!
             return extractField(type.getSuperclass(), target, fieldName);
@@ -272,8 +286,7 @@
       if (members == null || memberCount > members.size())
       {
          return false;
-      }
-      else if (memberCount < members.size())
+      } else if (memberCount < members.size())
       {
          // This is an exceptional condition
          StringBuffer sb = new StringBuffer("Cache at address ");
@@ -315,8 +328,7 @@
       if (members == null || memberCount > members.size())
       {
          return false;
-      }
-      else if (memberCount < members.size())
+      } else if (memberCount < members.size())
       {
          if (barfIfTooManyMembers)
          {
@@ -339,8 +351,7 @@
             sb.append(')');
 
             throw new IllegalStateException(sb.toString());
-         }
-         else return false;
+         } else return false;
       }
 
       return true;
@@ -596,8 +607,7 @@
          if (c == null)
          {
             System.out.println("  ** Cache " + count + " is null!");
-         }
-         else
+         } else
          {
             System.out.println("  ** Cache " + count + " is " + c.getLocalAddress());
             System.out.println("    " + CachePrinter.printCacheLockingInfo(c));

Modified: core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java	2008-05-12 16:45:25 UTC (rev 5830)
+++ core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferConcurrencyTest.java	2008-05-12 17:20:48 UTC (rev 5831)
@@ -7,20 +7,14 @@
 
 package org.jboss.cache.statetransfer;
 
-import org.jboss.cache.Cache;
-import org.jboss.cache.CacheException;
-import org.jboss.cache.CacheSPI;
-import org.jboss.cache.DefaultCacheFactory;
-import org.jboss.cache.Fqn;
-import org.jboss.cache.Node;
-import org.jboss.cache.Region;
-import org.jboss.cache.eviction.LRUConfiguration;
+import org.jboss.cache.*;
 import org.jboss.cache.config.Configuration;
-import org.jboss.cache.config.EvictionRegionConfig;
 import org.jboss.cache.config.Configuration.CacheMode;
 import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
 import org.jboss.cache.marshall.InactiveRegionException;
 import org.jboss.cache.misc.TestingUtil;
+import org.jboss.cache.util.internals.EvictionController;
+import org.jboss.cache.util.internals.ReplicationQueueNotifier;
 import static org.testng.AssertJUnit.*;
 import org.testng.annotations.Test;
 
@@ -111,8 +105,7 @@
          semaphore.release(count);
 
          // Sleep to ensure the threads get all the semaphore tickets
-         TestingUtil.sleepThread((long) 1000);
-
+         waitUntillUsersFinish(activators);
          // Reacquire the semaphore tickets; when we have them all
          // we know the threads are done
          for (int i = 0; i < count; i++)
@@ -124,10 +117,10 @@
             }
          }
 
-         // Sleep to allow any async calls to clear
+         // allow any async calls to clear
          if (!sync)
          {
-            TestingUtil.sleepThread(2000);
+            waitTillAllReplicationsFinish(count, caches);
          }
 
          // Ensure the caches held by the activators see all the values
@@ -153,6 +146,7 @@
       }
       catch (Exception ex)
       {
+         ex.printStackTrace();
          fail(ex.getLocalizedMessage());
       }
       finally
@@ -165,6 +159,24 @@
 
    }
 
+   private void waitUntillUsersFinish(CacheActivator[] activators)
+         throws Exception
+   {
+      for (CacheActivator activator : activators)
+      {
+         activator.waitUntillFinished();
+      }
+   }
+
+   private void waitTillAllReplicationsFinish(int count, CacheSPI[] caches)
+         throws Exception
+   {
+      for (int i = 0; i < count; i++)
+      {
+         new ReplicationQueueNotifier(caches[i]).waitUntillAllReplicated(2000);
+      }
+   }
+
    /**
     * Starts two caches where each cache has N regions. We put some data in each of the regions.
     * We run two threads where each thread creates a cache then goes into a loop where it
@@ -230,7 +242,7 @@
          // Sleep to allow any async calls to clear
          if (!sync)
          {
-            TestingUtil.sleepThread(1000);
+            waitTillAllReplicationsFinish(count, caches);
          }
 
          // Ensure the caches held by the activators see all the values
@@ -411,9 +423,11 @@
                TestingUtil.sleepThread(100);
             }
 
-            // Sleep to allow any in transit msgs to clear
-            //            if (!sync)
-            TestingUtil.sleepThread(1000);
+            // Sleep to allow any async calls to clear
+            if (!sync)
+            {
+               waitTillAllReplicationsFinish(count, caches);
+            }
 
             // Ensure the stressors saw no exceptions
             for (int i = 0; i < count; i++)
@@ -425,8 +439,6 @@
 
             }
 
-            TestingUtil.sleepThread(1000);
-
             // Compare cache contents
             for (int i = 0; i < count; i++)
             {
@@ -456,13 +468,10 @@
             }
          }
       }
-
    }
 
    /**
     * Test for JBCACHE-913
-    *
-    * @throws Exception
     */
    public void testEvictionSeesStateTransfer() throws Exception
    {
@@ -493,8 +502,6 @@
 
    /**
     * Further test for JBCACHE-913
-    *
-    * @throws Exception
     */
    public void testEvictionAfterStateTransfer() throws Exception
    {
@@ -516,24 +523,21 @@
          }
       }
 
-      Thread.sleep(5000);
-      assert cache1.getRoot().getChild(Fqn.fromString("/org/jboss/data")).getChildren().size() == 5000;
+      EvictionController ec1 = new EvictionController(cache1);
+      ec1.startEviction();
 
+     assert cache1.getRoot().getChild(Fqn.fromString("/org/jboss/data")).getChildren().size() == 5000;
+
       c = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC, true);
       final Cache<Object, Object> cache2 = new DefaultCacheFactory().createCache(c, false);
-      log.info("***** before starting the second cache");
       cache2.start();
-      log.info("***** after starting the second cache");
       caches.put("evict2", cache2);
 
       Node<Object, Object> parent = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/test/data"));
       parent = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/data"));
       Set children = parent.getChildren();
-      System.out.println("children.size() = " + children.size());
-      System.out.println("cache1.children size = " + cache1.getRoot().getChild(Fqn.fromString("/org/jboss/data")).getChildren().size());
-      log.info("***** cache1.children size = " + cache1.getRoot().getChild(Fqn.fromString("/org/jboss/data")).getChildren().size());
-      log.info("***** children.size() = " + children.size());
-      assertTrue("Minimum number of base children transferred", children.size() >= 4999); //4999 because the root of the region will also be counted, as it is not resident
+      //4999 because the root of the region will also be counted, as it is not resident
+      assertTrue("Minimum number of base children transferred", children.size() >= 4999);
 
       // Sleep 2.5 secs so the nodes we are about to create in data won't
       // exceed the 4 sec TTL when eviction thread runs
@@ -628,8 +632,8 @@
       assertNull("No exceptions in p1", p1.ex);
       assertNull("No exceptions in p2", p2.ex);
 
-      // Sleep 5.1 secs so we are sure the eviction thread ran
-      TestingUtil.sleepThread(5100);
+      EvictionController ec2 = new EvictionController(cache2);
+      ec2.startEviction();
 
       parent = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/test/data"));
       children = parent.getChildren();
@@ -648,61 +652,18 @@
 
       // Sleep more to let the eviction thread run again,
       // which will evict all data nodes due to their ttl of 4 secs
-      TestingUtil.sleepThread(8100);
+      ec2.evictRegionWithTimeToLive("/org/jboss/test/data");
 
       parent = cache2.getRoot().getChild(Fqn.fromString("/org/jboss/test/data"));
-      children = parent.getChildren();
-      if (children != null)
+      if (parent != null)
       {
-         assertEquals("All data children evicted", 0, children.size());
-      }
-   }
-
-   /**
-    * tests that after the state transfer takes place the correct number of nodes is being evcited.
-    */
-   public void testEvictionAfterStateTransferSimple() throws Exception
-   {
-      Configuration c = UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC, true);
-      String baseRegion = "/base";
-      int maxRegionNodeCount = 5;
-
-//      //set max node node to 5 on default
-      ((LRUConfiguration)c.getEvictionConfig().getEvictionRegionConfigs().get(0).getEvictionPolicyConfig()).setMaxNodes(maxRegionNodeCount);
-      EvictionRegionConfig baseRegionConfig = c.getEvictionConfig().getEvictionRegionConfigs().get(1).clone();
-      baseRegionConfig.setRegionFqn(Fqn.fromString(baseRegion));
-      ((LRUConfiguration)baseRegionConfig.getEvictionPolicyConfig()).setMaxAgeSeconds(1000);
-      ((LRUConfiguration)baseRegionConfig.getEvictionPolicyConfig()).setMaxNodes(maxRegionNodeCount);
-      c.getEvictionConfig().getEvictionRegionConfigs().add(baseRegionConfig);
-
-
-      Cache<Object, Object> cache1 = new DefaultCacheFactory().createCache(c, true);
-      caches.put("evict1", cache1);
-      cache1.getRegion(Fqn.fromString(baseRegion), true).activate();
-
-      for (int i = 0; i < maxRegionNodeCount  + 5; i++)
-      {
-         cache1.put(Fqn.fromString(baseRegion + "/" + i), "key", "base" + i);
-         if (i == 0)
+         children = parent.getChildren();
+         if (children != null)
          {
-            cache1.getRoot().getChild(Fqn.fromString(baseRegion)).setResident(true); //so that it won't be counted for eviction
+            assertEquals("All data children evicted", 0, children.size());
          }
       }
-      cache1.put(Fqn.fromString("/org/jboss/test/data/" + 0), "key", "data" + 0);
-
-      Thread.sleep(5000);
-      assert cache1.getRoot().getChild(Fqn.fromString(baseRegion)).getChildren().size() == maxRegionNodeCount;
-      System.out.println("cache1.getRoot().getChild(Fqn.fromString(baseRegion)).getChildren().size() = " + cache1.getRoot().getChild(Fqn.fromString(baseRegion)).getChildren());
-
-      final Cache<Object, Object> cache2 = new DefaultCacheFactory().createCache(c.clone(), false);
-      cache2.start();
-      caches.put("evict2", cache2);
-      Thread.sleep(5000);
-
-      Node parent = cache2.getRoot().getChild(Fqn.fromString(baseRegion));
-      Set children = parent.getChildren();
    }
-
    private class CacheActivator extends CacheUser
    {
 
@@ -722,42 +683,11 @@
          System.out.println("---- Cache" + name + " = " + cache.getLocalAddress() + " being used");
          TestingUtil.sleepRandom(5000);
          createAndActivateRegion(cache, A_B);
-//         waitUntillAllChachesActivatedRegion();
          System.out.println(name + " activated region" + " " + System.currentTimeMillis());
          Fqn childFqn = Fqn.fromRelativeElements(A_B, name);
-
          cache.put(childFqn, "KEY", "VALUE");
-         //         System.out.println(name + " put fqn " + childFqn + " " + System.currentTimeMillis());
-
       }
 
-      /**
-       * If we do not wait for all being activated, following scenario might happen:
-       * A activates the /a/b
-       * A puts something in /a/b and replicates
-       * B fails to accept the replication as it has the /a/b region inactive.
-       * <p/>
-       * So we cannot expect all the put operation to replicate accross all the members from the cluser, WITHOUTH
-       * having the region active on ALL members.
-       */
-      private void waitUntillAllChachesActivatedRegion()
-      {
-         boolean allActive = true;
-         do
-         {
-            allActive = true;
-            for (Cache cache : caches)
-            {
-               if (cache.getRegion(A_B, false) == null || !cache.getRegion(A_B, false).isActive())
-               {
-                  allActive = false;
-               }
-            }
-            TestingUtil.sleepThread(1000);
-         } while (!allActive);
-         System.out.println("---- /a/b is active on all cache instances");
-      }
-
       public Object getCacheValue(Fqn fqn) throws CacheException
       {
          return cache.get(fqn, "KEY");

Added: core/trunk/src/test/java/org/jboss/cache/util/internals/EvictionController.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/util/internals/EvictionController.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/util/internals/EvictionController.java	2008-05-12 17:20:48 UTC (rev 5831)
@@ -0,0 +1,89 @@
+package org.jboss.cache.util.internals;
+
+import org.jboss.cache.*;
+import org.jboss.cache.config.EvictionConfig;
+import org.jboss.cache.config.EvictionRegionConfig;
+import org.jboss.cache.eviction.EvictionTimerTask;
+import org.jboss.cache.eviction.LRUConfiguration;
+import org.jboss.cache.misc.TestingUtil;
+
+import java.lang.reflect.Method;
+import java.util.Timer;
+
+/**
+ * when used on a cache will disable defaul eviction behavior and it will supply means of kicking off evction
+ * programmatically. It is intended for replcaing Thread.sleep(xyz) - like statements in which the executing tests wait
+ * untill eviction finishes.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+public class EvictionController
+{
+   CacheSPI cache;
+   EvictionTimerTask timerTask;
+
+   public EvictionController(Cache cache)
+   {
+      this.cache = (CacheSPI) cache;
+      RegionManager regionManager = this.cache.getRegionManager();
+      if (regionManager == null)
+      {
+         throw new IllegalStateException("Null region manager; is the cache started?");
+      }
+      timerTask = (EvictionTimerTask) TestingUtil.extractField(regionManager, "evictionTimerTask");
+      if (timerTask == null)
+      {
+         throw new IllegalStateException("No timer task!!!");
+      }
+      Timer evictionThread = (Timer) TestingUtil.extractField(timerTask, "evictionThread");
+      evictionThread.cancel();
+   }
+
+   public void startEviction() throws Exception
+   {
+      Method method = EvictionTimerTask.class.getDeclaredMethod("processRegions", null);
+      method.setAccessible(true);
+      method.invoke(timerTask);
+   }
+
+   /**
+    * Evicts the given region but only after ensuring that region's TTL passed.
+    */
+   public void evictRegionWithTimeToLive(String region) throws Exception
+   {
+      EvictionConfig evConfig = cache.getConfiguration().getEvictionConfig();
+      EvictionRegionConfig erConfig = evConfig.getEvictionRegionConfig(region);
+      if (erConfig == null)
+      {
+         throw new IllegalStateException("No such region!");
+      }
+      int ttl = 0;
+      if (erConfig.getEvictionPolicyConfig() instanceof LRUConfiguration)
+      {
+         LRUConfiguration configuration = (LRUConfiguration) erConfig.getEvictionPolicyConfig();
+         ttl = configuration.getTimeToLiveSeconds();
+      } else
+      {
+         throw new IllegalArgumentException("Only LRU being handled for now; please add other implementations here");
+      }
+      TestingUtil.sleepThread(ttl * 1000 + 500);
+      evictRegion(region);
+   }
+
+   /**
+    * Only evicts the given region.
+    */
+   public void evictRegion(String regionStr) throws Exception
+   {
+      for (Region region : timerTask.getProcessedRegions())
+      {
+         if (region.getFqn().equals(Fqn.fromString(regionStr)))
+         {
+            Method method = EvictionTimerTask.class.getDeclaredMethod("handleRegion", Region.class);
+            method.setAccessible(true);
+            method.invoke(timerTask, region);
+         }
+      }
+   }
+}

Added: core/trunk/src/test/java/org/jboss/cache/util/internals/ReplicationQueueNotifier.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/util/internals/ReplicationQueueNotifier.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/util/internals/ReplicationQueueNotifier.java	2008-05-12 17:20:48 UTC (rev 5831)
@@ -0,0 +1,89 @@
+package org.jboss.cache.util.internals;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.cluster.ReplicationQueue;
+import org.jboss.cache.factories.ComponentRegistry;
+import org.jboss.cache.interceptors.BaseRpcInterceptor;
+import org.jboss.cache.interceptors.InterceptorChain;
+import org.jboss.cache.interceptors.base.CommandInterceptor;
+import org.jboss.cache.invocation.CacheInvocationDelegate;
+import org.jboss.cache.misc.TestingUtil;
+
+import java.util.List;
+
+/**
+ * Knows how to notify one whether on certain state changes in the replication queue.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 2.2
+ */
+public class ReplicationQueueNotifier
+{
+   private CacheInvocationDelegate cache;
+   private Object replicated = new Object();
+
+   public ReplicationQueueNotifier(Cache cache)
+   {
+      this.cache = (CacheInvocationDelegate) cache;
+      if (!isAsync(cache))
+      {
+         throw new RuntimeException("No  queue events expected on a sync cache!");
+      }
+      replaceInternal();
+   }
+
+   private boolean isAsync(Cache cache)
+   {
+      return cache.getConfiguration().getCacheMode() == Configuration.CacheMode.INVALIDATION_ASYNC ||
+            cache.getConfiguration().getCacheMode() == Configuration.CacheMode.REPL_ASYNC;
+   }
+
+   private void replaceInternal()
+   {
+      ComponentRegistry componentRegistry = TestingUtil.extractComponentRegistry(cache);
+      InterceptorChain ic = componentRegistry.getComponent(InterceptorChain.class);
+      List<CommandInterceptor> commands = ic.getInterceptorsWhichExtend(BaseRpcInterceptor.class);
+      for (CommandInterceptor interceptor: commands)
+      {
+         ReplicationQueue original = (ReplicationQueue) TestingUtil.extractField(BaseRpcInterceptor.class, interceptor, "replicationQueue");
+         TestingUtil.replaceField(new ReplicationQueueDelegate(original),"replicationQueue", interceptor, BaseRpcInterceptor.class);
+         log("replaced replicationQueue in " + interceptor.getClass());
+      }
+   }
+
+   public void waitUntillAllReplicated(long timeout) throws Exception
+   {
+      synchronized (replicated)
+      {
+         replicated.wait(timeout);
+      }
+      log("returning from waitUntillAllReplicated call");
+   }
+
+   private class ReplicationQueueDelegate extends ReplicationQueue
+   {
+      ReplicationQueue original;
+
+      private ReplicationQueueDelegate(ReplicationQueue original)
+      {
+         this.original = original;
+      }
+
+      @Override
+      public void flush()
+      {
+         log("Flush invoked!");
+         original.flush();
+         synchronized (replicated)
+         {
+            replicated.notifyAll();
+         }
+      }
+   }
+
+   private void log(String str)
+   {
+      System.out.println("ReplicationQueueNotifier >>>  " + str);
+   }
+}




More information about the jbosscache-commits mailing list