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