View Javadoc

1   package com.atlassian.vcache.internal.test;
2   
3   import java.time.Duration;
4   import java.util.Map;
5   import java.util.Optional;
6   import java.util.concurrent.CompletableFuture;
7   import java.util.concurrent.ExecutionException;
8   import java.util.stream.Collectors;
9   
10  import com.atlassian.vcache.ChangeRate;
11  import com.atlassian.vcache.DirectExternalCache;
12  import com.atlassian.vcache.ExternalCacheSettings;
13  import com.atlassian.vcache.ExternalCacheSettingsBuilder;
14  import com.atlassian.vcache.IdentifiedValue;
15  import com.atlassian.vcache.PutPolicy;
16  
17  import org.junit.Before;
18  import org.junit.Test;
19  
20  import static com.atlassian.vcache.internal.test.CompletableFutureSuccessful.successful;
21  import static com.atlassian.vcache.internal.test.CompletableFutureSuccessful.successfulWith;
22  import static org.hamcrest.MatcherAssert.assertThat;
23  import static org.hamcrest.Matchers.containsInAnyOrder;
24  import static org.hamcrest.Matchers.equalTo;
25  import static org.hamcrest.Matchers.is;
26  import static org.hamcrest.Matchers.notNullValue;
27  import static org.hamcrest.Matchers.nullValue;
28  
29  /**
30   * Base test class for the {@link DirectExternalCache}.
31   */
32  public abstract class AbstractDirectExternalCacheIT
33  {
34      private DirectExternalCache<String> cache;
35  
36      protected abstract DirectExternalCache<String> createCache(String name, ExternalCacheSettings settings);
37  
38      @Before
39      public void ensureCache()
40      {
41          final ExternalCacheSettings settings = new ExternalCacheSettingsBuilder()
42                  .entryGrowthRateHint(ChangeRate.LOW_CHANGE)
43                  .entryCountHint(5)
44                  .defaultTtl(Duration.ofMinutes(5))
45                  .dataChangeRateHint(ChangeRate.HIGH_CHANGE)
46                  .build();
47          cache = createCache("abc", settings);
48          final CompletableFuture<Void> rm = cache.removeAll();
49          assertThat(rm, successful());
50      }
51  
52      @Test
53      public void simple_get_set() throws ExecutionException, InterruptedException
54      {
55          final CompletableFuture<Optional<String>> eldestGet = cache.get("claira");
56  
57          assertThat(eldestGet, successfulWith(is(Optional.empty())));
58  
59          final CompletableFuture<Boolean> eldestAdd = cache.put("claira", "dancing", PutPolicy.ADD_ONLY);
60  
61          assertThat(eldestAdd, successfulWith(is(true)));
62  
63          final CompletableFuture<Optional<String>> eldestGet2 = cache.get("claira");
64  
65          assertThat(eldestGet2, successfulWith(is(Optional.of("dancing"))));
66  
67          final CompletableFuture<Boolean> eldestAdd2 = cache.put("claira", "singing", PutPolicy.ADD_ONLY);
68  
69          assertThat(eldestAdd2, successfulWith(is(false)));
70      }
71  
72      @Test
73      public void simple_get_with_supplier() throws ExecutionException, InterruptedException
74      {
75          final CompletableFuture<Optional<String>> eldestGet1 = cache.get("josephine");
76  
77          assertThat(eldestGet1, successfulWith(is(Optional.empty())));
78  
79          final CompletableFuture<String> eldestGet2 = cache.get("josephine", () -> "football");
80  
81          assertThat(eldestGet2, successfulWith(is("football")));
82  
83          final CompletableFuture<Optional<String>> eldestGet3 = cache.get("josephine");
84  
85          assertThat(eldestGet3, successfulWith(is(Optional.of("football"))));
86      }
87  
88      @Test
89      public void put_with_huge_key() throws ExecutionException, InterruptedException
90      {
91          final String key = "sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
92                  + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
93                  + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
94                  + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
95                  + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
96                  + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
97                  + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
98                  + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
99                  + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
100                 + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
101                 + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
102                 + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
103                 + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
104                 + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
105                 + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
106                 + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
107                 + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
108                 + "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss";
109 
110         final CompletableFuture<Boolean> hugeAdd = cache.put(key, "dancing", PutPolicy.ADD_ONLY);
111 
112         assertThat(hugeAdd, successfulWith(is(true)));
113 
114         final CompletableFuture<Optional<String>> hugeGet = cache.get(key);
115 
116         assertThat(hugeGet, successfulWith(is(Optional.of("dancing"))));
117     }
118 
119     @Test
120     public void simple_getBulkIdentified() throws ExecutionException, InterruptedException
121     {
122         final CompletableFuture<Boolean> put1 = cache.put("josie", "football", PutPolicy.PUT_ALWAYS);
123 
124         assertThat(put1, successfulWith(is(true)));
125 
126         final CompletableFuture<Optional<IdentifiedValue<String>>> get1 = cache.getIdentified("josie");
127 
128         assertThat(get1, successful());
129         final IdentifiedValue<String> iv1 = get1.get().get();
130         assertThat(iv1.identifier(), notNullValue());
131         assertThat(iv1.value(), is("football"));
132 
133         final CompletableFuture<Map<String, Optional<IdentifiedValue<String>>>> get2 =
134                 cache.getBulkIdentified("claira", "josie", "jasmin");
135 
136         assertThat(get2, successful());
137         final Map<String, Optional<IdentifiedValue<String>>> ivMap1 = get2.get();
138         assertThat(ivMap1.keySet(), containsInAnyOrder("jasmin", "claira", "josie"));
139         assertThat(ivMap1.get("claira"), is(Optional.empty()));
140         assertThat(ivMap1.get("jasmin"), is(Optional.empty()));
141         final IdentifiedValue<String> iv2 = ivMap1.get("josie").get();
142         assertThat(iv2.identifier(), notNullValue());
143         assertThat(iv2.identifier(), equalTo(iv1.identifier()));
144         assertThat(iv2.value(), is("football"));
145     }
146 
147     @Test
148     public void simple_getIdentified_removeIf() throws ExecutionException, InterruptedException
149     {
150         final CompletableFuture<Optional<IdentifiedValue<String>>> get1 = cache.getIdentified("josie");
151 
152         assertThat(get1, successfulWith(is(Optional.empty())));
153 
154         final CompletableFuture<Boolean> put1 = cache.put("josie", "football", PutPolicy.PUT_ALWAYS);
155 
156         assertThat(put1, successfulWith(is(true)));
157 
158         final CompletableFuture<Optional<IdentifiedValue<String>>> get2 = cache.getIdentified("josie");
159 
160         assertThat(get2, successful());
161         final IdentifiedValue<String> iv2 = get2.get().get();
162         assertThat(iv2.identifier(), notNullValue());
163         assertThat(iv2.value(), is("football"));
164 
165         final CompletableFuture<Boolean> rm1 = cache.removeIf("josie", iv2.identifier());
166 
167         assertThat(rm1, successfulWith(is(true)));
168 
169         final CompletableFuture<Boolean> put2 = cache.put("josie", "football", PutPolicy.PUT_ALWAYS);
170 
171         assertThat(put2, successfulWith(is(true)));
172 
173         final CompletableFuture<Boolean> rm2 = cache.removeIf("josie", iv2.identifier());
174 
175         assertThat(rm2, successfulWith(is(false)));
176 
177         final CompletableFuture<Optional<IdentifiedValue<String>>> get3 = cache.getIdentified("josie");
178 
179         assertThat(get3, successful());
180         final IdentifiedValue<String> iv3 = get3.get().get();
181         assertThat(iv3.identifier(), notNullValue());
182         assertThat(iv3.value(), is("football"));
183 
184         final CompletableFuture<Boolean> rm3 = cache.removeIf("josie", iv3.identifier());
185 
186         assertThat(rm3, successfulWith(is(true)));
187     }
188 
189     @Test
190     public void simple_getIdentified_replaceIf() throws ExecutionException, InterruptedException
191     {
192         final CompletableFuture<Boolean> put1 = cache.put("josie", "football", PutPolicy.PUT_ALWAYS);
193 
194         assertThat(put1, successfulWith(is(true)));
195 
196         final CompletableFuture<Optional<IdentifiedValue<String>>> get1 = cache.getIdentified("josie");
197 
198         assertThat(get1, successful());
199         final IdentifiedValue<String> iv1 = get1.get().get();
200         assertThat(iv1.identifier(), notNullValue());
201         assertThat(iv1.value(), is("football"));
202 
203         final CompletableFuture<Boolean> rm1 = cache.replaceIf("josie", iv1.identifier(), "soccer");
204 
205         assertThat(rm1, successfulWith(is(true)));
206 
207         final CompletableFuture<Boolean> put2 = cache.put("josie", "football", PutPolicy.PUT_ALWAYS);
208 
209         assertThat(put2, successfulWith(is(true)));
210 
211         final CompletableFuture<Boolean> rm2 = cache.removeIf("josie", iv1.identifier());
212 
213         assertThat(rm2, successfulWith(is(false)));
214 
215         final CompletableFuture<Optional<IdentifiedValue<String>>> get3 = cache.getIdentified("josie");
216 
217         assertThat(get3, successful());
218         final IdentifiedValue<String> iv3 = get3.get().get();
219         assertThat(iv3.identifier(), notNullValue());
220         assertThat(iv3.value(), is("football"));
221 
222         final CompletableFuture<Boolean> rm3 = cache.removeIf("josie", iv3.identifier());
223 
224         assertThat(rm3, successfulWith(is(true)));
225     }
226 
227     @Test
228     public void simple_put_remove() throws ExecutionException, InterruptedException
229     {
230         final CompletableFuture<Void> rm1 = cache.remove("claira");
231 
232         assertThat(rm1, successful());
233         assertThat(rm1.get(), nullValue());
234 
235         final CompletableFuture<Boolean> put1 = cache.put("claira", "dancing", PutPolicy.PUT_ALWAYS);
236 
237         assertThat(put1, successfulWith(is(true)));
238 
239         final CompletableFuture<Void> rm2 = cache.remove("claira");
240 
241         assertThat(rm2, successful());
242 
243         final CompletableFuture<Boolean> put2 = cache.put("claira", "dancing", PutPolicy.PUT_ALWAYS);
244 
245         assertThat(put2, successfulWith(is(true)));
246 
247         final CompletableFuture<Optional<String>> get1 = cache.get("claira");
248 
249         assertThat(get1, successfulWith(is(Optional.of("dancing"))));
250 
251         final CompletableFuture<Void> rm3 = cache.remove("josie", "claira", "jasmin");
252 
253         assertThat(rm3, successful());
254 
255         final CompletableFuture<Optional<String>> get2 = cache.get("claira");
256 
257         assertThat(get2, successfulWith(is(Optional.empty())));
258     }
259 
260     @Test
261     public void simple_removeAll() throws ExecutionException, InterruptedException
262     {
263         final CompletableFuture<Boolean> put1 = cache.put("claira", "", PutPolicy.PUT_ALWAYS);
264 
265         assertThat(put1, successfulWith(is(true)));
266 
267         final CompletableFuture<Optional<String>> get1 = cache.get("claira");
268 
269         assertThat(get1, successfulWith(is(Optional.of(""))));
270 
271         final CompletableFuture<Void> rm1 = cache.removeAll();
272 
273         assertThat(rm1, successful());
274 
275         final CompletableFuture<Optional<String>> get2 = cache.get("claira");
276 
277         assertThat(get2, successfulWith(is(Optional.empty())));
278     }
279 
280     @SuppressWarnings("unchecked")
281     @Test
282     public void simple_getBulk() throws ExecutionException, InterruptedException
283     {
284         final CompletableFuture<Map<String, Optional<String>>> get1 = cache.getBulk("claira", "jasmin", "josie", "josie");
285 
286         assertThat(get1, successful());
287         assertThat(get1.get().keySet(), containsInAnyOrder("claira", "jasmin", "josie"));
288         assertThat(get1.get().values(), containsInAnyOrder(Optional.empty(), Optional.empty(), Optional.empty()));
289 
290         final CompletableFuture<Boolean> put1 = cache.put("claira", "youtube", PutPolicy.PUT_ALWAYS);
291 
292         assertThat(put1, successfulWith(is(true)));
293 
294         final CompletableFuture<Map<String, Optional<String>>> get2 = cache.getBulk("jasmin", "claira", "josie", "claira");
295 
296         assertThat(get2, successful());
297         assertThat(get2.get().keySet(), containsInAnyOrder("claira", "jasmin", "josie"));
298         assertThat(get2.get().values(), containsInAnyOrder(Optional.of("youtube"), Optional.empty(), Optional.empty()));
299     }
300 
301     @Test
302     public void simple_getBulkFactory() throws ExecutionException, InterruptedException
303     {
304         final CompletableFuture<Map<String, String>> get1 =
305                 cache.getBulk(
306                         strings -> strings.stream().collect(Collectors.toMap(k -> k, k -> k + "-1")),
307                         "claira", "josie", "josie");
308 
309         assertThat(get1, successful());
310         assertThat(get1.get().keySet(), containsInAnyOrder("claira", "josie"));
311         assertThat(get1.get().values(), containsInAnyOrder("claira-1", "josie-1"));
312 
313         final CompletableFuture<Map<String, String>> get2 =
314                 cache.getBulk(
315                         strings -> strings.stream().collect(Collectors.toMap(k -> k, k -> k + "-2")),
316                         "claira", "josie", "jasmin");
317 
318         assertThat(get2, successful());
319         assertThat(get2.get().keySet(), containsInAnyOrder("claira", "josie", "jasmin"));
320         assertThat(get2.get().values(), containsInAnyOrder("claira-1", "josie-1", "jasmin-2"));
321     }
322 }