KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > collections > buffer > TestBlockingBuffer


1 /*
2  * Copyright 2003-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.collections.buffer;
17
18 import java.util.ArrayList JavaDoc;
19 import java.util.Collections JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.LinkedList JavaDoc;
22 import java.util.Set JavaDoc;
23
24 import junit.framework.Test;
25 import junit.framework.TestSuite;
26
27 import org.apache.commons.collections.AbstractTestObject;
28 import org.apache.commons.collections.Buffer;
29 import org.apache.commons.collections.BufferUnderflowException;
30
31 /**
32  * Extension of {@link TestObject} for exercising the {@link BlockingBuffer}
33  * implementation.
34  *
35  * @since Commons Collections 3.0
36  * @version $Revision: 1.5 $
37  *
38  * @author Janek Bogucki
39  * @author Phil Steitz
40  */

41 public class TestBlockingBuffer extends AbstractTestObject {
42
43     public TestBlockingBuffer(String JavaDoc testName) {
44         super(testName);
45     }
46
47     public static Test suite() {
48         return new TestSuite(TestBlockingBuffer.class);
49     }
50
51     public static void main(String JavaDoc args[]) {
52         String JavaDoc[] testCaseName = { TestBlockingBuffer.class.getName()};
53         junit.textui.TestRunner.main(testCaseName);
54     }
55
56     public Object JavaDoc makeObject() {
57         return BlockingBuffer.decorate(new MyBuffer());
58     }
59
60     public boolean isEqualsCheckable() {
61         return false;
62     }
63
64     //-----------------------------------------------------------------------
65
/**
66      * Tests {@link BlockingBuffer#get()} in combination with {@link BlockingBuffer#add()}.
67      */

68     public void testGetWithAdd() {
69       
70         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
71         Object JavaDoc obj = new Object JavaDoc();
72
73         new DelayedAdd(blockingBuffer, obj).start();
74
75         // verify does not throw BufferUnderflowException; should block until other thread has added to the buffer .
76
assertSame(obj, blockingBuffer.get());
77     }
78
79     //-----------------------------------------------------------------------
80
/**
81      * Tests {@link BlockingBuffer#get()} in combination with {@link BlockingBuffer#addAll()}.
82      */

83     public void testGetWithAddAll() {
84         
85         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
86         Object JavaDoc obj = new Object JavaDoc();
87
88         new DelayedAddAll(blockingBuffer, obj).start();
89
90         // verify does not throw BufferUnderflowException; should block until other thread has added to the buffer .
91
assertSame(obj, blockingBuffer.get());
92     }
93
94     //-----------------------------------------------------------------------
95
/**
96      * Tests {@link BlockingBuffer#remove()} in combination with {@link BlockingBuffer#add()}.
97      */

98     public void testRemoveWithAdd() {
99         
100         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
101         Object JavaDoc obj = new Object JavaDoc();
102
103         new DelayedAdd(blockingBuffer, obj).start();
104
105         // verify does not throw BufferUnderflowException; should block until other thread has added to the buffer .
106
assertSame(obj, blockingBuffer.remove());
107     }
108
109     //-----------------------------------------------------------------------
110
/**
111      * Tests {@link BlockingBuffer#remove()} in combination with {@link BlockingBuffer#addAll()}.
112      */

113     public void testRemoveWithAddAll() {
114         
115         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
116         Object JavaDoc obj = new Object JavaDoc();
117
118         new DelayedAddAll(blockingBuffer, obj).start();
119
120         // verify does not throw BufferUnderflowException; should block until other thread has added to the buffer .
121
assertSame(obj, blockingBuffer.remove());
122     }
123
124     //-----------------------------------------------------------------------
125
/**
126      * Tests {@link BlockingBuffer#get()} in combination with {@link BlockingBuffer#add()} using multiple read threads.
127      *
128      * Two read threads should block on an empty buffer until one object
129      * is added then both threads should complete.
130      */

131     public void testBlockedGetWithAdd() {
132         
133         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
134         Object JavaDoc obj = new Object JavaDoc();
135         
136         // run methods will get and compare -- must wait for add
137
Thread JavaDoc thread1 = new ReadThread(blockingBuffer, obj);
138         Thread JavaDoc thread2 = new ReadThread(blockingBuffer, obj);
139         thread1.start();
140         thread2.start();
141         
142         // give hungry read threads ample time to hang
143
delay();
144            
145         // notifyAll should allow both read threads to complete
146
blockingBuffer.add(obj);
147         
148         // allow notified threads to complete
149
delay();
150         
151         // There should not be any threads waiting.
152
if (thread1.isAlive() || thread2.isAlive())
153             fail("Live thread(s) when both should be dead.");
154     }
155     
156     //-----------------------------------------------------------------------
157
/**
158      * Tests {@link BlockingBuffer#get()} in combination with {@link BlockingBuffer#addAll()} using multiple read threads.
159      *
160      * Two read threads should block on an empty buffer until a
161      * singleton is added then both threads should complete.
162      */

163     public void testBlockedGetWithAddAll() {
164         
165         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
166         Object JavaDoc obj = new Object JavaDoc();
167         
168         // run methods will get and compare -- must wait for addAll
169
Thread JavaDoc thread1 = new ReadThread(blockingBuffer, obj);
170         Thread JavaDoc thread2 = new ReadThread(blockingBuffer, obj);
171         thread1.start();
172         thread2.start();
173         
174         // give hungry read threads ample time to hang
175
delay();
176            
177         // notifyAll should allow both read threads to complete
178
blockingBuffer.addAll(Collections.singleton(obj));
179                
180         // allow notified threads to complete
181
delay();
182         
183         // There should not be any threads waiting.
184
if (thread1.isAlive() || thread2.isAlive())
185             fail("Live thread(s) when both should be dead.");
186     }
187     
188     //-----------------------------------------------------------------------
189
/**
190      * Tests interrupted {@link BlockingBuffer#get()}.
191      */

192     public void testInterruptedGet() {
193         
194         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
195         Object JavaDoc obj = new Object JavaDoc();
196         
197         // spawn a read thread to wait on the empty buffer
198
ArrayList JavaDoc exceptionList = new ArrayList JavaDoc();
199         Thread JavaDoc thread = new ReadThread(blockingBuffer, obj, exceptionList);
200         thread.start();
201         
202         // Interrupting the thread should cause it to throw BufferUnderflowException
203
thread.interrupt();
204         
205         // Chill, so thread can throw and add message to exceptionList
206
delay();
207         
208         assertTrue("Thread interrupt should have led to underflow",
209             exceptionList.contains("BufferUnderFlow"));
210         
211         if (thread.isAlive()) {
212             fail("Read thread has hung.");
213         }
214         
215     }
216     
217     //-----------------------------------------------------------------------
218
/**
219      * Tests {@link BlockingBuffer#remove()} in combination with {@link BlockingBuffer#add()} using multiple read threads.
220      *
221      * Two read threads should block on an empty buffer until one
222      * object is added then one thread should complete. The remaining
223      * thread should complete after the addition of a second object.
224      */

225     public void testBlockedRemoveWithAdd() {
226         
227         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
228         Object JavaDoc obj = new Object JavaDoc();
229         
230         // run methods will remove and compare -- must wait for add
231
Thread JavaDoc thread1 = new ReadThread(blockingBuffer, obj, null, "remove");
232         Thread JavaDoc thread2 = new ReadThread(blockingBuffer, obj, null, "remove");
233         thread1.start();
234         thread2.start();
235         
236         // give hungry read threads ample time to hang
237
delay();
238            
239         blockingBuffer.add(obj);
240         
241         // allow notified threads to complete
242
delay();
243         
244         // There should be one thread waiting.
245
assertTrue ("There is one thread waiting", thread1.isAlive() ^ thread2.isAlive());
246            
247         blockingBuffer.add(obj);
248         
249         // allow notified thread to complete
250
delay();
251
252         // There should not be any threads waiting.
253
if(thread1.isAlive() || thread2.isAlive())
254             fail("Live thread(s) when both should be dead.");
255     }
256
257     //-----------------------------------------------------------------------
258
/**
259      * Tests {@link BlockingBuffer#remove()} in combination with {@link BlockingBuffer#addAll()} using multiple read threads.
260      *
261      * Two read threads should block on an empty buffer until a
262      * singleton collection is added then one thread should
263      * complete. The remaining thread should complete after the
264      * addition of a second singleton.
265      */

266     public void testBlockedRemoveWithAddAll1() {
267         
268         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
269         Object JavaDoc obj = new Object JavaDoc();
270         
271         // run methods will remove and compare -- must wait for addAll
272
Thread JavaDoc thread1 = new ReadThread(blockingBuffer, obj, null, "remove");
273         Thread JavaDoc thread2 = new ReadThread(blockingBuffer, obj, null, "remove");
274         thread1.start();
275         thread2.start();
276         
277         // give hungry read threads ample time to hang
278
delay();
279            
280         blockingBuffer.addAll(Collections.singleton(obj));
281         
282         // allow notified threads to complete
283
delay();
284         
285         // There should be one thread waiting.
286
assertTrue ("There is one thread waiting", thread1.isAlive() ^ thread2.isAlive());
287            
288         blockingBuffer.addAll(Collections.singleton(obj));
289         
290         // allow notified thread to complete
291
delay();
292
293         // There should not be any threads waiting.
294
if(thread1.isAlive() || thread2.isAlive())
295             fail("Live thread(s) when both should be dead.");
296     }
297
298    
299     //-----------------------------------------------------------------------
300
/**
301      * Tests {@link BlockingBuffer#remove()} in combination with {@link BlockingBuffer#addAll()} using multiple read threads.
302      *
303      * Two read threads should block on an empty buffer until a
304      * collection with two distinct objects is added then both
305      * threads should complete. Each thread should have read a
306      * different object.
307      */

308     public void testBlockedRemoveWithAddAll2() {
309         
310         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
311         Object JavaDoc obj1 = new Object JavaDoc();
312         Object JavaDoc obj2 = new Object JavaDoc();
313         
314         Set JavaDoc objs = Collections.synchronizedSet(new HashSet JavaDoc());
315         objs.add(obj1);
316         objs.add(obj2);
317
318         // run methods will remove and compare -- must wait for addAll
319
Thread JavaDoc thread1 = new ReadThread(blockingBuffer, objs, "remove");
320         Thread JavaDoc thread2 = new ReadThread(blockingBuffer, objs, "remove");
321         thread1.start();
322         thread2.start();
323         
324         // give hungry read threads ample time to hang
325
delay();
326            
327         blockingBuffer.addAll(objs);
328         
329         // allow notified threads to complete
330
delay();
331         
332         assertEquals("Both objects were removed", 0, objs.size());
333
334         // There should not be any threads waiting.
335
if(thread1.isAlive() || thread2.isAlive())
336             fail("Live thread(s) when both should be dead.");
337     }
338
339     //-----------------------------------------------------------------------
340
/**
341      * Tests interrupted remove.
342      */

343     public void testInterruptedRemove() {
344         
345         Buffer blockingBuffer = BlockingBuffer.decorate(new MyBuffer());
346         Object JavaDoc obj = new Object JavaDoc();
347         
348         // spawn a read thread to wait on the empty buffer
349
ArrayList JavaDoc exceptionList = new ArrayList JavaDoc();
350         Thread JavaDoc thread = new ReadThread(blockingBuffer, obj, exceptionList, "remove");
351         thread.start();
352         
353         // Interrupting the thread should cause it to throw BufferUnderflowException
354
thread.interrupt();
355         
356         // Chill, so thread can throw and add message to exceptionList
357
delay();
358         
359         assertTrue("Thread interrupt should have led to underflow",
360             exceptionList.contains("BufferUnderFlow"));
361         
362         if (thread.isAlive()) {
363             fail("Read thread has hung.");
364         }
365         
366     }
367     
368     protected static class DelayedAdd extends Thread JavaDoc {
369
370         Buffer buffer;
371         Object JavaDoc obj;
372
373         DelayedAdd (Buffer buffer, Object JavaDoc obj) {
374             super();
375             this.buffer = buffer;
376             this.obj = obj;
377         }
378                 
379         public void run() {
380
381             try {
382                 // wait for other thread to block on get() or remove()
383
Thread.currentThread().sleep(100);
384             }
385             catch (InterruptedException JavaDoc e) {}
386
387             buffer.add(obj);
388         }
389     }
390     
391     protected static class DelayedAddAll extends Thread JavaDoc {
392
393         Buffer buffer;
394         Object JavaDoc obj;
395
396         DelayedAddAll (Buffer buffer, Object JavaDoc obj) {
397             super();
398             this.buffer = buffer;
399             this.obj = obj;
400         }
401                 
402         public void run() {
403
404             try {
405                 // wait for other thread to block on get() or remove()
406
Thread.currentThread().sleep(100);
407             }
408             catch (InterruptedException JavaDoc e) {}
409
410             buffer.addAll(Collections.singleton(obj));
411         }
412     }
413     
414     protected static class ReadThread extends Thread JavaDoc {
415
416         Buffer buffer;
417         Object JavaDoc obj;
418         ArrayList JavaDoc exceptionList = null;
419         String JavaDoc action = "get";
420         Set JavaDoc objs;
421         
422         ReadThread (Buffer buffer, Object JavaDoc obj) {
423             super();
424             this.buffer = buffer;
425             this.obj = obj;
426         }
427
428         ReadThread (Buffer buffer, Object JavaDoc obj, ArrayList JavaDoc exceptionList) {
429             super();
430             this.buffer = buffer;
431             this.obj = obj;
432             this.exceptionList = exceptionList;
433         }
434         
435         ReadThread (Buffer buffer, Object JavaDoc obj, ArrayList JavaDoc exceptionList, String JavaDoc action) {
436             super();
437             this.buffer = buffer;
438             this.obj = obj;
439             this.exceptionList = exceptionList;
440             this.action = action;
441         }
442                 
443         ReadThread (Buffer buffer, Set JavaDoc objs, String JavaDoc action) {
444             super();
445             this.buffer = buffer;
446             this.objs = objs;
447             this.action = action;
448         }
449                 
450         public void run() {
451             try {
452                 if (action == "get") {
453                     assertSame(obj, buffer.get());
454                 } else {
455                     if (null != obj)
456                         assertSame(obj, buffer.remove());
457                     else
458                         assertTrue(objs.remove(buffer.remove()));
459                 }
460             } catch (BufferUnderflowException ex) {
461                 exceptionList.add("BufferUnderFlow");
462             }
463         }
464     }
465         
466
467     protected static class MyBuffer extends LinkedList JavaDoc implements Buffer {
468
469         public Object JavaDoc get() {
470             if(isEmpty())
471                 throw new BufferUnderflowException();
472             return get(0);
473         }
474
475         public Object JavaDoc remove() {
476             if(isEmpty())
477                 throw new BufferUnderflowException();
478             return remove(0);
479         }
480     }
481
482     private void delay(){
483         try {
484             Thread.currentThread().sleep(100);
485         } catch (InterruptedException JavaDoc e) {}
486     }
487
488     public String JavaDoc getCompatibilityVersion() {
489         return "3.1";
490     }
491
492 // public void testCreate() throws Exception {
493
// Buffer buffer = BlockingBuffer.decorate(new UnboundedFifoBuffer());
494
// writeExternalFormToDisk((java.io.Serializable) buffer, "D:/dev/collections/data/test/BlockingBuffer.emptyCollection.version3.1.obj");
495
// buffer = BlockingBuffer.decorate(new UnboundedFifoBuffer());
496
// buffer.add("A");
497
// buffer.add("B");
498
// buffer.add("C");
499
// writeExternalFormToDisk((java.io.Serializable) buffer, "D:/dev/collections/data/test/BlockingBuffer.fullCollection.version3.1.obj");
500
// }
501

502 }
503
Popular Tags