package org.infinispan.persistence; import static org.infinispan.test.TestingUtil.withCacheManager; import static org.infinispan.test.TestingUtil.withCacheManagers; import static org.testng.AssertJUnit.assertEquals; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.infinispan.Cache; import org.infinispan.configuration.cache.AbstractStoreConfigurationBuilder; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.cache.PersistenceConfigurationBuilder; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.AbstractInfinispanTest; import org.infinispan.test.CacheManagerCallable; import org.infinispan.test.MultiCacheManagerCallable; import org.infinispan.test.TestingUtil; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.testng.annotations.Test; /** * This is a base functional test class for tests with multiple cache stores * * @author Michal Linhard (mlinhard@redhat.com) */ @Test(groups = "unit", testName = "persistence.MultiStoresFunctionalTest") public abstract class MultiStoresFunctionalTest<TStoreConfigurationBuilder extends AbstractStoreConfigurationBuilder<?, ?>> extends AbstractInfinispanTest { private static final long TIMEOUT = 10000; protected abstract TStoreConfigurationBuilder buildCacheStoreConfig(PersistenceConfigurationBuilder builder, String discriminator) throws Exception; /** * * Create n configs using cache store. sets passivation = false, purge = false, fetch persistent * state = true */ protected List<ConfigurationBuilder> configs(int n, Method method) throws Exception { List<ConfigurationBuilder> r = new ArrayList<ConfigurationBuilder>(n); for (int i = 0; i < n; i++) { ConfigurationBuilder configBuilder = new ConfigurationBuilder(); configBuilder.clustering().cacheMode(CacheMode.DIST_SYNC).hash().numOwners(2); buildCacheStoreConfig(configBuilder.persistence().passivation(false), method.getName() + i).purgeOnStartup(false).fetchPersistentState(true); r.add(configBuilder); } return r; } /** * when a node that persisted KEY wakes up, it can't rewrite existing value. */ public void testStartStopOfBackupDoesntRewriteValue(Method m) throws Exception { final List<ConfigurationBuilder> configs = configs(2, m); withCacheManagers(new MultiCacheManagerCallable( TestCacheManagerFactory.createClusteredCacheManager(configs.get(0)), TestCacheManagerFactory.createClusteredCacheManager(configs.get(1))) { @Override public void call() { final EmbeddedCacheManager cacheManager0 = cms[0]; final EmbeddedCacheManager cacheManager1 = cms[1]; final Cache<String, String> cache0 = cacheManager0.getCache(); final Cache<String, String> cache1 = cacheManager1.getCache(); TestingUtil.blockUntilViewsChanged(TIMEOUT, 2, cache0, cache1); cache0.put("KEY", "VALUE V1"); assertEquals("VALUE V1", cache1.get("KEY")); TestingUtil.killCacheManagers(cacheManager1); TestingUtil.blockUntilViewsChanged(TIMEOUT, 1, cache0); cache0.put("KEY", "VALUE V2"); assertEquals("VALUE V2", cache0.get("KEY")); withCacheManager(new CacheManagerCallable( TestCacheManagerFactory.createClusteredCacheManager(configs.get(1))) { @Override public void call() { Cache<String, String> newCache = cm.getCache(); TestingUtil.blockUntilViewsChanged(TIMEOUT, 2, cache0, newCache); assertEquals("VALUE V2", newCache.get("KEY")); } }); } }); } /** * When node that persisted KEY2 it will resurrect previous value of KEY2. */ public void testStartStopOfBackupResurrectsDeletedKey(Method m) throws Exception { final List<ConfigurationBuilder> configs = configs(2, m); withCacheManagers(new MultiCacheManagerCallable( TestCacheManagerFactory.createClusteredCacheManager(configs.get(0)), TestCacheManagerFactory.createClusteredCacheManager(configs.get(1))) { @Override public void call() { final EmbeddedCacheManager cacheManager0 = cms[0]; final EmbeddedCacheManager cacheManager1 = cms[1]; final Cache<String, String> cache0 = cacheManager0.getCache(); final Cache<String, String> cache1 = cacheManager1.getCache(); TestingUtil.blockUntilViewsChanged(TIMEOUT, 2, cache0, cache1); cache0.put("KEY2", "VALUE2 V1"); assertEquals("VALUE2 V1", cache1.get("KEY2")); TestingUtil.killCacheManagers(cacheManager1); TestingUtil.blockUntilViewsChanged(TIMEOUT, 1, cache0); cache0.put("KEY2", "VALUE2 V2"); assertEquals("VALUE2 V2", cache0.get("KEY2")); cache0.remove("KEY2"); assertEquals(null, cache0.get("KEY2")); withCacheManager(new CacheManagerCallable( TestCacheManagerFactory.createClusteredCacheManager(configs.get(1))) { @Override public void call() { Cache<String, String> newCache = cm.getCache(); TestingUtil.blockUntilViewsChanged(TIMEOUT, 2, cache0, newCache); assertEquals("VALUE2 V1", newCache.get("KEY2")); } }); } }); } }