View Javadoc

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 }