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.CasIdentifier;
9 import com.atlassian.vcache.DirectExternalCache;
10 import com.atlassian.vcache.IdentifiedValue;
11
12 import org.junit.Before;
13 import org.junit.Test;
14 import org.junit.runner.RunWith;
15 import org.mockito.Mock;
16 import org.mockito.runners.MockitoJUnitRunner;
17
18 import static com.atlassian.vcache.internal.MetricLabel.NUMBER_OF_FAILED_IDENTIFIED_GET;
19 import static com.atlassian.vcache.internal.MetricLabel.NUMBER_OF_FAILED_IDENTIFIED_REMOVE;
20 import static com.atlassian.vcache.internal.MetricLabel.NUMBER_OF_FAILED_IDENTIFIED_REPLACE;
21 import static com.atlassian.vcache.internal.MetricLabel.NUMBER_OF_HITS;
22 import static com.atlassian.vcache.internal.MetricLabel.NUMBER_OF_MISSES;
23 import static com.atlassian.vcache.internal.MetricLabel.TIMED_IDENTIFIED_GET_CALL;
24 import static com.atlassian.vcache.internal.MetricLabel.TIMED_IDENTIFIED_REMOVE_CALL;
25 import static com.atlassian.vcache.internal.MetricLabel.TIMED_IDENTIFIED_REPLACE_CALL;
26 import static com.atlassian.vcache.internal.core.metrics.CacheType.EXTERNAL;
27 import static java.util.Collections.singletonList;
28 import static org.hamcrest.Matchers.equalTo;
29 import static org.junit.Assert.assertThat;
30 import static org.mockito.Matchers.anyLong;
31 import static org.mockito.Matchers.eq;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.verifyNoMoreInteractions;
35 import static org.mockito.Mockito.when;
36
37 @RunWith(MockitoJUnitRunner.class)
38 public class TimedDirectExternalCacheTest extends TimedExternalCacheTest
39 {
40 @Mock
41 private CasIdentifier casIdentifier;
42
43 @Mock
44 private IdentifiedValue<String> identifiedValue;
45
46 @Mock
47 private DirectExternalCache<String> delegate;
48
49 private TimedDirectExternalCache<String> timed;
50
51 @Before
52 public void init()
53 {
54 when(delegate.getName()).thenReturn(CACHE_NAME);
55 timed = new TimedDirectExternalCache<>(metricsCollector, delegate);
56 }
57
58 @Override
59 protected DirectExternalCache<String> getDelegate()
60 {
61 return delegate;
62 }
63
64 @Override
65 protected TimedDirectExternalCache<String> getTimed()
66 {
67 return timed;
68 }
69
70 @Test
71 public void getIdentified_failure() throws Exception
72 {
73 final CompletableFuture<Optional<IdentifiedValue<String>>> result = mock(CompletableFuture.class);
74 when(result.isCompletedExceptionally()).thenReturn(true);
75 when(getDelegate().getIdentified("game")).thenReturn(result);
76
77 final CompletableFuture<Optional<IdentifiedValue<String>>> passedResult = getTimed().getIdentified("game");
78
79 assertThat(passedResult, equalTo(result));
80
81 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_FAILED_IDENTIFIED_GET), eq(1L));
82 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_IDENTIFIED_GET_CALL), anyLong());
83 verifyNoMoreInteractions(metricsCollector);
84 }
85
86 @Test
87 public void getIdentified_miss() throws Exception
88 {
89 final CompletableFuture<Optional<IdentifiedValue<String>>> result = mock(CompletableFuture.class);
90 when(result.join()).thenReturn(Optional.empty());
91 when(getDelegate().getIdentified("game")).thenReturn(result);
92
93 final CompletableFuture<Optional<IdentifiedValue<String>>> passedResult = getTimed().getIdentified("game");
94
95 assertThat(passedResult, equalTo(result));
96
97 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_MISSES), eq(1L));
98 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_IDENTIFIED_GET_CALL), anyLong());
99 verifyNoMoreInteractions(metricsCollector);
100 }
101
102 @Test
103 public void getIdentified_hit() throws Exception
104 {
105 final CompletableFuture<Optional<IdentifiedValue<String>>> result = mock(CompletableFuture.class);
106 when(result.join()).thenReturn(Optional.of(identifiedValue));
107 when(getDelegate().getIdentified("game")).thenReturn(result);
108
109 final CompletableFuture<Optional<IdentifiedValue<String>>> passedResult = getTimed().getIdentified("game");
110
111 assertThat(passedResult, equalTo(result));
112
113 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_HITS), eq(1L));
114 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_IDENTIFIED_GET_CALL), anyLong());
115 verifyNoMoreInteractions(metricsCollector);
116 }
117
118 @Test
119 public void getBulkIdentified_success() throws Exception
120 {
121 final Map<String, Optional<IdentifiedValue<String>>> theMap = new HashMap<>();
122 theMap.put("foo", Optional.empty());
123 final CompletableFuture<Map<String, Optional<IdentifiedValue<String>>>> result = mock(CompletableFuture.class);
124 when(result.join()).thenReturn(theMap);
125
126 when(getDelegate().getBulkIdentified(singletonList("foo"))).thenReturn(result);
127
128 final CompletableFuture<Map<String, Optional<IdentifiedValue<String>>>> passedResult = getTimed().getBulkIdentified("foo");
129
130 assertThat(passedResult, equalTo(result));
131
132 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_IDENTIFIED_GET_CALL), anyLong());
133 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_MISSES), eq(1L));
134 verifyNoMoreInteractions(metricsCollector);
135 }
136
137 @Test
138 public void getBulkIdentified_failure() throws Exception
139 {
140 final CompletableFuture<Map<String, Optional<IdentifiedValue<String>>>> result = mock(CompletableFuture.class);
141 when(result.isCompletedExceptionally()).thenReturn(true);
142
143 when(getDelegate().getBulkIdentified(singletonList("foo"))).thenReturn(result);
144
145 final CompletableFuture<Map<String, Optional<IdentifiedValue<String>>>> passedResult = getTimed().getBulkIdentified("foo");
146
147 assertThat(passedResult, equalTo(result));
148
149 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_IDENTIFIED_GET_CALL), anyLong());
150 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_FAILED_IDENTIFIED_GET), eq(1L));
151 verifyNoMoreInteractions(metricsCollector);
152 }
153
154 @Test
155 public void removeIf_okay() throws Exception
156 {
157 final CompletableFuture<Boolean> result = mock(CompletableFuture.class);
158 when(result.join()).thenReturn(true);
159 when(getDelegate().removeIf("lock", casIdentifier)).thenReturn(result);
160
161 final CompletableFuture<Boolean> passedResult = getTimed().removeIf("lock", casIdentifier);
162
163 assertThat(passedResult, equalTo(result));
164
165 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_IDENTIFIED_REMOVE_CALL), anyLong());
166 verifyNoMoreInteractions(metricsCollector);
167 }
168
169 @Test
170 public void removeIf_failure() throws Exception
171 {
172 final CompletableFuture<Boolean> result = mock(CompletableFuture.class);
173 when(result.isCompletedExceptionally()).thenReturn(true);
174 when(getDelegate().removeIf("lock", casIdentifier)).thenReturn(result);
175
176 final CompletableFuture<Boolean> passedResult = getTimed().removeIf("lock", casIdentifier);
177
178 assertThat(passedResult, equalTo(result));
179
180 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_FAILED_IDENTIFIED_REMOVE), eq(1L));
181 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_IDENTIFIED_REMOVE_CALL), anyLong());
182 verifyNoMoreInteractions(metricsCollector);
183 }
184
185 @Test
186 public void replaceIf_okay() throws Exception
187 {
188 final CompletableFuture<Boolean> result = mock(CompletableFuture.class);
189 when(getDelegate().replaceIf("lock", casIdentifier, "wood")).thenReturn(result);
190
191 final CompletableFuture<Boolean> passedResult = getTimed().replaceIf("lock", casIdentifier,"wood");
192
193 assertThat(passedResult, equalTo(result));
194
195 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_IDENTIFIED_REPLACE_CALL), anyLong());
196 verifyNoMoreInteractions(metricsCollector);
197 }
198
199 @Test
200 public void replaceIf_failure() throws Exception
201 {
202 final CompletableFuture<Boolean> result = mock(CompletableFuture.class);
203 when(result.isCompletedExceptionally()).thenReturn(true);
204 when(getDelegate().replaceIf("lock", casIdentifier, "wood")).thenReturn(result);
205
206 final CompletableFuture<Boolean> passedResult = getTimed().replaceIf("lock", casIdentifier,"wood");
207
208 assertThat(passedResult, equalTo(result));
209
210 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(NUMBER_OF_FAILED_IDENTIFIED_REPLACE), eq(1L));
211 verify(metricsCollector).record(eq(EXTERNAL), eq(CACHE_NAME), eq(TIMED_IDENTIFIED_REPLACE_CALL), anyLong());
212 verifyNoMoreInteractions(metricsCollector);
213 }
214 }