1 package com.atlassian.cache.ehcache;
2
3 import java.util.Collections;
4 import java.util.List;
5 import java.util.concurrent.TimeUnit;
6
7 import com.atlassian.cache.CacheSettingsBuilder;
8 import com.atlassian.cache.ehcache.replication.rmi.RMICacheReplicatorConfigFactory;
9 import com.atlassian.cache.ehcache.replication.rmi.RMICacheReplicatorFactory;
10
11 import net.sf.ehcache.Ehcache;
12 import org.junit.Before;
13 import org.junit.Test;
14 import org.mockito.ArgumentCaptor;
15 import org.mockito.Mock;
16
17 import net.sf.ehcache.Cache;
18 import net.sf.ehcache.CacheManager;
19 import net.sf.ehcache.config.CacheConfiguration;
20 import net.sf.ehcache.config.Configuration;
21 import net.sf.ehcache.distribution.CacheManagerPeerProvider;
22
23 import static com.atlassian.cache.ehcache.EhCacheHelper.PERSISTENCE_STRATEGY;
24 import static java.util.Collections.singletonMap;
25 import static net.sf.ehcache.config.CacheConfiguration.CacheEventListenerFactoryConfiguration;
26 import static net.sf.ehcache.config.CacheConfiguration.DEFAULT_TTI;
27 import static net.sf.ehcache.config.CacheConfiguration.DEFAULT_TTL;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertTrue;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34 import static org.mockito.MockitoAnnotations.initMocks;
35
36 public class EhCacheHelperTest
37 {
38
39 private static final int MAX_ENTRIES = 10;
40 private static final long EXPIRE_AFTER_ACCESS = 20;
41 private static final long EXPIRE_AFTER_WRITE = 30;
42 private static final String CACHE_NAME = "MyCache";
43
44
45 private EhCacheHelper helper;
46 @Mock private CacheManager mockCacheManager;
47 private CacheConfiguration defaultCacheConfiguration;
48
49 @Before
50 public void setUp()
51 {
52 initMocks(this);
53 this.helper = new EhCacheHelper(new RMICacheReplicatorConfigFactory());
54
55 defaultCacheConfiguration = new CacheConfiguration();
56 final Configuration configuration = new Configuration();
57 configuration.setDefaultCacheConfiguration(defaultCacheConfiguration);
58 when(mockCacheManager.getConfiguration()).thenReturn(configuration);
59 }
60
61 @Test
62 public void cacheCreatedWithLimitedParametersShouldHaveExpectedValuesWhenLocalAndRmiSetUp()
63 {
64 assertCacheCreatedWithLimitedParameters(true, true, false);
65 }
66 @Test
67 public void cacheCreatedWithLimitedParametersShouldHaveExpectedValuesWhenLocalAndRmiNotSetUp()
68 {
69 assertCacheCreatedWithLimitedParameters(true, false, false);
70 }
71 @Test
72 public void cacheCreatedWithLimitedParametersShouldHaveExpectedValuesWhenNotLocalAndRmiSetUp()
73 {
74 assertCacheCreatedWithLimitedParameters(false, true, false);
75 }
76 @Test
77 public void selfLoadingCacheCreatedWithLimitedParametersShouldHaveExpectedValuesWhenNotLocalAndRmiSetUp()
78 {
79 assertCacheCreatedWithLimitedParameters(false, true, true);
80 }
81 @Test
82 public void cacheCreatedWithLimitedParametersShouldHaveExpectedValuesWhenNotLocalAndRmiNotSetUp()
83 {
84 assertCacheCreatedWithLimitedParameters(false, false, false);
85 }
86
87 private void assertCacheCreatedWithLimitedParameters(final boolean local, final boolean setUpRmiProvider, final boolean selfLoading)
88 {
89
90 if (setUpRmiProvider)
91 {
92 setUpCacheManagerPeerProvider();
93 }
94 final boolean replicateAsynchronously = false;
95 final boolean replicateViaCopy = false;
96 final CacheConfiguration cache = createCacheWithLimitedParameters(local, replicateAsynchronously, replicateViaCopy, selfLoading);
97
98
99 assertEquals(CACHE_NAME, cache.getName());
100 assertEquals(0L, cache.getMaxEntriesLocalHeap());
101 assertEquals(PERSISTENCE_STRATEGY, cache.getPersistenceConfiguration().getStrategy());
102 assertTrue(cache.getStatistics());
103 assertEquals(DEFAULT_TTI, cache.getTimeToIdleSeconds());
104 assertEquals(DEFAULT_TTL, cache.getTimeToLiveSeconds());
105 assertFalse(cache.isEternal());
106 @SuppressWarnings("unchecked")
107 final List<CacheEventListenerFactoryConfiguration> cacheEventListenerConfigurations = cache.getCacheEventListenerConfigurations();
108 if (local || !setUpRmiProvider)
109 {
110 assertEquals(Collections.<CacheEventListenerFactoryConfiguration>emptyList(), cacheEventListenerConfigurations);
111 }
112 else {
113 assertEquals(1, cacheEventListenerConfigurations.size());
114 final CacheEventListenerFactoryConfiguration listenerConfiguration = cacheEventListenerConfigurations.get(0);
115 assertEquals(RMICacheReplicatorFactory.class.getName(), listenerConfiguration.getFullyQualifiedClassPath());
116 if (!selfLoading && replicateViaCopy)
117 {
118 assertTrue(listenerConfiguration.getProperties().contains("replicatePuts=true"));
119 }
120 else
121 {
122 assertTrue(listenerConfiguration.getProperties().contains("replicatePuts=false"));
123 }
124 }
125 }
126
127 private void setUpCacheManagerPeerProvider()
128 {
129 final CacheManagerPeerProvider mockRmiProvider = mock(CacheManagerPeerProvider.class);
130 when(mockCacheManager.getCacheManagerPeerProviders()).thenReturn(singletonMap("RMI", mockRmiProvider));
131 }
132
133 @Test
134 public void cacheCreatedWithAllParametersShouldHaveSpecifiedName()
135 {
136
137 final CacheConfiguration cache = createCacheWithAllParameters(MAX_ENTRIES, EXPIRE_AFTER_ACCESS, EXPIRE_AFTER_WRITE);
138
139
140 assertEquals(CACHE_NAME, cache.getName());
141 }
142
143 @Test
144 public void cacheCreatedWithAllParametersShouldHaveSpecifiedMaxEntries()
145 {
146
147 final CacheConfiguration cache = createCacheWithAllParameters(MAX_ENTRIES, EXPIRE_AFTER_ACCESS, EXPIRE_AFTER_WRITE);
148
149
150 assertEquals(MAX_ENTRIES, cache.getMaxEntriesLocalHeap());
151 }
152
153 @Test
154 public void cacheCreatedWithAllParametersShouldHaveSpecifiedExpireAfterAccess()
155 {
156
157 final CacheConfiguration cache = createCacheWithAllParameters(MAX_ENTRIES, EXPIRE_AFTER_ACCESS, EXPIRE_AFTER_WRITE);
158
159
160 assertEquals(EXPIRE_AFTER_ACCESS, cache.getTimeToIdleSeconds());
161 }
162
163 @Test
164 public void cacheCreatedWithAllParametersShouldHaveSpecifiedExpireAfterWrite()
165 {
166
167 final CacheConfiguration cache = createCacheWithAllParameters(MAX_ENTRIES, EXPIRE_AFTER_ACCESS, EXPIRE_AFTER_WRITE);
168
169
170 assertEquals(EXPIRE_AFTER_WRITE, cache.getTimeToLiveSeconds());
171 }
172
173 @Test
174 public void cacheShouldDefaultToEHCacheDefaultValues()
175 {
176 defaultCacheConfiguration.setMaxEntriesLocalHeap(999);
177
178
179 final CacheConfiguration cache = createCacheWithLimitedParameters(false, false, false,false);
180
181 assertEquals(999, cache.getMaxEntriesLocalHeap());
182 }
183
184 private CacheConfiguration createCacheWithLimitedParameters(
185 final boolean local, final boolean replicateAsynchronously, final boolean replicateViaCopy, final boolean selfLoading)
186 {
187
188 CacheSettingsBuilder builder = new CacheSettingsBuilder();
189 if (local)
190 {
191 builder.local();
192 }
193 else
194 {
195 builder.remote();
196 }
197 if (replicateAsynchronously)
198 {
199 builder.replicateAsynchronously();
200 }
201 if (replicateViaCopy)
202 {
203 builder.replicateViaCopy();
204 }
205
206 helper.getEhcache(CACHE_NAME, mockCacheManager, builder.build(), selfLoading, true);
207
208
209 final ArgumentCaptor<? extends Ehcache> cacheCaptor = selfLoading ? ArgumentCaptor.forClass(SynchronizedLoadingCacheDecorator.class) : ArgumentCaptor.forClass(Cache.class);
210 verify(mockCacheManager).addCacheIfAbsent(cacheCaptor.capture());
211 return cacheCaptor.getValue().getCacheConfiguration();
212 }
213
214 private CacheConfiguration createCacheWithAllParameters(
215 final Integer maxEntries, final Long expireAfterAccess, final Long expireAfterWrite)
216 {
217
218 CacheSettingsBuilder builder = new CacheSettingsBuilder();
219 builder.local();
220 if (null != maxEntries)
221 {
222 builder.maxEntries(maxEntries);
223 }
224 if (null != expireAfterAccess)
225 {
226 builder.expireAfterAccess(expireAfterAccess, TimeUnit.SECONDS);
227 }
228 if (null != expireAfterWrite)
229 {
230 builder.expireAfterWrite(expireAfterWrite, TimeUnit.SECONDS);
231 }
232
233 helper.getEhcache(
234 CACHE_NAME, mockCacheManager, builder.build(), false, true);
235
236
237 final ArgumentCaptor<Cache> cacheCaptor = ArgumentCaptor.forClass(Cache.class);
238 verify(mockCacheManager).addCacheIfAbsent(cacheCaptor.capture());
239 return cacheCaptor.getValue().getCacheConfiguration();
240 }
241
242 @Test
243 public void cacheShouldBeEternalIfNoExpiryIsSetAndDefaultIsTrue()
244 {
245 defaultCacheConfiguration.setEternal(true);
246 assertEternal(null, null, true);
247 }
248
249 @Test
250 public void cacheShouldNotBeEternalIfNoExpiryIsSetAndDefaultIsFalse()
251 {
252 defaultCacheConfiguration.setEternal(false);
253 assertEternal(null, null, false);
254 }
255
256 @Test
257 public void cacheShouldNotBeEternalIfExpireAfterAccessIsSet()
258 {
259 defaultCacheConfiguration.setEternal(true);
260 assertEternal(200L, null, false);
261 }
262
263 @Test
264 public void cacheShouldNotBeEternalIfExpireAfterWriteIsSet()
265 {
266 defaultCacheConfiguration.setEternal(true);
267 assertEternal(null, 200L, false);
268 }
269
270 @Test
271 public void cacheShouldNotBeEternalIfExpireAfterAccessAndExpireAfterWriteAreSet()
272 {
273 defaultCacheConfiguration.setEternal(true);
274 assertEternal(100L, 200L, false);
275 }
276
277 private void assertEternal(final Long expireAfterAccess, final Long expireAfterWrite, final boolean expectedValue)
278 {
279
280 final CacheConfiguration configuration =
281 createCacheWithAllParameters(MAX_ENTRIES, expireAfterAccess, expireAfterWrite);
282
283
284 assertEquals(expectedValue, configuration.isEternal());
285 }
286 }