KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > lockmanager > api > ClientLockManagerTest


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.object.lockmanager.api;
6
7 import EDU.oswego.cs.dl.util.concurrent.BrokenBarrierException;
8 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
9 import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
10 import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
11
12 import com.tc.exception.TCRuntimeException;
13 import com.tc.logging.NullTCLogger;
14 import com.tc.logging.TCLogger;
15 import com.tc.object.lockmanager.api.TestRemoteLockManager.LockResponder;
16 import com.tc.object.lockmanager.impl.ClientLockManagerImpl;
17 import com.tc.object.session.SessionID;
18 import com.tc.object.session.SessionManager;
19 import com.tc.object.session.SessionProvider;
20 import com.tc.object.session.TestSessionManager;
21 import com.tc.object.tx.WaitInvocation;
22 import com.tc.util.concurrent.NoExceptionLinkedQueue;
23 import com.tc.util.concurrent.ThreadUtil;
24
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.LinkedList JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Set JavaDoc;
33
34 import junit.framework.TestCase;
35
36 /**
37  * @author steve
38  */

39 public class ClientLockManagerTest extends TestCase {
40   private ClientLockManager lockManager;
41
42   private TestRemoteLockManager rmtLockManager;
43
44   private TestSessionManager sessionManager;
45
46   protected void setUp() throws Exception JavaDoc {
47     super.setUp();
48     sessionManager = new TestSessionManager();
49     rmtLockManager = new TestRemoteLockManager(sessionManager);
50     lockManager = new ClientLockManagerImpl(new NullTCLogger(), rmtLockManager, sessionManager);
51     rmtLockManager.setClientLockManager(lockManager);
52   }
53
54   public void testNestedSynchronousWrite() {
55     final LockID lockID_1 = new LockID("1");
56     final LockID lockID_2 = new LockID("2");
57     final ThreadID threadID_1 = new ThreadID(1);
58     final ThreadID threadID_2 = new ThreadID(2);
59
60     rmtLockManager.resetFlushCount();
61
62     assertEquals(0, rmtLockManager.getFlushCount());
63     lockManager.lock(lockID_1, threadID_1, LockLevel.WRITE);
64     lockManager.lock(lockID_1, threadID_1, LockLevel.READ);
65     lockManager.lock(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE);
66     lockManager.lock(lockID_1, threadID_1, LockLevel.WRITE);
67     lockManager.lock(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE);
68     assertEquals(0, rmtLockManager.getFlushCount());
69     lockManager.unlock(lockID_1, threadID_1);
70     assertEquals(1, rmtLockManager.getFlushCount());
71     lockManager.unlock(lockID_1, threadID_1);
72     assertEquals(1, rmtLockManager.getFlushCount());
73     lockManager.unlock(lockID_1, threadID_1);
74     assertEquals(2, rmtLockManager.getFlushCount());
75     lockManager.unlock(lockID_1, threadID_1);
76     assertEquals(2, rmtLockManager.getFlushCount());
77     lockManager.unlock(lockID_1, threadID_1);
78     assertEquals(3, rmtLockManager.getFlushCount());
79
80     rmtLockManager.resetFlushCount();
81     rmtLockManager.makeLocksGreedy();
82
83     assertEquals(0, rmtLockManager.getFlushCount());
84     lockManager.lock(lockID_2, threadID_2, LockLevel.WRITE);
85     lockManager.lock(lockID_2, threadID_2, LockLevel.READ);
86     lockManager.lock(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE);
87     lockManager.lock(lockID_2, threadID_2, LockLevel.WRITE);
88     lockManager.lock(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE);
89     assertEquals(0, rmtLockManager.getFlushCount());
90     lockManager.unlock(lockID_2, threadID_2);
91     assertEquals(1, rmtLockManager.getFlushCount());
92     lockManager.unlock(lockID_2, threadID_2);
93     assertEquals(1, rmtLockManager.getFlushCount());
94     lockManager.unlock(lockID_2, threadID_2);
95     assertEquals(2, rmtLockManager.getFlushCount());
96     lockManager.unlock(lockID_2, threadID_2);
97     lockManager.unlock(lockID_2, threadID_2);
98     assertEquals(2, rmtLockManager.getFlushCount());
99     rmtLockManager.resetFlushCount();
100     rmtLockManager.makeLocksNotGreedy();
101   }
102
103   public void testSynchronousWriteUnlock() {
104     final LockID lockID_1 = new LockID("1");
105     final LockID lockID_2 = new LockID("2");
106     final ThreadID threadID_1 = new ThreadID(1);
107     final ThreadID threadID_2 = new ThreadID(2);
108
109     rmtLockManager.resetFlushCount();
110
111     assertEquals(0, rmtLockManager.getFlushCount());
112     lockManager.lock(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE);
113     assertEquals(0, rmtLockManager.getFlushCount());
114     lockManager.unlock(lockID_1, threadID_1);
115     assertEquals(1, rmtLockManager.getFlushCount());
116
117     rmtLockManager.makeLocksGreedy();
118
119     lockManager.lock(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE);
120     assertEquals(1, rmtLockManager.getFlushCount());
121     lockManager.unlock(lockID_2, threadID_2);
122     assertEquals(2, rmtLockManager.getFlushCount());
123
124     rmtLockManager.resetFlushCount();
125     rmtLockManager.makeLocksNotGreedy();
126   }
127
128   public void testSynchronousWriteWait() {
129
130     final LockID lockID_1 = new LockID("1");
131     final LockID lockID_2 = new LockID("2");
132     final ThreadID threadID_1 = new ThreadID(1);
133     final ThreadID threadID_2 = new ThreadID(2);
134
135     rmtLockManager.resetFlushCount();
136
137     assertEquals(0, rmtLockManager.getFlushCount());
138     lockManager.lock(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE);
139     assertEquals(0, rmtLockManager.getFlushCount());
140
141     WaitInvocation waitInvocation = new WaitInvocation();
142     NoExceptionLinkedQueue barrier = new NoExceptionLinkedQueue();
143     WaitLockRequest waitLockRequest = new WaitLockRequest(lockID_1, threadID_1, LockLevel.SYNCHRONOUS_WRITE,
144                                                           waitInvocation);
145     LockWaiter waiterThread = new LockWaiter(barrier, waitLockRequest, new Object JavaDoc());
146     waiterThread.start();
147     Object JavaDoc o = barrier.take();
148     assertNotNull(o);
149
150     assertEquals(1, rmtLockManager.getFlushCount());
151
152     rmtLockManager.makeLocksGreedy();
153
154     lockManager.lock(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE);
155     assertEquals(1, rmtLockManager.getFlushCount());
156
157     waitInvocation = new WaitInvocation();
158     waitLockRequest = new WaitLockRequest(lockID_2, threadID_2, LockLevel.SYNCHRONOUS_WRITE, waitInvocation);
159     waiterThread = new LockWaiter(barrier, waitLockRequest, new Object JavaDoc());
160     waiterThread.start();
161     o = barrier.take();
162     assertNotNull(o);
163
164     assertEquals(2, rmtLockManager.getFlushCount());
165
166     rmtLockManager.resetFlushCount();
167     rmtLockManager.makeLocksNotGreedy();
168   }
169
170   public void testTryLock() {
171     class TryLockRemoteLockManager extends TestRemoteLockManager {
172       private CyclicBarrier requestBarrier;
173       private CyclicBarrier awardBarrier;
174
175       public TryLockRemoteLockManager(SessionProvider sessionProvider, CyclicBarrier requestBarrier,
176                                       CyclicBarrier awardBarrier) {
177         super(sessionProvider);
178         this.requestBarrier = requestBarrier;
179         this.awardBarrier = awardBarrier;
180       }
181
182       public void tryRequestLock(LockID lockID, ThreadID threadID, int lockType) {
183         try {
184           requestBarrier.barrier();
185           awardBarrier.barrier();
186         } catch (BrokenBarrierException e) {
187           throw new TCRuntimeException(e);
188         } catch (InterruptedException JavaDoc e) {
189           throw new TCRuntimeException(e);
190         }
191       }
192     }
193
194     class TryLockClientLockManager extends ClientLockManagerImpl {
195       private CyclicBarrier awardBarrier;
196
197       public TryLockClientLockManager(TCLogger logger, RemoteLockManager remoteLockManager,
198                                       SessionManager sessionManager, CyclicBarrier awardBarrier) {
199         super(logger, remoteLockManager, sessionManager);
200         this.awardBarrier = awardBarrier;
201       }
202
203       public void awardLock(SessionID sessionID, LockID lockID, ThreadID threadID, int level) {
204         try {
205           awardBarrier.barrier();
206           super.awardLock(sessionID, lockID, threadID, level);
207         } catch (BrokenBarrierException e) {
208           throw new TCRuntimeException(e);
209         } catch (InterruptedException JavaDoc e) {
210           throw new TCRuntimeException(e);
211         }
212       }
213     }
214
215     final CyclicBarrier requestBarrier = new CyclicBarrier(2);
216     final CyclicBarrier awardBarrier = new CyclicBarrier(2);
217
218     rmtLockManager = new TryLockRemoteLockManager(sessionManager, requestBarrier, awardBarrier);
219     lockManager = new TryLockClientLockManager(new NullTCLogger(), rmtLockManager, sessionManager, awardBarrier);
220
221     final LockID lockID1 = new LockID("1");
222     final ThreadID txID = new ThreadID(1);
223
224     Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
225       public void run() {
226         try {
227           requestBarrier.barrier();
228           lockManager.awardLock(sessionManager.getSessionID(), lockID1, ThreadID.VM_ID, LockLevel
229               .makeGreedy(LockLevel.WRITE));
230         } catch (BrokenBarrierException e) {
231           throw new TCRuntimeException(e);
232         } catch (InterruptedException JavaDoc e) {
233           throw new TCRuntimeException(e);
234         }
235       }
236     });
237     t1.start();
238
239     lockManager.tryLock(lockID1, txID, LockLevel.WRITE);
240
241   }
242
243   public void testGreedyLockRequest() {
244     final LockID lockID1 = new LockID("1");
245     final ThreadID tx1 = new ThreadID(1);
246     final ThreadID tx2 = new ThreadID(2);
247     final NoExceptionLinkedQueue queue = new NoExceptionLinkedQueue();
248
249     rmtLockManager.lockResponder = new LockResponder() {
250
251       public void respondToLockRequest(LockRequest request) {
252         queue.put(request);
253         lockManager.awardLock(sessionManager.getSessionID(), request.lockID(), ThreadID.VM_ID, LockLevel
254             .makeGreedy(request.lockLevel()));
255       }
256     };
257
258     lockManager.lock(lockID1, tx1, LockLevel.WRITE); // Goes to RemoteLockManager
259

260     LockRequest request = (LockRequest) queue.poll(1000l);
261     assertNotNull(request);
262     assertEquals(tx1, request.threadID());
263     assertEquals(lockID1, request.lockID());
264     assertEquals(LockLevel.WRITE, request.lockLevel());
265
266     // None of these should end up in RemoteLockManager
267
lockManager.lock(lockID1, tx1, LockLevel.READ);
268     lockManager.unlock(lockID1, tx1);
269     lockManager.unlock(lockID1, tx1);
270     lockManager.lock(lockID1, tx1, LockLevel.READ);
271     lockManager.lock(lockID1, tx2, LockLevel.READ);
272
273     assertNull(queue.poll(1000l));
274   }
275
276   public void testNotified() throws Exception JavaDoc {
277     final LockID lockID1 = new LockID("1");
278     final LockID lockID2 = new LockID("2");
279     final ThreadID tx1 = new ThreadID(1);
280     final ThreadID tx2 = new ThreadID(2);
281     final Set JavaDoc heldLocks = new HashSet JavaDoc();
282     final Set JavaDoc waiters = new HashSet JavaDoc();
283
284     heldLocks.add(new LockRequest(lockID1, tx1, LockLevel.WRITE));
285     lockManager.lock(lockID1, tx1, LockLevel.WRITE);
286     assertNotNull(rmtLockManager.lockRequestCalls.poll(1));
287
288     NoExceptionLinkedQueue barrier = new NoExceptionLinkedQueue();
289     WaitInvocation waitInvocation = new WaitInvocation();
290
291     // In order to wait on a lock, we must first request and be granted the
292
// write lock. The TestRemoteLockManager
293
// takes care of awarding the lock when we ask for it.
294
//
295
// We don't add this lock request to the set of held locks because the
296
// call to wait moves it to being not
297
// held anymore.
298
lockManager.lock(lockID2, tx2, LockLevel.WRITE);
299     assertNotNull(rmtLockManager.lockRequestCalls.poll(1));
300
301     WaitLockRequest waitLockRequest = new WaitLockRequest(lockID2, tx2, LockLevel.WRITE, waitInvocation);
302     waiters.add(waitLockRequest);
303     final LockWaiter waiterThread = new LockWaiter(barrier, waitLockRequest, new Object JavaDoc());
304     waiterThread.start();
305
306     barrier.take();
307     assertTrue(barrier.isEmpty());
308     if (!waiterThread.exceptions.isEmpty()) {
309       for (Iterator JavaDoc i = waiterThread.exceptions.iterator(); i.hasNext();) {
310         ((Throwable JavaDoc) i.next()).printStackTrace();
311       }
312       fail("Waiter thread had exceptions!");
313     }
314
315     // pause the lock manager in preparation for pulling interrogating the
316
// state...
317
pauseAndStart();
318
319     Set JavaDoc s = new HashSet JavaDoc();
320     lockManager.addAllHeldLocksTo(s);
321     assertEquals(heldLocks, s);
322
323     s.clear();
324     lockManager.addAllWaitersTo(s);
325     assertEquals(waiters, s);
326     s.clear();
327
328     lockManager.addAllPendingLockRequestsTo(s);
329     assertTrue(s.size() == 0);
330
331     // Make sure there are no pending lock requests
332
rmtLockManager.lockResponder = rmtLockManager.NULL_LOCK_RESPONDER;
333     assertTrue(rmtLockManager.lockRequestCalls.isEmpty());
334
335     lockManager.unpause();
336
337     // now call notified() and make sure that the appropriate waits become
338
// pending requests
339
lockManager.notified(waitLockRequest.lockID(), waitLockRequest.threadID());
340
341     pauseAndStart();
342     // The held locks should be the same
343
s.clear();
344     lockManager.addAllHeldLocksTo(s);
345     assertEquals(heldLocks, s);
346
347     // the lock waits should be empty
348
s.clear();
349     lockManager.addAllWaitersTo(s);
350     assertEquals(Collections.EMPTY_SET, s);
351
352     lockManager.addAllPendingLockRequestsTo(s);
353     assertTrue(s.size() == 1);
354     LockRequest lr = (LockRequest) s.iterator().next();
355     assertNotNull(lr);
356     assertEquals(waitLockRequest.lockID(), lr.lockID());
357     assertEquals(waitLockRequest.threadID(), lr.threadID());
358     assertTrue(waitLockRequest.lockLevel() == lr.lockLevel());
359
360     lockManager.unpause();
361
362     // now make sure that if you award the lock, the right stuff happens
363
lockManager.awardLock(sessionManager.getSessionID(), waitLockRequest.lockID(), waitLockRequest.threadID(),
364                           waitLockRequest.lockLevel());
365     heldLocks.add(waitLockRequest);
366
367     pauseAndStart();
368     // the held locks should contain the newly awarded, previously notified
369
// lock.
370
s.clear();
371     lockManager.addAllHeldLocksTo(s);
372     assertEquals(heldLocks, s);
373
374     // there should still be no waiters
375
s.clear();
376     lockManager.addAllWaitersTo(s);
377     assertEquals(Collections.EMPTY_SET, s);
378
379     // the lock should have been awarded and no longer pending
380
assertTrue(rmtLockManager.lockRequestCalls.isEmpty());
381     lockManager.addAllPendingLockRequestsTo(null);
382     assertTrue(rmtLockManager.lockRequestCalls.isEmpty());
383   }
384
385   public void testAddAllOutstandingLocksTo() throws Exception JavaDoc {
386
387     // XXX: The current TestRemoteLockManager doesn't handle multiple
388
// read-locks by different transactions properly,
389
// so this test doesn't test that case.
390
final LockID lockID = new LockID("my lock");
391     final ThreadID tx1 = new ThreadID(1);
392     final int writeLockLevel = LockLevel.WRITE;
393
394     final LockID readLock = new LockID("my read lock");
395     final ThreadID tx2 = new ThreadID(2);
396     final int readLockLevel = LockLevel.READ;
397
398     // final LockID synchWriteLock = new LockID("my synch write lock");
399
// final ThreadID tx3 = new ThreadID(3);
400
// final int synchWriteLockLevel = LockLevel.SYNCHRONOUS_WRITE;
401

402     Set JavaDoc lockRequests = new HashSet JavaDoc();
403     lockRequests.add(new LockRequest(lockID, tx1, writeLockLevel));
404     lockRequests.add(new LockRequest(readLock, tx2, readLockLevel));
405     // lockRequests.add(new LockRequest(synchWriteLock, tx3, synchWriteLockLevel));
406

407     lockManager.lock(lockID, tx1, writeLockLevel);
408     lockManager.lock(readLock, tx2, readLockLevel);
409     // lockManager.lock(synchWriteLock, tx3, synchWriteLockLevel);
410

411     Set JavaDoc s = new HashSet JavaDoc();
412     try {
413       lockManager.addAllHeldLocksTo(s);
414       fail("Expected an assertion error.");
415     } catch (AssertionError JavaDoc e) {
416       // expected
417
}
418
419     pauseAndStart();
420     lockManager.addAllHeldLocksTo(s);
421     assertEquals(lockRequests.size(), s.size());
422     assertEquals(lockRequests, s);
423
424     lockManager.unpause();
425     lockManager.unlock(lockID, tx1);
426     lockManager.unlock(readLock, tx2);
427     // lockManager.unlock(synchWriteLock, tx3);
428
pauseAndStart();
429     assertEquals(0, lockManager.addAllHeldLocksTo(new HashSet JavaDoc()).size());
430   }
431
432   public void testAddAllOutstandingWaitersTo() throws Exception JavaDoc {
433     final LockID lockID = new LockID("my lock");
434     final ThreadID tx1 = new ThreadID(1);
435     final WaitInvocation waitInvocation = new WaitInvocation();
436     final Object JavaDoc waitObject = new Object JavaDoc();
437     final NoExceptionLinkedQueue barrier = new NoExceptionLinkedQueue();
438     lockManager.lock(lockID, tx1, LockLevel.WRITE);
439     Thread JavaDoc t = new LockWaiter(barrier, lockID, tx1, waitInvocation, waitObject);
440     t.start();
441     barrier.take();
442     ThreadUtil.reallySleep(200);
443
444     Set JavaDoc s = new HashSet JavaDoc();
445     try {
446       lockManager.addAllWaitersTo(s);
447       fail("Expected an assertion error.");
448     } catch (AssertionError JavaDoc e) {
449       // expected
450
}
451
452     pauseAndStart();
453     lockManager.addAllWaitersTo(s);
454     List JavaDoc waiters = new LinkedList JavaDoc(s);
455     assertEquals(1, waiters.size());
456     WaitLockRequest waitRequest = (WaitLockRequest) waiters.get(0);
457     assertEquals(lockID, waitRequest.lockID());
458     assertEquals(tx1, waitRequest.threadID());
459     assertEquals(waitInvocation, waitRequest.getWaitInvocation());
460
461     // The lock this waiter was in when wait was called should no longer be
462
// outstanding.
463
assertEquals(0, lockManager.addAllHeldLocksTo(new HashSet JavaDoc()).size());
464   }
465
466   public void testPauseBlocks() throws Exception JavaDoc {
467     final LinkedQueue flowControl = new LinkedQueue();
468     final LinkedQueue lockComplete = new LinkedQueue();
469     final LinkedQueue unlockComplete = new LinkedQueue();
470     final LockID lockID = new LockID("1");
471     final ThreadID txID = new ThreadID(1);
472     final int lockType = LockLevel.WRITE;
473
474     Thread JavaDoc locker = new Thread JavaDoc("LOCKER") {
475       public void run() {
476         try {
477           flowControl.put("locker: Calling lock");
478           lockManager.lock(lockID, txID, lockType);
479           lockComplete.put("locker: lock complete.");
480
481           // wait until I'm allowed to unlock...
482
System.out.println(flowControl.take());
483           lockManager.unlock(lockID, txID);
484           unlockComplete.put("locker: unlock complete.");
485
486           // wait until I'm allowed to call lock() again
487
System.out.println(flowControl.take());
488           rmtLockManager.lockResponder = rmtLockManager.NULL_LOCK_RESPONDER;
489           lockManager.lock(lockID, txID, lockType);
490           System.out.println("locker: Done calling lock again");
491
492         } catch (Throwable JavaDoc e) {
493           e.printStackTrace();
494           fail();
495         }
496       }
497     };
498
499     assertFalse(lockManager.isStarting());
500     pauseAndStart();
501     locker.start();
502
503     // wait until the locker has a chance to start up...
504
System.out.println(flowControl.take());
505
506     ThreadUtil.reallySleep(500);
507
508     // make sure it hasn't returned from the lock call.
509
assertTrue(lockComplete.peek() == null);
510     // unpause...
511
assertTrue(lockManager.isStarting());
512     lockManager.unpause();
513     assertFalse(lockManager.isStarting());
514     // make sure the call to lock(..) completes
515
System.out.println(lockComplete.take());
516     System.out.println("Done testing lock(..)");
517
518     // now pause again and allow the locker to call unlock...
519
pauseAndStart();
520     flowControl.put("test: lock manager paused, it's ok for locker to call unlock(..)");
521     ThreadUtil.reallySleep(500);
522     assertTrue(unlockComplete.peek() == null);
523     // now unpause and make sure the locker returns from unlock(..)
524
lockManager.unpause();
525     unlockComplete.take();
526     System.out.println("Done testing unlock(..)");
527
528     // TODO: test awardLock() and the other public methods I didn't have
529
// time to
530
// test...
531
}
532
533   public void testResendBasics() throws Exception JavaDoc {
534     final List JavaDoc requests = new ArrayList JavaDoc();
535     final LinkedQueue flowControl = new LinkedQueue();
536     final SynchronizedBoolean respond = new SynchronizedBoolean(true);
537     rmtLockManager.lockResponder = new LockResponder() {
538       public void respondToLockRequest(final LockRequest request) {
539         new Thread JavaDoc() {
540           public void run() {
541             requests.add(request);
542             if (respond.get()) {
543               lockManager.awardLock(sessionManager.getSessionID(), request.lockID(), request.threadID(), request
544                   .lockLevel());
545             }
546             try {
547               flowControl.put("responder: respondToLockRequest complete. Lock awarded: " + respond.get());
548             } catch (InterruptedException JavaDoc e) {
549               e.printStackTrace();
550               fail();
551             }
552           }
553         }.start();
554       }
555     };
556
557     final ThreadID tid0 = new ThreadID(0);
558     final ThreadID tid1 = new ThreadID(1);
559     final LockID lid0 = new LockID("0");
560     final LockID lid1 = new LockID("1");
561
562     LockRequest lr0 = new LockRequest(lid0, tid0, LockLevel.WRITE);
563     LockRequest lr1 = new LockRequest(lid1, tid1, LockLevel.WRITE);
564
565     // request a lock that gets a response
566
Thread JavaDoc t = new LockGetter(lid0, tid0, LockLevel.WRITE);
567     t.start();
568     // wait until the lock responder finishes...
569
System.out.println(flowControl.take());
570     assertEquals(1, requests.size());
571     assertEquals(lr0, requests.get(0));
572
573     // now request a lock that doesn't get a response.
574
requests.clear();
575     respond.set(false);
576
577     t = new LockGetter(lid1, tid1, LockLevel.WRITE);
578     t.start();
579     System.out.println(flowControl.take());
580
581     assertEquals(1, requests.size());
582     assertEquals(lr1, requests.get(0));
583
584     // resend outstanding lock requests and respond to them.
585
requests.clear();
586     respond.set(true);
587     pauseAndStart();
588     lockManager.addAllPendingLockRequestsTo(requests);
589     lockManager.unpause();
590     assertEquals(1, requests.size());
591     assertEquals(lr1, requests.get(0));
592
593     // there should be no outstanding lock requests.
594
// calling requestOutstanding() should cause no lock requests.
595

596     requests.clear();
597     rmtLockManager.lockResponder = rmtLockManager.LOOPBACK_LOCK_RESPONDER;
598
599   }
600
601   public void testAwardWhenNotPending() throws Exception JavaDoc {
602     LockID lockID = new LockID("1");
603     ThreadID txID = new ThreadID(1);
604     try {
605       lockManager.awardLock(sessionManager.getSessionID(), lockID, txID, LockLevel.WRITE);
606       fail("Should have thrown an error");
607     } catch (AssertionError JavaDoc e) {
608       // expected
609
}
610   }
611
612   public void testBasics() throws Exception JavaDoc {
613     final ThreadID tid0 = new ThreadID(0);
614     final LockID lid0 = new LockID("0");
615
616     final ThreadID tid1 = new ThreadID(1);
617
618     System.out.println("Get lock0 for tx0");
619     lockManager.lock(lid0, tid0, LockLevel.WRITE);
620     System.out.println("Got lock0 for tx0");
621     lockManager.lock(lid0, tid0, LockLevel.WRITE);
622     System.out.println("Got lock0 for tx0 AGAIN so the recursion lock is correct");
623     final boolean[] done = new boolean[1];
624     done[0] = false;
625     Thread JavaDoc t = new Thread JavaDoc() {
626       public void run() {
627         lockManager.lock(lid0, tid1, LockLevel.WRITE);
628         System.out.println("Got lock0 for tx1");
629         done[0] = true;
630       }
631     };
632     t.start();
633     ThreadUtil.reallySleep(500);
634     assertFalse(done[0]);
635     lockManager.unlock(lid0, tid0);
636     ThreadUtil.reallySleep(500);
637     assertFalse(done[0]);
638     lockManager.unlock(lid0, tid0);
639     ThreadUtil.reallySleep(500);
640     assertTrue(done[0]);
641   }
642
643   public void testBasicUnlock() throws Exception JavaDoc {
644     assertEquals(0, rmtLockManager.getLockRequestCount());
645     assertEquals(0, rmtLockManager.getUnlockRequestCount());
646     ThreadID tid0 = new ThreadID(0);
647     LockID lid0 = new LockID("0");
648
649     lockManager.lock(lid0, tid0, LockLevel.READ);
650     assertEquals(1, rmtLockManager.getLockRequestCount());
651     assertEquals(0, rmtLockManager.getUnlockRequestCount());
652
653     lockManager.unlock(lid0, tid0);
654     assertEquals(1, rmtLockManager.getLockRequestCount());
655     assertEquals(1, rmtLockManager.getUnlockRequestCount());
656
657     lockManager.lock(lid0, tid0, LockLevel.WRITE);
658     assertEquals(2, rmtLockManager.getLockRequestCount());
659     assertEquals(1, rmtLockManager.getUnlockRequestCount());
660
661     lockManager.unlock(lid0, tid0);
662     assertEquals(2, rmtLockManager.getLockRequestCount());
663     assertEquals(2, rmtLockManager.getUnlockRequestCount());
664   }
665
666   public void testLockChangesAfterUpgrade() throws Exception JavaDoc {
667     assertEquals(0, rmtLockManager.getLockRequestCount());
668     ThreadID tid0 = new ThreadID(0);
669     LockID lid0 = new LockID("0");
670
671     lockManager.lock(lid0, tid0, LockLevel.READ);
672     assertEquals(1, rmtLockManager.getLockRequestCount());
673
674     // upgrade lock
675
lockManager.lock(lid0, tid0, LockLevel.WRITE);
676     assertEquals(2, rmtLockManager.getLockRequestCount());
677
678     // get more locks (should see no requests to L2)
679
lockManager.lock(lid0, tid0, LockLevel.WRITE);
680     assertEquals(2, rmtLockManager.getLockRequestCount());
681     lockManager.lock(lid0, tid0, LockLevel.READ);
682     assertEquals(2, rmtLockManager.getLockRequestCount());
683   }
684
685   public void testLockUpgradeMakesRemoteRequest() throws Exception JavaDoc {
686     assertEquals(0, rmtLockManager.getLockRequestCount());
687     ThreadID tid0 = new ThreadID(0);
688     LockID lid0 = new LockID("0");
689
690     lockManager.lock(lid0, tid0, LockLevel.READ);
691     assertEquals(1, rmtLockManager.getLockRequestCount());
692
693     // upgrade lock
694
lockManager.lock(lid0, tid0, LockLevel.WRITE);
695     assertEquals(2, rmtLockManager.getLockRequestCount());
696   }
697
698   public void testNestedReadLocksGrantsLocally() throws Exception JavaDoc {
699     assertEquals(0, rmtLockManager.getLockRequestCount());
700     ThreadID tid0 = new ThreadID(0);
701     LockID lid0 = new LockID("0");
702
703     lockManager.lock(lid0, tid0, LockLevel.READ);
704     assertEquals(1, rmtLockManager.getLockRequestCount());
705
706     final int count = 25;
707
708     for (int i = 0; i < count; i++) {
709       // get nested read locks
710
lockManager.lock(lid0, tid0, LockLevel.READ);
711       assertEquals(1, rmtLockManager.getLockRequestCount());
712     }
713
714     for (int i = 0; i < count; i++) {
715       lockManager.unlock(lid0, tid0);
716       assertEquals(1, rmtLockManager.getLockRequestCount());
717       assertEquals(0, rmtLockManager.getUnlockRequestCount());
718     }
719
720     lockManager.unlock(lid0, tid0);
721     assertEquals(1, rmtLockManager.getLockRequestCount());
722     assertEquals(1, rmtLockManager.getUnlockRequestCount());
723   }
724
725   public void testUnlockAfterDowngrade() throws Exception JavaDoc {
726     assertEquals(0, rmtLockManager.getLockRequestCount());
727     assertEquals(0, rmtLockManager.getUnlockRequestCount());
728     ThreadID tid0 = new ThreadID(0);
729     LockID lid0 = new LockID("0");
730
731     lockManager.lock(lid0, tid0, LockLevel.WRITE);
732     assertEquals(1, rmtLockManager.getLockRequestCount());
733     assertEquals(0, rmtLockManager.getUnlockRequestCount());
734
735     // downgrade lock
736
lockManager.lock(lid0, tid0, LockLevel.READ);
737     assertEquals(1, rmtLockManager.getLockRequestCount());
738     assertEquals(0, rmtLockManager.getUnlockRequestCount());
739
740     lockManager.unlock(lid0, tid0);
741     assertEquals(1, rmtLockManager.getLockRequestCount());
742     assertEquals(0, rmtLockManager.getUnlockRequestCount());
743
744     lockManager.unlock(lid0, tid0);
745     assertEquals(1, rmtLockManager.getLockRequestCount());
746     assertEquals(1, rmtLockManager.getUnlockRequestCount());
747   }
748
749   private void pauseAndStart() {
750     lockManager.pause();
751     lockManager.starting();
752   }
753
754   public static void main(String JavaDoc[] args) {
755     //
756
}
757
758   public class LockWaiter extends Thread JavaDoc implements WaitListener {
759     private final LockID lid;
760
761     private final ThreadID tid;
762
763     private final WaitInvocation call;
764
765     private final NoExceptionLinkedQueue preWaitSignalQueue;
766
767     private final Object JavaDoc waitObject;
768
769     private final List JavaDoc exceptions = new LinkedList JavaDoc();
770
771     private LockWaiter(NoExceptionLinkedQueue preWaitSignalQueue, WaitLockRequest request, Object JavaDoc waitObject) {
772       this(preWaitSignalQueue, request.lockID(), request.threadID(), request.getWaitInvocation(), waitObject);
773     }
774
775     private LockWaiter(NoExceptionLinkedQueue preWaitSignalQueue, LockID lid, ThreadID threadID, WaitInvocation call,
776                        Object JavaDoc waitObject) {
777       this.preWaitSignalQueue = preWaitSignalQueue;
778       this.lid = lid;
779       this.tid = threadID;
780       this.waitObject = waitObject;
781       this.call = call;
782     }
783
784     public void run() {
785       try {
786         lockManager.wait(lid, tid, call, waitObject, this);
787       } catch (Throwable JavaDoc t) {
788         exceptions.add(t);
789       }
790     }
791
792     public void handleWaitEvent() {
793       preWaitSignalQueue.put(new Object JavaDoc());
794     }
795
796     public Collection JavaDoc getExceptions() {
797       return this.exceptions;
798     }
799   }
800
801   private class LockGetter extends Thread JavaDoc {
802     LockID lid;
803     ThreadID tid;
804     int lockType;
805
806     private LockGetter(LockID lid, ThreadID tid, int lockType) {
807       this.lid = lid;
808       this.tid = tid;
809       this.lockType = lockType;
810     }
811
812     public void run() {
813       lockManager.lock(lid, tid, lockType);
814     }
815   }
816 }
817
Popular Tags