1 package com.atlassian.vcache.internal.core.metrics;
2
3 import com.atlassian.vcache.LocalCacheOperations;
4 import org.junit.Test;
5 import org.junit.runner.RunWith;
6 import org.mockito.Mock;
7 import org.mockito.runners.MockitoJUnitRunner;
8
9 import java.util.Optional;
10 import java.util.function.Supplier;
11
12 import static com.atlassian.vcache.internal.MetricLabel.NUMBER_OF_HITS;
13 import static com.atlassian.vcache.internal.MetricLabel.NUMBER_OF_MISSES;
14 import static com.atlassian.vcache.internal.MetricLabel.TIMED_GET_CALL;
15 import static com.atlassian.vcache.internal.MetricLabel.TIMED_PUT_CALL;
16 import static com.atlassian.vcache.internal.MetricLabel.TIMED_REMOVE_ALL_CALL;
17 import static com.atlassian.vcache.internal.MetricLabel.TIMED_REMOVE_CALL;
18 import static com.atlassian.vcache.internal.MetricLabel.TIMED_SUPPLIER_CALL;
19 import static org.hamcrest.Matchers.equalTo;
20 import static org.junit.Assert.assertThat;
21 import static org.mockito.Matchers.any;
22 import static org.mockito.Matchers.anyLong;
23 import static org.mockito.Matchers.eq;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.verifyNoMoreInteractions;
26 import static org.mockito.Mockito.when;
27
28 @RunWith(MockitoJUnitRunner.class)
29 public abstract class TimedLocalCacheOperationsTest {
30 protected static final String CACHE_NAME = "peanuts";
31
32 @Mock
33 protected MetricsRecorder metricsRecorder;
34
35 protected abstract CacheType getCacheType();
36
37 protected abstract LocalCacheOperations<String, String> getDelegateOps();
38
39 protected abstract TimedLocalCacheOperations<String, String> getTimed();
40
41 @Test
42 public void get_hit() throws Exception {
43 final Optional<String> result = Optional.of("micro");
44 when(getDelegateOps().get("foo")).thenReturn(result);
45
46 final Optional<String> passedResult = getTimed().get("foo");
47
48 assertThat(passedResult, equalTo(result));
49
50 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_GET_CALL), anyLong());
51 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(NUMBER_OF_HITS), eq(1L));
52 verifyNoMoreInteractions(metricsRecorder);
53 }
54
55 @Test
56 public void get_miss() throws Exception {
57 final Optional<String> result = Optional.empty();
58 when(getDelegateOps().get("foo")).thenReturn(result);
59
60 final Optional<String> passedResult = getTimed().get("foo");
61
62 assertThat(passedResult, equalTo(result));
63
64 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_GET_CALL), anyLong());
65 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(NUMBER_OF_MISSES), eq(1L));
66 verifyNoMoreInteractions(metricsRecorder);
67 }
68
69 @Test
70 public void getSupplier_hit() throws Exception {
71 final String result = "chaos";
72 when(getDelegateOps().get(eq("foo"), any())).thenReturn(result);
73
74 final String passedResult = getTimed().get("foo", () -> "xxx");
75
76 assertThat(passedResult, equalTo(result));
77
78 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_GET_CALL), anyLong());
79 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(NUMBER_OF_HITS), eq(1L));
80 verifyNoMoreInteractions(metricsRecorder);
81 }
82
83 @Test
84 public void getSupplier_miss() throws Exception {
85 final String result = "chaos";
86 when(getDelegateOps().get(eq("foo"), any())).thenAnswer(invocation -> {
87 final Supplier func = (Supplier) invocation.getArguments()[1];
88 return func.get();
89 });
90
91 final String passedResult = getTimed().get("foo", () -> result);
92
93 assertThat(passedResult, equalTo(result));
94
95 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_GET_CALL), anyLong());
96 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_SUPPLIER_CALL), anyLong());
97 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(NUMBER_OF_MISSES), eq(1L));
98 verifyNoMoreInteractions(metricsRecorder);
99 }
100
101 @Test
102 public void put() throws Exception {
103 getTimed().put("abc", "def");
104
105 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_PUT_CALL), anyLong());
106 verifyNoMoreInteractions(metricsRecorder);
107 }
108
109 @Test
110 public void putIfAbsent() throws Exception {
111 final Optional<String> result = Optional.empty();
112 when(getDelegateOps().putIfAbsent("foo", "pain")).thenReturn(result);
113
114 final Optional<String> passedResult = getTimed().putIfAbsent("foo", "pain");
115
116 assertThat(passedResult, equalTo(result));
117
118 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_PUT_CALL), anyLong());
119 verifyNoMoreInteractions(metricsRecorder);
120 }
121
122 @Test
123 public void replaceIf() throws Exception {
124 when(getDelegateOps().replaceIf("foo", "pain", "hurt")).thenReturn(false);
125
126 final boolean passedResult = getTimed().replaceIf("foo", "pain", "hurt");
127
128 assertThat(passedResult, equalTo(false));
129
130 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_PUT_CALL), anyLong());
131 verifyNoMoreInteractions(metricsRecorder);
132 }
133
134 @Test
135 public void removeIf() throws Exception {
136 when(getDelegateOps().removeIf("foo", "hurt")).thenReturn(false);
137
138 final boolean passedResult = getTimed().removeIf("foo", "hurt");
139
140 assertThat(passedResult, equalTo(false));
141
142 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_REMOVE_CALL), anyLong());
143 verifyNoMoreInteractions(metricsRecorder);
144 }
145
146 @Test
147 public void remove() throws Exception {
148 getTimed().remove("foo");
149
150 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_REMOVE_CALL), anyLong());
151 verifyNoMoreInteractions(metricsRecorder);
152 }
153
154 @Test
155 public void removeAll() throws Exception {
156 getTimed().removeAll();
157
158 verify(metricsRecorder).record(eq(CACHE_NAME), eq(getCacheType()), eq(TIMED_REMOVE_ALL_CALL), anyLong());
159 verifyNoMoreInteractions(metricsRecorder);
160 }
161 }