001: package com.tctest;
002:
003: import net.sf.ehcache.Cache;
004: import net.sf.ehcache.CacheManager;
005: import net.sf.ehcache.Element;
006: import net.sf.ehcache.Status;
007: import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
008: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
009:
010: import com.tc.object.config.ConfigLockLevel;
011: import com.tc.object.config.ConfigVisitor;
012: import com.tc.object.config.DSOClientConfigHelper;
013: import com.tc.object.config.TransparencyClassSpec;
014: import com.tc.object.config.spec.CyclicBarrierSpec;
015: import com.tc.simulator.app.ApplicationConfig;
016: import com.tc.simulator.listener.ListenerProvider;
017: import com.tc.util.Assert;
018: import com.tc.util.DebugUtil;
019: import com.tc.util.TIMUtil;
020: import com.tctest.runner.AbstractErrorCatchingTransparentApp;
021:
022: import java.lang.reflect.Field;
023:
024: public class EhcacheEvictionTestApp extends
025: AbstractErrorCatchingTransparentApp {
026: private static final int NUM_OF_CACHE_ITEMS = 1000;
027:
028: private static final int TIME_TO_LIVE_IN_SECONDS = 100;
029:
030: static final int EXPECTED_THREAD_COUNT = 4;
031:
032: private final CyclicBarrier barrier;
033:
034: private CacheManager cacheManager;
035:
036: /**
037: * Test that Ehcache's CacheManger and Cache objects can be clustered.
038: *
039: * @param appId
040: * @param cfg
041: * @param listenerProvider
042: */
043: public EhcacheEvictionTestApp(final String appId,
044: final ApplicationConfig cfg,
045: final ListenerProvider listenerProvider) {
046: super (appId, cfg, listenerProvider);
047: barrier = new CyclicBarrier(getParticipantCount());
048: }
049:
050: /**
051: * Inject Ehcache 1.2.4 configuration, and instrument this test class
052: *
053: * @param visitor
054: * @param config
055: */
056: public static void visitL1DSOConfig(final ConfigVisitor visitor,
057: final DSOClientConfigHelper config) {
058: config.addModule(TIMUtil.EHCACHE_1_3, TIMUtil
059: .getVersion(TIMUtil.EHCACHE_1_3));
060: config.addAutolock("* *..*.*(..)", ConfigLockLevel.WRITE);
061:
062: final String testClass = EhcacheEvictionTestApp.class.getName();
063: final TransparencyClassSpec spec = config
064: .getOrCreateSpec(testClass);
065: spec.addRoot("barrier", "barrier");
066: spec.addRoot("cacheManager", "cacheManager");
067: new CyclicBarrierSpec().visit(visitor, config);
068: }
069:
070: protected void runTest() throws Throwable {
071: DebugUtil.DEBUG = true;
072:
073: int index = barrier.barrier();
074: if (index == 0) {
075: // Even though the singleton field of CacheManager is a root, we
076: // need to
077: // set cacheManager field to be a root and remove the shutdown hook
078: // of cache manager
079: // before assigning to root. This hack is to bypass the shutdown
080: // hook problem of 1.2.4
081: // in system test.
082: CacheManager cm = CacheManager.getInstance();
083: setShutDownHookToNull(cm);
084: cacheManager = cm;
085: }
086:
087: barrier.barrier();
088:
089: if (index == 0) {
090: // setting time to idle 10 times time to live to make sure that it
091: // will not expire because of the idle time.
092: addCache("CACHE", TIME_TO_LIVE_IN_SECONDS,
093: TIME_TO_LIVE_IN_SECONDS * 10);
094: }
095:
096: barrier.barrier();
097:
098: runSimplePutTimeToLiveTimeout(index);
099:
100: barrier.barrier();
101:
102: if (index == 0) {
103: addCache("CACHE", TIME_TO_LIVE_IN_SECONDS);
104: }
105:
106: barrier.barrier();
107:
108: runSimplePutTimeoutGet(index);
109:
110: if (index == 0) {
111: addCache("CACHE", TIME_TO_LIVE_IN_SECONDS * 4);
112: }
113:
114: barrier.barrier();
115:
116: runSimplePutSimpleGet(index);
117:
118: runSimplePut(index);
119:
120: if (index == 0) {
121: shutdownCacheManager();
122: }
123:
124: barrier.barrier();
125: verifyCacheManagerShutdown();
126: barrier.barrier();
127:
128: DebugUtil.DEBUG = false;
129: }
130:
131: private void runSimplePutTimeToLiveTimeout(int index)
132: throws Throwable {
133: DebugUtil.DEBUG = true;
134:
135: if (index == 1) {
136: doPut();
137: }
138:
139: barrier.barrier();
140:
141: Thread.sleep(TIME_TO_LIVE_IN_SECONDS * 500);
142:
143: barrier.barrier();
144:
145: doGet();
146:
147: barrier.barrier();
148:
149: Thread.sleep(TIME_TO_LIVE_IN_SECONDS * 700);
150:
151: barrier.barrier();
152:
153: doGetNull(index);
154:
155: DebugUtil.DEBUG = false;
156:
157: barrier.barrier();
158: }
159:
160: private void runSimplePutSimpleGet(int index) throws Throwable {
161: if (index == 1) {
162: doPut();
163: barrier.barrier();
164: } else {
165: barrier.barrier();
166:
167: long startGetTime = System.currentTimeMillis();
168: doGet();
169: long endGetTime = System.currentTimeMillis();
170:
171: System.err
172: .println("Time to get " + NUM_OF_CACHE_ITEMS
173: + " items: " + (endGetTime - startGetTime)
174: + " ms.");
175:
176: }
177:
178: barrier.barrier();
179: }
180:
181: private void runSimplePut(int index) throws Throwable {
182: Cache cache = cacheManager.getCache("CACHE");
183: int startKey = index * NUM_OF_CACHE_ITEMS;
184: int endKey = startKey + NUM_OF_CACHE_ITEMS;
185:
186: long st = System.currentTimeMillis();
187:
188: for (int i = startKey; i < endKey; i++) {
189: cache.put(new Element("key" + i, "value" + i));
190: }
191:
192: long en = System.currentTimeMillis();
193: System.err.println("Time to put " + NUM_OF_CACHE_ITEMS
194: + " objects into the cache: " + (en - st) + " ms.");
195:
196: barrier.barrier();
197:
198: }
199:
200: private void runSimplePutTimeoutGet(int index) throws Throwable {
201: if (index == 1) {
202: doPut();
203: Thread.sleep((long) (TIME_TO_LIVE_IN_SECONDS * 1.5 * 1000));
204: doGetNull(index);
205: }
206:
207: barrier.barrier();
208: }
209:
210: private void doPut() throws Throwable {
211: Cache cache = cacheManager.getCache("CACHE");
212: for (int i = 0; i < NUM_OF_CACHE_ITEMS; i++) {
213: cache.put(new Element("key" + i, "value" + i));
214: }
215: }
216:
217: private void doGet() throws Throwable {
218: Cache cache = cacheManager.getCache("CACHE");
219: for (int i = 0; i < NUM_OF_CACHE_ITEMS; i++) {
220: Object o = cache.get("key" + i);
221: Assert.assertEquals(new Element("key" + i, "value" + i), o);
222: }
223: }
224:
225: private void doGetNull(int index) throws Throwable {
226: Cache cache = cacheManager.getCache("CACHE");
227: for (int i = 0; i < NUM_OF_CACHE_ITEMS; i++) {
228: Object o = cache.get("key" + i);
229: Assert
230: .assertNull(
231: "Client "
232: + index
233: + " -- Object supposed to be Null, but is: "
234: + o, o);
235: }
236: }
237:
238: private Cache addCache(final String name, long timeToIdleSeconds)
239: throws Throwable {
240: cacheManager.removeCache(name);
241: Cache cache = new Cache(name, 2, MemoryStoreEvictionPolicy.LRU,
242: false, null, false, timeToIdleSeconds * 2,
243: timeToIdleSeconds, false, 1, null);
244: cacheManager.addCache(cache);
245:
246: cache = cacheManager.getCache(name);
247: return cache;
248: }
249:
250: private Cache addCache(final String name, long timeToLiveSeconds,
251: long timeToIdleSeconds) throws Throwable {
252: cacheManager.removeCache(name);
253: Cache cache = new Cache(name, 2, MemoryStoreEvictionPolicy.LRU,
254: false, null, false, timeToLiveSeconds,
255: timeToIdleSeconds, false, 1, null);
256:
257: cacheManager.addCache(cache);
258:
259: cache = cacheManager.getCache(name);
260: return cache;
261: }
262:
263: /**
264: * Shuts down the clustered cache manager.
265: */
266: private void shutdownCacheManager() throws Throwable {
267: cacheManager.shutdown();
268: }
269:
270: /**
271: * Verify that the clustered cache manager has shut down.
272: */
273: private void verifyCacheManagerShutdown() {
274: Assert.assertEquals(Status.STATUS_SHUTDOWN, cacheManager
275: .getStatus());
276: }
277:
278: private void setShutDownHookToNull(CacheManager cacheManager) {
279: try {
280: Field f = CacheManager.class
281: .getDeclaredField("shutdownHook");
282: f.setAccessible(true);
283: Thread t = (Thread) f.get(cacheManager);
284: if (t != null) {
285: Runtime.getRuntime().removeShutdownHook(t);
286: f.set(cacheManager, null);
287: }
288: } catch (Throwable t) {
289: t.printStackTrace(System.err);
290: throw new RuntimeException(t);
291: }
292: }
293:
294: }
|