1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.fulcrum.cache;
21
22
23
24 import java.util.ConcurrentModificationException;
25 import java.util.Date;
26 import java.util.Iterator;
27 import java.util.List;
28
29 import org.apache.avalon.framework.component.ComponentException;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.fulcrum.cache.impl.DefaultGlobalCacheService;
33 import org.apache.fulcrum.testcontainer.BaseUnitTest;
34
35
36
37
38
39
40
41
42
43 public class CacheTest extends BaseUnitTest
44 {
45
46 protected GlobalCacheService globalCache = null;
47
48 protected static final String cacheKey = "CacheKey";
49
50 protected static final String cacheKey_2 = "CacheKey_2";
51
52 public static final String SKIP_TESTS_KEY = "fulcrum.cache.skip.long.tests";
53
54 protected static final Log LOG = LogFactory.getLog(CacheTest.class);
55
56
57
58
59
60
61
62 public CacheTest(String name)
63 {
64 super(name);
65 }
66
67
68
69
70
71
72 protected String getCacheRoleName()
73 {
74 return GlobalCacheService.ROLE;
75 }
76
77 protected void setUp() throws Exception
78 {
79 super.setUp();
80
81 try
82 {
83 this.globalCache = (GlobalCacheService) this
84 .lookup(getCacheRoleName());
85 }
86 catch (ComponentException e)
87 {
88 e.printStackTrace();
89 fail(e.getMessage());
90 }
91 }
92
93
94
95
96
97
98 public void testSimpleAddGetCacheObject() throws Exception
99 {
100 String testString = "This is a test";
101 Object retrievedObject = null;
102 CachedObject cacheObject1 = null;
103
104 cacheObject1 = new CachedObject(testString);
105 assertNotNull("Failed to create a cachable object 1", cacheObject1);
106
107 this.globalCache.addObject(cacheKey, cacheObject1);
108
109 retrievedObject = this.globalCache.getObject(cacheKey);
110 assertNotNull("Did not retrieve a cached object 1", retrievedObject);
111 assertSame("Did not retrieve a correct, expected cached object 1",
112 retrievedObject, cacheObject1);
113
114 this.globalCache.removeObject(cacheKey);
115
116 retrievedObject = null;
117 cacheObject1 = null;
118 try
119 {
120 retrievedObject = this.globalCache.getObject(cacheKey);
121 assertNull(
122 "Retrieved the deleted cached object 1 and did not get expected ObjectExpiredException",
123 retrievedObject);
124 assertNotNull(
125 "Did not get expected ObjectExpiredException retrieving a deleted object",
126 retrievedObject);
127 }
128 catch (ObjectExpiredException e)
129 {
130 assertNull(
131 "Retrieved the deleted cached object 1, but caught expected ObjectExpiredException exception",
132 retrievedObject);
133 }
134
135 this.globalCache.removeObject(cacheKey);
136 }
137
138
139
140
141
142
143 public void test2ObjectAddGetCachedObject() throws Exception
144 {
145 String testString = "This is a test";
146 Object retrievedObject = null;
147 CachedObject cacheObject1 = null;
148 CachedObject cacheObject2 = null;
149
150 cacheObject1 = new CachedObject(testString);
151 assertNotNull("Failed to create a cachable object 1", cacheObject1);
152 this.globalCache.addObject(cacheKey, cacheObject1);
153 retrievedObject = this.globalCache.getObject(cacheKey);
154 assertNotNull("Did not retrieve a cached object 1", retrievedObject);
155 assertEquals("Did not retrieve correct cached object", cacheObject1,
156 retrievedObject);
157
158 cacheObject2 = new CachedObject(testString);
159 assertNotNull("Failed to create a cachable object 2", cacheObject2);
160 this.globalCache.addObject(cacheKey_2, cacheObject2);
161 retrievedObject = this.globalCache.getObject(cacheKey_2);
162 assertNotNull("Did not retrieve a cached object 2", retrievedObject);
163 assertEquals("Did not retrieve correct cached object 2", cacheObject2,
164 retrievedObject);
165
166 retrievedObject = this.globalCache.getObject(cacheKey);
167 assertNotNull("Did not retrieve a cached object 1. Attempt #2",
168 retrievedObject);
169 assertEquals("Did not retrieve correct cached object 1. Attempt #2",
170 cacheObject1, retrievedObject);
171
172 retrievedObject = this.globalCache.getObject(cacheKey);
173 assertNotNull("Did not retrieve a cached object 1. Attempt #3",
174 retrievedObject);
175 assertEquals("Did not retrieve correct cached object 1. Attempt #3",
176 cacheObject1, retrievedObject);
177
178 retrievedObject = this.globalCache.getObject(cacheKey_2);
179 assertNotNull("Did not retrieve a cached object 2. Attempt #2",
180 retrievedObject);
181 assertEquals("Did not retrieve correct cached object 2 Attempt #2",
182 cacheObject2, retrievedObject);
183
184 this.globalCache.removeObject(cacheKey);
185 this.globalCache.removeObject(cacheKey_2);
186 }
187
188
189
190
191
192
193
194 public void testObjectExpiration() throws Exception
195 {
196 String testString = "This is a test";
197 Object retrievedObject = null;
198 CachedObject cacheObject = null;
199
200 cacheObject = new CachedObject(testString, 1000);
201 assertNotNull("Failed to create a cachable object", cacheObject);
202 long addTime = System.currentTimeMillis();
203 this.globalCache.addObject(cacheKey, cacheObject);
204
205 try
206 {
207 retrievedObject = this.globalCache.getObject(cacheKey);
208 assertNotNull("Did not retrieve a cached object", retrievedObject);
209 assertEquals("Did not retrieve correct cached object",
210 cacheObject, retrievedObject);
211 }
212 catch (ObjectExpiredException e)
213 {
214 assertTrue("Object expired early ( "
215 + (System.currentTimeMillis() - addTime) + " millis)",
216 false);
217 }
218
219 Thread.sleep(1500);
220
221 try
222 {
223 retrievedObject = null;
224 retrievedObject = this.globalCache.getObject(cacheKey);
225 assertNull(
226 "Retrieved the expired cached object and did not get expected ObjectExpiredException",
227 retrievedObject);
228 assertNotNull(
229 "Did not get expected ObjectExpiredException retrieving an expired object",
230 retrievedObject);
231 }
232 catch (ObjectExpiredException e)
233 {
234 assertNull(
235 "Retrieved the expired cached object, but caught expected ObjectExpiredException exception",
236 retrievedObject);
237 }
238
239 this.globalCache.removeObject(cacheKey);
240 }
241
242
243
244
245
246
247
248
249 public void testCacheFlush() throws Exception
250 {
251 String testString = "This is a test";
252 CachedObject cacheObject = null;
253
254 cacheObject = new CachedObject(testString, (getCacheRefresh() * 5) + 1);
255 assertNotNull("Failed to create a cachable object", cacheObject);
256 this.globalCache.addObject(cacheKey, cacheObject);
257
258 Thread.sleep(getCacheRefresh() + 1);
259 assertTrue("No object in cache before flush", (0 < this.globalCache
260 .getNumberOfObjects()));
261
262 this.globalCache.flushCache();
263
264 Thread.sleep((getCacheRefresh() * 2) + 1);
265 assertEquals("After refresh", 0, this.globalCache.getNumberOfObjects());
266
267 this.globalCache.removeObject(cacheKey);
268 }
269
270
271
272
273
274
275 public void testObjectCount() throws Exception
276 {
277 assertNotNull("Could not retrieve cache service.", this.globalCache);
278
279 long cacheRefresh = getCacheRefresh();
280
281
282 long expireTime = cacheRefresh + cacheRefresh / 2;
283
284 CachedObject cacheObject = new CachedObject("This is a test",
285 expireTime);
286 assertNotNull("Failed to create a cachable object", cacheObject);
287
288 this.globalCache.addObject(cacheKey, cacheObject);
289 assertEquals("After adding 1 Object", 1, this.globalCache
290 .getNumberOfObjects());
291
292
293 Thread.sleep(cacheRefresh + cacheRefresh / 3);
294 assertEquals("After one refresh", 1, this.globalCache
295 .getNumberOfObjects());
296
297
298 Thread.sleep((cacheRefresh * 2) + cacheRefresh / 3);
299 assertEquals("After three refreshes", 0, this.globalCache
300 .getNumberOfObjects());
301 }
302
303
304
305
306
307
308
309
310
311
312 public void testRefreshableObject() throws Exception
313 {
314 Object retrievedObject = null;
315 RefreshableCachedObject cacheObject = null;
316
317 cacheObject = new RefreshableCachedObject(new RefreshableObject(),
318 getTestExpireTime());
319 assertNotNull("Failed to create a cachable object", cacheObject);
320 long addTime = System.currentTimeMillis();
321 this.globalCache.addObject(cacheKey, cacheObject);
322
323 try
324 {
325 retrievedObject = this.globalCache.getObject(cacheKey);
326 assertNotNull("Did not retrieve a cached object", retrievedObject);
327 assertEquals("Did not retrieve correct cached object",
328 cacheObject, retrievedObject);
329 }
330 catch (ObjectExpiredException e)
331 {
332 assertTrue("Object expired early ( "
333 + (System.currentTimeMillis() - addTime) + " millis)",
334 false);
335 }
336
337 Thread.sleep(getTestExpireTime() + 1000);
338
339 try
340 {
341 retrievedObject = null;
342 retrievedObject = this.globalCache.getObject(cacheKey);
343 assertNotNull("Did not retrieve a cached object, after sleep",
344 retrievedObject);
345 assertNotNull("Cached object has no contents, after sleep.",
346 ((RefreshableCachedObject) retrievedObject).getContents());
347 assertTrue(
348 "Object did not refresh.",
349 (((RefreshableObject) ((RefreshableCachedObject) retrievedObject)
350 .getContents()).getRefreshCount() > 0));
351 }
352 catch (ObjectExpiredException e)
353 {
354 assertTrue("Received unexpected ObjectExpiredException exception "
355 + "when retrieving refreshable object after ( "
356 + (System.currentTimeMillis() - addTime) + " millis)",
357 false);
358 }
359
360
361 for (int i = 0; i < 100; i++)
362 {
363 Thread.sleep(1000);
364
365 try
366 {
367 retrievedObject = null;
368 retrievedObject = this.globalCache.getObject(cacheKey);
369 assertNotNull("Did not retrieve a cached object, after sleep",
370 retrievedObject);
371 assertNotNull("Cached object has no contents, after sleep.",
372 ((RefreshableCachedObject) retrievedObject)
373 .getContents());
374 assertTrue(
375 "Object did not refresh.",
376 (((RefreshableObject) ((RefreshableCachedObject) retrievedObject)
377 .getContents()).getRefreshCount() > 0));
378 }
379 catch (ObjectExpiredException e)
380 {
381 assertTrue(
382 "Received unexpected ObjectExpiredException exception "
383 + "when retrieving refreshable object after ( "
384 + (System.currentTimeMillis() - addTime)
385 + " millis)", false);
386 }
387 }
388
389 this.globalCache.removeObject(cacheKey);
390 }
391
392
393
394
395
396
397
398
399
400 public void testRefreshableTimeToLive() throws Exception
401 {
402 String skipTestsProperty = System.getProperty(SKIP_TESTS_KEY, "false");
403 LOG.info("What is the value of the skipTestsProperty:"
404 + skipTestsProperty);
405 if (Boolean.valueOf(skipTestsProperty).booleanValue())
406 {
407 LOG.warn("Skipping testRefreshableTimeToLive test due to property "
408 + SKIP_TESTS_KEY + " being true.");
409 return;
410 }
411 else
412 {
413 LOG.warn("Running testRefreshableTimeToLive test due to property "
414 + SKIP_TESTS_KEY + " being false.");
415 }
416
417 Object retrievedObject = null;
418 RefreshableCachedObject cacheObject = null;
419
420 cacheObject = new RefreshableCachedObject(new RefreshableObject(),
421 getTestExpireTime());
422 assertNotNull("Failed to create a cachable object", cacheObject);
423 cacheObject.setTTL(getTestExpireTime());
424
425 assertEquals("Returned TimeToLive", getTestExpireTime(), cacheObject
426 .getTTL());
427
428 this.globalCache.addObject(cacheKey, cacheObject);
429 long addTime = System.currentTimeMillis();
430
431 try
432 {
433 retrievedObject = this.globalCache.getObject(cacheKey);
434 assertNotNull("Did not retrieve a cached object", retrievedObject);
435 assertEquals("Did not retrieve correct cached object",
436 cacheObject, retrievedObject);
437 }
438 catch (ObjectExpiredException e)
439 {
440 fail("Object expired early ( "
441 + (System.currentTimeMillis() - addTime) + " millis)");
442 }
443
444 long timeout = getTestExpireTime() - 0000;
445 Thread.sleep(timeout);
446
447 try
448 {
449 retrievedObject = null;
450 retrievedObject = this.globalCache.getObject(cacheKey);
451 assertNotNull("Did not retrieve a cached object, after sleep",
452 retrievedObject);
453 assertNotNull("Cached object has no contents, after sleep.",
454 ((RefreshableCachedObject) retrievedObject).getContents());
455
456
457
458
459
460
461
462 }
463 catch (ObjectExpiredException e)
464 {
465 assertTrue("Received unexpected ObjectExpiredException exception "
466 + "when retrieving refreshable object after ( "
467 + (System.currentTimeMillis() - addTime) + " millis)",
468 false);
469 }
470
471 Thread.sleep(getTestExpireTime() + 5000);
472
473 try
474 {
475 retrievedObject = null;
476 retrievedObject = this.globalCache.getObject(cacheKey);
477 assertNull("Retrieved a cached object, after exceeding TimeToLive",
478 retrievedObject);
479 }
480 catch (ObjectExpiredException e)
481 {
482 assertNull(
483 "Retrieved the expired cached object, but caught expected ObjectExpiredException exception",
484 retrievedObject);
485 }
486 }
487
488
489
490
491
492
493 public void testCacheGetKeyList()
494 {
495 this.globalCache.flushCache();
496 this.globalCache.addObject("date1", new CachedObject(new Date()));
497 this.globalCache.addObject("date2", new CachedObject(new Date()));
498 this.globalCache.addObject("date3", new CachedObject(new Date()));
499 assertTrue("Did not get key list back.",
500 (this.globalCache.getKeys() != null));
501 List keys = this.globalCache.getKeys();
502 for (Iterator itr = keys.iterator(); itr.hasNext();)
503 {
504 Object key = itr.next();
505 assertTrue("Key was not an instance of String.",
506 (key instanceof String));
507 }
508
509 }
510
511
512
513
514
515
516 public void testCacheGetCachedObjects()
517 {
518 this.globalCache.flushCache();
519 this.globalCache.addObject("date1", new CachedObject(new Date()));
520 this.globalCache.addObject("date2", new CachedObject(new Date()));
521 this.globalCache.addObject("date3", new CachedObject(new Date()));
522 assertTrue("Did not get object list back.", (this.globalCache
523 .getCachedObjects() != null));
524 List objects = this.globalCache.getCachedObjects();
525 for (Iterator itr = objects.iterator(); itr.hasNext();)
526 {
527 Object obj = itr.next();
528 assertNotNull("Object was null.", obj);
529 assertTrue("Object was not an instance of CachedObject",
530 (obj instanceof CachedObject));
531 }
532
533 }
534
535
536
537
538
539
540
541
542 public void testCacheModification()
543 {
544 this.globalCache.flushCache();
545 this.globalCache.addObject("date1", new CachedObject(new Date()));
546 this.globalCache.addObject("date2", new CachedObject(new Date()));
547 this.globalCache.addObject("date3", new CachedObject(new Date()));
548 assertTrue("Did not get key list back.",
549 (this.globalCache.getKeys() != null));
550 List keys = this.globalCache.getKeys();
551 try
552 {
553 for (Iterator itr = keys.iterator(); itr.hasNext();)
554 {
555 Object key = itr.next();
556 this.globalCache.addObject("date4",
557 new CachedObject(new Date()));
558 }
559 }
560 catch (ConcurrentModificationException cme)
561 {
562 fail("Caught ConcurrentModificationException adding to cache.");
563 }
564 List objects = this.globalCache.getCachedObjects();
565 try
566 {
567 for (Iterator itr = objects.iterator(); itr.hasNext();)
568 {
569 Object obj = itr.next();
570 this.globalCache.addObject("date4",
571 new CachedObject(new Date()));
572 }
573 }
574 catch (ConcurrentModificationException cme)
575 {
576 fail("Caught ConcurrentModificationException adding to cache.");
577 }
578 }
579
580
581
582
583
584
585
586 private long getCacheRefresh()
587 {
588 try
589 {
590 DefaultGlobalCacheService cache =
591 (DefaultGlobalCacheService)this.lookup(GlobalCacheService.ROLE);
592 return cache.getCacheCheckFrequency() * 1000L;
593 }
594 catch (ComponentException e)
595 {
596 return 5000;
597 }
598 }
599
600
601
602
603
604
605 private long getTestExpireTime()
606 {
607 return getCacheRefresh() + 1000;
608 }
609
610
611
612
613 class RefreshableObject implements Refreshable
614 {
615 private int refreshCount = 0;
616
617
618
619
620 public void refresh()
621 {
622 this.refreshCount++;
623 }
624
625
626
627
628
629
630 public int getRefreshCount()
631 {
632 return this.refreshCount;
633 }
634 }
635 }