001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.object.lockmanager.api;
005:
006: import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
007:
008: import com.tc.object.lockmanager.impl.ThreadLockManagerImpl;
009: import com.tc.object.tx.WaitInvocation;
010:
011: import junit.framework.TestCase;
012:
013: public class ThreadLockManagerTest extends TestCase {
014:
015: private TestLockManager lm;
016: private ThreadLockManager tlm;
017:
018: public void setUp() throws Exception {
019: lm = new TestLockManager();
020: tlm = new ThreadLockManagerImpl(lm);
021: }
022:
023: public void testLockIDFor() {
024: String lockName = "fo0";
025: tlm.lockIDFor(lockName);
026: assertEquals(lockName, lm.lockIDForCalls.get(0));
027: }
028:
029: public void testLock() throws Exception {
030: final LockID lockID = new LockID("lock");
031: final int lockLevel = LockLevel.WRITE;
032: assertEquals(0, lm.locks.size());
033: tlm.lock(lockID, lockLevel);
034: Object[] args = getLockCallArgs();
035:
036: verifyLockArgs(lockID, new ThreadID(1), lockLevel, args);
037:
038: tlm.lock(lockID, lockLevel);
039: args = getLockCallArgs();
040: // calling lock in the same thread should result in the same thread id being used to call lock with.
041: verifyLockArgs(lockID, new ThreadID(1), lockLevel, args);
042:
043: final CyclicBarrier barrier = new CyclicBarrier(2);
044:
045: Runnable getter = new Runnable() {
046: public void run() {
047: tlm.lock(lockID, lockLevel);
048: try {
049: barrier.barrier();
050: } catch (InterruptedException e) {
051: e.printStackTrace();
052: }
053: }
054: };
055:
056: new Thread(getter).start();
057: barrier.barrier();
058:
059: args = getLockCallArgs();
060: verifyLockArgs(lockID, new ThreadID(2), lockLevel, args);
061:
062: new Thread(getter).start();
063: barrier.barrier();
064:
065: args = getLockCallArgs();
066: verifyLockArgs(lockID, new ThreadID(3), lockLevel, args);
067: }
068:
069: private Object[] getLockCallArgs() {
070: assertEquals(1, lm.locks.size());
071: Object[] args = (Object[]) lm.locks.get(0);
072: lm.locks.clear();
073: return args;
074: }
075:
076: private void verifyLockArgs(LockID lockID, ThreadID threadID,
077: int lockLevel, Object[] args) {
078: assertEquals(lockID, args[0]);
079: assertEquals(threadID, args[1]);
080: assertEquals(new Integer(lockLevel), args[2]);
081: }
082:
083: public void testWait() throws Exception {
084: final LockID lockID = new LockID("lock");
085: final WaitInvocation call = new WaitInvocation();
086: final Object lockObject = new Object();
087: final WaitListener waitListener = null;
088: tlm.wait(lockID, call, lockObject, waitListener);
089:
090: verifyWaitArgs(lockID, new ThreadID(1), call, lockObject,
091: waitListener, getWaitCallArgs());
092:
093: // try it again in the same thread. The thread id should remain the same.
094: tlm.wait(lockID, call, lockObject, waitListener);
095: verifyWaitArgs(lockID, new ThreadID(1), call, lockObject,
096: waitListener, getWaitCallArgs());
097:
098: final CyclicBarrier barrier = new CyclicBarrier(2);
099:
100: Runnable waiter = new Runnable() {
101: public void run() {
102: try {
103: tlm.wait(lockID, call, lockObject, waitListener);
104: barrier.barrier();
105: } catch (InterruptedException e) {
106: e.printStackTrace();
107: }
108: }
109: };
110:
111: // try it in a different thread; the thread id should increment.
112: new Thread(waiter).start();
113: barrier.barrier();
114: verifyWaitArgs(lockID, new ThreadID(2), call, lockObject,
115: waitListener, getWaitCallArgs());
116:
117: new Thread(waiter).start();
118: barrier.barrier();
119: verifyWaitArgs(lockID, new ThreadID(3), call, lockObject,
120: waitListener, getWaitCallArgs());
121:
122: }
123:
124: private void verifyWaitArgs(LockID lockID, ThreadID threadID,
125: WaitInvocation call, Object lockObject,
126: WaitListener waitListener, Object[] args) {
127: assertEquals(lockID, args[0]);
128: assertEquals(threadID, args[1]);
129: assertEquals(call, args[2]);
130: assertEquals(lockObject, args[3]);
131: assertEquals(waitListener, args[4]);
132: }
133:
134: private Object[] getWaitCallArgs() {
135: assertEquals(1, lm.waitCalls.size());
136: Object[] args = (Object[]) lm.waitCalls.get(0);
137: lm.waitCalls.clear();
138: return args;
139: }
140:
141: public void testNotify() throws Exception {
142: final boolean notifyAll = false;
143: final LockID lockID = new LockID("lock");
144:
145: tlm.notify(lockID, notifyAll);
146: verifyNotifyArgs(lockID, new ThreadID(1), notifyAll,
147: getNotifyCallArgs());
148: // the same thread should have the same thread id.
149: tlm.notify(lockID, notifyAll);
150: verifyNotifyArgs(lockID, new ThreadID(1), notifyAll,
151: getNotifyCallArgs());
152:
153: final CyclicBarrier barrier = new CyclicBarrier(2);
154: Runnable notifier = new Runnable() {
155:
156: public void run() {
157: tlm.notify(lockID, notifyAll);
158: try {
159: barrier.barrier();
160: } catch (InterruptedException e) {
161: e.printStackTrace();
162: }
163: }
164:
165: };
166:
167: new Thread(notifier).start();
168: barrier.barrier();
169: verifyNotifyArgs(lockID, new ThreadID(2), notifyAll,
170: getNotifyCallArgs());
171:
172: // different threads should have different thread ids.
173: new Thread(notifier).start();
174: barrier.barrier();
175: verifyNotifyArgs(lockID, new ThreadID(3), notifyAll,
176: getNotifyCallArgs());
177:
178: }
179:
180: private void verifyNotifyArgs(LockID lockID, ThreadID threadID,
181: boolean notifyAll, Object[] args) {
182: assertEquals(lockID, args[0]);
183: assertEquals(threadID, args[1]);
184: assertEquals(new Boolean(notifyAll), args[2]);
185: }
186:
187: private Object[] getNotifyCallArgs() {
188: assertEquals(1, lm.notifyCalls.size());
189: Object[] args = (Object[]) lm.notifyCalls.get(0);
190: lm.notifyCalls.clear();
191: return args;
192: }
193:
194: public void testUnlock() throws Exception {
195: final LockID lockID = new LockID("lock");
196: tlm.unlock(lockID);
197: verifyUnlockArgs(lockID, new ThreadID(1), getUnlockArgs());
198:
199: tlm.unlock(lockID);
200: verifyUnlockArgs(lockID, new ThreadID(1), getUnlockArgs());
201:
202: final CyclicBarrier barrier = new CyclicBarrier(2);
203: Runnable unlocker = new Runnable() {
204: public void run() {
205: try {
206: tlm.unlock(lockID);
207: barrier.barrier();
208: } catch (InterruptedException e) {
209: e.printStackTrace();
210: }
211: }
212: };
213:
214: new Thread(unlocker).start();
215: barrier.barrier();
216: verifyUnlockArgs(lockID, new ThreadID(2), getUnlockArgs());
217:
218: new Thread(unlocker).start();
219: barrier.barrier();
220: verifyUnlockArgs(lockID, new ThreadID(3), getUnlockArgs());
221: }
222:
223: private void verifyUnlockArgs(LockID lockID, ThreadID threadID,
224: Object[] args) {
225: assertEquals(lockID, args[0]);
226: assertEquals(threadID, args[1]);
227: }
228:
229: private Object[] getUnlockArgs() {
230: assertEquals(1, lm.unlockCalls.size());
231: Object[] args = (Object[]) lm.unlockCalls.get(0);
232: lm.unlockCalls.clear();
233: return args;
234: }
235:
236: }
|