View Javadoc

1   package com.atlassian.cache;
2   
3   import java.util.SortedMap;
4   import java.util.concurrent.TimeUnit;
5   
6   import com.atlassian.util.concurrent.Supplier;
7   
8   import org.junit.Test;
9   
10  import static com.atlassian.cache.CacheStatisticsKey.EVICTION_COUNT;
11  import static com.atlassian.cache.CacheStatisticsKey.HIT_COUNT;
12  import static com.atlassian.cache.CacheStatisticsKey.MISS_COUNT;
13  import static com.atlassian.cache.CacheStatisticsKey.PUT_COUNT;
14  import static com.atlassian.cache.CacheStatisticsKey.REMOVE_COUNT;
15  import static com.atlassian.cache.CacheStatisticsKey.SIZE;
16  import static com.atlassian.cache.StatisticMatcher.stat;
17  import static org.hamcrest.MatcherAssert.assertThat;
18  import static org.hamcrest.Matchers.equalTo;
19  import static org.hamcrest.Matchers.not;
20  import static org.hamcrest.Matchers.nullValue;
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertFalse;
23  import static org.junit.Assert.assertNull;
24  import static org.junit.Assert.assertTrue;
25  
26  /**
27   * Test the Eager Cache
28   *
29   * @since 2.0
30   */
31  public abstract class AbstractCacheEagerTest extends AbstractCacheTest
32  {
33      public AbstractCacheEagerTest()
34      {
35      }
36  
37      public AbstractCacheEagerTest(CacheType cacheType)
38      {
39          super(cacheType);
40      }
41  
42      @Test
43      public void testGetName() throws Exception
44      {
45          Cache<String, Long> cache = makeSimpleCache();
46  
47          assertThat(cache.getName(), equalTo("mycache"));
48      }
49  
50      @Test
51      public void testFactoryGeneratedName() throws Exception
52      {
53          Cache<String, Long> cache = factory.getCache(Object.class, "mycache");
54  
55          assertThat(cache.getName(), equalTo("java.lang.Object.mycache"));
56      }
57  
58      @SuppressWarnings("ConstantConditions")
59      @Test
60      public void testGetKeys() throws Exception
61      {
62          Cache<String, Long> cache = makeSimpleCache();
63          // Add some entries using put
64          cache.put("1", 1L);
65          cache.put("2", 2L);
66          cache.put("3", 3L);
67          cache.put("4", 4L);
68          assertThat(cache.get("1"), equalTo(1L));
69          assertThat(cache.get("2"), equalTo(2L));
70          assertThat(cache.get("3"), equalTo(3L));
71          assertThat(cache.get("4"), equalTo(4L));
72          assertSize(cache, 4);
73  
74          final SortedMap<CacheStatisticsKey, Supplier<Long>> stats = ((ManagedCache)cache).getStatistics();
75          assertThat(stats.get(SIZE), stat(4L));
76          assertThat(stats.get(PUT_COUNT), stat(4L));
77          assertThat(stats.get(HIT_COUNT), stat(4L));
78          assertThat(stats.get(REMOVE_COUNT), stat(0L));
79          assertThat(stats.get(EVICTION_COUNT), stat(0L));
80          assertThat(stats.get(MISS_COUNT), stat(0L));
81      }
82  
83      @Test
84      public void testPut() throws Exception
85      {
86          Cache<String, Long> cache = makeSimpleCache();
87          // Add some entries using the builder
88          cache.put("1", 11L);
89          cache.put("2", 12L);
90          cache.put("3", 13L);
91          cache.put("4", 14L);
92          assertThat(cache.get("1"), equalTo(11L));
93          assertThat(cache.get("2"), equalTo(12L));
94          assertThat(cache.get("3"), equalTo(13L));
95          assertThat(cache.get("4"), equalTo(14L));
96          assertSize(cache, 4);
97      }
98  
99      @SuppressWarnings("ConstantConditions")
100     @Test
101     public void testGet() throws Exception
102     {
103         Cache<String, Long> cache = makeSimpleCache();
104         // Add some entries using the builder
105         cache.put("1", 11L);
106         cache.put("2", 12L);
107         cache.put("3", 13L);
108         cache.put("4", 14L);
109         assertThat(cache.get("1"), equalTo(11L));
110         assertThat(cache.get("2"), equalTo(12L));
111         assertThat(cache.get("3"), equalTo(13L));
112         assertThat(cache.get("4"), equalTo(14L));
113         assertThat(cache.get("5"), nullValue());
114         assertThat(cache.get("6"), nullValue());
115         assertThat(cache.get("7"), nullValue());
116         assertSize(cache, 4);
117 
118         final SortedMap<CacheStatisticsKey, Supplier<Long>> stats = ((ManagedCache)cache).getStatistics();
119         assertThat(stats.get(SIZE), stat(4L));
120         assertThat(stats.get(PUT_COUNT), stat(4L));
121         assertThat(stats.get(HIT_COUNT), stat(4L));
122         assertThat(stats.get(REMOVE_COUNT), stat(0L));
123         assertThat(stats.get(EVICTION_COUNT), stat(0L));
124         assertThat(stats.get(MISS_COUNT), stat(3L));
125     }
126 
127     @SuppressWarnings("ConstantConditions")
128     @Test
129     public void testGetWithSupplier() throws Exception
130     {
131         Cache<String, Long> cache = makeSimpleCache(true);
132 
133         com.atlassian.cache.Supplier<Long> valueSupplier1 = mockValueSupplier(1000);
134         com.atlassian.cache.Supplier<Long> valueSupplier2 = mockValueSupplier(2000);
135         // Add some entries using the builder
136         cache.put("1", 11L);
137         cache.put("2", 12L);
138         cache.put("3", 13L);
139         cache.put("4", 14L);
140         assertThat(cache.get("1", valueSupplier1), equalTo(11L));
141         assertThat(cache.get("2", valueSupplier1), equalTo(12L));
142         assertThat(cache.get("3", valueSupplier1), equalTo(13L));
143         assertThat(cache.get("4", valueSupplier1), equalTo(14L));
144         assertThat(cache.get("5", valueSupplier1), equalTo(1001L));
145         assertThat(cache.get("6", valueSupplier1), equalTo(1002L));
146         assertThat(cache.get("7", valueSupplier2), equalTo(2001L));
147         assertSize(cache, 7);
148 
149         final SortedMap<CacheStatisticsKey, Supplier<Long>> stats = ((ManagedCache)cache).getStatistics();
150         assertThat(stats.get(SIZE), stat(7L));
151         assertThat(stats.get(PUT_COUNT), stat(7L));
152         assertThat(stats.get(HIT_COUNT), stat(4L));
153         assertThat(stats.get(REMOVE_COUNT), stat(0L));
154         assertThat(stats.get(EVICTION_COUNT), stat(0L));
155         assertThat(stats.get(MISS_COUNT), stat(3L));
156     }
157 
158     private com.atlassian.cache.Supplier<Long> mockValueSupplier(final long initialValue)
159     {
160         return new com.atlassian.cache.Supplier<Long>()
161         {
162             private long value = initialValue;
163             @Override
164             public Long get()
165             {
166                 return ++value;
167             }
168         };
169     }
170 
171     @SuppressWarnings("ConstantConditions")
172     @Test
173     public void testRemove() throws Exception
174     {
175         Cache<String, Long> cache = makeSimpleCache();
176         // Add some entries to the cache
177         cache.put("1", 11L);
178         cache.put("2", 12L);
179         cache.put("3", 13L);
180         cache.put("4", 14L);
181         assertThat(cache.get("1"), equalTo(11L));
182         assertThat(cache.get("2"), equalTo(12L));
183         assertThat(cache.get("3"), equalTo(13L));
184         assertThat(cache.get("4"), equalTo(14L));
185         assertSize(cache, 4);
186 
187         cache.remove("1");
188         cache.remove("2");
189         cache.remove("3");
190         assertSize(cache, 1);
191 
192         // Removed values should be null
193         assertThat(cache.get("1"), nullValue());
194         assertThat(cache.get("2"), nullValue());
195         assertThat(cache.get("3"), nullValue());
196         assertThat(cache.get("4"), equalTo(14L));
197         assertSize(cache, 1);
198 
199         final SortedMap<CacheStatisticsKey, Supplier<Long>> stats = ((ManagedCache)cache).getStatistics();
200         assertThat(stats.get(SIZE), stat(1L));
201         assertThat(stats.get(PUT_COUNT), stat(4L));
202         assertThat(stats.get(HIT_COUNT), stat(5L));
203         assertThat(stats.get(REMOVE_COUNT), stat(3L));
204         assertThat(stats.get(EVICTION_COUNT), stat(0L));
205         assertThat(stats.get(MISS_COUNT), stat(3L));
206     }
207 
208     @Test
209     public void testRemoveTwice() throws Exception
210     {
211         Cache<String, Long> cache = makeSimpleCache();
212         // Add some entries to the cache
213         cache.put("1", 11L);
214         cache.put("2", 12L);
215         cache.put("3", 13L);
216         cache.put("4", 14L);
217         assertThat(cache.get("1"), equalTo(11L));
218         assertThat(cache.get("2"), equalTo(12L));
219         assertThat(cache.get("3"), equalTo(13L));
220         assertThat(cache.get("4"), equalTo(14L));
221         assertSize(cache, 4);
222 
223         cache.remove("1");
224         // Remove again should be a no-op
225         cache.remove("1");
226         assertSize(cache, 3);
227 
228         // Removed values should be null
229         assertThat(cache.get("1"), nullValue());
230         assertThat(cache.get("2"), equalTo(12L));
231         assertThat(cache.get("3"), equalTo(13L));
232         assertThat(cache.get("4"), equalTo(14L));
233         assertSize(cache, 3);
234     }
235 
236     @SuppressWarnings("ConstantConditions")
237     @Test
238     public void testRemoveAll() throws Exception
239     {
240         Cache<String, Long> cache = makeSimpleCache();
241         // Add some entries using the builder
242         cache.put("1", 11L);
243         cache.put("2", 12L);
244         cache.put("3", 13L);
245         cache.put("4", 14L);
246         assertThat(cache.get("1"), equalTo(11L));
247         assertThat(cache.get("2"), equalTo(12L));
248         assertThat(cache.get("3"), equalTo(13L));
249         assertThat(cache.get("4"), equalTo(14L));
250         assertSize(cache, 4);
251 
252         cache.removeAll();
253         assertEmpty(cache);
254 
255         // Removed values should be recomputed
256         assertThat(cache.get("1"), nullValue());
257         assertThat(cache.get("2"), nullValue());
258         assertThat(cache.get("3"), nullValue());
259         assertThat(cache.get("4"), nullValue());
260         assertEmpty(cache);
261 
262         final SortedMap<CacheStatisticsKey, Supplier<Long>> stats = ((ManagedCache)cache).getStatistics();
263         assertThat(stats.get(SIZE), stat(0L));
264         assertThat(stats.get(PUT_COUNT), stat(4L));
265         assertThat(stats.get(HIT_COUNT), stat(4L));
266         assertThat(stats.get(REMOVE_COUNT), stat(0L));
267         assertThat(stats.get(EVICTION_COUNT), stat(0L));
268         assertThat(stats.get(MISS_COUNT), stat(4L));
269     }
270 
271     @Test
272     public void testClear() throws Exception
273     {
274         Cache<String, Long> cache = makeSimpleCache();
275         // Add some entries using the builder
276         cache.put("1", 11L);
277         cache.put("2", 12L);
278         cache.put("3", 13L);
279         cache.put("4", 14L);
280         assertThat(cache.get("1"), equalTo(11L));
281         assertThat(cache.get("2"), equalTo(12L));
282         assertThat(cache.get("3"), equalTo(13L));
283         assertThat(cache.get("4"), equalTo(14L));
284         assertSize(cache, 4);
285         // A cache that doesn't expire any entries should return all the keys
286 
287         ((ManagedCache)cache).clear();
288         assertEmpty(cache);
289 
290         // Removed values should be recomputed
291         assertThat(cache.get("1"), nullValue());
292         assertThat(cache.get("2"), nullValue());
293         assertThat(cache.get("3"), nullValue());
294         assertThat(cache.get("4"), nullValue());
295         assertEmpty(cache);
296     }
297 
298     @Test
299     public void conditionalPutPutsIfAbsent()
300     {
301         Cache<String, Long> cache = makeSimpleCache();
302         assertNull(cache.putIfAbsent("A", 1L));
303         assertEquals(Long.valueOf(1), cache.get("A"));
304     }
305 
306     @Test
307     public void conditionalPutDoesNotPutIfPresent()
308     {
309         Cache<String, Long> cache = makeSimpleCache();
310         cache.putIfAbsent("A", 1L);
311         assertEquals(Long.valueOf(1), cache.putIfAbsent("A", 2L));
312         assertEquals(Long.valueOf(1), cache.get("A"));
313     }
314 
315     @Test
316     public void replaceDoesNotReplaceIfAbsent()
317     {
318         Cache<String, Long> cache = makeSimpleCache();
319         assertFalse(cache.replace("A", 1L, 2L));
320         assertNull(cache.get("A"));
321     }
322 
323     @Test
324     public void replaceReplacesWhenValueMatches()
325     {
326         Cache<String, Long> cache = makeSimpleCache();
327         cache.put("A", 1L);
328         assertTrue(cache.replace("A", 1L, 2L));
329         assertEquals(Long.valueOf(2), cache.get("A"));
330     }
331 
332     @Test
333     public void replaceDoesNothingWhenValueDoesNotMatch()
334     {
335         Cache<String, Long> cache = makeSimpleCache();
336         cache.put("A", 1L);
337         assertFalse(cache.replace("A", 2L, 3L));
338         assertEquals(Long.valueOf(1), cache.get("A"));
339     }
340 
341     @Test
342     public void removeDoesNothingWhenNoKeyIsPresent()
343     {
344         Cache<String, Long> cache = makeSimpleCache();
345         assertFalse(cache.remove("A", 1L));
346     }
347 
348     @Test
349     public void removeRemovesWhenValueMatches()
350     {
351         Cache<String, Long> cache = makeSimpleCache();
352         cache.put("A", 1L);
353         assertTrue(cache.remove("A", 1L));
354         assertNull(cache.get("A"));
355     }
356 
357     @Test
358     public void removeDoesNotRemoveWhenValueDoesNotMatch()
359     {
360         Cache<String, Long> cache = makeSimpleCache();
361         cache.put("A", 2L);
362         assertFalse(cache.remove("A", 1L));
363         assertEquals(Long.valueOf(2), cache.get("A"));
364     }
365 
366     @Test
367     public void testMaxEntries() throws Exception
368     {
369         Cache<String, Long> cache = makeSizeLimitedCache(3);
370 
371         // Add some entries using the builder
372         cache.put("1", 11L);
373         cache.put("2", 12L);
374         cache.put("3", 13L);
375         assertThat(cache.get("1"), equalTo(11L));
376         assertThat(cache.get("2"), equalTo(12L));
377         assertThat(cache.get("3"), equalTo(13L));
378         assertSize(cache, 3);
379         cache.put("4", 14L);
380         assertSize(cache, 3);
381     }
382 
383     @Test
384     public void testBothExpireHintsSpecified()
385     {
386         CacheSettings required = new CacheSettingsBuilder()
387                 .expireAfterAccess(60, TimeUnit.SECONDS)
388                 .expireAfterWrite(30, TimeUnit.SECONDS)
389                 .build();
390         Cache<String, String> cache = factory.getCache("fruity", null, required);
391         assertThat(cache, not(nullValue()));
392     }
393 }
394