KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > perseus > concurrency > TestPessimistic


1 /**
2  * Copyright (C) 2001-2002
3  * - France Telecom R&D
4  * - Laboratoire Logiciels, Systemes, Reseaux - UMR 5526, CNRS-INPG-UJF
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * Release: 1.0
21  *
22  * Authors:
23  *
24  */

25
26 package org.objectweb.perseus.concurrency;
27
28 import junit.framework.TestCase;
29 import org.objectweb.perseus.persistence.PInteger;
30 import org.objectweb.perseus.persistence.TPMTest;
31 import org.objectweb.perseus.persistence.PIntegerState;
32 import org.objectweb.perseus.cache.api.CacheEntry;
33 import org.objectweb.perseus.cache.replacement.lib.LRUReplacementManager;
34 import org.objectweb.perseus.concurrency.api.ConcurrencyException;
35 import org.objectweb.perseus.persistence.api.PersistenceException;
36 import org.objectweb.perseus.persistence.api.TransactionalWorkingSet;
37 import org.objectweb.perseus.persistence.api.WorkingSet;
38 import org.objectweb.perseus.persistence.concurrency.PPessimisticConcurrencyManager;
39
40 public class TestPessimistic extends TestCase {
41
42
43     PInteger o1, o2;
44     CacheEntry ce1, ce2;
45     TransactionalWorkingSet ctxt1, ctxt2, ctxt3;
46     Object JavaDoc oid1, oid2;
47
48     TPMTest tpm;
49
50
51
52     public TestPessimistic(String JavaDoc s) {
53         super(s);
54     }
55
56     protected void setUp() throws Exception JavaDoc {
57
58         tpm = new TPMTest("TPM", new PPessimisticConcurrencyManager(), new LRUReplacementManager());
59         ctxt1 = (TransactionalWorkingSet) tpm.createWS("1");
60         ctxt2 = (TransactionalWorkingSet) tpm.createWS("2");
61         ctxt3 = (TransactionalWorkingSet) tpm.createWS("3");
62         o1 = new PInteger(1);
63         o2 = new PInteger(2);
64
65         tpm.begin(ctxt1);
66         oid1 = tpm.export(ctxt1, o1);
67         oid2 = tpm.export(ctxt1, o2);
68         tpm.prepare(ctxt1);
69         tpm.commit(ctxt1);
70     }
71
72     // single context, single object, single read access
73
public void test1 () throws ConcurrencyException, PersistenceException {
74         tpm.begin(ctxt1);
75         tpm.readIntention(ctxt1, oid1);
76         assertTrue(tpm.prepare(ctxt1));
77         tpm.commit(ctxt1);
78     }
79
80     // single context, single object, single write access
81
public void test2 () throws ConcurrencyException, PersistenceException {
82         tpm.begin(ctxt1);
83         tpm.readIntention(ctxt1, oid1);
84         tpm.writeIntention(ctxt1, oid1);
85         assertTrue(tpm.prepare(ctxt1));
86         tpm.commit(ctxt1);
87     }
88
89     // two contexts, single object, simultaneous read accesses
90
public void test3 () throws ConcurrencyException, PersistenceException {
91         tpm.begin(ctxt1);
92         tpm.begin(ctxt2);
93         tpm.readIntention(ctxt1, oid1);
94         tpm.readIntention(ctxt2, oid1);
95         assertTrue(tpm.prepare(ctxt1));
96         assertTrue(tpm.prepare(ctxt2));
97         tpm.commit(ctxt1);
98         tpm.commit(ctxt2);
99     }
100
101     // two contexts, single object, one read access, one write access
102
public void test4 () throws ConcurrencyException, PersistenceException {
103         tpm.begin(ctxt1);
104         tpm.begin(ctxt2);
105         tpm.readIntention(ctxt1, oid1);
106         tpm.readIntention(ctxt2, oid1);
107         Thread JavaDoc t = assertLock(new Runnable JavaDoc () {
108             public void run () {
109                 try {
110                     tpm.writeIntention(ctxt2, oid1);
111                 } catch (PersistenceException e) {
112                     e.printStackTrace();
113                 }
114             }
115         });
116         assertTrue(tpm.prepare(ctxt1));
117         tpm.commit(ctxt1);
118         assertUnlock(t);
119         assertTrue(tpm.prepare(ctxt2));
120         tpm.commit(ctxt2);
121     }
122
123     // two contexts, single object, one write access, one read access
124
public void test5 () throws ConcurrencyException, PersistenceException {
125         tpm.begin(ctxt1);
126         tpm.begin(ctxt2);
127         tpm.readIntention(ctxt1, oid1);
128         tpm.writeIntention(ctxt1, oid1);
129         Thread JavaDoc t = assertLock(new Runnable JavaDoc () {
130             public void run () {
131                 try {
132                     tpm.readIntention(ctxt2, oid1);
133                 } catch (PersistenceException e) {
134                     e.printStackTrace();
135                 }
136             }
137         });
138         assertTrue(tpm.prepare(ctxt1));
139         tpm.commit(ctxt1);
140         assertUnlock(t);
141         assertTrue(tpm.prepare(ctxt2));
142         tpm.commit(ctxt2);
143     }
144
145     // two contexts, single object, simultaneous write access
146
public void test6 () throws ConcurrencyException, PersistenceException {
147         tpm.begin(ctxt1);
148         tpm.begin(ctxt2);
149         tpm.readIntention(ctxt1, oid1);
150         tpm.writeIntention(ctxt1, oid1);
151         Thread JavaDoc t = assertLock(new Runnable JavaDoc () {
152             public void run () {
153                 try {
154                     tpm.readIntention(ctxt2, oid1);
155                     tpm.writeIntention(ctxt2, oid1);
156                 } catch (PersistenceException e) {
157                     e.printStackTrace();
158                 }
159              }
160         });
161         assertTrue(tpm.prepare(ctxt1));
162         tpm.commit(ctxt1);
163         assertUnlock(t);
164         assertTrue(tpm.prepare(ctxt2));
165         tpm.commit(ctxt2);
166     }
167
168     // two contexts, two objects, each context writes its own object (no conflicts)
169
public void test7 () throws ConcurrencyException, PersistenceException {
170         tpm.begin(ctxt1);
171         tpm.begin(ctxt2);
172         tpm.readIntention(ctxt1, oid1);
173         tpm.writeIntention(ctxt1, oid1);
174         tpm.readIntention(ctxt2, oid2);
175         tpm.writeIntention(ctxt2, oid2);
176         assertTrue(tpm.prepare(ctxt1));
177         assertTrue(tpm.prepare(ctxt2));
178         tpm.commit(ctxt1);
179         tpm.commit(ctxt2);
180     }
181
182     // two contexts, two objects
183
// T1 read O1, T2 read O1, T1 write O2, T2 write O2
184
public void test8 () throws ConcurrencyException, PersistenceException {
185         tpm.begin(ctxt1);
186         tpm.begin(ctxt2);
187         tpm.readIntention(ctxt1, oid1);
188         tpm.readIntention(ctxt2, oid1);
189         tpm.readIntention(ctxt1, oid2);
190         tpm.writeIntention(ctxt1, oid2);
191         Thread JavaDoc t = assertLock(new Runnable JavaDoc () {
192             public void run () {
193                 try {
194                     tpm.readIntention(ctxt2, oid2);
195                     tpm.writeIntention(ctxt2, oid2);
196                 } catch (PersistenceException e) {
197                     e.printStackTrace();
198                 }
199              }
200         });
201         assertTrue(tpm.prepare(ctxt1));
202         tpm.commit(ctxt1);
203         assertUnlock(t);
204         assertTrue(tpm.prepare(ctxt2));
205         tpm.commit(ctxt2);
206     }
207
208     // two contexts, two objects
209
// T1 read O1, T2 read O2, T1 write O2, T2 write O1 -> deadlock
210
public void test9 () throws ConcurrencyException, PersistenceException {
211         tpm.begin(ctxt1);
212         tpm.begin(ctxt2);
213         tpm.readIntention(ctxt1, oid1);
214         tpm.readIntention(ctxt2, oid2);
215         Thread JavaDoc t = assertLock(new Runnable JavaDoc () {
216             public void run () {
217                 try {
218                     tpm.readIntention(ctxt1, oid2);
219                     tpm.writeIntention(ctxt1, oid2);
220                 } catch (PersistenceException e) {
221                     e.printStackTrace();
222                 }
223              }
224         });
225         try {
226             tpm.readIntention(ctxt2, oid1);
227             tpm.writeIntention(ctxt2, oid1);
228             fail();
229         } catch (PersistenceException _) {
230         }
231         assertTrue(!tpm.prepare(ctxt2));
232         tpm.rollback(ctxt2);
233
234         assertUnlock(t);
235         assertTrue(tpm.prepare(ctxt1));
236         tpm.commit(ctxt1);
237     }
238
239     // asserts that the given action suspends the thread on a lock
240
private Thread JavaDoc assertLock (Runnable JavaDoc r) {
241         Thread JavaDoc t = new Thread JavaDoc(r);
242         t.start();
243         try {
244             t.join(500);
245         } catch (InterruptedException JavaDoc _) {
246             // ignored
247
}
248         assertTrue("thread should be blocked", t.isAlive());
249         return t;
250     }
251
252     // asserts that the given thread has been unlocked
253
private void assertUnlock (Thread JavaDoc t) {
254         try {
255             t.join(500);
256         } catch (InterruptedException JavaDoc _) {
257             // ignored
258
}
259         assertTrue("thread should not be blocked", ! t.isAlive());
260     }
261
262
263
264 // attempt to use closed contexts
265
public void test10 () throws ConcurrencyException, PersistenceException {
266
267         ctxt1.setStatus(WorkingSet.CTX_CLOSED);
268         /* try to lock prior to opening context */
269         try {
270             tpm.readIntention(ctxt1, oid1);
271             fail("can lock within not open context");
272         } catch (PersistenceException _) {
273         }
274         try {
275             tpm.writeIntention(ctxt1, oid1);
276             fail("can lock within not open context");
277         } catch (PersistenceException _) {
278         }
279         try {
280             tpm.begin(ctxt1);
281             fail("can begin tx with closed WS");
282         } catch (PersistenceException _) {
283         }
284         try {
285             tpm.prepare(ctxt1);
286             fail("can prepare tx with closed WS");
287         } catch (PersistenceException _) {
288         }
289         try {
290             tpm.commit(ctxt1);
291             fail("can commit tx with closed WS");
292         } catch (PersistenceException _) {
293         }
294         try {
295             tpm.rollback(ctxt1);
296             fail("can rollback tx with closed WS");
297         } catch (PersistenceException _) {
298         }
299     }
300
301
302     // verifies that locks are released properly. 2 threads are waiting for a lock (one in read mode,
303
// the other in write mode), then their relative contexts are closed.
304
// Verifies that when waken up, the threads have gave up their tries and have died.
305
// Finally, checks that a new transaction can be granted the lock without waiting.
306

307     public void test11 () throws ConcurrencyException, PersistenceException {
308
309         tpm.begin(ctxt1);
310         tpm.begin(ctxt2);
311         tpm.begin(ctxt3);
312
313         /* t1 write-locks oid1 */
314         tpm.writeIntention(ctxt1, oid1);
315
316         /* t2 blocks in new thread while read-locking oid1 */
317         Thread JavaDoc t2 = assertLock(new Runnable JavaDoc () {
318             public void run () {
319                 try {
320                     tpm.readIntention(ctxt2, oid1);
321                 } catch (PersistenceException e) {
322                 }
323             }
324         });
325
326         /* t3 blocks in new thread while write-locking oid1 */
327         Thread JavaDoc t3 = assertLock(new Runnable JavaDoc () {
328             public void run () {
329                 try {
330                     tpm.writeIntention(ctxt3, oid1);
331                 } catch (PersistenceException e) {
332                 }
333             }
334         });
335
336
337         /* aborts t2 & t3 while they are waiting for a lock */
338         tpm.prepare(ctxt2);
339         tpm.rollback(ctxt2);
340         tpm.prepare(ctxt3);
341         tpm.rollback(ctxt3);
342
343         /* checks threads are finished */
344         assertUnlock(t2);
345         assertUnlock(t3);
346
347         /* validates t1 */
348         assertTrue(tpm.prepare(ctxt1));
349         tpm.commit(ctxt1);
350
351         /* checks that new Xact will not block while locking oid1 */
352         tpm.begin(ctxt1);
353         Thread JavaDoc t4 = new Thread JavaDoc(new Runnable JavaDoc () {
354             public void run () {
355                 try {
356                     tpm.readIntention(ctxt1, oid1);
357                 } catch (PersistenceException e) {
358                     e.printStackTrace();
359                 }
360             }
361         });
362         t4.start();
363         assertUnlock(t4);
364
365         assertTrue(tpm.prepare(ctxt1));
366         tpm.commit(ctxt1);
367     }
368
369     public void test12() throws PersistenceException {
370         boolean deadlocked = false;
371
372         tpm.begin(ctxt1);
373         tpm.begin(ctxt2);
374         Thread JavaDoc t = new Thread JavaDoc(new Runnable JavaDoc () {
375             public void run () {
376                 try {
377                     tpm.readIntention(ctxt2, oid1);
378                     tpm.writeIntention(ctxt2, oid1);
379                 } catch (PersistenceException e) {
380                     return;
381                 }
382             }
383         });
384
385         PIntegerState s1, s2 ;
386         s2 = (PIntegerState) tpm.readIntention(ctxt1, oid2);
387         s2 = (PIntegerState) tpm.writeIntention(ctxt1, s2.getCacheEntry());
388         s2.i = -1;
389
390         s1 = (PIntegerState) tpm.readIntention(ctxt1, oid1);
391         t.start();
392         try {
393             Thread.sleep(1000);
394         } catch (InterruptedException JavaDoc e) {
395             e.printStackTrace(); //To change body of catch statement use Options | File Templates.
396
}
397         try {
398             tpm.writeIntention(ctxt1, s1.getCacheEntry());
399         } catch (PersistenceException e) {
400             // should go here
401
deadlocked = true;
402         }
403
404         if (! deadlocked) fail();
405         tpm.rollback(ctxt1);
406
407         tpm.begin(ctxt1);
408         s2 = (PIntegerState) tpm.readIntention(ctxt1, oid2);
409         if (s2.i == -1) fail();
410         assertTrue(tpm.prepare(ctxt1));
411         tpm.commit(ctxt1);
412
413     }
414
415 }
416
Popular Tags