diff --git a/cache-jbosscache2/pom.xml b/cache-jbosscache2/pom.xml index 1b866be14b..aa186d7b7c 100644 --- a/cache-jbosscache2/pom.xml +++ b/cache-jbosscache2/pom.xml @@ -13,8 +13,8 @@ hibernate-jbosscache2 jar - Hibernate JBossCache2.x Integration - Integration of Hibernate with JBossCache (based on JBossCache2.x APIs) + Hibernate JBossCache3.x Integration + Integration of Hibernate with JBossCache 3 (based on JBossCache2.x+ APIs) @@ -25,7 +25,7 @@ org.jboss.cache jbosscache-core - 2.2.0.GA + 3.0.3.GA diff --git a/cache-jbosscache2/src/main/resources/org/hibernate/cache/jbc2/builder/jbc2-configs.xml b/cache-jbosscache2/src/main/resources/org/hibernate/cache/jbc2/builder/jbc2-configs.xml index 2873144c6a..a54d1fe8f6 100644 --- a/cache-jbosscache2/src/main/resources/org/hibernate/cache/jbc2/builder/jbc2-configs.xml +++ b/cache-jbosscache2/src/main/resources/org/hibernate/cache/jbc2/builder/jbc2-configs.xml @@ -76,14 +76,17 @@ 15000 - - true - - true + + true + + true + + + 0 @@ -109,7 +112,6 @@ - @@ -168,6 +170,93 @@ true + + 0 + + + + + 5 + + org.jboss.cache.eviction.LRUPolicy + + + + 10000 + + 1000 + + 120 + + + + + + + + + + + + + MVCC + + + READ_COMMITTED + + + INVALIDATION_SYNC + + + mvcc-entity + + + udp + + + false + + + 20000 + + + 20000 + + + 15000 + + + true + + true + + + 0 + @@ -245,14 +334,17 @@ 15000 - - true - - true + + true + + true + + + 0 @@ -278,6 +370,92 @@ + + + + + MVCC + + + REPEATABLE_READ + + + INVALIDATION_SYNC + + + mvcc-entity-rr + + + udp + + + false + + + 20000 + + + 20000 + + + 15000 + + + true + + true + + + 0 + + + + + 5 + + org.jboss.cache.eviction.LRUPolicy + + + + 10000 + + 1000 + + 120 + + + + + + + 15000 - - true - - true + + true + + true + + + 0 @@ -406,7 +587,7 @@ - PESSIMISTIC + MVCC 15000 - - true - - true + + true + + true + + + 0 @@ -485,7 +669,7 @@ OPTIMISTIC @@ -526,13 +710,16 @@ 15000 - - true - - true + --> + true + + true + + + 0 @@ -613,14 +800,17 @@ 15000 - - true - - true + + true + + true + + + 0 @@ -645,7 +835,95 @@ - + + + + + + + MVCC + + + READ_COMMITTED + + + REPL_SYNC + true + + + mvcc-shared + + + udp + + + true + + + 20000 + + + 20000 + + + 15000 + + + true + + true + + + 0 + + + + + 5 + + org.jboss.cache.eviction.LRUPolicy + + + + 10000 + + 1000 + + 120 + + + + + + + 15000 - - true - - true + --> + true + + true + + + 0 @@ -732,4 +1013,92 @@ + + + + + + + MVCC + + + REPEATABLE_READ + + + REPL_SYNC + true + + + mvcc-shared-rr + + + udp + + + true + + + 20000 + + + 20000 + + + 15000 + + + true + + true + + + 0 + + + + + 5 + + org.jboss.cache.eviction.LRUPolicy + + + + 10000 + + 1000 + + 120 + + + + + + + diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractRegionImplTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractRegionImplTestCase.java index 4eb09458f6..20891f4502 100644 --- a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractRegionImplTestCase.java +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/AbstractRegionImplTestCase.java @@ -67,7 +67,7 @@ public abstract class AbstractRegionImplTestCase extends AbstractJBossCacheTestC public void testActivationDeactivation() throws Exception { // Set up a cache to monitor affects of starting the region - Cache remoteCache = new DefaultCacheFactory().createCache(SharedCacheInstanceManager.DEFAULT_CACHE_RESOURCE, false); + Cache remoteCache = DefaultCacheFactory.getInstance().createCache(SharedCacheInstanceManager.DEFAULT_CACHE_RESOURCE, false); // This test assumes replication; verify that's correct assertEquals("Cache is REPL_SYNC", "REPL_SYNC", remoteCache.getConfiguration().getCacheModeString()); diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java index 8b3c987422..dfe3c5d852 100644 --- a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/AbstractCollectionRegionAccessStrategyTestCase.java @@ -56,9 +56,9 @@ import org.jboss.cache.Node; import org.jboss.cache.NodeSPI; import org.jboss.cache.transaction.BatchModeTransactionManager; -/** +/** * Base class for tests of CollectionRegionAccessStrategy impls. - * + * * @author Brian Stansberry * @version $Revision: 1 $ */ @@ -68,44 +68,44 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs public static final String KEY_BASE = "KEY"; public static final String VALUE1 = "VALUE1"; public static final String VALUE2 = "VALUE2"; - + protected static int testCount; - + protected static Configuration localCfg; protected static JBossCacheRegionFactory localRegionFactory; protected static Cache localCache; protected static Configuration remoteCfg; protected static JBossCacheRegionFactory remoteRegionFactory; protected static Cache remoteCache; - + protected CollectionRegion localCollectionRegion; protected CollectionRegionAccessStrategy localAccessStrategy; protected CollectionRegion remoteCollectionRegion; protected CollectionRegionAccessStrategy remoteAccessStrategy; - + protected boolean invalidation; protected boolean optimistic; protected boolean synchronous; - + protected Exception node1Exception; protected Exception node2Exception; - + protected AssertionFailedError node1Failure; protected AssertionFailedError node2Failure; - + public static Test getTestSetup(Class testClass, String configName) { TestSuite suite = new TestSuite(testClass); return new AccessStrategyTestSetup(suite, configName); } - + public static Test getTestSetup(Test test, String configName) { return new AccessStrategyTestSetup(test, configName); } - + /** * Create a new TransactionalAccessTestCase. - * + * * @param name */ public AbstractCollectionRegionAccessStrategyTestCase(String name) { @@ -116,38 +116,38 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs protected void setUp() throws Exception { super.setUp(); - + // Sleep a bit to avoid concurrent FLUSH problem avoidConcurrentFlush(); - + invalidation = CacheHelper.isClusteredInvalidation(localCache); synchronous = CacheHelper.isSynchronous(localCache); optimistic = localCache.getConfiguration().getNodeLockingScheme() == org.jboss.cache.config.Configuration.NodeLockingScheme.OPTIMISTIC; localCollectionRegion = localRegionFactory.buildCollectionRegion(REGION_NAME, localCfg.getProperties(), getCacheDataDescription()); localAccessStrategy = localCollectionRegion.buildAccessStrategy(getAccessType()); - + // Sleep a bit to avoid concurrent FLUSH problem avoidConcurrentFlush(); - + remoteCollectionRegion = remoteRegionFactory.buildCollectionRegion(REGION_NAME, remoteCfg.getProperties(), getCacheDataDescription()); remoteAccessStrategy = remoteCollectionRegion.buildAccessStrategy(getAccessType()); - + node1Exception = null; node2Exception = null; - + node1Failure = null; node2Failure = null; } protected void tearDown() throws Exception { - + super.tearDown(); - + if (localCollectionRegion != null) localCollectionRegion.destroy(); if (remoteCollectionRegion != null) remoteCollectionRegion.destroy(); - + try { localCache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true); localCache.removeNode(Fqn.ROOT); @@ -155,7 +155,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs catch (Exception e) { log.error("Problem purging local cache" ,e); } - + try { remoteCache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true); remoteCache.removeNode(Fqn.ROOT); @@ -163,46 +163,54 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs catch (Exception e) { log.error("Problem purging remote cache" ,e); } - + node1Exception = null; node2Exception = null; - + node1Failure = null; node2Failure = null; } - - protected static Configuration createConfiguration(String configName) { + + protected static Configuration createConfiguration(String configName, String configResource) { Configuration cfg = CacheTestUtil.buildConfiguration(REGION_PREFIX, MultiplexedJBossCacheRegionFactory.class, true, false); cfg.setProperty(MultiplexingCacheInstanceManager.ENTITY_CACHE_RESOURCE_PROP, configName); + if (configResource != null) { + cfg.setProperty(MultiplexingCacheInstanceManager.CACHE_FACTORY_RESOURCE_PROP, configResource); + } return cfg; } - + protected CacheDataDescription getCacheDataDescription() { return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE); } - + protected boolean isUsingOptimisticLocking() { return optimistic; } - + + public boolean isBlockingReads() + { + return !isUsingOptimisticLocking(); + } + protected boolean isUsingInvalidation() { return invalidation; } - + protected boolean isSynchronous() { return synchronous; } - + protected Fqn getRegionFqn(String regionName, String regionPrefix) { return BasicRegionAdapter.getTypeLastRegionFqn(regionName, regionPrefix, CollectionRegionImpl.TYPE); } - + /** * This is just a setup test where we assert that the cache config is * as we expected. */ public abstract void testCacheConfiguration(); - + /** * Test method for {@link TransactionalAccess#getRegion()}. */ @@ -223,7 +231,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs public void testPutFromLoadMinimal() throws Exception { putFromLoadTest(true); } - + /** * Simulate 2 nodes, both start, tx do a get, experience a cache miss, * then 'read from db.' First does a putFromLoad, then an evict (to represent a change). @@ -232,37 +240,37 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs * both start a new tx and get. First should see the updated data; * second should either see the updated data (isInvalidation()( == false) * or null (isInvalidation() == true). - * + * * @param useMinimalAPI * @throws Exception */ private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { - + final String KEY = KEY_BASE + testCount++; - + final CountDownLatch writeLatch1 = new CountDownLatch(1); final CountDownLatch writeLatch2 = new CountDownLatch(1); final CountDownLatch completionLatch = new CountDownLatch(2); - - Thread node1 = new Thread() { - + + Thread node1 = new Thread() { + public void run() { - - try { + + try { long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); - + assertEquals("node1 starts clean", null, localAccessStrategy.get(KEY, txTimestamp)); - + writeLatch1.await(); - + if (useMinimalAPI) { - localAccessStrategy.putFromLoad(KEY, VALUE2, txTimestamp, new Integer(2), true); + localAccessStrategy.putFromLoad(KEY, VALUE2, txTimestamp, new Integer(2), true); } else { localAccessStrategy.putFromLoad(KEY, VALUE2, txTimestamp, new Integer(2)); } - + BatchModeTransactionManager.getInstance().commit(); } catch (Exception e) { @@ -281,32 +289,32 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs } } }; - + Thread node2 = new Thread() { - - public void run() { - - try { + + public void run() { + + try { long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); - + assertNull("node2 starts clean", remoteAccessStrategy.get(KEY, txTimestamp)); - + // Let node1 write writeLatch1.countDown(); // Wait for node1 to finish writeLatch2.await(); - + // Let the first PFER propagate sleep(200); - + if (useMinimalAPI) { - remoteAccessStrategy.putFromLoad(KEY, VALUE1, txTimestamp, new Integer(1), true); + remoteAccessStrategy.putFromLoad(KEY, VALUE1, txTimestamp, new Integer(1), true); } else { remoteAccessStrategy.putFromLoad(KEY, VALUE1, txTimestamp, new Integer(1)); } - + BatchModeTransactionManager.getInstance().commit(); } catch (Exception e) { @@ -323,26 +331,26 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs } } }; - + node1.setDaemon(true); node2.setDaemon(true); - + node1.start(); - node2.start(); - + node2.start(); + assertTrue("Threads completed", completionLatch.await(2, TimeUnit.SECONDS)); - + if (node1Failure != null) throw node1Failure; if (node2Failure != null) throw node2Failure; - + assertEquals("node1 saw no exceptions", null, node1Exception); assertEquals("node2 saw no exceptions", null, node2Exception); - + // let the final PFER propagate sleep(100); - + long txTimestamp = System.currentTimeMillis(); String msg1 = "Correct node1 value"; String msg2 = "Correct node2 value"; @@ -361,8 +369,8 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs expected1 = VALUE2; expected2 = VALUE2; } - - assertEquals(msg1, expected1, localAccessStrategy.get(KEY, txTimestamp)); + + assertEquals(msg1, expected1, localAccessStrategy.get(KEY, txTimestamp)); assertEquals(msg2, expected2, remoteAccessStrategy.get(KEY, txTimestamp)); } @@ -382,7 +390,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs /** * Test method for {@link TransactionalAccess#evict(java.lang.Object)}. - * + * * FIXME add testing of the "immediately without regard for transaction * isolation" bit in the CollectionRegionAccessStrategy API. */ @@ -392,7 +400,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs /** * Test method for {@link TransactionalAccess#evictAll()}. - * + * * FIXME add testing of the "immediately without regard for transaction * isolation" bit in the CollectionRegionAccessStrategy API. */ @@ -401,41 +409,41 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs } private void evictOrRemoveTest(boolean evict) { - + final String KEY = KEY_BASE + testCount++; - + assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis())); assertNull("remote is clean", remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, localAccessStrategy.get(KEY, System.currentTimeMillis())); remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + // Wait for async propagation sleep(250); - + if (evict) localAccessStrategy.evict(KEY); else localAccessStrategy.remove(KEY); - + assertEquals(null, localAccessStrategy.get(KEY, System.currentTimeMillis())); - + assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); } private void evictOrRemoveAllTest(boolean evict) { - + final String KEY = KEY_BASE + testCount++; - + Fqn regionFqn = getRegionFqn(REGION_NAME, REGION_PREFIX); - + Node regionRoot = localCache.getRoot().getChild(regionFqn); assertFalse(regionRoot == null); assertEquals(0, getValidChildrenCount(regionRoot)); assertTrue(regionRoot.isResident()); - + if (isUsingOptimisticLocking()) { assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass()); } @@ -444,37 +452,37 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs assertFalse(regionRoot == null); assertEquals(0, getValidChildrenCount(regionRoot)); assertTrue(regionRoot.isResident()); - + if (isUsingOptimisticLocking()) { assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass()); } - + assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis())); assertNull("remote is clean", remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, localAccessStrategy.get(KEY, System.currentTimeMillis())); remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + // Wait for async propagation sleep(250); - + if (isUsingOptimisticLocking()) { regionRoot = localCache.getRoot().getChild(regionFqn); assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass()); regionRoot = remoteCache.getRoot().getChild(regionFqn); assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass()); } - + if (evict) localAccessStrategy.evictAll(); else localAccessStrategy.removeAll(); - + // This should re-establish the region root node in the optimistic case assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis())); - + regionRoot = localCache.getRoot().getChild(regionFqn); if (isUsingOptimisticLocking()) { assertFalse(regionRoot == null); @@ -486,7 +494,7 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid()); } - // Re-establishing the region root on the local node doesn't + // Re-establishing the region root on the local node doesn't // propagate it to other nodes. Do a get on the remote node to re-establish // This only adds a node in the case of optimistic locking assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); @@ -498,15 +506,15 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs assertTrue(regionRoot.isResident()); // Not invalidation, so we didn't insert a child above assertEquals(0, getValidChildrenCount(regionRoot)); - } + } else { assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid()); } - + // Test whether the get above messes up the optimistic version remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + // Revalidate the region root regionRoot = remoteCache.getRoot().getChild(regionFqn); assertFalse(regionRoot == null); @@ -514,14 +522,14 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs assertTrue(regionRoot.isResident()); // Region root should have 1 child -- the one we added above assertEquals(1, getValidChildrenCount(regionRoot)); - + // Wait for async propagation of the putFromLoad sleep(250); - + assertEquals("local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(KEY, System.currentTimeMillis())); assertEquals("remote is correct", VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); } - + private int getValidChildrenCount(Node node) { int result = 0; for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { @@ -529,9 +537,9 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs result++; } } - return result; + return result; } - + private void rollback() { try { BatchModeTransactionManager.getInstance().rollback(); @@ -539,58 +547,64 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs catch (Exception e) { log.error(e.getMessage(), e); } - + } - + private static class AccessStrategyTestSetup extends TestSetup { - + private static final String PREFER_IPV4STACK = "java.net.preferIPv4Stack"; - - private String configName; + + private final String configResource; + private final String configName; private String preferIPv4Stack; - + public AccessStrategyTestSetup(Test test, String configName) { + this(test, configName, null); + } + + public AccessStrategyTestSetup(Test test, String configName, String configResource) { super(test); this.configName = configName; + this.configResource = configResource; } @Override protected void setUp() throws Exception { - super.setUp(); - - // Try to ensure we use IPv4; otherwise cluster formation is very slow + super.setUp(); + + // Try to ensure we use IPv4; otherwise cluster formation is very slow preferIPv4Stack = System.getProperty(PREFER_IPV4STACK); System.setProperty(PREFER_IPV4STACK, "true"); - - localCfg = createConfiguration(configName); + + localCfg = createConfiguration(configName, configResource); localRegionFactory = CacheTestUtil.startRegionFactory(localCfg); localCache = localRegionFactory.getCacheInstanceManager().getCollectionCacheInstance(); - - remoteCfg = createConfiguration(configName); + + remoteCfg = createConfiguration(configName, configResource); remoteRegionFactory = CacheTestUtil.startRegionFactory(remoteCfg); remoteCache = remoteRegionFactory.getCacheInstanceManager().getCollectionCacheInstance(); } @Override - protected void tearDown() throws Exception { + protected void tearDown() throws Exception { try { super.tearDown(); } finally { if (preferIPv4Stack == null) System.clearProperty(PREFER_IPV4STACK); - else - System.setProperty(PREFER_IPV4STACK, preferIPv4Stack); + else + System.setProperty(PREFER_IPV4STACK, preferIPv4Stack); } - + if (localRegionFactory != null) localRegionFactory.stop(); - + if (remoteRegionFactory != null) remoteRegionFactory.stop(); } - - + + } } diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccInvalidatedTransactionalTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccInvalidatedTransactionalTestCase.java new file mode 100644 index 0000000000..e42d06b6f6 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccInvalidatedTransactionalTestCase.java @@ -0,0 +1,62 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.collection; + +import org.hibernate.test.util.CacheTestUtil; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Tests TRANSACTIONAL access when pessimistic locking and invalidation are used. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccInvalidatedTransactionalTestCase extends AbstractTransactionalAccessTestCase { + + /** + * Create a new PessimisticTransactionalAccessTestCase. + * + * @param name + */ + public MvccInvalidatedTransactionalTestCase(String name) { + super(name); + } + + public static Test suite() throws Exception { + TestSuite suite = CacheTestUtil.createFailureExpectedSuite(MvccInvalidatedTransactionalTestCase.class); + return getTestSetup(suite, "mvcc-entity"); + } + + @Override + public void testCacheConfiguration() { + assertTrue("Using Invalidation", isUsingInvalidation()); + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + assertTrue("Synchronous mode", isSynchronous()); + } + + // Known failures + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccReadOnlyExtraAPITestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccReadOnlyExtraAPITestCase.java new file mode 100644 index 0000000000..060ab31da2 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccReadOnlyExtraAPITestCase.java @@ -0,0 +1,72 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.collection; + +import org.hibernate.cache.access.CollectionRegionAccessStrategy; + +/** + * Tests for the "extra API" in EntityRegionAccessStrategy; in this + * version using pessimistic locking with READ_ONLY access. + *

+ * By "extra API" we mean those methods that are superfluous to the + * function of the JBC integration, where the impl is a no-op or a static + * false return value, UnsupportedOperationException, etc. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccReadOnlyExtraAPITestCase extends OptimisticReadOnlyExtraAPITestCase { + + private static CollectionRegionAccessStrategy localAccessStrategy; + + /** + * Create a new PessimisticAccessStrategyExtraAPITestCase. + * + * @param name + */ + public MvccReadOnlyExtraAPITestCase(String name) { + super(name); + } + + @Override + protected String getCacheConfigName() { + return "mvcc-entity"; + } + + @Override + protected CollectionRegionAccessStrategy getCollectionAccessStrategy() { + return localAccessStrategy; + } + + @Override + protected void setCollectionAccessStrategy(CollectionRegionAccessStrategy strategy) { + localAccessStrategy = strategy; + } + + @Override + public void testCacheConfiguration() { + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + } + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccReadOnlyTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccReadOnlyTestCase.java new file mode 100644 index 0000000000..ee0ab78259 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccReadOnlyTestCase.java @@ -0,0 +1,63 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.collection; + +import org.hibernate.test.util.CacheTestUtil; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Tests READ_ONLY access when pessimistic locking and invalidation are used. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccReadOnlyTestCase extends AbstractReadOnlyAccessTestCase { + + /** + * Create a new PessimisticTransactionalAccessTestCase. + * + * @param name + */ + public MvccReadOnlyTestCase(String name) { + super(name); + } + + public static Test suite() throws Exception { + TestSuite suite = CacheTestUtil.createFailureExpectedSuite(MvccReadOnlyTestCase.class); + return getTestSetup(suite, "mvcc-entity"); + } + + // Known failures + + // Overrides + + @Override + public void testCacheConfiguration() { + assertTrue("Using Invalidation", isUsingInvalidation()); + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + } + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccReplicatedTransactionalTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccReplicatedTransactionalTestCase.java new file mode 100644 index 0000000000..cbf29dd181 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccReplicatedTransactionalTestCase.java @@ -0,0 +1,58 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.collection; + +import junit.framework.Test; + +/** + * Tests TRANSACTIONAL access when pessimistic locking and replication are used. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccReplicatedTransactionalTestCase extends AbstractTransactionalAccessTestCase { + + /** + * Create a new PessimisticTransactionalAccessTestCase. + * + * @param name + */ + public MvccReplicatedTransactionalTestCase(String name) { + super(name); + } + + public static Test suite() throws Exception { + return getTestSetup(MvccReplicatedTransactionalTestCase.class, "mvcc-shared"); + } + + @Override + public void testCacheConfiguration() { + assertFalse("Using Invalidation", isUsingInvalidation()); + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + assertTrue("Synchronous mode", isSynchronous()); + } + + + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccTransactionalExtraAPITestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccTransactionalExtraAPITestCase.java new file mode 100644 index 0000000000..d566c6cd59 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/collection/MvccTransactionalExtraAPITestCase.java @@ -0,0 +1,72 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.collection; + +import org.hibernate.cache.access.CollectionRegionAccessStrategy; + +/** + * Tests for the "extra API" in EntityRegionAccessStrategy; in this base + * version using Optimistic locking with TRANSACTIONAL access. + *

+ * By "extra API" we mean those methods that are superfluous to the + * function of the JBC integration, where the impl is a no-op or a static + * false return value, UnsupportedOperationException, etc. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccTransactionalExtraAPITestCase extends OptimisticTransactionalExtraAPITestCase { + + private static CollectionRegionAccessStrategy localAccessStrategy; + + /** + * Create a new PessimisticAccessStrategyExtraAPITestCase. + * + * @param name + */ + public MvccTransactionalExtraAPITestCase(String name) { + super(name); + } + + @Override + protected String getCacheConfigName() { + return "mvcc-entity"; + } + + @Override + protected CollectionRegionAccessStrategy getCollectionAccessStrategy() { + return localAccessStrategy; + } + + @Override + protected void setCollectionAccessStrategy(CollectionRegionAccessStrategy strategy) { + localAccessStrategy = strategy; + } + + @Override + public void testCacheConfiguration() { + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + } + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java index 43b671de6e..d73f9f833d 100644 --- a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/AbstractEntityRegionAccessStrategyTestCase.java @@ -55,9 +55,9 @@ import org.jboss.cache.Node; import org.jboss.cache.NodeSPI; import org.jboss.cache.transaction.BatchModeTransactionManager; -/** +/** * Base class for tests of EntityRegionAccessStrategy impls. - * + * * @author Brian Stansberry * @version $Revision: 1 $ */ @@ -67,46 +67,54 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac public static final String KEY_BASE = "KEY"; public static final String VALUE1 = "VALUE1"; public static final String VALUE2 = "VALUE2"; - + protected static int testCount; - + protected static Configuration localCfg; protected static JBossCacheRegionFactory localRegionFactory; protected static Cache localCache; protected static Configuration remoteCfg; protected static JBossCacheRegionFactory remoteRegionFactory; protected static Cache remoteCache; - + protected static boolean invalidation; protected static boolean optimistic; protected static boolean synchronous; - + protected EntityRegion localEntityRegion; protected EntityRegionAccessStrategy localAccessStrategy; protected EntityRegion remoteEntityRegion; protected EntityRegionAccessStrategy remoteAccessStrategy; - + protected Exception node1Exception; protected Exception node2Exception; - + protected AssertionFailedError node1Failure; protected AssertionFailedError node2Failure; - - + + public static Test getTestSetup(Class testClass, String configName) { - TestSuite suite = new TestSuite(testClass); - return new AccessStrategyTestSetup(suite, configName); + return getTestSetup(testClass, configName, null); } - + public static Test getTestSetup(Test test, String configName) { - return new AccessStrategyTestSetup(test, configName); + return getTestSetup(test, configName, null); } - - + + public static Test getTestSetup(Class testClass, String configName, String configResource) { + TestSuite suite = new TestSuite(testClass); + return new AccessStrategyTestSetup(suite, configName, configResource); + } + + public static Test getTestSetup(Test test, String configName, String configResource) { + return new AccessStrategyTestSetup(test, configName, configResource); + } + + /** * Create a new TransactionalAccessTestCase. - * + * * @param name */ public AbstractEntityRegionAccessStrategyTestCase(String name) { @@ -117,35 +125,35 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac protected void setUp() throws Exception { super.setUp(); - + // Sleep a bit to avoid concurrent FLUSH problem avoidConcurrentFlush(); - + localEntityRegion = localRegionFactory.buildEntityRegion(REGION_NAME, localCfg.getProperties(), getCacheDataDescription()); localAccessStrategy = localEntityRegion.buildAccessStrategy(getAccessType()); - + // Sleep a bit to avoid concurrent FLUSH problem avoidConcurrentFlush(); - + remoteEntityRegion = remoteRegionFactory.buildEntityRegion(REGION_NAME, remoteCfg.getProperties(), getCacheDataDescription()); remoteAccessStrategy = remoteEntityRegion.buildAccessStrategy(getAccessType()); - + node1Exception = null; node2Exception = null; - + node1Failure = null; node2Failure = null; } protected void tearDown() throws Exception { - + super.tearDown(); - + if (localEntityRegion != null) localEntityRegion.destroy(); if (remoteEntityRegion != null) remoteEntityRegion.destroy(); - + try { localCache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true); localCache.removeNode(Fqn.ROOT); @@ -153,7 +161,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac catch (Exception e) { log.error("Problem purging local cache" ,e); } - + try { remoteCache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true); remoteCache.removeNode(Fqn.ROOT); @@ -161,36 +169,39 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac catch (Exception e) { log.error("Problem purging remote cache" ,e); } - + node1Exception = null; node2Exception = null; - + node1Failure = null; node2Failure = null; } - - protected static Configuration createConfiguration(String configName) { + + protected static Configuration createConfiguration(String configName, String configResource) { Configuration cfg = CacheTestUtil.buildConfiguration(REGION_PREFIX, MultiplexedJBossCacheRegionFactory.class, true, false); cfg.setProperty(MultiplexingCacheInstanceManager.ENTITY_CACHE_RESOURCE_PROP, configName); + if (configResource != null) { + cfg.setProperty(MultiplexingCacheInstanceManager.CACHE_FACTORY_RESOURCE_PROP, configResource); + } return cfg; } - + protected CacheDataDescription getCacheDataDescription() { return new CacheDataDescriptionImpl(true, true, ComparableComparator.INSTANCE); } - + protected boolean isUsingOptimisticLocking() { return optimistic; } - + protected boolean isUsingInvalidation() { return invalidation; } - + protected boolean isSynchronous() { return synchronous; } - + protected Fqn getRegionFqn(String regionName, String regionPrefix) { return BasicRegionAdapter.getTypeLastRegionFqn(regionName, regionPrefix, EntityRegionImpl.TYPE); } @@ -201,24 +212,24 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac throw node1Failure; if (node2Failure != null) throw node2Failure; - + if (node1Exception != null) { log.error("node1 saw an exception", node1Exception); assertEquals("node1 saw no exceptions", null, node1Exception); } - + if (node2Exception != null) { log.error("node2 saw an exception", node2Exception); assertEquals("node2 saw no exceptions", null, node2Exception); } } - + /** * This is just a setup test where we assert that the cache config is * as we expected. */ public abstract void testCacheConfiguration(); - + /** * Test method for {@link TransactionalAccess#getRegion()}. */ @@ -239,7 +250,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac public void testPutFromLoadMinimal() throws Exception { putFromLoadTest(true); } - + /** * Simulate 2 nodes, both start, tx do a get, experience a cache miss, * then 'read from db.' First does a putFromLoad, then an update. @@ -248,39 +259,39 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac * both start a new tx and get. First should see the updated data; * second should either see the updated data (isInvalidation() == false) * or null (isInvalidation() == true). - * + * * @param useMinimalAPI * @throws Exception */ private void putFromLoadTest(final boolean useMinimalAPI) throws Exception { - + final String KEY = KEY_BASE + testCount++; - + final CountDownLatch writeLatch1 = new CountDownLatch(1); final CountDownLatch writeLatch2 = new CountDownLatch(1); final CountDownLatch completionLatch = new CountDownLatch(2); - - Thread node1 = new Thread() { - + + Thread node1 = new Thread() { + public void run() { - - try { + + try { long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); - + assertNull("node1 starts clean", localAccessStrategy.get(KEY, txTimestamp)); - + writeLatch1.await(); - + if (useMinimalAPI) { - localAccessStrategy.putFromLoad(KEY, VALUE1, txTimestamp, new Integer(1), true); + localAccessStrategy.putFromLoad(KEY, VALUE1, txTimestamp, new Integer(1), true); } else { localAccessStrategy.putFromLoad(KEY, VALUE1, txTimestamp, new Integer(1)); } - + localAccessStrategy.update(KEY, VALUE2, new Integer(2), new Integer(1)); - + BatchModeTransactionManager.getInstance().commit(); } catch (Exception e) { @@ -299,29 +310,29 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac } } }; - + Thread node2 = new Thread() { - - public void run() { - - try { + + public void run() { + + try { long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); - + assertNull("node1 starts clean", remoteAccessStrategy.get(KEY, txTimestamp)); - + // Let node1 write writeLatch1.countDown(); // Wait for node1 to finish writeLatch2.await(); - + if (useMinimalAPI) { - remoteAccessStrategy.putFromLoad(KEY, VALUE1, txTimestamp, new Integer(1), true); + remoteAccessStrategy.putFromLoad(KEY, VALUE1, txTimestamp, new Integer(1), true); } else { remoteAccessStrategy.putFromLoad(KEY, VALUE1, txTimestamp, new Integer(1)); } - + BatchModeTransactionManager.getInstance().commit(); } catch (Exception e) { @@ -338,32 +349,32 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac } } }; - + node1.setDaemon(true); node2.setDaemon(true); - + node1.start(); - node2.start(); - + node2.start(); + assertTrue("Threads completed", completionLatch.await(2, TimeUnit.SECONDS)); - + assertThreadsRanCleanly(); - + long txTimestamp = System.currentTimeMillis(); assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp)); - + if (isUsingInvalidation()) { if (isUsingOptimisticLocking()) - // The node is "deleted" but it's ghost data version prevents the stale node2 PFER + // The node is "deleted" but it's ghost data version prevents the stale node2 PFER assertEquals("Correct node2 value", null, remoteAccessStrategy.get(KEY, txTimestamp)); else { // no data version to prevent the PFER; we count on db locks preventing this - assertEquals("Expected node2 value", VALUE1, remoteAccessStrategy.get(KEY, txTimestamp)); + assertEquals("Expected node2 value", VALUE1, remoteAccessStrategy.get(KEY, txTimestamp)); } } else { // The node1 update is replicated, preventing the node2 PFER - assertEquals("Correct node2 value", VALUE2, remoteAccessStrategy.get(KEY, txTimestamp)); + assertEquals("Correct node2 value", VALUE2, remoteAccessStrategy.get(KEY, txTimestamp)); } } @@ -371,28 +382,28 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac * Test method for {@link TransactionalAccess#insert(java.lang.Object, java.lang.Object, java.lang.Object)}. */ public void testInsert() throws Exception { - + final String KEY = KEY_BASE + testCount++; - + final CountDownLatch readLatch = new CountDownLatch(1); final CountDownLatch commitLatch = new CountDownLatch(1); final CountDownLatch completionLatch = new CountDownLatch(2); - - Thread inserter = new Thread() { - + + Thread inserter = new Thread() { + public void run() { - - try { + + try { long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); - + assertNull("Correct initial value", localAccessStrategy.get(KEY, txTimestamp)); - + localAccessStrategy.insert(KEY, VALUE1, new Integer(1)); - + readLatch.countDown(); commitLatch.await(); - + BatchModeTransactionManager.getInstance().commit(); } catch (Exception e) { @@ -409,20 +420,20 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac } } }; - - Thread reader = new Thread() { - + + Thread reader = new Thread() { + public void run() { - - try { + + try { long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); - + readLatch.await(); - Object expected = isUsingOptimisticLocking() ? null : VALUE1; - + Object expected = !isBlockingReads() ? null : VALUE1; + assertEquals("Correct initial value", expected, localAccessStrategy.get(KEY, txTimestamp)); - + BatchModeTransactionManager.getInstance().commit(); } catch (Exception e) { @@ -440,13 +451,13 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac } } }; - + inserter.setDaemon(true); reader.setDaemon(true); inserter.start(); reader.start(); - - if (isUsingOptimisticLocking()) + + if (! isBlockingReads()) assertTrue("Threads completed", completionLatch.await(1, TimeUnit.SECONDS)); else { // Reader should be blocking for lock @@ -454,48 +465,53 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac commitLatch.countDown(); assertTrue("Threads completed", completionLatch.await(1, TimeUnit.SECONDS)); } - + assertThreadsRanCleanly(); - + long txTimestamp = System.currentTimeMillis(); assertEquals("Correct node1 value", VALUE1, localAccessStrategy.get(KEY, txTimestamp)); Object expected = isUsingInvalidation() ? null : VALUE1; assertEquals("Correct node2 value", expected, remoteAccessStrategy.get(KEY, txTimestamp)); } + public boolean isBlockingReads() + { + return !isUsingOptimisticLocking(); + } + /** * Test method for {@link TransactionalAccess#update(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)}. */ public void testUpdate() throws Exception { - + final String KEY = KEY_BASE + testCount++; - + // Set up initial state localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); - + // Let the async put propagate sleep(250); - + final CountDownLatch readLatch = new CountDownLatch(1); final CountDownLatch commitLatch = new CountDownLatch(1); final CountDownLatch completionLatch = new CountDownLatch(2); - - Thread updater = new Thread() { - + + Thread updater = new Thread() { + public void run() { - - try { + + try { long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); - + assertEquals("Correct initial value", VALUE1, localAccessStrategy.get(KEY, txTimestamp)); - + localAccessStrategy.update(KEY, VALUE2, new Integer(2), new Integer(1)); - + readLatch.countDown(); commitLatch.await(); - + BatchModeTransactionManager.getInstance().commit(); } catch (Exception e) { @@ -512,22 +528,22 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac } } }; - - Thread reader = new Thread() { - - public void run() { - try { + + Thread reader = new Thread() { + + public void run() { + try { long txTimestamp = System.currentTimeMillis(); BatchModeTransactionManager.getInstance().begin(); - + readLatch.await(); - + // This will block w/ pessimistic locking and then // read the new value; w/ optimistic it shouldn't // block and will read the old value - Object expected = isUsingOptimisticLocking() ? VALUE1 : VALUE2; + Object expected = !isBlockingReads() ? VALUE1 : VALUE2; assertEquals("Correct value", expected, localAccessStrategy.get(KEY, txTimestamp)); - + BatchModeTransactionManager.getInstance().commit(); } catch (Exception e) { @@ -542,28 +558,28 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac finally { commitLatch.countDown(); completionLatch.countDown(); - } + } } }; - + updater.setDaemon(true); reader.setDaemon(true); updater.start(); reader.start(); - - if (isUsingOptimisticLocking()) + + if (! isBlockingReads()) // Should complete promptly assertTrue(completionLatch.await(1, TimeUnit.SECONDS)); - else { + else { // Reader thread should be blocking assertFalse(completionLatch.await(250, TimeUnit.MILLISECONDS)); // Let the writer commit down commitLatch.countDown(); assertTrue(completionLatch.await(1, TimeUnit.SECONDS)); } - + assertThreadsRanCleanly(); - + long txTimestamp = System.currentTimeMillis(); assertEquals("Correct node1 value", VALUE2, localAccessStrategy.get(KEY, txTimestamp)); Object expected = isUsingInvalidation() ? null : VALUE2; @@ -586,7 +602,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac /** * Test method for {@link TransactionalAccess#evict(java.lang.Object)}. - * + * * FIXME add testing of the "immediately without regard for transaction * isolation" bit in the EntityRegionAccessStrategy API. */ @@ -596,7 +612,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac /** * Test method for {@link TransactionalAccess#evictAll()}. - * + * * FIXME add testing of the "immediately without regard for transaction * isolation" bit in the EntityRegionAccessStrategy API. */ @@ -605,43 +621,43 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac } private void evictOrRemoveTest(boolean evict) { - + final String KEY = KEY_BASE + testCount++; - + assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis())); assertNull("remote is clean", remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, localAccessStrategy.get(KEY, System.currentTimeMillis())); remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + // Wait for async propagation sleep(250); - + if (evict) localAccessStrategy.evict(KEY); else localAccessStrategy.remove(KEY); - + assertEquals(null, localAccessStrategy.get(KEY, System.currentTimeMillis())); - + // sleep(1000); - + assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); } private void evictOrRemoveAllTest(boolean evict) { - + final String KEY = KEY_BASE + testCount++; - + Fqn regionFqn = getRegionFqn(REGION_NAME, REGION_PREFIX); - + Node regionRoot = localCache.getRoot().getChild(regionFqn); assertFalse(regionRoot == null); assertEquals(0, getValidChildrenCount(regionRoot)); assertTrue(regionRoot.isResident()); - + if (isUsingOptimisticLocking()) { assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass()); } @@ -650,41 +666,41 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac assertFalse(regionRoot == null); assertEquals(0, getValidChildrenCount(regionRoot)); assertTrue(regionRoot.isResident()); - + if (isUsingOptimisticLocking()) { assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass()); } - + assertNull("local is clean", localAccessStrategy.get(KEY, System.currentTimeMillis())); assertNull("remote is clean", remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + localAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, localAccessStrategy.get(KEY, System.currentTimeMillis())); - + // Wait for async propagation sleep(250); - + remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + // Wait for async propagation sleep(250); - + if (isUsingOptimisticLocking()) { regionRoot = localCache.getRoot().getChild(regionFqn); assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass()); regionRoot = remoteCache.getRoot().getChild(regionFqn); assertEquals(NonLockingDataVersion.class, ((NodeSPI) regionRoot).getVersion().getClass()); } - + if (evict) localAccessStrategy.evictAll(); else localAccessStrategy.removeAll(); - + // This should re-establish the region root node in the optimistic case assertNull(localAccessStrategy.get(KEY, System.currentTimeMillis())); - + regionRoot = localCache.getRoot().getChild(regionFqn); if (isUsingOptimisticLocking()) { assertFalse(regionRoot == null); @@ -696,7 +712,7 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid()); } - // Re-establishing the region root on the local node doesn't + // Re-establishing the region root on the local node doesn't // propagate it to other nodes. Do a get on the remote node to re-establish assertEquals(null, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); @@ -707,15 +723,15 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac assertTrue(regionRoot.isResident()); // Not invalidation, so we didn't insert a child above assertEquals(0, getValidChildrenCount(regionRoot)); - } + } else { assertTrue("region root is removed", regionRoot == null || !regionRoot.isValid()); } - + // Test whether the get above messes up the optimistic version remoteAccessStrategy.putFromLoad(KEY, VALUE1, System.currentTimeMillis(), new Integer(1)); assertEquals(VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); - + // Revalidate the region root regionRoot = remoteCache.getRoot().getChild(regionFqn); assertFalse(regionRoot == null); @@ -723,14 +739,14 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac assertTrue(regionRoot.isResident()); // Region root should have 1 child -- the one we added above assertEquals(1, getValidChildrenCount(regionRoot)); - + // Wait for async propagation sleep(250); - + assertEquals("local is correct", (isUsingInvalidation() ? null : VALUE1), localAccessStrategy.get(KEY, System.currentTimeMillis())); assertEquals("remote is correct", VALUE1, remoteAccessStrategy.get(KEY, System.currentTimeMillis())); } - + private int getValidChildrenCount(Node node) { int result = 0; for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { @@ -738,9 +754,9 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac result++; } } - return result; + return result; } - + protected void rollback() { try { BatchModeTransactionManager.getInstance().rollback(); @@ -748,19 +764,25 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac catch (Exception e) { log.error(e.getMessage(), e); } - + } - + private static class AccessStrategyTestSetup extends TestSetup { - + private static final String PREFER_IPV4STACK = "java.net.preferIPv4Stack"; - - private String configName; + + private final String configResource; + private final String configName; private String preferIPv4Stack; - + public AccessStrategyTestSetup(Test test, String configName) { + this(test, configName, null); + } + + public AccessStrategyTestSetup(Test test, String configName, String configResource) { super(test); this.configName = configName; + this.configResource = configResource; } @Override @@ -771,39 +793,39 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac finally { if (preferIPv4Stack == null) System.clearProperty(PREFER_IPV4STACK); - else - System.setProperty(PREFER_IPV4STACK, preferIPv4Stack); + else + System.setProperty(PREFER_IPV4STACK, preferIPv4Stack); } - - // Try to ensure we use IPv4; otherwise cluster formation is very slow + + // Try to ensure we use IPv4; otherwise cluster formation is very slow preferIPv4Stack = System.getProperty(PREFER_IPV4STACK); System.setProperty(PREFER_IPV4STACK, "true"); - - localCfg = createConfiguration(configName); + + localCfg = createConfiguration(configName, configResource); localRegionFactory = CacheTestUtil.startRegionFactory(localCfg); localCache = localRegionFactory.getCacheInstanceManager().getEntityCacheInstance(); - - remoteCfg = createConfiguration(configName); + + remoteCfg = createConfiguration(configName, configResource); remoteRegionFactory = CacheTestUtil.startRegionFactory(remoteCfg); remoteCache = remoteRegionFactory.getCacheInstanceManager().getEntityCacheInstance(); - + invalidation = CacheHelper.isClusteredInvalidation(localCache); synchronous = CacheHelper.isSynchronous(localCache); optimistic = localCache.getConfiguration().getNodeLockingScheme() == org.jboss.cache.config.Configuration.NodeLockingScheme.OPTIMISTIC; } @Override - protected void tearDown() throws Exception { + protected void tearDown() throws Exception { super.tearDown(); - + if (localRegionFactory != null) localRegionFactory.stop(); - + if (remoteRegionFactory != null) remoteRegionFactory.stop(); } - - + + } } diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccInvalidatedTransactionalTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccInvalidatedTransactionalTestCase.java new file mode 100644 index 0000000000..84c5a79d89 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccInvalidatedTransactionalTestCase.java @@ -0,0 +1,68 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.entity; + +import org.hibernate.test.util.CacheTestUtil; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Tests TRANSACTIONAL access when MVCC locking and invalidation are used. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccInvalidatedTransactionalTestCase extends AbstractTransactionalAccessTestCase { + + /** + * Create a new PessimisticTransactionalAccessTestCase. + * + * @param name + */ + public MvccInvalidatedTransactionalTestCase(String name) { + super(name); + } + + public static Test suite() throws Exception { + TestSuite suite = CacheTestUtil.createFailureExpectedSuite(MvccInvalidatedTransactionalTestCase.class); + return getTestSetup(suite, "mvcc-entity"); + } + + // Known failures + + // Overrides + + @Override + public void testCacheConfiguration() { + assertTrue("Using Invalidation", isUsingInvalidation()); + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + assertTrue("Synchronous mode", isSynchronous()); + } + + @Override + public boolean isBlockingReads() { + return false; + } +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccReadOnlyExtraAPITestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccReadOnlyExtraAPITestCase.java new file mode 100644 index 0000000000..7a09044548 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccReadOnlyExtraAPITestCase.java @@ -0,0 +1,71 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.entity; + +import org.hibernate.cache.access.EntityRegionAccessStrategy; + +/** + * Tests for the "extra API" in EntityRegionAccessStrategy; in this + * version using pessimistic locking with READ_ONLY access. + *

+ * By "extra API" we mean those methods that are superfluous to the + * function of the JBC integration, where the impl is a no-op or a static + * false return value, UnsupportedOperationException, etc. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccReadOnlyExtraAPITestCase extends OptimisticReadOnlyExtraAPITestCase { + + private static EntityRegionAccessStrategy localAccessStrategy; + + /** + * Create a new PessimisticAccessStrategyExtraAPITestCase. + * + * @param name + */ + public MvccReadOnlyExtraAPITestCase(String name) { + super(name); + } + + @Override + protected String getCacheConfigName() { + return "mvcc-entity"; + } + + @Override + protected EntityRegionAccessStrategy getEntityAccessStrategy() { + return localAccessStrategy; + } + + @Override + protected void setEntityRegionAccessStrategy(EntityRegionAccessStrategy strategy) { + localAccessStrategy = strategy; + } + + @Override + public void testCacheConfiguration() { + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + } +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccReadOnlyTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccReadOnlyTestCase.java new file mode 100644 index 0000000000..c4c063f956 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccReadOnlyTestCase.java @@ -0,0 +1,68 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.entity; + +import org.hibernate.test.util.CacheTestUtil; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Tests READ_ONLY access when pessimistic locking and invalidation are used. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccReadOnlyTestCase extends AbstractReadOnlyAccessTestCase { + + /** + * Create a new PessimisticTransactionalAccessTestCase. + * + * @param name + */ + public MvccReadOnlyTestCase(String name) { + super(name); + } + + public static Test suite() throws Exception { + TestSuite suite = CacheTestUtil.createFailureExpectedSuite(MvccReadOnlyTestCase.class); + return getTestSetup(suite, "mvcc-entity"); + } + + // Known failures + + // Overrides + + + @Override + public void testCacheConfiguration() { + assertTrue("Using Invalidation", isUsingInvalidation()); + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + } + + @Override + public boolean isBlockingReads() { + return false; + } +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccReplicatedTransactionalTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccReplicatedTransactionalTestCase.java new file mode 100644 index 0000000000..8f4ce6448d --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccReplicatedTransactionalTestCase.java @@ -0,0 +1,62 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.entity; + +import junit.framework.Test; + +/** + * Tests TRANSACTIONAL access when pessimistic locking and replication are used. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccReplicatedTransactionalTestCase extends AbstractTransactionalAccessTestCase { + + /** + * Create a new PessimisticTransactionalAccessTestCase. + * + * @param name + */ + public MvccReplicatedTransactionalTestCase(String name) { + super(name); + } + + public static Test suite() throws Exception { + return getTestSetup(MvccReplicatedTransactionalTestCase.class, "mvcc-shared"); + } + + @Override + public void testCacheConfiguration() { + assertFalse("Using Invalidation", isUsingInvalidation()); + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + assertTrue("Synchronous mode", isSynchronous()); + } + + @Override + public boolean isBlockingReads() { + return false; + } + + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccTransactionalExtraAPITestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccTransactionalExtraAPITestCase.java new file mode 100644 index 0000000000..fa80612e7a --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/entity/MvccTransactionalExtraAPITestCase.java @@ -0,0 +1,71 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.entity; + +import org.hibernate.cache.access.EntityRegionAccessStrategy; + +/** + * Tests for the "extra API" in EntityRegionAccessStrategy; in this base + * version using Optimistic locking with TRANSACTIONAL access. + *

+ * By "extra API" we mean those methods that are superfluous to the + * function of the JBC integration, where the impl is a no-op or a static + * false return value, UnsupportedOperationException, etc. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MvccTransactionalExtraAPITestCase extends OptimisticTransactionalExtraAPITestCase { + + private static EntityRegionAccessStrategy localAccessStrategy; + + /** + * Create a new PessimisticAccessStrategyExtraAPITestCase. + * + * @param name + */ + public MvccTransactionalExtraAPITestCase(String name) { + super(name); + } + + @Override + protected String getCacheConfigName() { + return "mvcc-entity"; + } + + @Override + protected EntityRegionAccessStrategy getEntityAccessStrategy() { + return localAccessStrategy; + } + + @Override + protected void setEntityRegionAccessStrategy(EntityRegionAccessStrategy strategy) { + localAccessStrategy = strategy; + } + + @Override + public void testCacheConfiguration() { + assertFalse("Using Optimistic locking", isUsingOptimisticLocking()); + } +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/MVCCEntityReplicationTest.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/MVCCEntityReplicationTest.java new file mode 100644 index 0000000000..1784077139 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/MVCCEntityReplicationTest.java @@ -0,0 +1,47 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.functional; + + +/** + * Executes the superclass tests, but with Hibernate and JBoss Cache + * configured for optimistic locking. + * + * @author Brian Stansberry + */ +public class MVCCEntityReplicationTest extends PessimisticEntityReplicationTest +{ + + public MVCCEntityReplicationTest(String name) + { + super(name); + } + + @Override + protected String getEntityCacheConfigName() + { + return "mvcc-shared"; + } + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/MVCCJBossCacheTest.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/MVCCJBossCacheTest.java new file mode 100644 index 0000000000..6408825ac8 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/MVCCJBossCacheTest.java @@ -0,0 +1,64 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2007, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors.  All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.cache.jbc2.functional; + +import junit.framework.Test; + +import org.hibernate.cache.RegionFactory; +import org.hibernate.cache.jbc2.JBossCacheRegionFactory; +import org.hibernate.cache.jbc2.builder.SharedCacheInstanceManager; +import org.hibernate.cfg.Configuration; +import org.hibernate.junit.functional.FunctionalTestClassTestSuite; + +/** + * Basic functional test of a pessimistic locking entity + query cache. + * + * @author Brian Stansberry + */ +public class MVCCJBossCacheTest extends AbstractQueryCacheFunctionalTestCase { + + private static final String JBC_CONFIG = "org/hibernate/test/cache/jbc2/functional/mvcc-treecache.xml"; + + public MVCCJBossCacheTest(String x) { + super(x); + } + + public static Test suite() { + return new FunctionalTestClassTestSuite(MVCCJBossCacheTest.class); + } + + protected Class getCacheRegionFactory() { + return JBossCacheRegionFactory.class; + } + + /** + * Apply any region-factory specific configurations. + * + * @param the Configuration to update. + */ + protected void configureCacheFactory(Configuration cfg) { + cfg.setProperty(SharedCacheInstanceManager.CACHE_RESOURCE_PROP, JBC_CONFIG); + } + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/MVCCSessionRefreshTest.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/MVCCSessionRefreshTest.java new file mode 100644 index 0000000000..9a7caeb287 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/MVCCSessionRefreshTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, v. 2.1. This program is distributed in the + * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. You should have received a + * copy of the GNU Lesser General Public License, v.2.1 along with this + * distribution; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Red Hat Author(s): Brian Stansberry + */ + +package org.hibernate.test.cache.jbc2.functional; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.hibernate.test.cache.jbc2.functional.util.IsolatedCacheTestSetup; + +/** + * A SessionRefreshTest that uses an OPTIMISTIC cache config. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MVCCSessionRefreshTest extends PessimisticSessionRefreshTest +{ + + private static final String CACHE_CONFIG = "mvcc-entity"; + + /** + * Create a new OptimisticSessionRefreshTest. + * + * @param x + */ + public MVCCSessionRefreshTest(String x) + { + super(x); + } + + public static Test suite() throws Exception { + TestSuite suite = new TestSuite(MVCCSessionRefreshTest.class); + String[] acctClasses = { OUR_PACKAGE + ".Account", OUR_PACKAGE + ".AccountHolder" }; + return new IsolatedCacheTestSetup(suite, acctClasses, CACHE_CONFIG); + } + + @Override + protected String getEntityCacheConfigName() { + return CACHE_CONFIG; + } + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/bulk/MVCCBulkOperationsTest.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/bulk/MVCCBulkOperationsTest.java new file mode 100644 index 0000000000..73bf52af39 --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/bulk/MVCCBulkOperationsTest.java @@ -0,0 +1,59 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2006, Red Hat Middleware LLC, and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +package org.hibernate.test.cache.jbc2.functional.bulk; + +import junit.framework.Test; + +import org.hibernate.test.cache.jbc2.collection.OptimisticInvalidatedTransactionalTestCase; +import org.hibernate.test.util.CacheTestUtil; + + +/** + * Optimistic version of BulkOperationsUnitTestCase. + * + * @author Brian Stansberry + * + */ +public class MVCCBulkOperationsTest + extends PessimisticBulkOperationsTest +{ + + public static Test suite() throws Exception { + return CacheTestUtil.createFailureExpectedSuite(MVCCBulkOperationsTest.class); + } + + /** + * @param name + */ + public MVCCBulkOperationsTest(String name) + { + super(name); + } + + @Override + protected String getEntityCacheConfigName() + { + return "mvcc-entity"; + } + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/classloader/MVCCIsolatedClassLoaderTest.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/classloader/MVCCIsolatedClassLoaderTest.java new file mode 100644 index 0000000000..67fc9f12ce --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/classloader/MVCCIsolatedClassLoaderTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, v. 2.1. This program is distributed in the + * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. You should have received a + * copy of the GNU Lesser General Public License, v.2.1 along with this + * distribution; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Red Hat Author(s): Brian Stansberry + */ + +package org.hibernate.test.cache.jbc2.functional.classloader; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.hibernate.test.cache.jbc2.functional.util.IsolatedCacheTestSetup; + +/** + * Optimistic locking version of IsolatedClassLoaderTest. + * + * @author Brian Stansberry + * @version $Revision: 1 $ + */ +public class MVCCIsolatedClassLoaderTest extends PessimisticIsolatedClassLoaderTest +{ + private static final String CACHE_CONFIG = "mvcc-shared"; + + /** + * Create a new OptimisticIsolatedClassLoaderTest. + * + * @param name + */ + public MVCCIsolatedClassLoaderTest(String name) + { + super(name); + } + + public static Test suite() throws Exception { + TestSuite suite = new TestSuite(MVCCIsolatedClassLoaderTest.class); + String[] acctClasses = { OUR_PACKAGE + ".Account", OUR_PACKAGE + ".AccountHolder" }; + return new IsolatedCacheTestSetup(suite, acctClasses, CACHE_CONFIG); + } + + protected String getEntityCacheConfigName() { + return CACHE_CONFIG; + } + +} diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/mvcc-treecache.xml b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/mvcc-treecache.xml new file mode 100644 index 0000000000..002af9c5fc --- /dev/null +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/mvcc-treecache.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + jboss:service=Naming + jboss:service=TransactionManager + + + MVCC + + + + READ_COMMITTED + + + LOCAL + + + TreeCache-Cluster + + + + + + + + + + + + + + + + + + + + + true + + true + + + 20000 + + + 20000 + + + 15000 + + + 0 + + + + + 5 + + org.jboss.cache.eviction.LRUPolicy + + + 5000 + 1000 + + + + 0 + 0 + + + + + + + diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/optimistic-treecache.xml b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/optimistic-treecache.xml index 745f67db20..26c9259d8c 100755 --- a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/optimistic-treecache.xml +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/optimistic-treecache.xml @@ -56,7 +56,8 @@ OPTIMISTIC @@ -137,6 +138,9 @@ true + + 0 + diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/pessimistic-treecache.xml b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/pessimistic-treecache.xml index e8b5844b73..5d5ff35f01 100755 --- a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/pessimistic-treecache.xml +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/functional/pessimistic-treecache.xml @@ -45,6 +45,15 @@ jboss:service=Naming jboss:service=TransactionManager + + + PESSIMISTIC + 15000 + + 0 + diff --git a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/query/QueryRegionImplTestCase.java b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/query/QueryRegionImplTestCase.java index cf63f0cc77..97f5c25d84 100644 --- a/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/query/QueryRegionImplTestCase.java +++ b/cache-jbosscache2/src/test/java/org/hibernate/test/cache/jbc2/query/QueryRegionImplTestCase.java @@ -94,6 +94,10 @@ public class QueryRegionImplTestCase extends AbstractGeneralDataRegionTestCase { public void testPutDoesNotBlockGetPessimistic() throws Exception { putDoesNotBlockGetTest("pessimistic-shared"); } + + public void testPutDoesNotBlockGetMVCC() throws Exception { + putDoesNotBlockGetTest("mvcc-shared"); + } private void putDoesNotBlockGetTest(String configName) throws Exception { @@ -190,6 +194,10 @@ public class QueryRegionImplTestCase extends AbstractGeneralDataRegionTestCase { getDoesNotBlockPutTest("pessimistic-shared-repeatable"); } + public void testGetDoesNotBlockPutMVCC() throws Exception { + getDoesNotBlockPutTest("mvcc-shared"); + } + private void getDoesNotBlockPutTest(String configName) throws Exception { Configuration cfg = createConfiguration(configName); diff --git a/cache-jbosscache2/src/test/resources/treecache.xml b/cache-jbosscache2/src/test/resources/treecache.xml index fced8c1c30..291f842255 100755 --- a/cache-jbosscache2/src/test/resources/treecache.xml +++ b/cache-jbosscache2/src/test/resources/treecache.xml @@ -51,9 +51,9 @@ - PESSIMISTIC + MVCC true + + 0 +