Author: manik.surtani(a)jboss.com
Date: 2008-03-31 13:53:52 -0400 (Mon, 31 Mar 2008)
New Revision: 5479
Added:
core/trunk/src/test/java/org/jboss/cache/marshall/InvalidRegionForStateTransferTest.java
Log:
JBCACHE-1170 - added test
Added:
core/trunk/src/test/java/org/jboss/cache/marshall/InvalidRegionForStateTransferTest.java
===================================================================
---
core/trunk/src/test/java/org/jboss/cache/marshall/InvalidRegionForStateTransferTest.java
(rev 0)
+++
core/trunk/src/test/java/org/jboss/cache/marshall/InvalidRegionForStateTransferTest.java 2008-03-31
17:53:52 UTC (rev 5479)
@@ -0,0 +1,90 @@
+package org.jboss.cache.marshall;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Region;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.misc.TestingUtil;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * This test ensures the CacheMarshaller doesn't use stale regions when attempting to
unmarshall state transfers. Seen intermittently
+ * when async replication is used, since JGroups doesn't attempt to marshall a return
value, thereby leaving a stale region in thread local
+ * in the cache marshaller, which then gets reused when the thread is reused to provide
state.
+ * <p/>
+ * Need to ensure that the same thread is used to process incoming requests as well as
state transfers, hence limiting the JGroups
+ * thread pool size to 1.
+ * <p/>
+ *
+ * @author Manik Surtani (<a
href="mailto:manik@jboss.org">manik@jboss.org</a>)
+ * @since 2.1.0
+ */
+@Test(groups = "functional")
+public class InvalidRegionForStateTransferTest
+{
+ Cache<Object, Object> c1, c2;
+
+ @BeforeMethod
+ public void setUp() throws CloneNotSupportedException
+ {
+ c1 = new DefaultCacheFactory<Object,
Object>().createCache(UnitTestCacheConfigurationFactory.createConfiguration(Configuration.CacheMode.REPL_ASYNC),
false);
+
+ String jgroupsCfg = c1.getConfiguration().getClusterConfig();
+
+ // make sure we use STATE_TRANSFER and not STREAMING_STATE_TRANSFER, so the same
thread pool is used for incoming calls and ST
+ jgroupsCfg = jgroupsCfg.replace("STREAMING_STATE_TRANSFER",
"STATE_TRANSFER");
+ // also make sure we use a thread pool size of 1
+ jgroupsCfg = jgroupsCfg.replaceFirst("thread_pool.max_threads=[0-9]*;",
"thread_pool.max_threads=1;");
+
+ System.out.println(">>>> " + jgroupsCfg);
+ c1.getConfiguration().setClusterConfig(jgroupsCfg);
+
+ c1.getConfiguration().setUseRegionBasedMarshalling(true);
+ c1.start();
+
+ c2 = new DefaultCacheFactory<Object,
Object>().createCache(c1.getConfiguration().clone());
+
+ TestingUtil.blockUntilViewsReceived(60000, c1, c2);
+ }
+
+ @AfterMethod
+ public void tearDown()
+ {
+ TestingUtil.killCaches(c1, c2);
+ }
+
+ public void testUseOfInvalidRegion()
+ {
+ Fqn fqn = Fqn.fromString("/a/b/c/d");
+ c1.getRegion(fqn.getParent(),
true).registerContextClassLoader(getClass().getClassLoader());
+ c2.getRegion(fqn.getParent(),
true).registerContextClassLoader(getClass().getClassLoader());
+
+ // write something; will cause a stale region to be stored in C2's cache
marshaller
+ c1.put(fqn, "k", "v");
+ assert c1.get(fqn, "k").equals("v");
+
+ TestingUtil.sleepThread(250); // async repl
+
+ // assert that this made it to c2
+ assert c2.get(fqn, "k").equals("v");
+
+ // c2's cache marshaller's thread local would be polluted now.
+
+ // restart c1 so that it forces a state transfer from c2
+ c1.destroy();
+ c1.create();
+ Region r = c1.getRegion(fqn.getParent(), true);
+ r.registerContextClassLoader(getClass().getClassLoader());
+ r.deactivate();
+ c1.start();
+
+ TestingUtil.blockUntilViewsReceived(60000, c1, c2);
+
+ // assert that the state has been transferred to C1
+ assert c1.get(fqn, "k").equals("v");
+ }
+}
Show replies by date