1 package com.atlassian.vcache.internal.core.metrics;
2
3 import java.util.HashMap;
4 import java.util.Map;
5 import java.util.Optional;
6 import java.util.concurrent.CompletableFuture;
7
8 import com.atlassian.vcache.ExternalCache;
9
10 import org.junit.Test;
11 import org.mockito.Mock;
12
13 import static com.atlassian.vcache.internal.MetricLabel.NUMBER_OF_FAILED_GET;
14 import static com.atlassian.vcache.internal.MetricLabel.NUMBER_OF_HITS;
15 import static com.atlassian.vcache.internal.MetricLabel.TIMED_GET_CALL;
16 import static com.atlassian.vcache.internal.core.metrics.CacheType.EXTERNAL;
17 import static java.util.Collections.singletonList;
18 import static org.hamcrest.Matchers.equalTo;
19 import static org.junit.Assert.assertThat;
20 import static org.mockito.Matchers.any;
21 import static org.mockito.Matchers.anyLong;
22 import static org.mockito.Matchers.eq;
23 import static org.mockito.Mockito.mock;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.verifyNoMoreInteractions;
26 import static org.mockito.Mockito.when;
27
28 public abstract class TimedExternalCacheTest
29 {
30 protected static final String CACHE_NAME = "cashew";
31
32 @Mock
33 protected MetricsCollector metricsCollector;
34
35 protected abstract ExternalCache<String> getDelegate();
36 protected abstract TimedExternalCache<String> getTimed();
37
38 @Test
39 public void get_hit()
40 {
41 final CompletableFuture<Optional<String>> result = mock(CompletableFuture.class);
42 when(result.join()).thenReturn(Optional.of("politics of dancing"));
43 when(getDelegate().get("foo")).thenReturn(result);
44
45 final CompletableFuture<Optional<String>> passedResult = getTimed().get("foo");
46
47 assertThat(passedResult, equalTo(result));
48
49 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_GET_CALL), anyLong());
50 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_HITS), eq(1L));
51 verifyNoMoreInteractions(metricsCollector);
52 }
53
54 @Test
55 public void get_miss() throws Exception
56 {
57 final CompletableFuture<Optional<String>> result = mock(CompletableFuture.class);
58 when(result.join()).thenReturn(Optional.of("politics of dancing"));
59 when(getDelegate().get("foo")).thenReturn(result);
60
61 final CompletableFuture<Optional<String>> passedResult = getTimed().get("foo");
62
63 assertThat(passedResult, equalTo(result));
64
65 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_GET_CALL), anyLong());
66 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_HITS), eq(1L));
67 verifyNoMoreInteractions(metricsCollector);
68 }
69
70 @Test
71 public void getSupplier_hit()
72 {
73 final CompletableFuture<String> result = mock(CompletableFuture.class);
74 when(result.join()).thenReturn("politics of dancing");
75
76 when(getDelegate().get(eq("foo"), any())).thenReturn(result);
77
78 final CompletableFuture<String> passedResult = getTimed().get("foo", () -> "");
79
80 assertThat(passedResult, equalTo(result));
81
82 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_GET_CALL), anyLong());
83 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_HITS), eq(1L));
84 verifyNoMoreInteractions(metricsCollector);
85 }
86
87 @Test
88 public void getBulk_success()
89 {
90 final Map<String, Optional<String>> theMap = new HashMap<>();
91 theMap.put("foo", Optional.of("moving"));
92 final CompletableFuture<Map<String, Optional<String>>> result = mock(CompletableFuture.class);
93 when(result.join()).thenReturn(theMap);
94
95 when(getDelegate().getBulk(singletonList("foo"))).thenReturn(result);
96
97 final CompletableFuture<Map<String, Optional<String>>> passedResult = getTimed().getBulk("foo");
98
99 assertThat(passedResult, equalTo(result));
100
101 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_GET_CALL), anyLong());
102 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_HITS), eq(1L));
103 verifyNoMoreInteractions(metricsCollector);
104 }
105
106 @Test
107 public void getBulk_fail()
108 {
109 final CompletableFuture<Map<String, Optional<String>>> result = mock(CompletableFuture.class);
110 when(result.isCompletedExceptionally()).thenReturn(true);
111 when(getDelegate().getBulk(singletonList("foo"))).thenReturn(result);
112
113 final CompletableFuture<Map<String, Optional<String>>> passedResult = getTimed().getBulk("foo");
114
115 assertThat(passedResult, equalTo(result));
116
117 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_GET_CALL), anyLong());
118 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_FAILED_GET), eq(1L));
119 verifyNoMoreInteractions(metricsCollector);
120 }
121
122 @Test
123 public void getBulkFactory_success()
124 {
125 final Map<String, String> theMap = new HashMap<>();
126 theMap.put("foo", "moving");
127 final CompletableFuture<Map<String, String>> result = mock(CompletableFuture.class);
128 when(result.join()).thenReturn(theMap);
129
130 when(getDelegate().getBulk(any(), eq(singletonList("foo")))).thenReturn(result);
131
132 final CompletableFuture<Map<String, String>> passedResult = getTimed().getBulk(keys -> new HashMap(), "foo");
133
134 assertThat(passedResult, equalTo(result));
135
136 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_GET_CALL), anyLong());
137 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_HITS), eq(1L));
138 verifyNoMoreInteractions(metricsCollector);
139 }
140 }