001: package org.apache.turbine.services.cache;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import junit.awtui.TestRunner;
023: import junit.framework.Test;
024: import junit.framework.TestSuite;
025: import org.apache.cactus.ServletTestCase;
026:
027: // Turbine imports
028: import org.apache.turbine.services.TurbineServices;
029: import org.apache.turbine.services.cache.GlobalCacheService;
030: import org.apache.turbine.services.cache.CachedObject;
031: import org.apache.turbine.services.cache.ObjectExpiredException;
032: import org.apache.turbine.services.cache.Refreshable;
033: import org.apache.turbine.services.cache.RefreshableCachedObject;
034: import org.apache.turbine.Turbine;
035:
036: /**
037: * TurbineCacheTest
038: *
039: * @author <a href="paulsp@apache.org">Paul Spencer</a>
040: * @version $Id: TurbineCacheTest.java 534527 2007-05-02 16:10:59Z tv $
041: */
042: public class TurbineCacheTest extends ServletTestCase {
043:
044: private Turbine turbine = null;
045: private static final String cacheKey = new String("CacheKey");
046: private static final String cacheKey_2 = new String("CacheKey_2");
047: private static final long TURBINE_CACHE_REFRESH = 5000; // in millis
048: private static final long TEST_EXPIRETIME = TURBINE_CACHE_REFRESH + 1000;
049: private static final long TEST_TIMETOLIVE = TEST_EXPIRETIME * 5;
050:
051: /**
052: * Defines the testcase name for JUnit.
053: *
054: * @param name the testcase's name.
055: */
056: public TurbineCacheTest(String name) {
057: super (name);
058: }
059:
060: /**
061: * Start the tests.
062: *
063: * @param args the arguments. Not used
064: */
065: public static void main(String args[]) {
066: TestRunner
067: .main(new String[] { TurbineCacheTest.class.getName() });
068: }
069:
070: /**
071: * Creates the test suite.
072: *
073: * @return a test suite (<code>TestSuite</code>) that includes all methods
074: * starting with "test"
075: */
076: public static Test suite() {
077: // All methods starting with "test" will be executed in the test suite.
078: return new TestSuite(TurbineCacheTest.class);
079: }
080:
081: /**
082: * This setup will be running server side. We startup Turbine and
083: * get our test port from the properties. This gets run before
084: * each testXXX test.
085: */
086: protected void setUp() throws Exception {
087: super .setUp();
088: config.setInitParameter("properties",
089: "/WEB-INF/conf/TurbineComplete.properties");
090: turbine = new Turbine();
091: turbine.init(config);
092: }
093:
094: /**
095: * After each testXXX test runs, shut down the Turbine servlet.
096: */
097: protected void tearDown() throws Exception {
098: turbine.destroy();
099: super .tearDown();
100: }
101:
102: /**
103: * Simple test that verify an object can be created and deleted.
104: * @throws Exception
105: */
106: public void testSimpleAddGetCacheObject() throws Exception {
107: String testString = new String("This is a test");
108: Object retrievedObject = null;
109: CachedObject cacheObject1 = null;
110:
111: GlobalCacheService globalCache = (GlobalCacheService) TurbineServices
112: .getInstance().getService(
113: GlobalCacheService.SERVICE_NAME);
114:
115: // Create object
116: cacheObject1 = new CachedObject(testString);
117: assertNotNull("Failed to create a cachable object 1",
118: cacheObject1);
119:
120: // Add object to cache
121: globalCache.addObject(cacheKey, cacheObject1);
122:
123: // Get object from cache
124: retrievedObject = globalCache.getObject(cacheKey);
125: assertNotNull("Did not retrieved a cached object 1",
126: retrievedObject);
127: assertTrue(
128: "Did not retrieved a correct, expected cached object 1",
129: retrievedObject == cacheObject1);
130:
131: // Remove object from cache
132: globalCache.removeObject(cacheKey);
133:
134: // Verify object removed from cache
135: retrievedObject = null;
136: cacheObject1 = null;
137: try {
138: retrievedObject = globalCache.getObject(cacheKey);
139: assertNull(
140: "Retrieved the deleted cached object 1 and did not get expected ObjectExpiredException",
141: retrievedObject);
142: assertNotNull(
143: "Did not get expected ObjectExpiredException retrieving a deleted object",
144: retrievedObject);
145: } catch (ObjectExpiredException e) {
146: assertNull(
147: "Retrieved the deleted cached object 1, but caught expected ObjectExpiredException exception",
148: retrievedObject);
149: } catch (Exception e) {
150: throw e;
151: }
152:
153: // Remove object from cache that does NOT exist in the cache
154: globalCache.removeObject(cacheKey);
155: }
156:
157: /**
158: * Simple test that adds, retrieves, and deletes 2 object.
159: *
160: * @throws Exception
161: */
162: public void test2ObjectAddGetCachedObject() throws Exception {
163: String testString = new String("This is a test");
164: Object retrievedObject = null;
165: CachedObject cacheObject1 = null;
166: CachedObject cacheObject2 = null;
167:
168: GlobalCacheService globalCache = (GlobalCacheService) TurbineServices
169: .getInstance().getService(
170: GlobalCacheService.SERVICE_NAME);
171:
172: // Create and add Object #1
173: cacheObject1 = new CachedObject(testString);
174: assertNotNull("Failed to create a cachable object 1",
175: cacheObject1);
176: globalCache.addObject(cacheKey, cacheObject1);
177: retrievedObject = globalCache.getObject(cacheKey);
178: assertNotNull("Did not retrieved a cached object 1",
179: retrievedObject);
180: assertEquals("Did not retrieved correct cached object",
181: cacheObject1, retrievedObject);
182:
183: // Create and add Object #2
184: cacheObject2 = new CachedObject(testString);
185: assertNotNull("Failed to create a cachable object 2",
186: cacheObject2);
187: globalCache.addObject(cacheKey_2, cacheObject2);
188: retrievedObject = globalCache.getObject(cacheKey_2);
189: assertNotNull("Did not retrieved a cached object 2",
190: retrievedObject);
191: assertEquals("Did not retrieved correct cached object 2",
192: cacheObject2, retrievedObject);
193:
194: // Get object #1
195: retrievedObject = globalCache.getObject(cacheKey);
196: assertNotNull(
197: "Did not retrieved a cached object 1. Attempt #2",
198: retrievedObject);
199: assertEquals(
200: "Did not retrieved correct cached object 1. Attempt #2",
201: cacheObject1, retrievedObject);
202:
203: // Get object #1
204: retrievedObject = globalCache.getObject(cacheKey);
205: assertNotNull(
206: "Did not retrieved a cached object 1. Attempt #3",
207: retrievedObject);
208: assertEquals(
209: "Did not retrieved correct cached object 1. Attempt #3",
210: cacheObject1, retrievedObject);
211:
212: // Get object #2
213: retrievedObject = globalCache.getObject(cacheKey_2);
214: assertNotNull(
215: "Did not retrieved a cached object 2. Attempt #2",
216: retrievedObject);
217: assertEquals(
218: "Did not retrieved correct cached object 2 Attempt #2",
219: cacheObject2, retrievedObject);
220:
221: // Remove objects
222: globalCache.removeObject(cacheKey);
223: globalCache.removeObject(cacheKey_2);
224: }
225:
226: /**
227: * Verify that an object will throw the ObjectExpiredException
228: * when it now longer exists in cache.
229: *
230: * @throws Exception
231: */
232: public void testObjectExpiration() throws Exception {
233: String testString = new String("This is a test");
234: Object retrievedObject = null;
235: CachedObject cacheObject = null;
236:
237: GlobalCacheService globalCache = (GlobalCacheService) TurbineServices
238: .getInstance().getService(
239: GlobalCacheService.SERVICE_NAME);
240:
241: // Create and add Object that expires in 1000 millis (1 second)
242: cacheObject = new CachedObject(testString, 1000);
243: assertNotNull("Failed to create a cachable object", cacheObject);
244: long addTime = System.currentTimeMillis();
245: globalCache.addObject(cacheKey, cacheObject);
246:
247: // Try to get un-expired object
248: try {
249: retrievedObject = null;
250: retrievedObject = globalCache.getObject(cacheKey);
251: assertNotNull("Did not retrieved a cached object",
252: retrievedObject);
253: assertEquals("Did not retrieved correct cached object",
254: cacheObject, retrievedObject);
255: } catch (ObjectExpiredException e) {
256: assertTrue("Object expired early ( "
257: + (System.currentTimeMillis() - addTime)
258: + " millis)", false);
259: } catch (Exception e) {
260: throw e;
261: }
262:
263: // Sleep 1500 Millis (1.5 seconds)
264: Thread.sleep(1500);
265:
266: // Try to get expired object
267: try {
268: retrievedObject = null;
269: retrievedObject = globalCache.getObject(cacheKey);
270: assertNull(
271: "Retrieved the expired cached object and did not get expected ObjectExpiredException",
272: retrievedObject);
273: assertNotNull(
274: "Did not get expected ObjectExpiredException retrieving an expired object",
275: retrievedObject);
276: } catch (ObjectExpiredException e) {
277: assertNull(
278: "Retrieved the expired cached object, but caught expected ObjectExpiredException exception",
279: retrievedObject);
280: } catch (Exception e) {
281: throw e;
282: }
283:
284: // Remove objects
285: globalCache.removeObject(cacheKey);
286: }
287:
288: /**
289: * Verify the all object will be flushed from the cache.
290: *
291: * This test can take server minutes.
292: *
293: * @throws Exception
294: */
295: public void testCacheFlush() throws Exception {
296: String testString = new String("This is a test");
297: Object retrievedObject = null;
298: CachedObject cacheObject = null;
299:
300: GlobalCacheService globalCache = (GlobalCacheService) TurbineServices
301: .getInstance().getService(
302: GlobalCacheService.SERVICE_NAME);
303:
304: // Create and add Object that expires in 1 turbine Refresh + 1 millis
305: cacheObject = new CachedObject(testString,
306: (TURBINE_CACHE_REFRESH * 5) + 1);
307: assertNotNull("Failed to create a cachable object", cacheObject);
308: long addTime = System.currentTimeMillis();
309: globalCache.addObject(cacheKey, cacheObject);
310:
311: // 1 Refresh
312: Thread.sleep(TURBINE_CACHE_REFRESH + 1);
313: assertTrue("No object in cache before flush", (0 < globalCache
314: .getNumberOfObjects()));
315:
316: // Flush Cache
317: globalCache.flushCache();
318:
319: // Wait 15 seconds, 3 Refresh
320: Thread.sleep((TURBINE_CACHE_REFRESH * 2) + 1);
321: assertEquals("After refresh", 0, globalCache
322: .getNumberOfObjects());
323:
324: // Remove objects
325: globalCache.removeObject(cacheKey);
326: }
327:
328: /**
329: * Verify the Cache count is correct.
330: * @throws Exception
331: */
332: public void testObjectCount() throws Exception {
333: GlobalCacheService globalCache = (GlobalCacheService) TurbineServices
334: .getInstance().getService(
335: GlobalCacheService.SERVICE_NAME);
336: assertNotNull("Could not retrive cache service.", globalCache);
337:
338: // Create and add Object that expires in 1.5 turbine Refresh
339: long expireTime = TURBINE_CACHE_REFRESH + TURBINE_CACHE_REFRESH
340: / 2;
341: CachedObject cacheObject = new CachedObject("This is a test",
342: expireTime);
343: assertNotNull("Failed to create a cachable object", cacheObject);
344:
345: globalCache.addObject(cacheKey, cacheObject);
346: assertEquals("After adding 1 Object", 1, globalCache
347: .getNumberOfObjects());
348:
349: // Wait until we're passed 1 refresh, but not half way.
350: Thread.sleep(TURBINE_CACHE_REFRESH + TURBINE_CACHE_REFRESH / 3);
351: assertEquals("After one refresh", 1, globalCache
352: .getNumberOfObjects());
353:
354: // Wait until we're passed 2 more refreshes
355: Thread.sleep((TURBINE_CACHE_REFRESH * 2)
356: + TURBINE_CACHE_REFRESH / 3);
357: assertEquals("After three refreshes", 0, globalCache
358: .getNumberOfObjects());
359: }
360:
361: /**
362: * Verfy a refreshable object will refreshed in the following cases:
363: * o The object is retrieved via getObject an it is stale.
364: * o The object is determied to be stale during a cache
365: * refresh
366: *
367: * This test can take serveral minutes.
368: *
369: * @throws Exception
370: */
371: public void testRefreshableObject() throws Exception {
372: String testString = new String("This is a test");
373: Object retrievedObject = null;
374: RefreshableCachedObject cacheObject = null;
375:
376: GlobalCacheService globalCache = (GlobalCacheService) TurbineServices
377: .getInstance().getService(
378: GlobalCacheService.SERVICE_NAME);
379:
380: // Create and add Object that expires in TEST_EXPIRETIME millis.
381: cacheObject = new RefreshableCachedObject(
382: new RefreshableObject(), TEST_EXPIRETIME);
383: assertNotNull("Failed to create a cachable object", cacheObject);
384: long addTime = System.currentTimeMillis();
385: globalCache.addObject(cacheKey, cacheObject);
386:
387: // Try to get un-expired object
388: try {
389: retrievedObject = null;
390: retrievedObject = globalCache.getObject(cacheKey);
391: assertNotNull("Did not retrieved a cached object",
392: retrievedObject);
393: assertEquals("Did not retrieved correct cached object",
394: cacheObject, retrievedObject);
395: } catch (ObjectExpiredException e) {
396: assertTrue("Object expired early ( "
397: + (System.currentTimeMillis() - addTime)
398: + " millis)", false);
399: } catch (Exception e) {
400: throw e;
401: }
402:
403: // Wait 1 Turbine cache refresh + 1 second.
404: Thread.sleep(TEST_EXPIRETIME + 1000);
405:
406: // Try to get expired object
407: try {
408: retrievedObject = null;
409: retrievedObject = globalCache.getObject(cacheKey);
410: assertNotNull(
411: "Did not retrieved a cached object, after sleep",
412: retrievedObject);
413: assertNotNull(
414: "Cached object has no contents, after sleep.",
415: ((RefreshableCachedObject) retrievedObject)
416: .getContents());
417: assertTrue(
418: "Object did not refresh.",
419: (((RefreshableObject) ((RefreshableCachedObject) retrievedObject)
420: .getContents()).getRefreshCount() > 0));
421: } catch (ObjectExpiredException e) {
422: assertTrue(
423: "Received unexpected ObjectExpiredException exception "
424: + "when retrieving refreshable object after ( "
425: + (System.currentTimeMillis() - addTime)
426: + " millis)", false);
427: } catch (Exception e) {
428: throw e;
429: }
430:
431: // See if object will expires (testing every second for 100 seconds. It sould not!
432: for (int i = 0; i < 100; i++) {
433: Thread.sleep(1000); // Sleep 0.5 seconds
434:
435: // Try to get expired object
436: try {
437: retrievedObject = null;
438: retrievedObject = globalCache.getObject(cacheKey);
439: assertNotNull(
440: "Did not retrieved a cached object, after sleep",
441: retrievedObject);
442: assertNotNull(
443: "Cached object has no contents, after sleep.",
444: ((RefreshableCachedObject) retrievedObject)
445: .getContents());
446: assertTrue(
447: "Object did not refresh.",
448: (((RefreshableObject) ((RefreshableCachedObject) retrievedObject)
449: .getContents()).getRefreshCount() > 0));
450: } catch (ObjectExpiredException e) {
451: assertTrue(
452: "Received unexpected ObjectExpiredException exception "
453: + "when retrieving refreshable object after ( "
454: + (System.currentTimeMillis() - addTime)
455: + " millis)", false);
456: } catch (Exception e) {
457: throw e;
458: }
459: }
460: // Remove objects
461: globalCache.removeObject(cacheKey);
462: }
463:
464: /**
465: * Verify a cached object will be delete after it has been
466: * untouched beyond it's TimeToLive.
467: *
468: * This test can take serveral minutes.
469: *
470: * @throws Exception
471: */
472: public void testRefreshableTimeToLive() throws Exception {
473: String testString = new String("This is a test");
474: Object retrievedObject = null;
475: RefreshableCachedObject cacheObject = null;
476:
477: GlobalCacheService globalCache = (GlobalCacheService) TurbineServices
478: .getInstance().getService(
479: GlobalCacheService.SERVICE_NAME);
480:
481: // Create and add Object that expires in TEST_EXPIRETIME millis.
482: cacheObject = new RefreshableCachedObject(
483: new RefreshableObject(), TEST_EXPIRETIME);
484: assertNotNull("Failed to create a cachable object", cacheObject);
485: cacheObject.setTTL(TEST_TIMETOLIVE);
486:
487: // Verify TimeToLive was set
488: assertEquals("Returned TimeToLive", TEST_TIMETOLIVE,
489: cacheObject.getTTL());
490:
491: // Add object to Cache
492: long addTime = System.currentTimeMillis();
493: globalCache.addObject(cacheKey, cacheObject);
494:
495: // Try to get un-expired object
496: try {
497: retrievedObject = null;
498: retrievedObject = globalCache.getObject(cacheKey);
499: assertNotNull("Did not retrieved a cached object",
500: retrievedObject);
501: assertEquals("Did not retrieved correct cached object",
502: cacheObject, retrievedObject);
503: } catch (ObjectExpiredException e) {
504: assertTrue("Object expired early ( "
505: + (System.currentTimeMillis() - addTime)
506: + " millis)", false);
507: } catch (Exception e) {
508: throw e;
509: }
510:
511: // Wait long enough to allow object to expire, but do not exceed TTL
512: Thread.sleep(TEST_TIMETOLIVE - 2000);
513:
514: // Try to get expired object
515: try {
516: retrievedObject = null;
517: retrievedObject = globalCache.getObject(cacheKey);
518: assertNotNull(
519: "Did not retrieved a cached object, after sleep",
520: retrievedObject);
521: assertNotNull(
522: "Cached object has no contents, after sleep.",
523: ((RefreshableCachedObject) retrievedObject)
524: .getContents());
525: assertTrue(
526: "Object did not refresh.",
527: (((RefreshableObject) ((RefreshableCachedObject) retrievedObject)
528: .getContents()).getRefreshCount() > 0));
529: } catch (ObjectExpiredException e) {
530: assertTrue(
531: "Received unexpected ObjectExpiredException exception "
532: + "when retrieving refreshable object after ( "
533: + (System.currentTimeMillis() - addTime)
534: + " millis)", false);
535: } catch (Exception e) {
536: throw e;
537: }
538:
539: // Wait long enough to allow object to expire and exceed TTL
540: Thread.sleep(TEST_TIMETOLIVE + 5000);
541:
542: // Try to get expired object
543: try {
544: retrievedObject = null;
545: retrievedObject = globalCache.getObject(cacheKey);
546: assertNull(
547: "Retrieved a cached object, after exceeding TimeToLive",
548: retrievedObject);
549: } catch (ObjectExpiredException e) {
550: assertNull(
551: "Retrieved the expired cached object, but caught expected ObjectExpiredException exception",
552: retrievedObject);
553: } catch (Exception e) {
554: throw e;
555: }
556: }
557:
558: /**
559: * Simple object that can be refreshed
560: */
561: class RefreshableObject implements Refreshable {
562:
563: private int refreshCount = 0;
564:
565: /**
566: * Increment the refresh counter
567: */
568: public void refresh() {
569: this .refreshCount++;
570: }
571:
572: /**
573: * Reutrn the number of time this object has been refreshed
574: *
575: * @return Number of times refresh() has been called
576: */
577: public int getRefreshCount() {
578: return this.refreshCount;
579: }
580: }
581: }
|