001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tctest;
006:
007: import org.apache.commons.io.FileUtils;
008:
009: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
010:
011: import com.tc.object.bytecode.ManagerUtil;
012: import com.tc.object.config.ConfigVisitor;
013: import com.tc.object.config.DSOClientConfigHelper;
014: import com.tc.object.config.TransparencyClassSpec;
015: import com.tc.objectserver.control.ExtraL1ProcessControl;
016: import com.tc.simulator.app.ApplicationConfig;
017: import com.tc.simulator.listener.ListenerProvider;
018: import com.tc.util.Assert;
019: import com.tc.util.DebugUtil;
020: import com.tc.util.TIMUtil;
021: import com.tcclient.ehcache.TimeExpiryMap;
022:
023: import java.io.File;
024: import java.util.ArrayList;
025: import java.util.List;
026:
027: public class TimeExpiryMapGlobalEvictionTestApp extends
028: ServerCrashingAppBase {
029: private final static int NUM_OF_L1 = 2;
030:
031: public TimeExpiryMapGlobalEvictionTestApp(String appId,
032: ApplicationConfig cfg, ListenerProvider listenerProvider) {
033: super (appId, cfg, listenerProvider);
034: }
035:
036: public void runTest() throws Throwable {
037: basicGlobalEvictionTest();
038:
039: }
040:
041: private void basicGlobalEvictionTest() throws Exception {
042: DebugUtil.DEBUG = true;
043:
044: Thread t1 = new Thread(new Runnable() {
045: public void run() {
046: try {
047: spawnNewClient("0", L1Client.class,
048: new String[] { "0" });
049: } catch (Exception e) {
050: e.printStackTrace(System.err);
051: }
052: }
053:
054: });
055: Thread t2 = new Thread(new Runnable() {
056: public void run() {
057: try {
058: spawnNewClient("1", L1Client.class,
059: new String[] { "1" });
060: } catch (Exception e) {
061: e.printStackTrace(System.err);
062: }
063: }
064:
065: });
066:
067: t1.start();
068: t2.start();
069:
070: Thread.sleep(60000);
071:
072: DebugUtil.DEBUG = false;
073: }
074:
075: protected ExtraL1ProcessControl spawnNewClient(String clientId,
076: Class clientClass, String[] mainArgs) throws Exception {
077: final String hostName = getHostName();
078: final int port = getPort();
079: final File configFile = new File(getConfigFilePath());
080: File workingDir = new File(configFile.getParentFile(),
081: "client-" + clientId);
082: FileUtils.forceMkdir(workingDir);
083:
084: List jvmArgs = new ArrayList();
085: addTestTcPropertiesFile(jvmArgs);
086: ExtraL1ProcessControl client = new ExtraL1ProcessControl(
087: hostName, port, clientClass, configFile
088: .getAbsolutePath(), mainArgs, workingDir,
089: jvmArgs);
090: client.start();
091: client.mergeSTDERR();
092: client.mergeSTDOUT();
093: client.waitFor();
094: System.err.println("\n### Started New Client");
095: return client;
096: }
097:
098: public static void visitL1DSOConfig(ConfigVisitor visitor,
099: DSOClientConfigHelper config) {
100: TransparencyClassSpec spec = config
101: .getOrCreateSpec(CyclicBarrier.class.getName());
102: config.addWriteAutolock("* " + CyclicBarrier.class.getName()
103: + "*.*(..)");
104:
105: String testClass = TimeExpiryMapGlobalEvictionTestApp.class
106: .getName();
107: spec = config.getOrCreateSpec(testClass);
108: config.addIncludePattern(testClass + "$DataRoot");
109: config.addIncludePattern(testClass + "$MockTimeExpiryMap");
110: config.addIncludePattern(testClass + "$L1Client");
111: String methodExpression = "* " + testClass + "*.*(..)";
112: config.addWriteAutolock(methodExpression);
113:
114: spec = config.getOrCreateSpec(testClass + "$L1Client");
115: spec.addRoot("barrier", "barrier");
116: spec.addRoot("dataRoot", "dataRoot");
117:
118: config.addModule(TIMUtil.EHCACHE_1_2_4, TIMUtil
119: .getVersion(TIMUtil.EHCACHE_1_2_4)); // this is just a quick way
120: // to add TimeExpiryMap to
121: // the
122: // instrumentation list
123: }
124:
125: public static class L1Client {
126: private CyclicBarrier barrier = new CyclicBarrier(NUM_OF_L1);
127: private DataRoot dataRoot;
128: private final int index;
129:
130: public L1Client(int index) {
131: this .index = index;
132: if (index == 0) {
133: dataRoot = new DataRoot();
134: dataRoot.setMap(new MockTimeExpiryMap(3, 50, 6));
135: }
136: }
137:
138: public static void main(String args[]) throws Exception {
139: DebugUtil.DEBUG = true;
140:
141: int index = Integer.parseInt(args[0]);
142: L1Client l1 = new L1Client(index);
143: l1.execute();
144:
145: DebugUtil.DEBUG = false;
146: }
147:
148: public void execute() throws Exception {
149: barrier.barrier();
150: addData(index, 1);
151: barrier.barrier();
152:
153: Thread.sleep(1000);
154: Assert.assertEquals("val01", dataRoot.get("key01"));
155: Assert.assertEquals("val02", dataRoot.get("key02"));
156: Assert.assertEquals("val03", dataRoot.get("key03"));
157: Assert.assertEquals("val11", dataRoot.get("key11"));
158: Assert.assertEquals("val12", dataRoot.get("key12"));
159: Assert.assertEquals("val13", dataRoot.get("key13"));
160: Assert.assertEquals(6, dataRoot.size());
161:
162: Thread.sleep(10000);
163: Assert.assertTrue(dataRoot.isExpired("key01"));
164: Assert.assertTrue(dataRoot.isExpired("key02"));
165: Assert.assertTrue(dataRoot.isExpired("key03"));
166: Assert.assertTrue(dataRoot.isExpired("key11"));
167: Assert.assertTrue(dataRoot.isExpired("key12"));
168: Assert.assertTrue(dataRoot.isExpired("key13"));
169: Assert.assertEquals(0, dataRoot.size());
170: Assert.assertEquals(6, dataRoot.getNumOfEvicted());
171:
172: barrier.barrier();
173:
174: addData(index, 4);
175: Thread.sleep(1000);
176: Assert.assertEquals("val04", dataRoot.get("key04"));
177: Assert.assertEquals("val05", dataRoot.get("key05"));
178: Assert.assertEquals("val06", dataRoot.get("key06"));
179: Assert.assertEquals("val14", dataRoot.get("key14"));
180: Assert.assertEquals("val15", dataRoot.get("key15"));
181: Assert.assertEquals("val16", dataRoot.get("key16"));
182: Assert.assertEquals(6, dataRoot.size());
183:
184: if (index == 0) {
185: Thread.sleep(20000);
186:
187: Assert.assertTrue(dataRoot.isExpired("key04"));
188: Assert.assertTrue(dataRoot.isExpired("key05"));
189: Assert.assertTrue(dataRoot.isExpired("key06"));
190: Assert.assertTrue(dataRoot.isExpired("key14"));
191: Assert.assertTrue(dataRoot.isExpired("key15"));
192: Assert.assertTrue(dataRoot.isExpired("key16"));
193: Assert.assertEquals(0, dataRoot.size());
194: Assert.assertEquals(12, dataRoot.getNumOfEvicted());
195: }
196: }
197:
198: private void addData(int index, int startIndex) {
199: dataRoot.put("key" + index + startIndex, "val" + index
200: + startIndex);
201: dataRoot.put("key" + index + (startIndex + 1), "val"
202: + index + (startIndex + 1));
203: dataRoot.put("key" + index + (startIndex + 2), "val"
204: + index + (startIndex + 2));
205: }
206: }
207:
208: public static class DataRoot {
209: private MockTimeExpiryMap map;
210:
211: public DataRoot() {
212: super ();
213: }
214:
215: public synchronized void put(Object key, Object val) {
216: map.put(key, val);
217: }
218:
219: public synchronized Object get(Object key) {
220: return map.get(key);
221: }
222:
223: public synchronized int size() {
224: return map.size();
225: }
226:
227: public synchronized int getNumOfEvicted() {
228: return map.getNumOfEvicted();
229: }
230:
231: public synchronized void setMap(MockTimeExpiryMap map) {
232: this .map = map;
233: this .map.initialize();
234: }
235:
236: public synchronized boolean isExpired(Object key) {
237: return map.isExpired(key);
238: }
239: }
240:
241: public static class MockTimeExpiryMap extends TimeExpiryMap {
242: private int numOfEvicted = 0;
243:
244: public MockTimeExpiryMap(int invalidatorSleepSeconds,
245: int maxIdleTimeoutSeconds, int maxTTLSeconds) {
246: super (invalidatorSleepSeconds, maxIdleTimeoutSeconds,
247: maxTTLSeconds, "MockCache", true, 3, 4, 2, true,
248: true, 2, 10);
249: }
250:
251: protected final synchronized void processExpired(Object key) {
252: numOfEvicted++;
253: if (DebugUtil.DEBUG) {
254: System.err.println("Client "
255: + ManagerUtil.getClientID()
256: + " expiring ... key: " + key
257: + ", numOfExpired: " + numOfEvicted);
258: }
259: }
260:
261: public synchronized int getNumOfEvicted() {
262: return this.numOfEvicted;
263: }
264: }
265:
266: }
|