1 package com.atlassian.cache;
2
3 import org.hamcrest.Matchers;
4 import org.junit.Test;
5
6 import java.util.concurrent.TimeUnit;
7 import java.util.concurrent.atomic.AtomicInteger;
8
9 import static junit.framework.Assert.fail;
10 import static org.hamcrest.Matchers.hasSize;
11 import static org.hamcrest.core.IsEqual.equalTo;
12 import static org.hamcrest.core.IsInstanceOf.instanceOf;
13 import static org.junit.Assert.assertThat;
14
15
16
17
18
19
20 public abstract class AbstractCacheLazyTest
21 {
22
23 protected CacheFactory factory;
24
25 @Test
26 public void testGetName() throws Exception
27 {
28 Cache<String, Long> cache = makeUnexpiringCache();
29
30 assertThat(((ManagedCache) cache).getName(), equalTo("mycache"));
31 }
32
33 @Test
34 public void testFactoryGeneratedName() throws Exception
35 {
36 Cache<String,Long> cache = factory.getCache(Object.class, "mycache");
37
38 assertThat(((ManagedCache) cache).getName(), equalTo("java.lang.Object.mycache"));
39 }
40
41 @Test
42 public void testGetKeys() throws Exception
43 {
44 Cache<String, Long> cache = makeUnexpiringCache();
45
46 cache.get("1");
47 cache.get("2");
48 cache.get("3");
49 cache.get("4");
50 assertThat(cache.get("1"), equalTo(1L));
51 assertThat(cache.get("2"), equalTo(2L));
52 assertThat(cache.get("3"), equalTo(3L));
53 assertThat(cache.get("4"), equalTo(4L));
54 assertSize(cache, 4);
55 }
56
57 @Test
58 public void testConstructExpiringCache() throws Exception
59 {
60 Cache<String, Long> cache = makeExpiringCache();
61
62 cache.get("1");
63 cache.get("2");
64 cache.get("3");
65 cache.get("4");
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
73 @Test
74 public void testPut() throws Exception
75 {
76 Cache<String, Long> cache = makeUnexpiringCache();
77
78 cache.put("1", 11L);
79 cache.put("2", 12L);
80 cache.put("3", 13L);
81 cache.put("4", 14L);
82 assertThat(cache.get("1"), equalTo(11L));
83 assertThat(cache.get("2"), equalTo(12L));
84 assertThat(cache.get("3"), equalTo(13L));
85 assertThat(cache.get("4"), equalTo(14L));
86 assertSize(cache, (4));
87 }
88
89 @Test
90 public void testGet() throws Exception
91 {
92 Cache<String, Long> cache = makeUnexpiringCache();
93
94 cache.put("1", 11L);
95 cache.put("2", 12L);
96 cache.put("3", 13L);
97 cache.put("4", 14L);
98 assertThat(cache.get("1"), equalTo(11L));
99 assertThat(cache.get("2"), equalTo(12L));
100 assertThat(cache.get("3"), equalTo(13L));
101 assertThat(cache.get("4"), equalTo(14L));
102 assertThat(cache.get("5"), equalTo(5L));
103 assertThat(cache.get("6"), equalTo(6L));
104 assertThat(cache.get("7"), equalTo(7L));
105 assertSize(cache, (7));
106 }
107
108 @Test
109 public void testRemove() throws Exception
110 {
111 Cache<String, Long> cache = makeUnexpiringCache();
112
113 cache.put("1", 11L);
114 cache.put("2", 12L);
115 cache.put("3", 13L);
116 cache.put("4", 14L);
117 assertThat(cache.get("1"), equalTo(11L));
118 assertThat(cache.get("2"), equalTo(12L));
119 assertThat(cache.get("3"), equalTo(13L));
120 assertThat(cache.get("4"), equalTo(14L));
121 assertSize(cache, (4));
122
123 cache.remove("1");
124 cache.remove("2");
125 cache.remove("3");
126 assertSize(cache, (1));
127
128
129 assertThat(cache.get("1"), equalTo(1L));
130 assertThat(cache.get("2"), equalTo(2L));
131 assertThat(cache.get("3"), equalTo(3L));
132 assertThat(cache.get("4"), equalTo(14L));
133 assertSize(cache, (4));
134 }
135
136 @Test
137 public void testRemoveTwice() throws Exception
138 {
139 Cache<String, Long> cache = makeUnexpiringCache();
140
141
142 cache.put("1", 11L);
143 cache.put("2", 12L);
144 cache.put("3", 13L);
145 cache.put("4", 14L);
146 assertThat(cache.get("1"), equalTo(11L));
147 assertThat(cache.get("2"), equalTo(12L));
148 assertThat(cache.get("3"), equalTo(13L));
149 assertThat(cache.get("4"), equalTo(14L));
150 assertSize(cache, (4));
151
152 cache.remove("1");
153
154 cache.remove("1");
155 assertSize(cache, (3));
156
157
158 assertThat(cache.get("1"), equalTo(1L));
159 assertThat(cache.get("2"), equalTo(12L));
160 assertThat(cache.get("3"), equalTo(13L));
161 assertThat(cache.get("4"), equalTo(14L));
162 assertSize(cache, (4));
163 }
164
165 @Test
166 public void testRemoveAll() throws Exception
167 {
168 Cache<String, Long> cache = makeUnexpiringCache();
169
170 cache.put("1", 11L);
171 cache.put("2", 12L);
172 cache.put("3", 13L);
173 cache.put("4", 14L);
174 assertThat(cache.get("1"), equalTo(11L));
175 assertThat(cache.get("2"), equalTo(12L));
176 assertThat(cache.get("3"), equalTo(13L));
177 assertThat(cache.get("4"), equalTo(14L));
178 assertSize(cache, (4));
179
180 cache.removeAll();
181 assertEmpty(cache);
182
183
184 assertThat(cache.get("1"), equalTo(1L));
185 assertThat(cache.get("2"), equalTo(2L));
186 assertThat(cache.get("3"), equalTo(3L));
187 assertThat(cache.get("4"), equalTo(4L));
188 assertSize(cache, (4));
189 }
190
191 @Test
192 public void testClear() throws Exception
193 {
194 Cache<String, Long> cache = makeUnexpiringCache();
195
196 cache.put("1", 11L);
197 cache.put("2", 12L);
198 cache.put("3", 13L);
199 cache.put("4", 14L);
200 assertThat(cache.get("1"), equalTo(11L));
201 assertThat(cache.get("2"), equalTo(12L));
202 assertThat(cache.get("3"), equalTo(13L));
203 assertThat(cache.get("4"), equalTo(14L));
204 assertSize(cache, (4));
205
206 ((ManagedCache) cache).clear();
207 assertEmpty(cache);
208
209
210 assertThat(cache.get("1"), equalTo(1L));
211 assertThat(cache.get("2"), equalTo(2L));
212 assertThat(cache.get("3"), equalTo(3L));
213 assertThat(cache.get("4"), equalTo(4L));
214 assertSize(cache, (4));
215 }
216
217 @Test
218 public void testNullHandling() throws Exception
219 {
220 Cache<String, Long> cache = makeNullReturningCache();
221
222
223 assertThat(cache.get("1"), equalTo(1L));
224 assertThat(cache.get("2"), equalTo(2L));
225 assertThat(cache.get("3"), equalTo(3L));
226 try
227 {
228 Long v = cache.get("George");
229 fail("Should throw CacheException when the loader computes a null");
230 }
231 catch (CacheException ex)
232 {
233
234 }
235 try
236 {
237 Long v = cache.get(null);
238 fail("Should throw CacheException when the Key is a null");
239 }
240 catch (CacheException ex)
241 {
242
243 }
244 assertSize(cache, (3));
245 }
246
247 @Test
248 public void testMaxEntries() throws Exception
249 {
250 final AtomicInteger loadCounter = new AtomicInteger();
251 Cache<String, Long> cache = makeSizeLimitedCache(3, loadCounter);
252
253
254 assertThat(cache.get("1"), equalTo(1L));
255 assertThat(cache.get("1"), equalTo(1L));
256 assertThat(cache.get("2"), equalTo(2L));
257 assertThat(cache.get("3"), equalTo(3L));
258 assertThat("loadCounter", loadCounter.get(), equalTo(3));
259 assertSize(cache, (3));
260 assertThat(cache.get("3"), equalTo(3L));
261 assertThat(cache.get("3"), equalTo(3L));
262 assertThat("loadCounter", loadCounter.get(), equalTo(3));
263 assertSize(cache, (3));
264 assertThat(cache.get("4"), equalTo(4L));
265 assertThat("loadCounter", loadCounter.get(), equalTo(4));
266 assertSize(cache, (3));
267 }
268
269 @Test
270 public void testExceptionHandling() throws Exception
271 {
272 Cache<String, Long> cache = makeExceptionalCache();
273
274
275 assertThat(cache.get("1"), equalTo(1L));
276 assertThat(cache.get("2"), equalTo(2L));
277 assertThat(cache.get("3"), equalTo(3L));
278 try
279 {
280 Long v = cache.get("George");
281 fail("Should throw CacheException when the loader throws an exception");
282 }
283 catch (CacheException ex)
284 {
285 assertThat("This exception should wrap the original Exception", ex.getCause(), instanceOf(NumberFormatException.class));
286 }
287 try
288 {
289 Long v = cache.get(null);
290 fail("Should throw CacheException when the Key is a null");
291 }
292 catch (CacheException ex)
293 {
294 assertThat("This exception should wrap the original Exception", ex.getCause(), instanceOf(NullPointerException.class));
295 }
296 assertSize(cache, (3));
297 }
298
299 private Cache<String, Long> makeUnexpiringCache()
300 {
301
302 CacheLoader<String, Long> loader = new CacheLoader<String, Long>()
303 {
304 @Override
305 public Long load(final String key)
306 {
307 try
308 {
309 return Long.valueOf(key);
310 }
311 catch (NumberFormatException e)
312 {
313 return -21L;
314 }
315 }
316 };
317 final Cache<String, Long> cache = factory.getCache("mycache", loader);
318 assertEmpty(cache);
319 return cache;
320 }
321
322 private Cache<String, Long> makeSizeLimitedCache(final int maxEntries, final AtomicInteger loadCounter)
323 {
324
325 CacheLoader<String, Long> loader = new CacheLoader<String, Long>()
326 {
327 @Override
328 public Long load(final String key)
329 {
330 loadCounter.incrementAndGet();
331 return Long.valueOf(key);
332 }
333 };
334 CacheSettings settings = new CacheSettingsBuilder().maxEntries(maxEntries).build();
335 final Cache<String, Long> cache = factory.getCache("mycache", loader, settings);
336 assertEmpty(cache);
337 return cache;
338 }
339
340 private Cache<String, Long> makeExpiringCache()
341 {
342
343 CacheLoader<String, Long> loader = new CacheLoader<String, Long>()
344 {
345 @Override
346 public Long load(final String key)
347 {
348 try
349 {
350 return Long.valueOf(key);
351 }
352 catch (NumberFormatException e)
353 {
354 return -21L;
355 }
356 }
357 };
358 CacheSettings settings = new CacheSettingsBuilder().expireAfterAccess(10, TimeUnit.MILLISECONDS).build();
359 final Cache<String, Long> cache = factory.getCache("mycache", loader, settings);
360 assertEmpty(cache);
361 return cache;
362 }
363
364 private Cache<String,Long> makeNullReturningCache()
365 {
366
367 CacheLoader<String, Long> loader = new CacheLoader<String, Long>()
368 {
369 @Override
370 public Long load(final String key)
371 {
372 try
373 {
374 return Long.valueOf(key);
375 }
376 catch (NumberFormatException e)
377 {
378 return null;
379 }
380 }
381 };
382 final Cache<String, Long> cache = factory.getCache("mycache", loader);
383 assertEmpty(cache);
384 return cache;
385 }
386
387 private Cache<String,Long> makeExceptionalCache()
388 {
389
390 CacheLoader<String, Long> loader = new CacheLoader<String, Long>()
391 {
392 @Override
393 public Long load(final String key)
394 {
395 return Long.valueOf(key);
396 }
397 };
398 final Cache<String, Long> cache = factory.getCache("mycache", loader);
399 assertEmpty(cache);
400 return cache;
401 }
402
403
404
405
406
407 private static <K,V> void assertEmpty(Cache<K,V> cache)
408 {
409 assertThat(cache.getKeys(), Matchers.<K>empty());
410 }
411
412 private static <K,V> void assertSize(Cache<K,V> cache, final int expectedSize)
413 {
414 assertThat(cache.getKeys(), hasSize(expectedSize));
415 }
416 }