1 package com.atlassian.vcache.internal.test;
2
3 import com.atlassian.vcache.DirectExternalCache;
4 import com.atlassian.vcache.PutPolicy;
5 import com.atlassian.vcache.TransactionalExternalCache;
6 import com.atlassian.vcache.internal.LongMetric;
7 import com.atlassian.vcache.internal.MetricLabel;
8 import com.atlassian.vcache.internal.RequestMetrics;
9 import com.google.common.collect.Maps;
10 import org.junit.Rule;
11 import org.junit.Test;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15 import java.util.Map;
16 import java.util.Optional;
17 import java.util.concurrent.CompletionStage;
18 import java.util.stream.Collectors;
19
20 import static com.atlassian.vcache.VCacheUtils.unsafeJoin;
21 import static com.atlassian.vcache.internal.test.CacheMetricsMatcher.hasMetric;
22 import static com.atlassian.vcache.internal.test.CacheMetricsMatcher.hasSize;
23 import static com.atlassian.vcache.internal.test.CompletionStageSuccessful.successful;
24 import static com.atlassian.vcache.internal.test.CompletionStageSuccessful.successfulWith;
25 import static org.hamcrest.Matchers.containsInAnyOrder;
26 import static org.hamcrest.Matchers.greaterThan;
27 import static org.hamcrest.Matchers.is;
28 import static org.hamcrest.Matchers.not;
29 import static org.junit.Assert.assertThat;
30
31
32
33
34 public abstract class AbstractTransactionalExternalCacheIT {
35 protected static final String CACHE_NAME = "fragileSting";
36 private static final Logger log = LoggerFactory.getLogger(AbstractTransactionalExternalCacheIT.class);
37
38 @Rule
39 public LoggingTestWatcher watcher = new LoggingTestWatcher(log);
40
41 protected abstract TransactionalExternalCache<String> cache();
42
43 protected abstract DirectExternalCache<String> directCache();
44
45 protected abstract void directCacheRefresh();
46
47 protected abstract void cacheTransactionSync();
48 protected abstract void cacheTransactionDiscard();
49 protected abstract RequestMetrics requestMetrics();
50
51 @Test
52 public void existing_getSupplier_getSupplier() {
53 final CompletionStage<Boolean> put = directCache().put("josie", "football", PutPolicy.PUT_ALWAYS);
54
55 assertThat(put, successfulWith(is(true)));
56
57 final CompletionStage<String> get1 = cache().get("josie", () -> "soccer");
58
59 assertThat(get1, successfulWith(is("football")));
60
61 final CompletionStage<String> get2 = cache().get("josie", () -> "soccer");
62
63 assertThat(get2, successfulWith(is("football")));
64
65 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
66 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
67 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
68 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(2L), is(2L)));
69 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
70 assertThat(cacheMetrics, hasSize(is(3)));
71 }
72
73 @Test
74 public void put_get_sync_successful2() {
75 cache().put("claira", "dancing", PutPolicy.PUT_ALWAYS);
76
77 final CompletionStage<Optional<String>> get1 = cache().get("claira");
78
79 assertThat(get1, successfulWith(is(Optional.of("dancing"))));
80
81
82 directCacheRefresh();
83 final CompletionStage<Optional<String>> get2 = directCache().get("claira");
84
85 assertThat(get2, successfulWith(is(Optional.empty())));
86
87
88 cacheTransactionSync();
89
90
91 directCacheRefresh();
92 final CompletionStage<Optional<String>> get3 = directCache().get("claira");
93
94 assertThat(get3, successfulWith(is(Optional.of("dancing"))));
95
96
97 final CompletionStage<Optional<String>> get4 = cache().get("claira");
98
99 assertThat(get4, successfulWith(is(Optional.of("dancing"))));
100
101 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
102 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
103 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
104 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L)));
105 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(2L), is(2L)));
106 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
107 assertThat(cacheMetrics, hasSize(is(4)));
108 }
109
110 @Test
111 public void put_get_sync_unsuccessful2() throws Exception {
112 cache().put("claira", "dancing", PutPolicy.ADD_ONLY);
113
114 final CompletionStage<Optional<String>> get1 = cache().get("claira");
115
116 assertThat(get1, successfulWith(is(Optional.of("dancing"))));
117
118
119 directCacheRefresh();
120 final CompletionStage<Optional<String>> get2 = directCache().get("claira");
121
122 assertThat(get2, successfulWith(is(Optional.empty())));
123
124
125 final CompletionStage<Map<String, String>> get3 =
126 directCache().getBulk(keys -> Maps.asMap(keys, k -> k + "-1"), "claira", "josephine");
127
128 assertThat(get3, successful());
129 assertThat(unsafeJoin(get3).keySet(), containsInAnyOrder("claira", "josephine"));
130 assertThat(unsafeJoin(get3).values(), containsInAnyOrder("claira-1", "josephine-1"));
131
132
133 cacheTransactionSync();
134
135
136 directCacheRefresh();
137 final CompletionStage<Map<String, Optional<String>>> get4 = directCache().getBulk("claira", "josephine");
138
139 assertThat(get4, successful());
140 assertThat(unsafeJoin(get4).keySet(), containsInAnyOrder("claira", "josephine"));
141 assertThat(unsafeJoin(get4).values(), containsInAnyOrder(Optional.empty(), Optional.empty()));
142
143 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
144 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
145 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(1L), greaterThan(0L)));
146 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L)));
147 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
148 assertThat(cacheMetrics, hasSize(is(3)));
149 }
150
151 @Test
152 public void getBulk_getBulkFunction_directPut_sync() throws Exception {
153 final CompletionStage<Boolean> put1 = directCache().put("claira", "dancing", PutPolicy.PUT_ALWAYS);
154
155 assertThat(put1, successful());
156
157 final CompletionStage<Map<String, Optional<String>>> get1 = cache().getBulk("claira", "josephine");
158
159 assertThat(get1, successful());
160 assertThat(unsafeJoin(get1).keySet(), containsInAnyOrder("claira", "josephine"));
161 assertThat(unsafeJoin(get1).values(), containsInAnyOrder(Optional.of("dancing"), Optional.empty()));
162
163 final CompletionStage<Map<String, String>> get2 =
164 cache().getBulk(keys -> Maps.asMap(keys, k -> "football"), "claira", "josephine");
165
166 assertThat(get2, successful());
167 assertThat(unsafeJoin(get2).keySet(), containsInAnyOrder("claira", "josephine"));
168 assertThat(unsafeJoin(get2).values(), containsInAnyOrder("dancing", "football"));
169
170
171 directCacheRefresh();
172 final CompletionStage<Boolean> put2 = directCache().put("josephine", "soccer", PutPolicy.ADD_ONLY);
173
174 assertThat(put2, successfulWith(is(true)));
175
176 cacheTransactionSync();
177
178
179 directCacheRefresh();
180 final CompletionStage<Map<String, Optional<String>>> get3 = directCache().getBulk("claira", "josephine");
181
182 assertThat(get3, successful());
183 assertThat(unsafeJoin(get3).keySet(), containsInAnyOrder("claira", "josephine"));
184 assertThat(unsafeJoin(get3).values(), containsInAnyOrder(Optional.empty(), Optional.empty()));
185
186 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
187 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
188 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
189 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_FACTORY_CALL, is(1L), greaterThan(0L)));
190 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FACTORY_KEYS, is(1L), is(1L)));
191 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(2L), is(2L)));
192 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(2L), is(2L)));
193 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
194 assertThat(cacheMetrics, hasSize(is(6)));
195 }
196
197 @Test
198 public void put_get_remove_get() {
199 cache().put("nirvana", "shotgun", PutPolicy.PUT_ALWAYS);
200
201 final CompletionStage<Optional<String>> get1 = cache().get("nirvana");
202
203 assertThat(get1, successfulWith(is(Optional.of("shotgun"))));
204
205 cache().remove("a", "b", "nirvana");
206
207 final CompletionStage<Optional<String>> get2 = cache().get("nirvana");
208
209 assertThat(get2, successfulWith(is(Optional.empty())));
210
211 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
212 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
213 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
214 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L)));
215 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_CALL, is(1L), greaterThan(0L)));
216 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
217 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L)));
218 assertThat(cacheMetrics, hasSize(is(5)));
219 }
220
221 @Test
222 public void getSupplier_removeAll_get() {
223 final CompletionStage<String> get1 = cache().get("vienna", () -> "sandwiches");
224
225 assertThat(get1, successfulWith(is("sandwiches")));
226
227 cache().removeAll();
228
229 final CompletionStage<Optional<String>> get2 = cache().get("vienna");
230
231 assertThat(get2, successfulWith(is(Optional.empty())));
232
233 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
234 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
235 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
236 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L)));
237 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, is(1L), greaterThan(0L)));
238 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(2L), is(2L)));
239 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
240 assertThat(cacheMetrics, hasSize(is(5)));
241 }
242
243 @Test
244 public void getSupplier_removeAll_getSupplier_getSupplier() {
245 final CompletionStage<String> get1 = cache().get("vienna", () -> "sandwiches");
246
247 assertThat(get1, successfulWith(is("sandwiches")));
248
249 cache().removeAll();
250
251 final CompletionStage<Optional<String>> get2 = cache().get("vienna");
252
253 assertThat(get2, successfulWith(is(Optional.empty())));
254
255 final CompletionStage<String> get3 = cache().get("vienna", () -> "new value");
256
257 assertThat(get3, successfulWith(is("new value")));
258
259 final CompletionStage<String> get4 = cache().get("vienna", () -> "not used");
260
261 assertThat(get4, successfulWith(is("new value")));
262
263 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
264 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
265 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(4L), greaterThan(0L)));
266 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L)));
267 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, is(2L), greaterThan(0L)));
268 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
269 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(3L), is(3L)));
270 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
271 assertThat(cacheMetrics, hasSize(is(6)));
272 }
273
274 @Test
275 public void getSupplier_removeAll_getBulk_getBulk() {
276 final CompletionStage<String> get1 = cache().get("vienna", () -> "sandwiches");
277
278 assertThat(get1, successfulWith(is("sandwiches")));
279
280 cache().removeAll();
281
282 final CompletionStage<Optional<String>> get2 = cache().get("vienna");
283
284 assertThat(get2, successfulWith(is(Optional.empty())));
285
286 final CompletionStage<Map<String, String>> get3 = cache().getBulk(keys -> Maps.asMap(keys, k -> k + "-1"), "vienna");
287
288 assertThat(get3, successful());
289 assertThat(unsafeJoin(get3).keySet(), containsInAnyOrder("vienna"));
290 assertThat(unsafeJoin(get3).values(), containsInAnyOrder("vienna-1"));
291
292 final CompletionStage<Map<String, String>> get4 = cache().getBulk(keys -> Maps.asMap(keys, k -> k + "-2"), "vienna");
293
294 assertThat(get4, successful());
295 assertThat(unsafeJoin(get4).keySet(), containsInAnyOrder("vienna"));
296 assertThat(unsafeJoin(get4).values(), containsInAnyOrder("vienna-1"));
297
298 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
299 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
300 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(4L), greaterThan(0L)));
301 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_FACTORY_CALL, is(1L), greaterThan(0L)));
302 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L)));
303 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, is(1L), greaterThan(0L)));
304 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FACTORY_KEYS, is(1L), is(1L)));
305 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
306 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(3L), is(3L)));
307 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
308 assertThat(cacheMetrics, hasSize(is(8)));
309 }
310
311 @Test
312 public void put_get_discard() {
313 cache().put("josie", "surfing", PutPolicy.PUT_ALWAYS);
314
315 final CompletionStage<Optional<String>> get1 = cache().get("josie");
316
317 assertThat(get1, successfulWith(is(Optional.of("surfing"))));
318
319
320 directCacheRefresh();
321 final CompletionStage<Optional<String>> get2 = directCache().get("josie");
322
323 assertThat(get2, successfulWith(is(Optional.empty())));
324
325
326 cacheTransactionDiscard();
327
328
329 directCacheRefresh();
330 final CompletionStage<Optional<String>> get3 = directCache().get("josie");
331
332 assertThat(get3, successfulWith(is(Optional.empty())));
333
334 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
335 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
336 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(1L), greaterThan(0L)));
337 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_PUT_CALL, is(1L), greaterThan(0L)));
338 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
339 assertThat(cacheMetrics, hasSize(is(3)));
340 }
341
342 @Test
343 public void existing_remove_get() {
344 directCache().put("key", "existing", PutPolicy.PUT_ALWAYS);
345
346 final CompletionStage<Optional<String>> get1 = cache().get("key");
347
348 assertThat(get1, successfulWith(is(Optional.of("existing"))));
349
350 cache().remove("key");
351
352 final CompletionStage<Optional<String>> get2 = cache().get("key");
353
354 assertThat(get2, successfulWith(is(Optional.empty())));
355
356 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
357 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
358 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
359 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_CALL, is(1L), greaterThan(0L)));
360 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
361 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L)));
362 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
363 assertThat(cacheMetrics, hasSize(is(5)));
364 }
365
366 @Test
367 public void existing_remove_getSupplier() {
368 directCache().put("key", "existing", PutPolicy.PUT_ALWAYS);
369
370 final CompletionStage<Optional<String>> get1 = cache().get("key");
371
372 assertThat(get1, successfulWith(is(Optional.of("existing"))));
373
374 cache().remove("key");
375
376 final CompletionStage<String> get2 = cache().get("key", () -> "new");
377
378 assertThat(get2, successfulWith(is("new")));
379
380 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
381 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
382 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
383 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_CALL, is(1L), greaterThan(0L)));
384 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, is(1L), greaterThan(0L)));
385 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
386 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L)));
387 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
388 assertThat(cacheMetrics, hasSize(is(6)));
389 }
390
391 @Test
392 public void existing_remove_getBulk() {
393 directCache().put("key", "existing", PutPolicy.PUT_ALWAYS);
394
395 final CompletionStage<Optional<String>> get1 = cache().get("key");
396
397 assertThat(get1, successfulWith(is(Optional.of("existing"))));
398
399 cache().remove("key");
400
401 final CompletionStage<Map<String, String>> get2 = cache().getBulk(
402 strings -> strings.stream().collect(Collectors.toMap(k -> k, k -> k + "-new")),
403 "key", "extra");
404
405 assertThat(get2, successful());
406 assertThat(unsafeJoin(get2).keySet(), containsInAnyOrder("key", "extra"));
407 assertThat(unsafeJoin(get2).values(), containsInAnyOrder("key-new", "extra-new"));
408
409 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
410 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
411 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
412 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_FACTORY_CALL, is(1L), greaterThan(0L)));
413 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_CALL, is(1L), greaterThan(0L)));
414 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FACTORY_KEYS, is(1L), is(2L)));
415 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
416 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(2L)));
417 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(2L), is(2L)));
418 assertThat(cacheMetrics, hasSize(is(7)));
419 }
420
421 @Test
422 public void existing_removeAll_get() {
423 directCache().put("key", "existing", PutPolicy.PUT_ALWAYS);
424
425 final CompletionStage<Optional<String>> get1 = cache().get("key");
426
427 assertThat(get1, successfulWith(is(Optional.of("existing"))));
428
429 cache().removeAll();
430
431 final CompletionStage<Optional<String>> get2 = cache().get("key");
432
433 assertThat(get2, successfulWith(is(Optional.empty())));
434
435 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
436 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
437 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
438 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L)));
439 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
440 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L)));
441 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
442 assertThat(cacheMetrics, hasSize(is(5)));
443 }
444
445 @Test
446 public void existing_removeAll_getSupplier() {
447 directCache().put("key", "existing", PutPolicy.PUT_ALWAYS);
448
449 final CompletionStage<Optional<String>> get1 = cache().get("key");
450
451 assertThat(get1, successfulWith(is(Optional.of("existing"))));
452
453 cache().removeAll();
454
455 final CompletionStage<String> get2 = cache().get("key", () -> "new");
456
457 assertThat(get2, successfulWith(is("new")));
458
459 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
460 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
461 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
462 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L)));
463 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_SUPPLIER_CALL, is(1L), greaterThan(0L)));
464 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
465 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L)));
466 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
467 assertThat(cacheMetrics, hasSize(is(6)));
468 }
469
470 @Test
471 public void existing_removeAll_getBulk() {
472 directCache().put("key", "existing", PutPolicy.PUT_ALWAYS);
473
474 final CompletionStage<Optional<String>> get1 = cache().get("key");
475
476 assertThat(get1, successfulWith(is(Optional.of("existing"))));
477
478 cache().removeAll();
479
480 final CompletionStage<Map<String, String>> get2 = cache().getBulk(
481 strings -> strings.stream().collect(Collectors.toMap(k -> k, k -> k + "-new")),
482 "key");
483
484 assertThat(get2, successful());
485 assertThat(unsafeJoin(get2).keySet(), containsInAnyOrder("key"));
486 assertThat(unsafeJoin(get2).values(), containsInAnyOrder("key-new"));
487
488 final Map<MetricLabel, ? extends LongMetric> cacheMetrics =
489 requestMetrics().allExternalCacheLongMetrics().get(CACHE_NAME);
490 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_GET_CALL, is(2L), greaterThan(0L)));
491 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_FACTORY_CALL, is(1L), greaterThan(0L)));
492 assertThat(cacheMetrics, hasMetric(MetricLabel.TIMED_REMOVE_ALL_CALL, is(1L), greaterThan(0L)));
493 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_FACTORY_KEYS, is(1L), is(1L)));
494 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_HITS, is(1L), is(1L)));
495 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_MISSES, is(1L), is(1L)));
496 assertThat(cacheMetrics, hasMetric(MetricLabel.NUMBER_OF_REMOTE_GET, is(1L), is(1L)));
497 assertThat(cacheMetrics, hasSize(is(7)));
498 }
499
500 @Test
501 public void check_get_null_detection() {
502 assertThat(cache().get("kenny", () -> null), not(successful()));
503 assertThat(cache().getBulk(
504 strings -> strings.stream().collect(Collectors.toMap(k -> k, k -> null)),
505 "extra"),
506 not(successful()));
507 }
508
509 @SuppressWarnings("ConstantConditions")
510 @Test(expected = NullPointerException.class)
511 public void check_put_null_detection() {
512 cache().put("key", null, PutPolicy.ADD_ONLY);
513 }
514 }
515