/** * Copyright 2011-2013 Terracotta, Inc. * Copyright 2011-2013 Oracle, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jsr107.tck.expiry; import org.jsr107.tck.event.CacheEntryListenerClient; import org.jsr107.tck.event.CacheEntryListenerServer; import org.jsr107.tck.integration.CacheLoaderClient; import org.jsr107.tck.integration.CacheLoaderServer; import org.jsr107.tck.integration.RecordingCacheLoader; import org.jsr107.tck.processor.AssertNotPresentEntryProcessor; import org.jsr107.tck.processor.CombineEntryProcessor; import org.jsr107.tck.processor.GetEntryProcessor; import org.jsr107.tck.processor.SetEntryProcessor; import org.jsr107.tck.testutil.CacheTestSupport; import org.jsr107.tck.testutil.ExcludeListExcluder; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import javax.cache.Cache; import javax.cache.Cache.Entry; import javax.cache.configuration.Factory; import javax.cache.configuration.FactoryBuilder; import javax.cache.configuration.MutableCacheEntryListenerConfiguration; import javax.cache.configuration.MutableConfiguration; import javax.cache.expiry.AccessedExpiryPolicy; import javax.cache.expiry.CreatedExpiryPolicy; import javax.cache.expiry.Duration; import javax.cache.expiry.ExpiryPolicy; import javax.cache.expiry.ModifiedExpiryPolicy; import javax.cache.expiry.TouchedExpiryPolicy; import javax.cache.integration.CompletionListenerFuture; import javax.cache.processor.EntryProcessor; import java.io.IOException; import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.jsr107.tck.testutil.TestSupport.MBeanType.CacheStatistics; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** * Unit Tests for expiring cache entries with {@link javax.cache.expiry.ExpiryPolicy}s. * * @author Brian Oliver * @author Joe Fialli */ public class CacheExpiryTest extends CacheTestSupport<Integer, Integer> { /** * Rule used to exclude tests */ @Rule public ExcludeListExcluder rule = new ExcludeListExcluder(this.getClass()); private ExpiryPolicyServer expiryPolicyServer; private ExpiryPolicyClient expiryPolicyClient; @Before public void setUp() throws IOException { //establish and open a ExpiryPolicyServer to handle cache //cache loading requests from a ExpiryPolicyClient expiryPolicyServer = new ExpiryPolicyServer(10005); expiryPolicyServer.open(); //establish a ExpiryPolicyClient that a Cache can use for computing expiry policy //(via the ExpiryPolicyServer) expiryPolicyClient = new ExpiryPolicyClient(expiryPolicyServer.getInetAddress(), expiryPolicyServer.getPort()); cacheEntryListenerServer = new CacheEntryListenerServer<Integer, Integer>(10011, Integer.class, Integer.class); cacheEntryListenerServer.open(); cacheEntryListerClient = new CacheEntryListenerClient<>(cacheEntryListenerServer.getInetAddress(), cacheEntryListenerServer.getPort()); } @Override protected MutableConfiguration<Integer, Integer> newMutableConfiguration() { return new MutableConfiguration<Integer, Integer>().setTypes(Integer.class, Integer.class); } @Override protected MutableConfiguration<Integer, Integer> extraSetup(MutableConfiguration<Integer, Integer> configuration) { listener = new CacheTestSupport.MyCacheEntryListener<Integer, Integer>(); //establish a CacheEntryListenerClient that a Cache can use for CacheEntryListening //(via the CacheEntryListenerServer) listenerConfiguration = new MutableCacheEntryListenerConfiguration<>(FactoryBuilder.factoryOf(cacheEntryListerClient), null, true, true); cacheEntryListenerServer.addCacheEventListener(listener); return configuration.addCacheEntryListenerConfiguration(listenerConfiguration); } @After public void cleanupAfterEachTest() throws InterruptedException { for (String cacheName : getCacheManager().getCacheNames()) { getCacheManager().destroyCache(cacheName); } expiryPolicyServer.close(); expiryPolicyServer = null; //close the server cacheEntryListenerServer.close(); cacheEntryListenerServer = null; } @Test public void testCacheStatisticsRemoveAll() throws Exception { long _EXPIRY_MILLIS = 3; //cannot be zero or will not be added to the cache ExpiryPolicy policy = new CreatedExpiryPolicy(new Duration(TimeUnit.MILLISECONDS, _EXPIRY_MILLIS)); expiryPolicyServer.setExpiryPolicy(policy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)).setStatisticsEnabled(true); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); for (int i = 0; i < 100; i++) { cache.put(i, i+100); } //should work with all implementations Thread.sleep(_EXPIRY_MILLIS); cache.removeAll(); assertEquals(100L, lookupManagementAttribute(cache, CacheStatistics, "CachePuts")); //Removals does not count expired entries assertEquals(0L, lookupManagementAttribute(cache, CacheStatistics, "CacheRemovals")); } @Test public void testCacheStatisticsRemoveAllNoneExpired() throws Exception { ExpiryPolicy policy = new CreatedExpiryPolicy(Duration.ETERNAL); expiryPolicyServer.setExpiryPolicy(policy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)) .setStatisticsEnabled(true); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); for (int i = 0; i < 100; i++) { cache.put(i, i+100); } cache.removeAll(); assertEquals(100L, lookupManagementAttribute(cache, CacheStatistics, "CachePuts")); assertEquals(100L, lookupManagementAttribute(cache, CacheStatistics, "CacheRemovals")); } /** * Assert "The minimum allowed TimeUnit is TimeUnit.MILLISECONDS. */ @Test(expected = IllegalArgumentException.class) public void microsecondsInvalidDuration() { Duration invalidDuration = new Duration(TimeUnit.MICROSECONDS, 0); assertTrue("expected IllegalArgumentException for TimeUnit below minimum of MILLISECONDS", invalidDuration == null); } @Test(expected = IllegalArgumentException.class) public void nanosecondsInvalidDuration() { Duration invalidDuration = new Duration(TimeUnit.NANOSECONDS, 0); assertTrue("expected IllegalArgumentException for TimeUnit below minimum of MILLISECONDS", invalidDuration == null); } /** * Ensure that a cache using a {@link javax.cache.expiry.ExpiryPolicy} configured to * return a {@link Duration#ZERO} for newly created entries will immediately * expire the entries. */ private void expire_whenCreated(Factory<? extends ExpiryPolicy> expiryPolicyFactory) { MutableConfiguration<Integer, Integer> config = new MutableConfiguration<Integer, Integer>(); config.setTypes(Integer.class, Integer.class); config.setExpiryPolicyFactory(expiryPolicyFactory); config = extraSetup(config); config.setStatisticsEnabled(true); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.put(1, 1); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); assertEquals(0, listener.getCreated()); cache.put(1, 1); assertFalse(cache.remove(1)); cache.put(1, 1); assertFalse(cache.remove(1, 1)); cache.getAndPut(1, 1); assertEquals(0, listener.getCreated()); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.putIfAbsent(1, 1); assertEquals(0, listener.getCreated()); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); map.put(1, 1); cache.putAll(map); assertEquals(0, listener.getCreated()); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.put(1, 1); assertEquals(0, listener.getCreated()); assertFalse(cache.iterator().hasNext()); cache.getAndPut(1, 1); assertEquals(0, listener.getCreated()); } @Test public void expire_whenCreated_ParameterizedExpiryPolicy() { expire_whenCreated(FactoryBuilder.factoryOf(new ParameterizedExpiryPolicy(Duration.ZERO, null, null))); } @Test public void expire_whenCreated_CreatedExpiryPolicy() { expire_whenCreated(FactoryBuilder.factoryOf(new CreatedExpiryPolicy(Duration.ZERO))); } @Test public void expire_whenCreated_AccessedExpiryPolicy() { // since AccessedExpiryPolicy uses same duration for created and accessed, this policy will work same as // CreatedExpiryPolicy for this test. expire_whenCreated(FactoryBuilder.factoryOf(new AccessedExpiryPolicy(Duration.ZERO))); } @Test public void expire_whenCreated_TouchedExpiryPolicy() { // since TouchedExpiryPolicy uses same duration for created and accessed, this policy will work same as // CreatedExpiryPolicy for this test. expire_whenCreated(FactoryBuilder.factoryOf(new TouchedExpiryPolicy(Duration.ZERO))); } @Test public void expire_whenCreated_ModifiedExpiryPolicy() { // since TouchedExpiryPolicy uses same duration for created and accessed, this policy will work same as // CreatedExpiryPolicy for this test. expire_whenCreated(FactoryBuilder.factoryOf(new ModifiedExpiryPolicy(Duration.ZERO))); } /** * Ensure that a cache using a {@link javax.cache.expiry.ExpiryPolicy} configured to * return a {@link Duration#ZERO} after accessing entries will immediately * expire the entries. */ @Test public void expire_whenAccessed() { MutableConfiguration<Integer, Integer> config = new MutableConfiguration<Integer, Integer>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(new ParameterizedExpiryPolicy(Duration.ETERNAL, Duration.ZERO, null))); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertNotNull(cache.get(1)); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertNotNull(cache.get(1)); assertFalse(cache.containsKey(1)); assertNull(cache.getAndReplace(1, 2)); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertNotNull(cache.get(1)); assertFalse(cache.containsKey(1)); assertNull(cache.getAndRemove(1)); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertNotNull(cache.get(1)); assertFalse(cache.remove(1)); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertNotNull(cache.get(1)); assertFalse(cache.remove(1, 1)); cache.getAndPut(1, 1); assertTrue(cache.containsKey(1)); assertNotNull(cache.get(1)); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.getAndPut(1, 1); assertTrue(cache.containsKey(1)); assertNotNull(cache.getAndPut(1, 1)); assertTrue(cache.containsKey(1)); assertNotNull(cache.get(1)); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.putIfAbsent(1, 1); assertTrue(cache.containsKey(1)); assertNotNull(cache.get(1)); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); map.put(1, 1); cache.putAll(map); assertTrue(cache.containsKey(1)); assertNotNull(cache.get(1)); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.put(1, 1); Iterator<Entry<Integer, Integer>> iterator = cache.iterator(); assertTrue(iterator.hasNext()); assertEquals((Integer) 1, iterator.next().getValue()); assertFalse(cache.iterator().hasNext()); } /** * Ensure that a cache using a {@link javax.cache.expiry.ExpiryPolicy} configured to * return a {@link Duration#ZERO} after modifying entries will immediately * expire the entries. */ @Test public void expire_whenModified() { MutableConfiguration<Integer, Integer> config = new MutableConfiguration<Integer, Integer>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(new ParameterizedExpiryPolicy(Duration.ETERNAL, null, Duration.ZERO))); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertTrue(cache.containsKey(1)); assertEquals((Integer) 1, cache.get(1)); assertEquals((Integer) 1, cache.get(1)); cache.put(1, 2); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertEquals((Integer) 1, cache.get(1)); cache.put(1, 2); assertFalse(cache.remove(1)); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertEquals((Integer) 1, cache.get(1)); cache.put(1, 2); assertFalse(cache.remove(1, 2)); cache.getAndPut(1, 1); assertTrue(cache.containsKey(1)); assertEquals((Integer) 1, cache.get(1)); cache.put(1, 2); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.getAndPut(1, 1); assertTrue(cache.containsKey(1)); assertEquals((Integer) 1, cache.getAndPut(1, 2)); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertEquals((Integer) 1, cache.get(1)); HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); map.put(1, 2); cache.putAll(map); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertEquals((Integer) 1, cache.get(1)); cache.replace(1, 2); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.put(1, 1); assertTrue(cache.containsKey(1)); assertEquals((Integer) 1, cache.get(1)); cache.replace(1, 1, 2); assertFalse(cache.containsKey(1)); assertNull(cache.get(1)); cache.put(1, 1); assertTrue(cache.iterator().hasNext()); assertEquals((Integer) 1, cache.iterator().next().getValue()); assertTrue(cache.containsKey(1)); assertEquals((Integer) 1, cache.iterator().next().getValue()); cache.put(1, 2); assertFalse(cache.iterator().hasNext()); } // Next set of tests verify table from jsr 107 spec on how each of the cache methods interact with a // configured ExpiryPolicy method getting called. // There is one test per row in table. @Test public void containsKeyShouldNotCallExpiryPolicyMethods() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); } @Test public void getShouldCallGetExpiryForAccessedEntry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); // when getting a non-existent entry, getExpiryForAccessedEntry is not called. cache.get(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); // when getting an existing entry, getExpiryForAccessedEntry is called. cache.get(1); assertThat(expiryPolicy.getCreationCount(),is(0)); assertThat(expiryPolicy.getAccessCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); } @Test public void getAllShouldCallGetExpiryForAccessedEntry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); Set<Integer> keys = new HashSet<>(); keys.add(1); keys.add(2); // when getting a non-existent entry, getExpiryForAccessedEntry is not called. cache.getAll(keys); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.put(1, 1); cache.put(2, 2); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(2)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); // when getting an existing entry, getExpiryForAccessedEntry is called. cache.get(1); cache.get(2); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), greaterThanOrEqualTo(2)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); } @Test public void getAndPutShouldCallEitherCreatedOrModifiedExpiryPolicy() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.getAndPut(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); cache.getAndPut(1, 2); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(1)); expiryPolicy.resetCount(); } @Test public void getAndRemoveShouldNotCallExpiryPolicyMethods() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); // verify case when entry is non-existent cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.getAndRemove(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); // verify case when entry exist cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); int value = cache.getAndRemove(1); assertThat(value, is(1)); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); } @Test public void getAndReplaceShouldCallGetExpiryForModifiedEntry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.getAndReplace(1, 1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); int oldValue = cache.getAndReplace(1, 2); assertEquals(1, oldValue); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(1)); expiryPolicy.resetCount(); } // Skip negative to verify getCacheManager, getConfiguration or getName not calling getExpiryFor*. // They are not methods that access/mutate entries in cache. @Test public void iteratorNextShouldCallGetExpiryForAccessedEntry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); Set<Integer> keys = new HashSet<>(); keys.add(1); keys.add(2); cache.put(1, 1); cache.put(2, 2); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(2)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); // when getting an existing entry, getExpiryForAccessedEntry is called. Iterator<Entry<Integer, Integer>> iter = cache.iterator(); int count = 0; while (iter.hasNext()) { Entry<Integer, Integer> entry = iter.next(); count++; assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); } } @Test public void loadAllWithReadThroughEnabledShouldCallGetExpiryForCreatedEntry() throws IOException, ExecutionException, InterruptedException { //establish and open a CacheLoaderServer to handle cache //cache loading requests from a CacheLoaderClient // this cacheLoader just returns the key as the value. RecordingCacheLoader<Integer> recordingCacheLoader = new RecordingCacheLoader<>(); try (CacheLoaderServer<Integer, Integer> cacheLoaderServer = new CacheLoaderServer<>(10000, recordingCacheLoader)) { cacheLoaderServer.open(); //establish a CacheLoaderClient that a Cache can use for loading entries //(via the CacheLoaderServer) CacheLoaderClient<Integer, Integer> cacheLoader = new CacheLoaderClient<>(cacheLoaderServer.getInetAddress(), cacheLoaderServer.getPort()); CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); config.setCacheLoaderFactory(FactoryBuilder.factoryOf(cacheLoader)); config.setReadThrough(true); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); final Integer INITIAL_KEY = 123; final Integer MAX_KEY_VALUE = INITIAL_KEY + 4; // set half of the keys so half of loadAdd will be loaded Set<Integer> keys = new HashSet<>(); for (int key = INITIAL_KEY; key <= MAX_KEY_VALUE; key++) { keys.add(key); } // verify read-through of getValue of non-existent entries CompletionListenerFuture future = new CompletionListenerFuture(); cache.loadAll(keys, false, future); //wait for the load to complete future.get(); assertThat(future.isDone(), is(true)); assertThat(recordingCacheLoader.getLoadCount(), is(keys.size())); assertThat(expiryPolicy.getCreationCount(),greaterThanOrEqualTo(keys.size())); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); for (Integer key : keys) { assertThat(recordingCacheLoader.hasLoaded(key), is(true)); assertThat(cache.get(key), is(equalTo(key))); } assertThat(expiryPolicy.getAccessCount(), greaterThanOrEqualTo(keys.size())); expiryPolicy.resetCount(); // verify read-through of getValue for existing entries AND replaceExistingValues is true. final boolean REPLACE_EXISTING_VALUES = true; future = new CompletionListenerFuture(); cache.loadAll(keys, REPLACE_EXISTING_VALUES, future); //wait for the load to complete future.get(); assertThat(future.isDone(), is(true)); assertThat(recordingCacheLoader.getLoadCount(), is(keys.size() * 2)); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(keys.size())); expiryPolicy.resetCount(); for (Integer key : keys) { assertThat(recordingCacheLoader.hasLoaded(key), is(true)); assertThat(cache.get(key), is(equalTo(key))); } } } @Test public void putShouldCallGetExpiry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(1)); expiryPolicy.resetCount(); } @Test public void putAllShouldCallGetExpiry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); Map<Integer, Integer> map = new HashMap<>(); map.put(1, 1); map.put(2, 2); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); cache.putAll(map); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(1)); expiryPolicy.resetCount(); } @Test public void putIfAbsentShouldCallGetExpiry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); boolean result = cache.putIfAbsent(1, 1); assertTrue(result); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); result = cache.putIfAbsent(1, 2); assertFalse(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); } @Test public void removeEntryShouldNotCallExpiryPolicyMethods() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); boolean result = cache.remove(1); assertFalse(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); result = cache.remove(1); assertTrue(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); } @Test public void removeSpecifiedEntryShouldNotCallExpiryPolicyMethods() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); boolean result = cache.remove(1, 1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); result = cache.remove(1, 2); assertFalse(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(1)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); result = cache.remove(1, 1); assertTrue(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); } // skipping test for removeAll and removeAll specified keys for now. negative test of remove seems enough. @Test public void invokeSetValueShouldCallGetExpiry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); final Integer key = 123; final Integer setValue = 456; final Integer modifySetValue = 789; // verify create EntryProcessor processors[] = new EntryProcessor[]{ new AssertNotPresentEntryProcessor(null), new SetEntryProcessor<Integer, Integer>(setValue), new GetEntryProcessor<Integer, Integer>() }; Object[] result = (Object[]) cache.invoke(key, new CombineEntryProcessor(processors)); assertEquals(result[1], setValue); assertEquals(result[2], setValue); // expiry called should be for create, not for the get or modify. // Operations get combined in entry processor and only net result should be expiryPolicy method called. assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); // verify modify Integer resultValue = cache.invoke(key, new SetEntryProcessor<Integer, Integer>(modifySetValue)); assertEquals(modifySetValue, resultValue); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(1)); } @Test public void invokeMultiSetValueShouldCallGetExpiry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); final Integer key = 123; final Integer setValue = 456; final Integer modifySetValue = 789; // verify create EntryProcessor processors[] = new EntryProcessor[]{ new AssertNotPresentEntryProcessor(null), new SetEntryProcessor<Integer, Integer>(111), new SetEntryProcessor<Integer, Integer>(setValue), new GetEntryProcessor<Integer, Integer>() }; Object[] result = (Object[]) cache.invoke(key, new CombineEntryProcessor(processors)); assertEquals(result[1], 111); assertEquals(result[2], setValue); assertEquals(result[3], setValue); // expiry called should be for create, not for the get or modify. // Operations get combined in entry processor and only net result should be expiryPolicy method called. assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), greaterThanOrEqualTo(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(0)); } @Test public void invokeGetValueShouldCallGetExpiry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); final Integer key = 123; final Integer setValue = 456; // verify non-access to non-existent entry does not call getExpiryForAccessedEntry. no read-through scenario. Integer resultValue = cache.invoke(key, new GetEntryProcessor<Integer, Integer>()); assertEquals(null, resultValue); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); // verify access to existing entry. resultValue = cache.invoke(key, new SetEntryProcessor<Integer, Integer>(setValue)); assertEquals(resultValue, setValue); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); resultValue = cache.invoke(key, new GetEntryProcessor<Integer, Integer>()); assertEquals(setValue, resultValue); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); } @Test public void invokeGetValueWithReadThroughForNonExistentEntryShouldCallGetExpiryForCreatedEntry() throws IOException { //establish and open a CacheLoaderServer to handle cache //cache loading requests from a CacheLoaderClient // this cacheLoader just returns the key as the value. RecordingCacheLoader<Integer> recordingCacheLoader = new RecordingCacheLoader<>(); try (CacheLoaderServer<Integer, Integer> cacheLoaderServer = new CacheLoaderServer<>(10000, recordingCacheLoader)) { cacheLoaderServer.open(); //establish a CacheLoaderClient that a Cache can use for loading entries //(via the CacheLoaderServer) CacheLoaderClient<Integer, Integer> cacheLoader = new CacheLoaderClient<>(cacheLoaderServer.getInetAddress(), cacheLoaderServer.getPort()); CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); config.setCacheLoaderFactory(FactoryBuilder.factoryOf(cacheLoader)); config.setReadThrough(true); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); final Integer key = 123; final Integer recordingCacheLoaderValue = key; // verify create when read through is enabled and entry was non-existent in cache. Integer resultValue = cache.invoke(key, new GetEntryProcessor<Integer, Integer>()); assertEquals(recordingCacheLoaderValue, resultValue); assertTrue(recordingCacheLoader.hasLoaded(key)); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); } } @Test public void invokeAllSetValueShouldCallGetExpiry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); final Integer INITIAL_KEY = 123; final Integer MAX_KEY_VALUE = INITIAL_KEY + 4; final Integer setValue = 456; final Integer modifySetValue = 789; // set half of the keys so half of invokeAll will be modify and rest will be create. Set<Integer> keys = new HashSet<>(); int createdCount = 0; for (int key = INITIAL_KEY; key <= MAX_KEY_VALUE; key++) { keys.add(key); if (key <= MAX_KEY_VALUE - 2) { cache.put(key, setValue); createdCount++; } } assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(createdCount)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); // verify modify or create cache.invokeAll(keys, new SetEntryProcessor<Integer, Integer>(setValue)); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(keys.size() - createdCount)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(createdCount)); expiryPolicy.resetCount(); // verify accessed cache.invokeAll(keys, new GetEntryProcessor<Integer, Integer>()); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), greaterThanOrEqualTo(keys.size())); assertThat(expiryPolicy.getUpdatedCount(), is(0)); } @Test public void invokeAllReadThroughEnabledGetOnNonExistentEntry() throws IOException { //establish and open a CacheLoaderServer to handle cache //cache loading requests from a CacheLoaderClient // this cacheLoader just returns the key as the value. RecordingCacheLoader<Integer> recordingCacheLoader = new RecordingCacheLoader<>(); try (CacheLoaderServer<Integer, Integer> cacheLoaderServer = new CacheLoaderServer<>(10000, recordingCacheLoader)) { cacheLoaderServer.open(); //establish a CacheLoaderClient that a Cache can use for loading entries //(via the CacheLoaderServer) CacheLoaderClient<Integer, Integer> cacheLoader = new CacheLoaderClient<>(cacheLoaderServer.getInetAddress(), cacheLoaderServer.getPort()); CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); config.setCacheLoaderFactory(FactoryBuilder.factoryOf(cacheLoader)); config.setReadThrough(true); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); final Integer INITIAL_KEY = 123; final Integer MAX_KEY_VALUE = INITIAL_KEY + 4; // set keys to read through Set<Integer> keys = new HashSet<>(); for (int key = INITIAL_KEY; key <= MAX_KEY_VALUE; key++) { keys.add(key); } // verify read-through of getValue of non-existent entries cache.invokeAll(keys, new GetEntryProcessor<Integer, Integer>()); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(keys.size())); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); } } @Test public void replaceShouldCallGetExpiryForModifiedEntry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); // verify case that replace does not occur so no expiry policy called boolean result = cache.replace(1, 1); assertFalse(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); result = cache.replace(1, 2); assertTrue(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(1)); } // optimized out test for unwrap method since it does not access/mutate an entry. @Test public void replaceSpecificShouldCallGetExpiry() { CountingExpiryPolicy expiryPolicy = new CountingExpiryPolicy(); expiryPolicyServer.setExpiryPolicy(expiryPolicy); MutableConfiguration<Integer, Integer> config = new MutableConfiguration<>(); config.setExpiryPolicyFactory(FactoryBuilder.factoryOf(expiryPolicyClient)); Cache<Integer, Integer> cache = getCacheManager().createCache(getTestCacheName(), config); cache.containsKey(1); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); boolean result = cache.replace(1, 1, 2); assertFalse(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); cache.put(1, 1); assertThat(expiryPolicy.getCreationCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); // verify case when entry exist for key, but oldValue is incorrect. So replacement does not happen. // this counts as an access of entry referred to by key. result = cache.replace(1, 2, 5); assertFalse(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), greaterThanOrEqualTo(1)); assertThat(expiryPolicy.getUpdatedCount(), is(0)); expiryPolicy.resetCount(); // verify the modify case when replace does succeed. result = cache.replace(1, 1, 2); assertTrue(result); assertThat(expiryPolicy.getCreationCount(), is(0)); assertThat(expiryPolicy.getAccessCount(), is(0)); assertThat(expiryPolicy.getUpdatedCount(), greaterThanOrEqualTo(1)); expiryPolicy.resetCount(); } public static class CountingExpiryPolicy implements ExpiryPolicy, Serializable { /** * The number of times {@link #getExpiryForCreation()} was called. */ private AtomicInteger creationCount; /** * The number of times {@link #getExpiryForAccess()} ()} was called. */ private AtomicInteger accessedCount; /** * The number of times {@link #getExpiryForUpdate()} was called. */ private AtomicInteger updatedCount; /** * Constructs a new {@link CountingExpiryPolicy}. */ public CountingExpiryPolicy() { this.creationCount = new AtomicInteger(0); this.accessedCount = new AtomicInteger(0); this.updatedCount = new AtomicInteger(0); } /** * {@inheritDoc} */ @Override public Duration getExpiryForCreation() { creationCount.incrementAndGet(); return Duration.ETERNAL; } /** * Obtains the number of times {@link #getExpiryForCreation()} has been called. * * @return the count */ public int getCreationCount() { return creationCount.get(); } /** * {@inheritDoc} */ @Override public Duration getExpiryForAccess() { accessedCount.incrementAndGet(); return null; } /** * Obtains the number of times {@link #getExpiryForAccess()} has been called. * * @return the count */ public int getAccessCount() { return accessedCount.get(); } /** * {@inheritDoc} */ @Override public Duration getExpiryForUpdate() { updatedCount.incrementAndGet(); return null; } /** * Obtains the number of times {@link #getExpiryForUpdate()} has been called. * * @return the count */ public int getUpdatedCount() { return updatedCount.get(); } public void resetCount() { creationCount.set(0); accessedCount.set(0); updatedCount.set(0); } } /** * A {@link javax.cache.expiry.ExpiryPolicy} that updates the expiry time based on * defined parameters. */ public static class ParameterizedExpiryPolicy implements ExpiryPolicy, Serializable { /** * The serialVersionUID required for {@link java.io.Serializable}. */ public static final long serialVersionUID = 201306141148L; /** * The {@link Duration} after which a Cache Entry will expire when created. */ private Duration createdExpiryDuration; /** * The {@link Duration} after which a Cache Entry will expire when accessed. * (when <code>null</code> the current expiry duration will be used) */ private Duration accessedExpiryDuration; /** * The {@link Duration} after which a Cache Entry will expire when modified. * (when <code>null</code> the current expiry duration will be used) */ private Duration updatedExpiryDuration; /** * Constructs an {@link ParameterizedExpiryPolicy}. * * @param createdExpiryDuration the {@link Duration} to expire when an entry is created * (must not be <code>null</code>) * @param accessedExpiryDuration the {@link Duration} to expire when an entry is accessed * (<code>null</code> means don't change the expiry) * @param updatedExpiryDuration the {@link Duration} to expire when an entry is updated * (<code>null</code> means don't change the expiry) */ public ParameterizedExpiryPolicy(Duration createdExpiryDuration, Duration accessedExpiryDuration, Duration updatedExpiryDuration) { if (createdExpiryDuration == null) { throw new NullPointerException("createdExpiryDuration can't be null"); } this.createdExpiryDuration = createdExpiryDuration; this.accessedExpiryDuration = accessedExpiryDuration; this.updatedExpiryDuration = updatedExpiryDuration; } /** * {@inheritDoc} */ @Override public Duration getExpiryForCreation() { return createdExpiryDuration; } /** * {@inheritDoc} */ @Override public Duration getExpiryForAccess() { return accessedExpiryDuration; } /** * {@inheritDoc} */ @Override public Duration getExpiryForUpdate() { return updatedExpiryDuration; } } private CacheEntryListenerServer<Integer, Integer> cacheEntryListenerServer; private CacheEntryListenerClient<Integer, Integer> cacheEntryListerClient; }