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 HazelcastAsyncHybridCacheLazyTest 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 .replicateAsynchronously()
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 public void testPutInvalidatesCache()
79 {
80
81 assertThat(cacheNode1.get("key"), equalTo(1L));
82
83 cacheNode2.put("key", 99L);
84 assertThat(cacheNode2.get("key"), equalTo(99L));
85
86
87 assertEventuallyThat(() -> cacheNode1.get("key"), equalTo(2L));
88 assertThat(cacheNode2.get("key"), equalTo(99L));
89 }
90
91 @Test(timeout = 2000L)
92 public void testPutIfAbsentInvalidatesCache() throws InterruptedException
93 {
94
95 assertThat(cacheNode1.get("key"), equalTo(1L));
96
97 Long oldValue = cacheNode2.putIfAbsent("key", 99L);
98 assertThat(oldValue, nullValue());
99 assertThat(cacheNode2.get("key"), equalTo(99L));
100
101
102 assertEventuallyThat(() -> cacheNode1.get("key"), equalTo(2L));
103
104 assertThat(cacheNode1.get("key"), equalTo(2L));
105 assertThat(cacheNode2.get("key"), equalTo(99L));
106
107
108 oldValue = cacheNode2.putIfAbsent("key", 101L);
109 assertThat(oldValue, equalTo(99L));
110
111 assertEventuallyThat(() -> cacheNode1.get("key"), equalTo(2L));
112 }
113
114 @Test
115 public void testReplaceInvalidatesCache()
116 {
117
118 assertThat(cacheNode1.get("key"), equalTo(1L));
119 assertThat(cacheNode2.get("key"), equalTo(2L));
120
121 cacheNode2.replace("key", 2L, 99L);
122 assertEventuallyThat(() -> cacheNode1.get("key"), equalTo(3L));
123 assertThat(cacheNode2.get("key"), equalTo(99L));
124
125
126 boolean replaced = cacheNode2.replace("key", 10012L, 1L);
127 assertThat(replaced, is(false));
128 assertThat(cacheNode1.get("key"), equalTo(3L));
129 assertThat(cacheNode2.get("key"), equalTo(99L));
130 }
131
132 @Test
133 public void testRemoveInvalidatesCache()
134 {
135
136 assertThat(cacheNode1.get("key"), equalTo(1L));
137 assertThat(cacheNode2.get("key"), equalTo(2L));
138
139 cacheNode2.remove("key");
140 assertEventuallyThat(() -> cacheNode1.get("key"), equalTo(3L));
141 assertThat(cacheNode2.get("key"), equalTo(4L));
142
143
144 boolean removed = cacheNode2.remove("key", 3L);
145 assertThat(removed, is(false));
146 assertThat(cacheNode1.get("key"), equalTo(3L));
147 assertThat(cacheNode2.get("key"), equalTo(4L));
148
149 removed = cacheNode2.remove("key", 4L);
150 assertThat(removed, is(true));
151 assertEventuallyThat(() -> cacheNode1.get("key"), equalTo(5L));
152 assertThat(cacheNode2.get("key"), equalTo(6L));
153 }
154
155 @Test
156 public void testRemoveAllInvalidatesCache()
157 {
158
159 assertThat(cacheNode1.get("key"), equalTo(1L));
160 assertThat(cacheNode2.get("key"), equalTo(2L));
161
162 cacheNode2.removeAll();
163 assertEventuallyThat(() -> cacheNode1.get("key"), equalTo(3L));
164 assertThat(cacheNode2.get("key"), equalTo(4L));
165 }
166
167 @Test
168 public void testRemoveConcurrentWithLoadClustered()
169 {
170 final CacheFactory factory2 = HazelcastTestSupport.createDistributedFactory(cluster.getNode(1));
171 removeConcurrentWithLoader(factory, factory2, REMOVE_0);
172 }
173
174 @Test
175 public void testRemoveAllConcurrentWithLoadClustered()
176 {
177 final CacheFactory factory2 = HazelcastTestSupport.createDistributedFactory(cluster.getNode(1));
178 removeConcurrentWithLoader(factory, factory2, REMOVE_ALL);
179 }
180
181 private static class BadLoader implements CacheLoader<String, Long>
182 {
183 private long value;
184
185 @Nonnull
186 @Override
187 public Long load(@Nonnull String key)
188 {
189 return ++value;
190 }
191 }
192 }