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.tc.objectserver.lockmanager.impl;
006:
007: import com.tc.management.L2LockStatsManager;
008: import com.tc.management.L2LockStatsManagerImpl;
009: import com.tc.management.L2LockStatsManagerImpl.LockStat;
010: import com.tc.net.groups.ClientID;
011: import com.tc.net.protocol.tcm.ChannelID;
012: import com.tc.object.lockmanager.api.LockID;
013: import com.tc.object.lockmanager.api.LockLevel;
014: import com.tc.object.lockmanager.api.ThreadID;
015: import com.tc.object.tx.WaitInvocation;
016: import com.tc.objectserver.api.TestSink;
017: import com.tc.objectserver.lockmanager.api.LockHolder;
018: import com.tc.objectserver.lockmanager.api.NullChannelManager;
019: import com.tc.util.Assert;
020: import com.tc.util.runtime.Os;
021:
022: import java.util.Collection;
023: import java.util.Iterator;
024:
025: import junit.framework.TestCase;
026:
027: public class LockStatManagerTest extends TestCase {
028: private TestSink sink;
029: private LockManagerImpl lockManager;
030: private L2LockStatsManager lockStatManager;
031:
032: protected void setUp() throws Exception {
033: super .setUp();
034: resetLockManager();
035: sink = new TestSink();
036: }
037:
038: private void resetLockManager() {
039: if (lockManager != null) {
040: try {
041: lockManager.stop();
042: } catch (InterruptedException e) {
043: fail();
044: }
045: }
046:
047: lockStatManager = new L2LockStatsManagerImpl();
048: lockManager = new LockManagerImpl(new NullChannelManager(),
049: lockStatManager);
050: lockManager
051: .setLockPolicy(LockManagerImpl.ALTRUISTIC_LOCK_POLICY);
052: lockManager.start();
053: lockStatManager.start(new NullChannelManager(), lockManager,
054: sink);
055: }
056:
057: protected void tearDown() throws Exception {
058: assertEquals(0, lockManager.getLockCount());
059: assertEquals(0, lockManager.getThreadContextCount());
060: super .tearDown();
061: }
062:
063: public void testLockHeldDuration() {
064: try {
065: LockID l1 = new LockID("1");
066: final ClientID cid1 = new ClientID(new ChannelID(1));
067: ThreadID s1 = new ThreadID(0);
068: final ClientID cid2 = new ClientID(new ChannelID(2));
069: ThreadID s2 = new ThreadID(1);
070:
071: lockManager
072: .requestLock(l1, cid1, s1, LockLevel.WRITE, sink);
073: lockManager.requestLock(l1, cid2, s2, LockLevel.READ, sink);
074:
075: LockHolder lockHolder1 = lockStatManager.getLockHolder(l1,
076: cid1, s1);
077: LockHolder lockHolder2 = lockStatManager.getLockHolder(l1,
078: cid2, s2);
079: Thread.sleep(5000);
080: lockManager.unlock(l1, cid1, s1);
081:
082: assertTrue(lockHolder1.getAndSetHeldTimeInMillis() > lockHolder2
083: .getAndSetHeldTimeInMillis());
084: lockManager.unlock(l1, cid2, s2);
085: } catch (InterruptedException e) {
086: // ignore
087: } finally {
088: resetLockManager();
089: }
090: }
091:
092: public void testLockHeldAggregateDuration() {
093: try {
094: LockID l1 = new LockID("1");
095: final ClientID cid1 = new ClientID(new ChannelID(1));
096: ThreadID s1 = new ThreadID(0);
097: final ClientID cid2 = new ClientID(new ChannelID(2));
098: ThreadID s2 = new ThreadID(1);
099:
100: lockManager
101: .requestLock(l1, cid1, s1, LockLevel.WRITE, sink);
102: Thread.sleep(5000);
103: lockManager.unlock(l1, cid1, s1);
104: lockManager.requestLock(l1, cid2, s2, LockLevel.READ, sink);
105: Thread.sleep(3000);
106: lockManager.unlock(l1, cid2, s2);
107: Collection c = lockStatManager
108: .getTopAggregateLockHolderStats(100);
109: Assert.assertEquals(1, c.size());
110: Iterator i = c.iterator();
111: LockStat lockStat = (LockStat) i.next();
112: long avgHeldTimeInMillis = lockStat
113: .getAvgHeldTimeInMillis();
114: System.out.println("Average held time in millis: "
115: + avgHeldTimeInMillis);
116: // Supported to be 4000 but changed to 3990
117: // This is due to System.currentTimeMillis() which is not that accurate,
118: // according to javadoc, the granularity can be in units of tens of milliseconds
119: if (Os.isWindows()) {
120: // on windows, System.currentTimeMills() only changes every 15-16 millis! It’s even worse on windows 95 (~55ms)
121: Assert.assertTrue(avgHeldTimeInMillis >= 3890);
122: } else {
123: Assert.assertTrue(avgHeldTimeInMillis >= 3990);
124: }
125: } catch (InterruptedException e) {
126: // ignore
127: } finally {
128: resetLockManager();
129: }
130: }
131:
132: public void testLockStatsManager() {
133: veriyLockStatsManagerStatistics();
134:
135: lockStatManager.setLockStatisticsEnabled(false);
136:
137: LockID l1 = new LockID("1");
138: ThreadID s1 = new ThreadID(0);
139:
140: final ClientID cid1 = new ClientID(new ChannelID(1));
141:
142: lockManager.requestLock(l1, cid1, s1, LockLevel.WRITE, sink);
143: assertEquals(0, lockStatManager.getNumberOfLockRequested(l1));
144: lockManager.unlock(l1, cid1, s1);
145:
146: lockStatManager.setLockStatisticsEnabled(true);
147:
148: veriyLockStatsManagerStatistics();
149: }
150:
151: private void veriyLockStatsManagerStatistics() {
152: LockID l1 = new LockID("1");
153: ThreadID s1 = new ThreadID(0);
154:
155: final ClientID cid1 = new ClientID(new ChannelID(1));
156: final ClientID cid2 = new ClientID(new ChannelID(2));
157: final ClientID cid3 = new ClientID(new ChannelID(3));
158: final ClientID cid4 = new ClientID(new ChannelID(4));
159:
160: lockManager.requestLock(l1, cid1, s1, LockLevel.WRITE, sink);
161: assertEquals(1, lockStatManager.getNumberOfLockRequested(l1));
162: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
163:
164: lockManager.requestLock(l1, cid2, s1, LockLevel.WRITE, sink); // c2 should pend
165: assertEquals(2, lockStatManager.getNumberOfLockRequested(l1));
166: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
167:
168: lockManager.tryRequestLock(l1, cid3, s1, LockLevel.WRITE,
169: new WaitInvocation(0, 0), sink);
170: assertEquals(3, lockStatManager.getNumberOfLockRequested(l1));
171: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
172:
173: lockManager.unlock(l1, cid1, s1); // it will grant request to c2
174: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
175: assertEquals(1, lockStatManager.getNumberOfLockReleased(l1));
176: assertEquals(1, lockStatManager.getNumberOfLockReleased(l1));
177:
178: lockManager.requestLock(l1, cid1, s1, LockLevel.WRITE, sink); // c1 request again
179: assertEquals(4, lockStatManager.getNumberOfLockRequested(l1));
180: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
181:
182: lockManager.unlock(l1, cid2, s1); // grant to c1 again
183: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
184: assertEquals(2, lockStatManager.getNumberOfLockReleased(l1));
185:
186: lockManager.requestLock(l1, cid3, s1, LockLevel.WRITE, sink);
187: lockManager.requestLock(l1, cid4, s1, LockLevel.WRITE, sink);
188: assertEquals(6, lockStatManager.getNumberOfLockRequested(l1));
189: assertEquals(2, lockStatManager.getNumberOfPendingRequests(l1));
190:
191: lockManager.unlock(l1, cid1, s1); // grant to c3
192: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
193: assertEquals(3, lockStatManager.getNumberOfLockReleased(l1));
194:
195: lockManager.unlock(l1, cid3, s1); // grant to c4
196: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
197: assertEquals(4, lockStatManager.getNumberOfLockReleased(l1));
198: lockManager.requestLock(l1, cid3, s1, LockLevel.WRITE, sink);
199: assertEquals(7, lockStatManager.getNumberOfLockRequested(l1));
200: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
201:
202: lockManager.unlock(l1, cid4, s1); // grant to c3 again
203: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
204: assertEquals(5, lockStatManager.getNumberOfLockReleased(l1));
205:
206: lockManager.unlock(l1, cid3, s1);
207: assertEquals(6, lockStatManager.getNumberOfLockReleased(l1));
208: }
209:
210: public void testGreedyLockStatsManagerStatistics() {
211: lockManager = new LockManagerImpl(new NullChannelManager(),
212: lockStatManager);
213: lockManager.setLockPolicy(LockManagerImpl.GREEDY_LOCK_POLICY);
214: lockManager.start();
215: lockStatManager.start(new NullChannelManager(), lockManager,
216: sink);
217:
218: LockID l1 = new LockID("1");
219: ThreadID s1 = new ThreadID(0);
220:
221: final ClientID cid1 = new ClientID(new ChannelID(1));
222: final ClientID cid2 = new ClientID(new ChannelID(2));
223: final ClientID cid3 = new ClientID(new ChannelID(3));
224: final ClientID cid4 = new ClientID(new ChannelID(4));
225:
226: lockManager.requestLock(l1, cid1, s1, LockLevel.WRITE, sink); // c1 award greedily
227: assertEquals(1, lockStatManager.getNumberOfLockRequested(l1));
228: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
229:
230: lockManager.requestLock(l1, cid2, s1, LockLevel.WRITE, sink); // c2 should pend
231: assertEquals(2, lockStatManager.getNumberOfLockRequested(l1));
232: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
233:
234: lockManager.tryRequestLock(l1, cid3, s1, LockLevel.WRITE,
235: new WaitInvocation(0, 0), sink);
236: assertEquals(3, lockStatManager.getNumberOfLockRequested(l1));
237: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
238:
239: lockManager.unlock(l1, cid1, ThreadID.VM_ID); // it will grant to c2 greedily
240: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
241: assertEquals(1, lockStatManager.getNumberOfLockReleased(l1));
242: assertEquals(1, lockStatManager.getNumberOfLockReleased(l1));
243:
244: lockManager.requestLock(l1, cid1, s1, LockLevel.WRITE, sink); // c1 request again
245: assertEquals(4, lockStatManager.getNumberOfLockRequested(l1));
246: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
247:
248: lockManager.unlock(l1, cid2, ThreadID.VM_ID); // grant to c1 greedily again
249: assertEquals(2, lockStatManager.getNumberOfLockHopRequests(l1));
250: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
251: assertEquals(2, lockStatManager.getNumberOfLockReleased(l1));
252:
253: lockManager.requestLock(l1, cid3, s1, LockLevel.WRITE, sink);
254: lockManager.requestLock(l1, cid4, s1, LockLevel.WRITE, sink);
255: assertEquals(6, lockStatManager.getNumberOfLockRequested(l1));
256: assertEquals(2, lockStatManager.getNumberOfPendingRequests(l1));
257:
258: lockManager.unlock(l1, cid1, ThreadID.VM_ID); // grant to c3 non-greedily
259: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
260: assertEquals(3, lockStatManager.getNumberOfLockReleased(l1));
261:
262: lockManager.unlock(l1, cid3, s1); // grant to c4 greedily
263: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
264: assertEquals(4, lockStatManager.getNumberOfLockReleased(l1));
265: lockManager.requestLock(l1, cid3, s1, LockLevel.WRITE, sink);
266: assertEquals(7, lockStatManager.getNumberOfLockRequested(l1));
267: assertEquals(1, lockStatManager.getNumberOfPendingRequests(l1));
268:
269: lockManager.unlock(l1, cid4, ThreadID.VM_ID); // grant to c3 greedily again
270: assertEquals(4, lockStatManager.getNumberOfLockHopRequests(l1));
271: assertEquals(0, lockStatManager.getNumberOfPendingRequests(l1));
272: assertEquals(5, lockStatManager.getNumberOfLockReleased(l1));
273:
274: lockManager.unlock(l1, cid3, ThreadID.VM_ID);
275: assertEquals(6, lockStatManager.getNumberOfLockReleased(l1));
276: }
277:
278: }
|