1 package com.atlassian.cache.hazelcast;
2
3 import javax.annotation.Nonnull;
4
5 import com.atlassian.cache.AbstractCacheLazyTest;
6 import com.atlassian.cache.Cache;
7 import com.atlassian.cache.CacheFactory;
8 import com.atlassian.cache.CacheLoader;
9 import com.atlassian.cache.CacheSettingsBuilder;
10
11 import org.junit.After;
12 import org.junit.Before;
13 import org.junit.ClassRule;
14 import org.junit.Test;
15
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.hamcrest.Matchers.equalTo;
18 import static org.hamcrest.Matchers.is;
19 import static org.hamcrest.Matchers.nullValue;
20
21 public class HazelcastHybridCacheLazyTest extends AbstractCacheLazyTest
22 {
23 @ClassRule
24 public static InitOnceHazelcastCluster cluster = InitOnceHazelcastCluster.getInstance();
25
26 private Cache<String, Long> cacheNode1;
27 private Cache<String, Long> cacheNode2;
28 private HazelcastCacheManager factory1;
29 private HazelcastCacheManager factory2;
30
31 @Before
32 public void setUp() throws Exception
33 {
34 cluster.reset();
35 factory1 = HazelcastTestSupport.createDistributedFactory(cluster.getNode(0));
36 factory2 = HazelcastTestSupport.createDistributedFactory(cluster.getNode(1));
37
38
39
40 CacheLoader<String, Long> loader = new BadLoader();
41
42 cacheNode1 = factory1.getCache("test", loader, settingsBuilder().build());
43 cacheNode2 = factory2.getCache("test", loader, settingsBuilder().build());
44
45 factory = factory1;
46 }
47
48 @After
49 public void tearDown()
50 {
51 factory1.destroy();
52 factory2.destroy();
53 }
54
55 @Override
56 protected CacheSettingsBuilder settingsBuilder()
57 {
58 return new CacheSettingsBuilder()
59 .remote()
60 .replicateSynchronously()
61 .replicateViaInvalidation();
62 }
63
64 @Test
65 public void testLazyCreationDoestNotInvalidateCache()
66 {
67
68 assertThat(cacheNode1.get("key"), equalTo(1L));
69 assertThat(cacheNode1.get("key"), equalTo(1L));
70
71
72 assertThat(cacheNode2.get("key"), equalTo(2L));
73
74
75 assertThat(cacheNode1.get("key"), equalTo(1L));
76 }
77
78 @Test
79 public void testPutInvalidatesCache()
80 {
81
82 assertThat(cacheNode1.get("key"), equalTo(1L));
83
84 cacheNode2.put("key", 99L);
85 assertThat(cacheNode2.get("key"), equalTo(99L));
86
87
88 assertThat(cacheNode1.get("key"), equalTo(2L));
89 assertThat(cacheNode2.get("key"), equalTo(99L));
90 }
91
92 @Test(timeout = 2000L)
93 public void testPutIfAbsentInvalidatesCache() throws InterruptedException
94 {
95
96 assertThat(cacheNode1.get("key"), equalTo(1L));
97
98 Long oldValue = cacheNode2.putIfAbsent("key", 99L);
99 assertThat(oldValue, nullValue());
100 assertThat(cacheNode2.get("key"), equalTo(99L));
101
102
103 assertEventuallyThat(() -> cacheNode1.get("key"), equalTo(2L));
104
105 assertThat(cacheNode1.get("key"), equalTo(2L));
106 assertThat(cacheNode2.get("key"), equalTo(99L));
107
108
109 oldValue = cacheNode2.putIfAbsent("key", 101L);
110 assertThat(oldValue, equalTo(99L));
111
112 assertEventuallyThat(() -> cacheNode1.get("key"), equalTo(2L));
113 }
114
115 @Test
116 public void testReplaceInvalidatesCache()
117 {
118
119 assertThat(cacheNode1.get("key"), equalTo(1L));
120 assertThat(cacheNode2.get("key"), equalTo(2L));
121
122 cacheNode2.replace("key", 2L, 99L);
123 assertThat(cacheNode1.get("key"), equalTo(3L));
124 assertThat(cacheNode2.get("key"), equalTo(99L));
125
126
127 boolean replaced = cacheNode2.replace("key", 10012L, 1L);
128 assertThat(replaced, is(false));
129 assertThat(cacheNode1.get("key"), equalTo(3L));
130 assertThat(cacheNode2.get("key"), equalTo(99L));
131 }
132
133 @Test
134 public void testRemoveInvalidatesCache()
135 {
136
137 assertThat(cacheNode1.get("key"), equalTo(1L));
138 assertThat(cacheNode2.get("key"), equalTo(2L));
139
140 cacheNode2.remove("key");
141 assertThat(cacheNode1.get("key"), equalTo(3L));
142 assertThat(cacheNode2.get("key"), equalTo(4L));
143
144
145 boolean removed = cacheNode2.remove("key", 3L);
146 assertThat(removed, is(false));
147 assertThat(cacheNode1.get("key"), equalTo(3L));
148 assertThat(cacheNode2.get("key"), equalTo(4L));
149
150 removed = cacheNode2.remove("key", 4L);
151 assertThat(removed, is(true));
152 assertThat(cacheNode1.get("key"), equalTo(5L));
153 assertThat(cacheNode2.get("key"), equalTo(6L));
154 }
155
156 @Test
157 public void testRemoveAllInvalidatesCache()
158 {
159
160 assertThat(cacheNode1.get("key"), equalTo(1L));
161 assertThat(cacheNode2.get("key"), equalTo(2L));
162
163 cacheNode2.removeAll();
164 assertThat(cacheNode1.get("key"), equalTo(3L));
165 assertThat(cacheNode2.get("key"), equalTo(4L));
166 }
167
168 @Test
169 public void testRemoveConcurrentWithLoadClustered()
170 {
171 final CacheFactory factory2 = HazelcastTestSupport.createDistributedFactory(cluster.getNode(1));
172 removeConcurrentWithLoader(factory, factory2, REMOVE_0);
173 }
174
175 @Test
176 public void testRemoveAllConcurrentWithLoadClustered()
177 {
178 final CacheFactory factory2 = HazelcastTestSupport.createDistributedFactory(cluster.getNode(1));
179 removeConcurrentWithLoader(factory, factory2, REMOVE_ALL);
180 }
181
182 private static class BadLoader implements CacheLoader<String, Long>
183 {
184 private long value;
185
186 @Nonnull
187 @Override
188 public Long load(@Nonnull String key)
189 {
190 return ++value;
191 }
192 }
193 }