package org.infinispan.expiration.impl; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNull; import java.util.concurrent.TimeUnit; import org.infinispan.Cache; import org.infinispan.atomic.AtomicMap; import org.infinispan.atomic.AtomicMapLookup; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.cache.VersioningScheme; import org.infinispan.container.entries.CacheEntry; import org.infinispan.expiration.ExpirationManager; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.MultipleCacheManagersTest; import org.infinispan.test.TestingUtil; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.infinispan.transaction.LockingMode; import org.infinispan.transaction.TransactionMode; import org.infinispan.util.ControlledConsistentHashFactory; import org.infinispan.util.ControlledTimeService; import org.infinispan.util.TimeService; import org.infinispan.util.concurrent.IsolationLevel; import org.testng.annotations.Test; /** * Test that the default expiration parameters are set properly with clustered write skew checks enabled. * * See https://issues.jboss.org/browse/ISPN-7105 */ @Test(groups = "functional", testName = "expiration.impl.ExpirationWriteSkewFunctionalTest") public class ExpirationWithClusteredWriteSkewTest extends MultipleCacheManagersTest { public static final String KEY = "key"; public static final String VALUE = "value"; private ControlledTimeService timeService = new ControlledTimeService(0); private ExpirationManager expirationManager1; private ExpirationManager expirationManager2; @Override protected void createCacheManagers() throws Throwable { ControlledConsistentHashFactory chf = new ControlledConsistentHashFactory(0, 1); ConfigurationBuilder builder = TestCacheManagerFactory.getDefaultCacheConfiguration(true); builder .clustering() .cacheMode(CacheMode.REPL_SYNC) .hash() .numSegments(1) .consistentHashFactory(chf) .expiration() .lifespan(10, TimeUnit.SECONDS) .transaction() .transactionMode(TransactionMode.TRANSACTIONAL) .lockingMode(LockingMode.OPTIMISTIC) .locking() .isolationLevel(IsolationLevel.REPEATABLE_READ) .writeSkewCheck(true) .versioning() .enable() .scheme(VersioningScheme.SIMPLE); createCluster(builder, 2); TestingUtil.replaceComponent(manager(0), TimeService.class, timeService, true); expirationManager1 = TestingUtil.extractComponent(cache(0), ExpirationManager.class); TestingUtil.replaceComponent(manager(1), TimeService.class, timeService, true); expirationManager2 = TestingUtil.extractComponent(cache(1), ExpirationManager.class); } public void testDefaultExpirationInTransaction() throws Exception { Cache<Object, Object> cache0 = cache(0); tm(0).begin(); assertNull(cache0.get(KEY)); cache0.put(KEY, VALUE); CacheEntry entryInTx = cache0.getAdvancedCache().getCacheEntry(KEY); assertEquals(10000, entryInTx.getLifespan()); tm(0).commit(); CacheEntry entryAfterCommit = cache0.getAdvancedCache().getCacheEntry(KEY); assertEquals(10000, entryAfterCommit.getLifespan()); timeService.advance(TimeUnit.SECONDS.toMillis(10) + 1); // Required since cache loader size calls to store - we have to make sure the store expires entries expirationManager1.processExpiration(); expirationManager2.processExpiration(); assertEquals(0, cache0.size()); } }