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.google.common.collect.Maps;
7 import org.junit.Rule;
8 import org.junit.Test;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11
12 import java.util.Map;
13 import java.util.Optional;
14 import java.util.concurrent.CompletionStage;
15 import java.util.stream.Collectors;
16
17 import static com.atlassian.vcache.VCacheUtils.unsafeJoin;
18 import static com.atlassian.vcache.internal.test.CompletionStageSuccessful.successful;
19 import static com.atlassian.vcache.internal.test.CompletionStageSuccessful.successfulWith;
20 import static org.hamcrest.Matchers.containsInAnyOrder;
21 import static org.hamcrest.Matchers.is;
22 import static org.hamcrest.Matchers.not;
23 import static org.junit.Assert.assertThat;
24
25
26
27
28 public abstract class AbstractTransactionalExternalCacheIT {
29 protected static final String CACHE_NAME = "fragileSting";
30 private static final Logger log = LoggerFactory.getLogger(AbstractStableReadExternalCacheIT.class);
31
32 @Rule
33 public LoggingTestWatcher watcher = new LoggingTestWatcher(log);
34
35 protected abstract TransactionalExternalCache<String> cache();
36
37 protected abstract DirectExternalCache<String> directCache();
38
39 protected abstract void directCacheRefresh();
40
41 protected abstract void cacheTransactionSync();
42 protected abstract void cacheTransactionDiscard();
43
44 @Test
45 public void put_get_sync_successful2() {
46 cache().put("claira", "dancing", PutPolicy.PUT_ALWAYS);
47
48 final CompletionStage<Optional<String>> get1 = cache().get("claira");
49
50 assertThat(get1, successfulWith(is(Optional.of("dancing"))));
51
52
53 directCacheRefresh();
54 final CompletionStage<Optional<String>> get2 = directCache().get("claira");
55
56 assertThat(get2, successfulWith(is(Optional.empty())));
57
58
59 cacheTransactionSync();
60
61
62 directCacheRefresh();
63 final CompletionStage<Optional<String>> get3 = directCache().get("claira");
64
65 assertThat(get3, successfulWith(is(Optional.of("dancing"))));
66
67
68 final CompletionStage<Optional<String>> get4 = cache().get("claira");
69
70 assertThat(get4, successfulWith(is(Optional.of("dancing"))));
71 }
72
73 @Test
74 public void put_get_sync_unsuccessful2() throws Exception {
75 cache().put("claira", "dancing", PutPolicy.ADD_ONLY);
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 final CompletionStage<Map<String, String>> get3 =
89 directCache().getBulk(keys -> Maps.asMap(keys, k -> k + "-1"), "claira", "josephine");
90
91 assertThat(get3, successful());
92 assertThat(unsafeJoin(get3).keySet(), containsInAnyOrder("claira", "josephine"));
93 assertThat(unsafeJoin(get3).values(), containsInAnyOrder("claira-1", "josephine-1"));
94
95
96 cacheTransactionSync();
97
98
99 directCacheRefresh();
100 final CompletionStage<Map<String, Optional<String>>> get4 = directCache().getBulk("claira", "josephine");
101
102 assertThat(get4, successful());
103 assertThat(unsafeJoin(get4).keySet(), containsInAnyOrder("claira", "josephine"));
104 assertThat(unsafeJoin(get4).values(), containsInAnyOrder(Optional.empty(), Optional.empty()));
105 }
106
107 @Test
108 public void getBulk_getBulkFunction_directPut_sync() throws Exception {
109 final CompletionStage<Boolean> put1 = directCache().put("claira", "dancing", PutPolicy.PUT_ALWAYS);
110
111 assertThat(put1, successful());
112
113 final CompletionStage<Map<String, Optional<String>>> get1 = cache().getBulk("claira", "josephine");
114
115 assertThat(get1, successful());
116 assertThat(unsafeJoin(get1).keySet(), containsInAnyOrder("claira", "josephine"));
117 assertThat(unsafeJoin(get1).values(), containsInAnyOrder(Optional.of("dancing"), Optional.empty()));
118
119 final CompletionStage<Map<String, String>> get2 =
120 cache().getBulk(keys -> Maps.asMap(keys, k -> "football"), "claira", "josephine");
121
122 assertThat(get2, successful());
123 assertThat(unsafeJoin(get2).keySet(), containsInAnyOrder("claira", "josephine"));
124 assertThat(unsafeJoin(get2).values(), containsInAnyOrder("dancing", "football"));
125
126
127 directCacheRefresh();
128 final CompletionStage<Boolean> put2 = directCache().put("josephine", "soccer", PutPolicy.ADD_ONLY);
129
130 assertThat(put2, successfulWith(is(true)));
131
132 cacheTransactionSync();
133
134
135 directCacheRefresh();
136 final CompletionStage<Map<String, Optional<String>>> get3 = directCache().getBulk("claira", "josephine");
137
138 assertThat(get3, successful());
139 assertThat(unsafeJoin(get3).keySet(), containsInAnyOrder("claira", "josephine"));
140 assertThat(unsafeJoin(get3).values(), containsInAnyOrder(Optional.empty(), Optional.empty()));
141 }
142
143 @Test
144 public void put_get_remove_get() {
145 cache().put("nirvana", "shotgun", PutPolicy.PUT_ALWAYS);
146
147 final CompletionStage<Optional<String>> get1 = cache().get("nirvana");
148
149 assertThat(get1, successfulWith(is(Optional.of("shotgun"))));
150
151 cache().remove("a", "b", "nirvana");
152
153 final CompletionStage<Optional<String>> get2 = cache().get("nirvana");
154
155 assertThat(get2, successfulWith(is(Optional.empty())));
156 }
157
158 @Test
159 public void getSupplier_removeAll_get() {
160 final CompletionStage<String> get1 = cache().get("vienna", () -> "sandwiches");
161
162 assertThat(get1, successfulWith(is("sandwiches")));
163
164 cache().removeAll();
165
166 final CompletionStage<Optional<String>> get2 = cache().get("vienna");
167
168 assertThat(get2, successfulWith(is(Optional.empty())));
169 }
170
171 @Test
172 public void put_get_discard() {
173 cache().put("josie", "surfing", PutPolicy.PUT_ALWAYS);
174
175 final CompletionStage<Optional<String>> get1 = cache().get("josie");
176
177 assertThat(get1, successfulWith(is(Optional.of("surfing"))));
178
179
180 directCacheRefresh();
181 final CompletionStage<Optional<String>> get2 = directCache().get("josie");
182
183 assertThat(get2, successfulWith(is(Optional.empty())));
184
185
186 cacheTransactionDiscard();
187
188
189 directCacheRefresh();
190 final CompletionStage<Optional<String>> get3 = directCache().get("josie");
191
192 assertThat(get3, successfulWith(is(Optional.empty())));
193 }
194
195 @Test
196 public void check_get_null_detection() {
197 assertThat(cache().get("kenny", () -> null), not(successful()));
198 assertThat(cache().getBulk(
199 strings -> strings.stream().collect(Collectors.toMap(k -> k, k -> null)),
200 "extra"),
201 not(successful()));
202 }
203
204 @SuppressWarnings("ConstantConditions")
205 @Test(expected = NullPointerException.class)
206 public void check_put_null_detection() {
207 cache().put("key", null, PutPolicy.ADD_ONLY);
208 }
209 }
210