Author: dpospisi(a)redhat.com
Date: 2008-08-08 15:04:05 -0400 (Fri, 08 Aug 2008)
New Revision: 6549
Added:
core/trunk/src/test/java/org/jboss/cache/UnitTestCacheFactory.java
Log:
Added UnitTestCacheFactory.
Added: core/trunk/src/test/java/org/jboss/cache/UnitTestCacheFactory.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/UnitTestCacheFactory.java
(rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/UnitTestCacheFactory.java 2008-08-08 19:04:05
UTC (rev 6549)
@@ -0,0 +1,192 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at
gnu.org.
+ */
+package org.jboss.cache;
+
+import java.io.InputStream;
+import java.util.Vector;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.ConfigurationException;
+import org.jboss.cache.config.OldFileFormatException;
+import org.jboss.cache.config.parsing.XmlConfigurationParser;
+import org.jboss.cache.config.parsing.XmlConfigurationParser2x;
+import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
+import org.jboss.cache.util.TestingUtil;
+
+/**
+ *
+ * @author <a href="mailto:dpospisi@redhat.com">Dominik Pospisil
(dpospisi(a)redhat.com)</a>
+ */
+public class UnitTestCacheFactory<K, V> implements CacheFactory<K, V>
+{
+
+ private final Log log = LogFactory.getLog(UnitTestCacheFactory.class);
+
+
+ /**
+ * Holds unique mcast_addr for each thread used for JGroups channel construction.
+ */
+ private static final ThreadLocal<String> threadMcastIP = new
ThreadLocal<String>() {
+
+ private final AtomicInteger uniqueAddr = new AtomicInteger(10);
+ @Override protected String initialValue() {
+ return "228.10.10." + String.valueOf(uniqueAddr.getAndIncrement());
+ }
+ };
+
+ /**
+ * Holds unique mcast_port for each thread used for JGroups channel construction.
+ */
+ private static final ThreadLocal<Integer> threadMcastPort = new
ThreadLocal<Integer>() {
+
+ private final AtomicInteger uniquePort = new AtomicInteger(45588);
+
+ @Override protected Integer initialValue() {
+ return uniquePort.getAndIncrement();
+ }
+ };
+
+ /**
+ * For each thread holds list of caches created using this factory.
+ */
+ private static final ThreadLocal<Vector<Cache>> threadCaches =
+ new ThreadLocal<Vector<Cache>>() {
+
+
+ @Override protected Vector<Cache> initialValue() {
+ return new Vector<Cache>();
+ }
+ };
+
+ // factory methods
+
+ public Cache<K, V> createCache() throws ConfigurationException {
+ return createCache(true);
+ }
+
+ public Cache<K, V> createCache(boolean start) throws ConfigurationException {
+ return createCache(new Configuration(), start);
+ }
+
+ public Cache<K, V> createCache(String configFileName) throws
ConfigurationException {
+ return createCache(configFileName, true);
+ }
+
+ public Cache<K, V> createCache(String configFileName, boolean start) throws
ConfigurationException {
+ XmlConfigurationParser parser = new XmlConfigurationParser();
+ Configuration c;
+ try
+ {
+ c = parser.parseFile(configFileName);
+ }
+ catch (OldFileFormatException e)
+ {
+ System.out.println("Detected legacy configuration file format when parsing
[" + configFileName + "]. Migrating to the new (3.x) file format is
recommended. See FAQs for details.");
+ XmlConfigurationParser2x oldParser = new XmlConfigurationParser2x();
+ c = oldParser.parseFile(configFileName);
+ }
+ return createCache(c, start);
+ }
+
+ public Cache<K, V> createCache(Configuration configuration) throws
ConfigurationException {
+ return createCache(configuration, true);
+ }
+
+ public Cache<K, V> createCache(InputStream is) throws ConfigurationException {
+ return createCache(is, true);
+ }
+
+ public Cache<K, V> createCache(InputStream is, boolean start) throws
ConfigurationException {
+ XmlConfigurationParser parser = new XmlConfigurationParser();
+ Configuration c = parser.parseStream(is);
+ return createCache(c, start);
+ }
+
+ public Cache<K, V> createCache(Configuration configuration, boolean start)
throws ConfigurationException {
+
+ switch (configuration.getCacheMode())
+ {
+ case LOCAL:
+ // local cache, no channel used
+ break;
+ case REPL_SYNC:
+ case REPL_ASYNC:
+ case INVALIDATION_ASYNC:
+ case INVALIDATION_SYNC:
+ // replicated cache, update channel setup
+ mangleConfiguration(configuration);
+ break;
+ default:
+ log.info("Unknown cache mode!");
+ }
+
+ Cache<K, V> cache = new DefaultCacheFactory<K,
V>().createCache(configuration, start);
+
+ Vector<Cache> caches = threadCaches.get();
+ caches.add(cache);
+
+ return cache;
+
+ }
+
+ /**
+ * Destroys all caches created by this factory in the current thread.
+ */
+ public void cleanUp() {
+ Vector<Cache> caches = threadCaches.get();
+ for (Cache cache : caches) {
+ TestingUtil.killCaches(cache);
+ }
+ caches.setSize(0);
+ }
+
+ /**
+ * Updates cluster configuration to ensure mutual thread isolation.
+ * @param configuration Configuration to update.
+ */
+ private void mangleConfiguration(Configuration configuration) {
+ String clusterConfig = configuration.getClusterConfig();
+
+ if (clusterConfig == null) {
+ // No explicit cluster configuration found. we need to resolve the default
config
+ // now in orded to be able to update it before the cache (and the channel)
starts.
+
+ // TODO: this does not seems to be the best solution :(
+ clusterConfig = UnitTestCacheConfigurationFactory.getClusterConfigFromFile(
+ configuration.getDefaultClusterConfig());
+
+ }
+
+ // replace mcast_addr
+ Pattern pattern = Pattern.compile("mcast_addr=[^;]*");
+ Matcher m = pattern.matcher(clusterConfig);
+ if (m.find()) {
+ String origAddr = m.group().substring(m.group().indexOf("=") + 1);
+ String newAddr = threadMcastIP.get();
+ System.out.println("Replacing mcast_addr " + origAddr + " with
" + newAddr);
+ clusterConfig = m.replaceFirst("mcast_addr=" + newAddr);
+ }
+
+ // replace mcast_port
+ pattern = Pattern.compile("mcast_port=[^;]*");
+ m = pattern.matcher(clusterConfig);
+ if (m.find()) {
+ String origPort = m.group().substring(m.group().indexOf("=") + 1);
+ String newPort = threadMcastPort.get().toString();
+ System.out.println("Replacing mcast_port " + origPort + " with
" + newPort);
+ clusterConfig = m.replaceFirst("mcast_port=" + newPort);
+ }
+
+ configuration.setClusterConfig(clusterConfig);
+
+ }
+
+}