1 package com.atlassian.cache;
2
3 import org.junit.Test;
4 import org.junit.runner.RunWith;
5 import org.mockito.ArgumentCaptor;
6 import org.mockito.runners.MockitoJUnitRunner;
7
8 import java.util.concurrent.TimeUnit;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNull;
12 import static org.mockito.Mockito.atLeastOnce;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.timeout;
15 import static org.mockito.Mockito.verify;
16 import static org.mockito.Mockito.when;
17
18 @RunWith(MockitoJUnitRunner.class)
19 public abstract class AbstractCacheListenerTest
20 {
21 protected CacheFactory factory;
22
23 @Test
24 public void testOnAdd() throws Exception
25 {
26 CacheLoader<String, String> cacheLoader = mock(CacheLoader.class);
27 when(cacheLoader.load("add")).thenReturn("ADD");
28
29 Cache<String, String> cache = factory.getCache("ADD_CACHE", cacheLoader, settingsBuilder().build());
30
31 CacheEntryListener listener = mock(CacheEntryListener.class);
32 cache.addListener(listener, true);
33
34 cache.get("add");
35
36 ArgumentCaptor<CacheEntryEvent> captor = ArgumentCaptor.forClass(CacheEntryEvent.class);
37 verify(listener, timeout(1000)).onAdd(captor.capture());
38
39 CacheEntryEvent<String, String> event = captor.getValue();
40 assertEquals("add", event.getKey());
41 assertNull(event.getOldValue());
42 if (supportsAddValue())
43 {
44 assertEquals("ADD", event.getValue());
45 }
46 else
47 {
48 assertNull(event.getValue());
49 }
50 }
51
52 @Test
53 public void testOnAddPut() throws Exception
54 {
55 Cache<String, String> cache = factory.getCache("PUT_CACHE");
56
57 CacheEntryListener listener = mock(CacheEntryListener.class);
58 cache.addListener(listener, true);
59
60 cache.put("put", "PUT");
61
62 ArgumentCaptor<CacheEntryEvent> captor = ArgumentCaptor.forClass(CacheEntryEvent.class);
63 verify(listener, timeout(1000)).onAdd(captor.capture());
64
65 CacheEntryEvent<String, String> event = captor.getValue();
66 assertEquals("put", event.getKey());
67 assertNull(event.getOldValue());
68 if (supportsPutValue())
69 {
70 assertEquals("PUT", event.getValue());
71 }
72 else
73 {
74 assertNull(event.getValue());
75 }
76 }
77
78 @Test
79 public void testOnReplace() throws Exception
80 {
81 CacheLoader<String, String> cacheLoader = mock(CacheLoader.class);
82 when(cacheLoader.load("replace")).thenReturn("REPLACE");
83
84 Cache<String, String> cache = factory.getCache("REPLACE_CACHE", cacheLoader, settingsBuilder().build());
85 CacheEntryListener listener = mock(CacheEntryListener.class);
86 cache.addListener(listener, true);
87
88 cache.get("replace");
89 cache.replace("replace", "REPLACE", "REPLACED");
90
91 ArgumentCaptor<CacheEntryEvent> captor = ArgumentCaptor.forClass(CacheEntryEvent.class);
92 verify(listener, timeout(1000)).onUpdate(captor.capture());
93
94 CacheEntryEvent<String, String> event = captor.getValue();
95 assertEquals("replace", event.getKey());
96 if (supportsUpdateOldValue())
97 {
98 assertEquals("REPLACE", event.getOldValue());
99 }
100 else
101 {
102 assertNull(event.getOldValue());
103 }
104 if (supportsUpdateValue())
105 {
106 assertEquals("REPLACED", event.getValue());
107 }
108 else
109 {
110 assertNull(event.getValue());
111 }
112 }
113
114 @Test
115 public void testOnUpdate() throws Exception
116 {
117 CacheLoader<String, String> cacheLoader = mock(CacheLoader.class);
118 when(cacheLoader.load("update")).thenReturn("UPDATE");
119
120 Cache<String, String> cache = factory.getCache("UPDATE_CACHE", cacheLoader, settingsBuilder().build());
121 CacheEntryListener listener = mock(CacheEntryListener.class);
122 cache.addListener(listener, true);
123
124 cache.get("update");
125 cache.put("update", "UPDATED");
126
127 ArgumentCaptor<CacheEntryEvent> captor = ArgumentCaptor.forClass(CacheEntryEvent.class);
128 verify(listener, timeout(1000)).onUpdate(captor.capture());
129
130 CacheEntryEvent<String, String> event = captor.getValue();
131 assertEquals("update", event.getKey());
132 if (supportsUpdateOldValue())
133 {
134 assertEquals("UPDATE", event.getOldValue());
135 }
136 else
137 {
138 assertNull(event.getOldValue());
139 }
140 if (supportsUpdateValue())
141 {
142 assertEquals("UPDATED", event.getValue());
143 }
144 else
145 {
146 assertNull(event.getValue());
147 }
148 }
149
150 @Test
151 public void testOnRemove() throws Exception
152 {
153 CacheLoader<String, String> cacheLoader = mock(CacheLoader.class);
154 when(cacheLoader.load("remove")).thenReturn("REMOVE");
155
156 Cache<String, String> cache = factory.getCache("REMOVE_CACHE", cacheLoader, settingsBuilder().build());
157 CacheEntryListener listener = mock(CacheEntryListener.class);
158 cache.addListener(listener, true);
159
160 cache.get("remove");
161 cache.remove("remove");
162
163 ArgumentCaptor<CacheEntryEvent> captor = ArgumentCaptor.forClass(CacheEntryEvent.class);
164 verify(listener, timeout(1000)).onRemove(captor.capture());
165
166 CacheEntryEvent<String, String> event = captor.getValue();
167 assertEquals("remove", event.getKey());
168 if (supportsRemoveOldValue())
169 {
170 assertEquals("REMOVE", event.getOldValue());
171 }
172 else
173 {
174 assertNull(event.getOldValue());
175 }
176 assertNull(event.getValue());
177 }
178
179 @Test
180 public void testOnEvict() throws Exception
181 {
182 CacheLoader<String, String> cacheLoader = mock(CacheLoader.class);
183 when(cacheLoader.load("evict")).thenReturn("EVICT");
184
185 Cache<String, String> cache = factory.getCache("EVICT_CACHE", cacheLoader,
186 settingsBuilder().expireAfterAccess(1, TimeUnit.SECONDS).expireAfterWrite(1, TimeUnit.SECONDS).build());
187 CacheEntryListener listener = mock(CacheEntryListener.class);
188 cache.addListener(listener, true);
189
190 cache.get("evict");
191
192 Thread.sleep(2000);
193
194 cache.get("evict");
195
196 ArgumentCaptor<CacheEntryEvent> captor = ArgumentCaptor.forClass(CacheEntryEvent.class);
197 verify(listener, atLeastOnce()).onEvict(captor.capture());
198
199 CacheEntryEvent<String, String> event = captor.getValue();
200 assertEquals("evict", event.getKey());
201 if (supportsEvictOldValue())
202 {
203 assertEquals("EVICT", event.getOldValue());
204 }
205 else
206 {
207 assertNull(event.getOldValue());
208 }
209 assertNull(event.getValue());
210 }
211
212 protected CacheSettingsBuilder settingsBuilder()
213 {
214 return new CacheSettingsBuilder();
215 }
216
217 protected boolean supportsAddValue()
218 {
219 return true;
220 }
221
222 protected boolean supportsPutValue()
223 {
224 return true;
225 }
226
227 protected boolean supportsUpdateOldValue()
228 {
229 return true;
230 }
231
232 protected boolean supportsUpdateValue()
233 {
234 return true;
235 }
236
237 protected boolean supportsRemoveOldValue()
238 {
239 return true;
240 }
241
242 protected boolean supportsEvictOldValue()
243 {
244 return true;
245 }
246 }