001: /*
002: * All content copyright (c) 2003-2007 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 com.tc.async.api.Sink;
008: import com.tc.exception.ImplementMe;
009: import com.tc.io.TCByteBufferOutput;
010: import com.tc.io.TCByteBufferOutputStream;
011: import com.tc.logging.NullTCLogger;
012: import com.tc.management.ClientLockStatManager;
013: import com.tc.management.ClientLockStatManagerImpl;
014: import com.tc.management.L2LockStatsManager;
015: import com.tc.management.L2LockStatsManagerImpl;
016: import com.tc.management.L2LockStatsManagerImpl.LockStackTracesStat;
017: import com.tc.net.groups.ClientID;
018: import com.tc.net.protocol.tcm.ChannelEventListener;
019: import com.tc.net.protocol.tcm.ChannelID;
020: import com.tc.net.protocol.tcm.ChannelIDProvider;
021: import com.tc.net.protocol.tcm.ClientMessageChannel;
022: import com.tc.net.protocol.tcm.MessageChannel;
023: import com.tc.net.protocol.tcm.MessageMonitor;
024: import com.tc.net.protocol.tcm.MockMessageChannel;
025: import com.tc.net.protocol.tcm.NullMessageMonitor;
026: import com.tc.net.protocol.tcm.TCMessage;
027: import com.tc.net.protocol.tcm.TCMessageImpl;
028: import com.tc.net.protocol.tcm.TCMessageSink;
029: import com.tc.net.protocol.tcm.TCMessageType;
030: import com.tc.object.lockmanager.api.LockID;
031: import com.tc.object.lockmanager.api.LockLevel;
032: import com.tc.object.lockmanager.api.ThreadID;
033: import com.tc.object.lockmanager.impl.ClientLockManagerImpl;
034: import com.tc.object.lockmanager.impl.ClientServerLockManagerGlue;
035: import com.tc.object.lockmanager.impl.ClientServerLockStatManagerGlue;
036: import com.tc.object.lockmanager.impl.TCStackTraceElement;
037: import com.tc.object.msg.AcknowledgeTransactionMessageFactory;
038: import com.tc.object.msg.ClientHandshakeMessageFactory;
039: import com.tc.object.msg.CommitTransactionMessageFactory;
040: import com.tc.object.msg.CompletedTransactionLowWaterMarkMessageFactory;
041: import com.tc.object.msg.JMXMessage;
042: import com.tc.object.msg.LockRequestMessageFactory;
043: import com.tc.object.msg.LockStatisticsResponseMessage;
044: import com.tc.object.msg.ObjectIDBatchRequestMessageFactory;
045: import com.tc.object.msg.RequestManagedObjectMessageFactory;
046: import com.tc.object.msg.RequestRootMessageFactory;
047: import com.tc.object.net.DSOChannelManager;
048: import com.tc.object.net.DSOClientMessageChannel;
049: import com.tc.object.session.SessionID;
050: import com.tc.object.session.TestSessionManager;
051: import com.tc.objectserver.api.TestSink;
052: import com.tc.objectserver.lockmanager.api.NullChannelManager;
053: import com.tc.objectserver.lockmanager.impl.LockManagerImpl;
054: import com.tc.properties.TCProperties;
055: import com.tc.properties.TCPropertiesImpl;
056: import com.tc.util.Assert;
057:
058: import java.lang.reflect.Constructor;
059: import java.util.Collection;
060: import java.util.Iterator;
061: import java.util.List;
062:
063: import junit.framework.TestCase;
064:
065: public class ClientServerLockStatisticsTest extends TestCase {
066:
067: private ClientLockManagerImpl clientLockManager;
068: private LockManagerImpl serverLockManager;
069: private ClientServerLockManagerGlue glue1;
070: private TestSessionManager sessionManager;
071: private ClientLockStatManager clientLockStatManager;
072: private L2LockStatsManager serverLockStatManager;
073: private ClientServerLockStatManagerGlue statGlue;
074: private ChannelID channelId1 = new ChannelID(1);
075:
076: protected void setUp() throws Exception {
077: super .setUp();
078: sessionManager = new TestSessionManager();
079: glue1 = new ClientServerLockManagerGlue(sessionManager);
080: clientLockStatManager = new ClientLockStatManagerImpl();
081: clientLockManager = new ClientLockManagerImpl(
082: new NullTCLogger(), glue1, sessionManager,
083: clientLockStatManager);
084:
085: DSOChannelManager nullChannelManager = new NullChannelManager();
086: serverLockStatManager = new L2LockStatsManagerImpl();
087: serverLockManager = new LockManagerImpl(nullChannelManager,
088: serverLockStatManager);
089: serverLockManager
090: .setLockPolicy(LockManagerImpl.ALTRUISTIC_LOCK_POLICY);
091: glue1.set(clientLockManager, serverLockManager);
092:
093: TestSink sink = new TestSink();
094: serverLockStatManager.start(nullChannelManager,
095: serverLockManager, sink);
096:
097: ClientMessageChannel channel1 = new TestClientMessageChannel(
098: channelId1);
099:
100: clientLockStatManager.start(new TestClientChannel(channel1),
101: sink);
102: statGlue = new ClientServerLockStatManagerGlue(sink);
103: statGlue.set(clientLockStatManager, serverLockStatManager);
104: }
105:
106: private int getClientLockStatCollectionFrequency() {
107: TCProperties tcProperties = TCPropertiesImpl.getProperties()
108: .getPropertiesFor("l1.lock");
109: return tcProperties.getInt("collectFrequency");
110: }
111:
112: public void testCollectLockStackTraces() {
113: final LockID lockID1 = new LockID("1");
114: final ThreadID tx1 = new ThreadID(1);
115: final ThreadID tx2 = new ThreadID(1);
116: clientLockManager.lock(lockID1, tx1, LockLevel.READ);
117:
118: serverLockStatManager.enableClientStackTrace(lockID1, 1, 1);
119: sleep(1000);
120: clientLockManager.lock(lockID1, tx2, LockLevel.READ);
121: sleep(2000);
122: assertStackTraces(lockID1, 1, 1);
123:
124: clientLockManager.unlock(lockID1, tx2);
125: sleep(2000);
126: assertStackTraces(lockID1, 2, 1);
127:
128: serverLockStatManager.enableClientStackTrace(lockID1, 2, 1);
129: sleep(1000);
130: clientLockManager.lock(lockID1, tx2, LockLevel.READ);
131: sleep(2000);
132: assertStackTraces(lockID1, 1, 2);
133: clientLockManager.unlock(lockID1, tx2);
134:
135: sleep(1000);
136: serverLockStatManager.enableClientStackTrace(lockID1);
137: sleep(1000);
138: int clientLockStatCollectFrequency = getClientLockStatCollectionFrequency();
139: for (int i = 0; i < clientLockStatCollectFrequency + 1; i++) {
140: clientLockManager.lock(lockID1, tx2, LockLevel.READ);
141: }
142: sleep(2000);
143: assertStackTraces(lockID1, 1, 1); // all lock() requests have the same stack trace
144: for (int i = 0; i < clientLockStatCollectFrequency + 1; i++) {
145: clientLockManager.unlock(lockID1, tx2);
146: }
147:
148: clientLockManager.unlock(lockID1, tx2);
149: }
150:
151: private void assertStackTraces(LockID lockID, int numOfStackTraces,
152: int depthOfStackTraces) {
153: Collection stackTraces = serverLockStatManager
154: .getStackTraces(lockID);
155:
156: Assert.assertEquals(1, stackTraces.size()); // only one client in this test
157: for (Iterator i = stackTraces.iterator(); i.hasNext();) {
158: LockStackTracesStat s = (LockStackTracesStat) i.next();
159: Assert.assertEquals(channelId1, ((ClientID) s.getNodeID())
160: .getChannelID());
161: List oneStackTraces = s.getStackTraces();
162: for (Iterator j = oneStackTraces.iterator(); j.hasNext();) {
163: TCStackTraceElement stackTracesElement = (TCStackTraceElement) j
164: .next();
165: Assert
166: .assertEquals(depthOfStackTraces,
167: stackTracesElement
168: .getStackTraceElements().length);
169: }
170: Assert
171: .assertEquals(numOfStackTraces, oneStackTraces
172: .size());
173: }
174: }
175:
176: private void sleep(long l) {
177: try {
178: Thread.sleep(l);
179: } catch (InterruptedException e) {
180: // NOP
181: }
182: }
183:
184: protected void tearDown() throws Exception {
185: glue1.stop();
186: super .tearDown();
187: }
188:
189: private static class TestClientMessageChannel extends
190: MockMessageChannel implements ClientMessageChannel {
191: public TestClientMessageChannel(ChannelID channelId) {
192: super (channelId);
193: super .registerType(
194: TCMessageType.LOCK_STATISTICS_RESPONSE_MESSAGE,
195: LockStatisticsResponseMessage.class);
196: }
197:
198: public TCMessage createMessage(TCMessageType type) {
199: Class theClass = super .getRegisteredMessageClass(type);
200:
201: if (theClass == null)
202: throw new ImplementMe();
203:
204: try {
205: Constructor constructor = theClass
206: .getConstructor(new Class[] { SessionID.class,
207: MessageMonitor.class,
208: TCByteBufferOutput.class,
209: MessageChannel.class,
210: TCMessageType.class });
211: TCMessageImpl message = (TCMessageImpl) constructor
212: .newInstance(new Object[] {
213: SessionID.NULL_ID,
214: new NullMessageMonitor(),
215: new TCByteBufferOutputStream(4, 4096,
216: false), this , type });
217: message.seal();
218: return message;
219: } catch (Exception e) {
220: throw new ImplementMe("Failed", e);
221: }
222: }
223:
224: public void addClassMapping(TCMessageType type, Class msgClass) {
225: throw new ImplementMe();
226:
227: }
228:
229: public ChannelIDProvider getChannelIDProvider() {
230: return null;
231: }
232:
233: public int getConnectAttemptCount() {
234: return 0;
235: }
236:
237: public int getConnectCount() {
238: return 0;
239: }
240:
241: public void routeMessageType(TCMessageType messageType,
242: Sink destSink, Sink hydrateSink) {
243: throw new ImplementMe();
244:
245: }
246:
247: public void routeMessageType(TCMessageType type,
248: TCMessageSink sink) {
249: throw new ImplementMe();
250:
251: }
252:
253: public void unrouteMessageType(TCMessageType type) {
254: throw new ImplementMe();
255:
256: }
257: }
258:
259: private static class TestClientChannel implements
260: DSOClientMessageChannel {
261: private ClientMessageChannel clientMessageChannel;
262:
263: public TestClientChannel(
264: ClientMessageChannel clientMessageChannel) {
265: this .clientMessageChannel = clientMessageChannel;
266: }
267:
268: public ClientMessageChannel channel() {
269: return clientMessageChannel;
270: }
271:
272: public void addClassMapping(TCMessageType messageType,
273: Class messageClass) {
274: throw new ImplementMe();
275:
276: }
277:
278: public void addListener(ChannelEventListener listener) {
279: throw new ImplementMe();
280:
281: }
282:
283: public void close() {
284: throw new ImplementMe();
285:
286: }
287:
288: public AcknowledgeTransactionMessageFactory getAcknowledgeTransactionMessageFactory() {
289: throw new ImplementMe();
290: }
291:
292: public ChannelIDProvider getChannelIDProvider() {
293: throw new ImplementMe();
294: }
295:
296: public ClientHandshakeMessageFactory getClientHandshakeMessageFactory() {
297: throw new ImplementMe();
298: }
299:
300: public CommitTransactionMessageFactory getCommitTransactionMessageFactory() {
301: throw new ImplementMe();
302: }
303:
304: public JMXMessage getJMXMessage() {
305: throw new ImplementMe();
306: }
307:
308: public LockRequestMessageFactory getLockRequestMessageFactory() {
309: throw new ImplementMe();
310: }
311:
312: public ObjectIDBatchRequestMessageFactory getObjectIDBatchRequestMessageFactory() {
313: throw new ImplementMe();
314: }
315:
316: public RequestManagedObjectMessageFactory getRequestManagedObjectMessageFactory() {
317: throw new ImplementMe();
318: }
319:
320: public RequestRootMessageFactory getRequestRootMessageFactory() {
321: throw new ImplementMe();
322: }
323:
324: public boolean isConnected() {
325: throw new ImplementMe();
326: }
327:
328: public void open() {
329: throw new ImplementMe();
330:
331: }
332:
333: public void routeMessageType(TCMessageType messageType,
334: Sink destSink, Sink hydrateSink) {
335: throw new ImplementMe();
336:
337: }
338:
339: public CompletedTransactionLowWaterMarkMessageFactory getCompletedTransactionLowWaterMarkMessageFactory() {
340: throw new ImplementMe();
341: }
342: }
343: }
|