1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| package org.jboss.cache.notifications; |
10 |
| |
11 |
| import junit.framework.TestCase; |
12 |
| import org.jboss.cache.Cache; |
13 |
| import org.jboss.cache.DefaultCacheFactory; |
14 |
| import org.jboss.cache.Fqn; |
15 |
| import org.jboss.cache.Node; |
16 |
| import org.jboss.cache.config.Configuration; |
17 |
| import org.jboss.cache.lock.IsolationLevel; |
18 |
| import org.jboss.cache.notifications.event.Event; |
19 |
| import static org.jboss.cache.notifications.event.Event.Type.*; |
20 |
| import org.jboss.cache.notifications.event.EventImpl; |
21 |
| import static org.jboss.cache.notifications.event.NodeModifiedEvent.ModificationType.*; |
22 |
| |
23 |
| import javax.transaction.Transaction; |
24 |
| import javax.transaction.TransactionManager; |
25 |
| import java.util.ArrayList; |
26 |
| import java.util.Collections; |
27 |
| import java.util.HashMap; |
28 |
| import java.util.List; |
29 |
| import java.util.Map; |
30 |
| |
31 |
| |
32 |
| |
33 |
| |
34 |
| |
35 |
| |
36 |
| |
37 |
| public class CacheListenerTest extends TestCase |
38 |
| { |
39 |
| |
40 |
| protected boolean optLocking = false; |
41 |
| |
42 |
24
| public CacheListenerTest(String s)
|
43 |
| { |
44 |
24
| super(s);
|
45 |
| } |
46 |
| |
47 |
| private Cache cache; |
48 |
| private TransactionManager tm; |
49 |
| private EventLog eventLog = new EventLog(); |
50 |
| private Fqn fqn = Fqn.fromString("/test"); |
51 |
| |
52 |
24
| protected void setUp() throws Exception
|
53 |
| { |
54 |
24
| super.setUp();
|
55 |
24
| Configuration c = new Configuration();
|
56 |
24
| c.setCacheMode(Configuration.CacheMode.LOCAL);
|
57 |
24
| c.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
|
58 |
12
| if (optLocking) c.setNodeLockingScheme(Configuration.NodeLockingScheme.OPTIMISTIC);
|
59 |
24
| c.setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
|
60 |
24
| cache = DefaultCacheFactory.getInstance().createCache(c);
|
61 |
24
| tm = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
|
62 |
24
| eventLog.events.clear();
|
63 |
24
| cache.addCacheListener(eventLog);
|
64 |
| } |
65 |
| |
66 |
24
| protected void tearDown() throws Exception
|
67 |
| { |
68 |
24
| super.tearDown();
|
69 |
24
| Transaction t = tm.getTransaction();
|
70 |
0
| if (t != null) t.rollback();
|
71 |
24
| cache.stop();
|
72 |
24
| cache.destroy();
|
73 |
| } |
74 |
| |
75 |
| |
76 |
| |
77 |
2
| public void testCreation() throws Exception
|
78 |
| { |
79 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
80 |
2
| cache.put(fqn, "key", "value");
|
81 |
2
| Map data = new HashMap();
|
82 |
2
| data.put("key", "value");
|
83 |
| |
84 |
| |
85 |
2
| List<Event> expected = new ArrayList<Event>();
|
86 |
2
| if (optLocking)
|
87 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, false, null, TRANSACTION_REGISTERED));
|
88 |
2
| expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_CREATED));
|
89 |
2
| expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_CREATED));
|
90 |
2
| expected.add(new EventImpl(true, cache, PUT_DATA, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_MODIFIED));
|
91 |
2
| expected.add(new EventImpl(false, cache, PUT_DATA, data, fqn, null, true, null, false, null, NODE_MODIFIED));
|
92 |
2
| if (optLocking)
|
93 |
| { |
94 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, true, null, TRANSACTION_COMPLETED));
|
95 |
1
| eventLog.scrubImplicitTransactions();
|
96 |
| } |
97 |
2
| assertEquals(expected, eventLog.events);
|
98 |
2
| assertEquals("value", cache.get(fqn, "key"));
|
99 |
| } |
100 |
| |
101 |
2
| public void testOnlyModification() throws Exception
|
102 |
| { |
103 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
104 |
2
| cache.put(fqn, "key", "value");
|
105 |
2
| Map oldData = new HashMap();
|
106 |
2
| oldData.put("key", "value");
|
107 |
| |
108 |
| |
109 |
2
| eventLog.events.clear();
|
110 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
111 |
| |
112 |
| |
113 |
2
| cache.put(fqn, "key", "value2");
|
114 |
2
| Map newData = new HashMap();
|
115 |
2
| newData.put("key", "value2");
|
116 |
| |
117 |
| |
118 |
2
| List<Event> expected = new ArrayList<Event>();
|
119 |
2
| if (optLocking)
|
120 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, false, null, TRANSACTION_REGISTERED));
|
121 |
2
| expected.add(new EventImpl(true, cache, PUT_DATA, oldData, fqn, null, true, null, false, null, NODE_MODIFIED));
|
122 |
2
| expected.add(new EventImpl(false, cache, PUT_DATA, newData, fqn, null, true, null, false, null, NODE_MODIFIED));
|
123 |
2
| if (optLocking)
|
124 |
| { |
125 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, true, null, TRANSACTION_COMPLETED));
|
126 |
1
| eventLog.scrubImplicitTransactions();
|
127 |
| } |
128 |
| |
129 |
2
| assertEquals(expected.size(), eventLog.events.size());
|
130 |
2
| assertEquals(expected, eventLog.events);
|
131 |
| } |
132 |
| |
133 |
| |
134 |
2
| public void testOnlyRemoval() throws Exception
|
135 |
| { |
136 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
137 |
2
| cache.put(fqn, "key", "value");
|
138 |
2
| Map oldData = new HashMap();
|
139 |
2
| oldData.put("key", "value");
|
140 |
| |
141 |
2
| assertEquals("value", cache.get(fqn, "key"));
|
142 |
| |
143 |
| |
144 |
2
| eventLog.events.clear();
|
145 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
146 |
| |
147 |
| |
148 |
2
| cache.removeNode(fqn);
|
149 |
| |
150 |
| |
151 |
2
| List<Event> expected = new ArrayList<Event>();
|
152 |
2
| if (optLocking)
|
153 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, false, null, TRANSACTION_REGISTERED));
|
154 |
2
| expected.add(new EventImpl(true, cache, null, oldData, fqn, null, true, null, false, null, NODE_REMOVED));
|
155 |
2
| expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_REMOVED));
|
156 |
2
| if (optLocking)
|
157 |
| { |
158 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, true, null, TRANSACTION_COMPLETED));
|
159 |
1
| eventLog.scrubImplicitTransactions();
|
160 |
| } |
161 |
| |
162 |
2
| assertEquals(expected, eventLog.events);
|
163 |
| |
164 |
| |
165 |
2
| assertNull("Should be null", cache.getRoot().getChild(fqn));
|
166 |
| } |
167 |
| |
168 |
| |
169 |
2
| public void testRemoveData() throws Exception
|
170 |
| { |
171 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
172 |
2
| cache.put(fqn, "key", "value");
|
173 |
2
| cache.put(fqn, "key2", "value2");
|
174 |
2
| Map oldData = new HashMap();
|
175 |
2
| oldData.put("key", "value");
|
176 |
2
| oldData.put("key2", "value2");
|
177 |
| |
178 |
| |
179 |
2
| eventLog.events.clear();
|
180 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
181 |
| |
182 |
| |
183 |
2
| cache.remove(fqn, "key2");
|
184 |
2
| Map removedData = new HashMap();
|
185 |
2
| removedData.put("key2", "value2");
|
186 |
| |
187 |
| |
188 |
2
| List<Event> expected = new ArrayList<Event>();
|
189 |
| |
190 |
2
| if (optLocking)
|
191 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, false, null, TRANSACTION_REGISTERED));
|
192 |
2
| expected.add(new EventImpl(true, cache, REMOVE_DATA, oldData, fqn, null, true, null, false, null, NODE_MODIFIED));
|
193 |
2
| expected.add(new EventImpl(false, cache, REMOVE_DATA, removedData, fqn, null, true, null, false, null, NODE_MODIFIED));
|
194 |
2
| if (optLocking)
|
195 |
| { |
196 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, true, null, TRANSACTION_COMPLETED));
|
197 |
1
| eventLog.scrubImplicitTransactions();
|
198 |
| } |
199 |
| |
200 |
2
| assertEquals(expected, eventLog.events);
|
201 |
| } |
202 |
| |
203 |
2
| public void testPutMap() throws Exception
|
204 |
| { |
205 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
206 |
2
| Map oldData = new HashMap();
|
207 |
2
| oldData.put("key", "value");
|
208 |
2
| oldData.put("key2", "value2");
|
209 |
| |
210 |
| |
211 |
2
| eventLog.events.clear();
|
212 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
213 |
| |
214 |
| |
215 |
2
| cache.put(fqn, oldData);
|
216 |
| |
217 |
| |
218 |
2
| List<Event> expected = new ArrayList<Event>();
|
219 |
2
| if (optLocking)
|
220 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, false, null, TRANSACTION_REGISTERED));
|
221 |
2
| expected.add(new EventImpl(true, cache, null, null, fqn, null, true, null, false, null, NODE_CREATED));
|
222 |
2
| expected.add(new EventImpl(false, cache, null, null, fqn, null, true, null, false, null, NODE_CREATED));
|
223 |
2
| expected.add(new EventImpl(true, cache, PUT_MAP, Collections.emptyMap(), fqn, null, true, null, false, null, NODE_MODIFIED));
|
224 |
2
| expected.add(new EventImpl(false, cache, PUT_MAP, oldData, fqn, null, true, null, false, null, NODE_MODIFIED));
|
225 |
2
| if (optLocking)
|
226 |
| { |
227 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, true, null, TRANSACTION_COMPLETED));
|
228 |
1
| eventLog.scrubImplicitTransactions();
|
229 |
| } |
230 |
| |
231 |
2
| assertEquals(expected, eventLog.events);
|
232 |
| } |
233 |
| |
234 |
2
| public void testMove()
|
235 |
| { |
236 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
237 |
2
| Fqn newParent = Fqn.fromString("/a");
|
238 |
2
| cache.put(fqn, "key", "value");
|
239 |
2
| cache.put(newParent, "key", "value");
|
240 |
| |
241 |
2
| Node n1 = cache.getRoot().getChild(fqn);
|
242 |
2
| Node n2 = cache.getRoot().getChild(newParent);
|
243 |
2
| eventLog.events.clear();
|
244 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
245 |
| |
246 |
2
| cache.move(n1.getFqn(), n2.getFqn());
|
247 |
| |
248 |
2
| Fqn newFqn = new Fqn(newParent, fqn.getLastElement());
|
249 |
2
| List<Event> expected = new ArrayList<Event>();
|
250 |
| |
251 |
2
| if (optLocking)
|
252 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, false, null, TRANSACTION_REGISTERED));
|
253 |
2
| expected.add(new EventImpl(true, cache, null, null, fqn, null, true, newFqn, false, null, NODE_MOVED));
|
254 |
2
| expected.add(new EventImpl(false, cache, null, null, fqn, null, true, newFqn, false, null, NODE_MOVED));
|
255 |
2
| if (optLocking)
|
256 |
| { |
257 |
1
| expected.add(new EventImpl(false, cache, null, null, null, null, true, null, true, null, TRANSACTION_COMPLETED));
|
258 |
1
| eventLog.scrubImplicitTransactions();
|
259 |
| } |
260 |
| |
261 |
2
| assertEquals(expected, eventLog.events);
|
262 |
| } |
263 |
| |
264 |
| |
265 |
| |
266 |
2
| public void testTxCreationCommit() throws Exception
|
267 |
| { |
268 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
269 |
2
| tm.begin();
|
270 |
2
| Transaction tx = tm.getTransaction();
|
271 |
2
| cache.put(fqn, "key", "value");
|
272 |
| |
273 |
2
| Map data = new HashMap();
|
274 |
2
| data.put("key", "value");
|
275 |
2
| List<Event> expected = new ArrayList<Event>();
|
276 |
| |
277 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
|
278 |
2
| expected.add(new EventImpl(true, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
|
279 |
2
| expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
|
280 |
2
| expected.add(new EventImpl(true, cache, PUT_DATA, Collections.emptyMap(), fqn, tx, true, null, false, null, NODE_MODIFIED));
|
281 |
2
| expected.add(new EventImpl(false, cache, PUT_DATA, data, fqn, tx, true, null, false, null, NODE_MODIFIED));
|
282 |
2
| assertEquals(expected, eventLog.events);
|
283 |
2
| tm.commit();
|
284 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
|
285 |
2
| assertEquals(expected, eventLog.events);
|
286 |
2
| assertEquals("value", cache.get(fqn, "key"));
|
287 |
| } |
288 |
| |
289 |
2
| public void testTxCreationRollback() throws Exception
|
290 |
| { |
291 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
292 |
2
| tm.begin();
|
293 |
2
| Transaction tx = tm.getTransaction();
|
294 |
2
| cache.put(fqn, "key", "value");
|
295 |
| |
296 |
2
| Map data = new HashMap();
|
297 |
2
| data.put("key", "value");
|
298 |
2
| List<Event> expected = new ArrayList<Event>();
|
299 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
|
300 |
2
| expected.add(new EventImpl(true, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
|
301 |
2
| expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, null, false, null, NODE_CREATED));
|
302 |
2
| expected.add(new EventImpl(true, cache, PUT_DATA, Collections.emptyMap(), fqn, tx, true, null, false, null, NODE_MODIFIED));
|
303 |
2
| expected.add(new EventImpl(false, cache, PUT_DATA, data, fqn, tx, true, null, false, null, NODE_MODIFIED));
|
304 |
| |
305 |
| |
306 |
2
| assertEquals(expected, eventLog.events);
|
307 |
2
| tm.rollback();
|
308 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_COMPLETED));
|
309 |
2
| assertEquals(expected, eventLog.events);
|
310 |
| } |
311 |
| |
312 |
| |
313 |
2
| public void testTxOnlyModification() throws Exception
|
314 |
| { |
315 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
316 |
2
| cache.put(fqn, "key", "value");
|
317 |
2
| Map oldData = new HashMap();
|
318 |
2
| oldData.put("key", "value");
|
319 |
| |
320 |
| |
321 |
2
| eventLog.events.clear();
|
322 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
323 |
| |
324 |
| |
325 |
2
| tm.begin();
|
326 |
2
| Transaction tx = tm.getTransaction();
|
327 |
2
| cache.put(fqn, "key", "value2");
|
328 |
2
| Map newData = new HashMap();
|
329 |
2
| newData.put("key", "value2");
|
330 |
| |
331 |
| |
332 |
2
| List<Event> expected = new ArrayList<Event>();
|
333 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
|
334 |
2
| expected.add(new EventImpl(true, cache, PUT_DATA, oldData, fqn, tx, true, null, false, null, NODE_MODIFIED));
|
335 |
2
| expected.add(new EventImpl(false, cache, PUT_DATA, newData, fqn, tx, true, null, false, null, NODE_MODIFIED));
|
336 |
| |
337 |
2
| assertEquals(expected, eventLog.events);
|
338 |
2
| tm.commit();
|
339 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
|
340 |
2
| assertEquals(expected, eventLog.events);
|
341 |
| } |
342 |
| |
343 |
| |
344 |
2
| public void testTxOnlyRemoval() throws Exception
|
345 |
| { |
346 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
347 |
2
| cache.put(fqn, "key", "value");
|
348 |
2
| Map oldData = new HashMap();
|
349 |
2
| oldData.put("key", "value");
|
350 |
| |
351 |
2
| assertEquals("value", cache.get(fqn, "key"));
|
352 |
| |
353 |
| |
354 |
2
| eventLog.events.clear();
|
355 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
356 |
| |
357 |
| |
358 |
2
| tm.begin();
|
359 |
2
| Transaction tx = tm.getTransaction();
|
360 |
2
| cache.removeNode(fqn);
|
361 |
| |
362 |
2
| List<Event> expected = new ArrayList<Event>();
|
363 |
| |
364 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
|
365 |
2
| expected.add(new EventImpl(true, cache, null, oldData, fqn, tx, true, null, false, null, NODE_REMOVED));
|
366 |
2
| expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, null, false, null, NODE_REMOVED));
|
367 |
| |
368 |
2
| assertEquals(expected, eventLog.events);
|
369 |
2
| tm.commit();
|
370 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
|
371 |
2
| assertEquals(expected, eventLog.events);
|
372 |
| |
373 |
2
| assertNull("Should be null", cache.getRoot().getChild(fqn));
|
374 |
| } |
375 |
| |
376 |
| |
377 |
2
| public void testTxRemoveData() throws Exception
|
378 |
| { |
379 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
380 |
2
| cache.put(fqn, "key", "value");
|
381 |
2
| cache.put(fqn, "key2", "value2");
|
382 |
2
| Map oldData = new HashMap();
|
383 |
2
| oldData.put("key", "value");
|
384 |
2
| oldData.put("key2", "value2");
|
385 |
| |
386 |
| |
387 |
2
| eventLog.events.clear();
|
388 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
389 |
| |
390 |
| |
391 |
2
| tm.begin();
|
392 |
2
| Transaction tx = tm.getTransaction();
|
393 |
2
| cache.remove(fqn, "key2");
|
394 |
2
| Map removedData = new HashMap();
|
395 |
2
| removedData.put("key2", "value2");
|
396 |
| |
397 |
| |
398 |
2
| List<Event> expected = new ArrayList<Event>();
|
399 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
|
400 |
2
| expected.add(new EventImpl(true, cache, REMOVE_DATA, oldData, fqn, tx, true, null, false, null, NODE_MODIFIED));
|
401 |
2
| expected.add(new EventImpl(false, cache, REMOVE_DATA, removedData, fqn, tx, true, null, false, null, NODE_MODIFIED));
|
402 |
| |
403 |
2
| tm.commit();
|
404 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
|
405 |
2
| assertEquals(expected, eventLog.events);
|
406 |
| |
407 |
2
| assertEquals(expected, eventLog.events);
|
408 |
| } |
409 |
| |
410 |
2
| public void testTxMove() throws Exception
|
411 |
| { |
412 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
413 |
2
| Fqn newParent = Fqn.fromString("/a");
|
414 |
2
| cache.put(fqn, "key", "value");
|
415 |
2
| cache.put(newParent, "key", "value");
|
416 |
| |
417 |
2
| Node n1 = cache.getRoot().getChild(fqn);
|
418 |
2
| Node n2 = cache.getRoot().getChild(newParent);
|
419 |
2
| eventLog.events.clear();
|
420 |
2
| assertEquals("Event log should be empty", Collections.emptyList(), eventLog.events);
|
421 |
| |
422 |
2
| tm.begin();
|
423 |
2
| Transaction tx = tm.getTransaction();
|
424 |
2
| cache.move(n1.getFqn(), n2.getFqn());
|
425 |
| |
426 |
2
| Fqn newFqn = new Fqn(newParent, fqn.getLastElement());
|
427 |
2
| List<Event> expected = new ArrayList<Event>();
|
428 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, false, null, TRANSACTION_REGISTERED));
|
429 |
2
| expected.add(new EventImpl(true, cache, null, null, fqn, tx, true, newFqn, false, null, NODE_MOVED));
|
430 |
2
| expected.add(new EventImpl(false, cache, null, null, fqn, tx, true, newFqn, false, null, NODE_MOVED));
|
431 |
| |
432 |
2
| assertEquals(expected, eventLog.events);
|
433 |
2
| tm.commit();
|
434 |
2
| expected.add(new EventImpl(false, cache, null, null, null, tx, true, null, true, null, TRANSACTION_COMPLETED));
|
435 |
2
| assertEquals(expected, eventLog.events);
|
436 |
| } |
437 |
| } |