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