ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ArrayBlockingQueueTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ArrayBlockingQueueTest.java (file contents):
Revision 1.3 by dl, Sun Sep 14 20:42:40 2003 UTC vs.
Revision 1.73 by jsr166, Mon Oct 17 01:52:04 2016 UTC

# Line 1 | Line 1
1   /*
2 < * Written by members of JCP JSR-166 Expert Group and released to the
3 < * public domain. Use, modify, and redistribute this code in any way
4 < * without acknowledgement. Other contributors include Andrew Wright,
5 < * Jeffrey Hayes, Pat Fischer, Mike Judd.
2 > * Written by Doug Lea with assistance from members of JCP JSR-166
3 > * Expert Group and released to the public domain, as explained at
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5 > * Other contributors include Andrew Wright, Jeffrey Hayes,
6 > * Pat Fisher, Mike Judd.
7   */
8  
9 < import junit.framework.*;
10 < import java.util.*;
11 < import java.util.concurrent.*;
12 < import java.io.*;
9 > import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 >
11 > import java.util.ArrayList;
12 > import java.util.Arrays;
13 > import java.util.Collection;
14 > import java.util.Iterator;
15 > import java.util.NoSuchElementException;
16 > import java.util.Queue;
17 > import java.util.concurrent.ArrayBlockingQueue;
18 > import java.util.concurrent.BlockingQueue;
19 > import java.util.concurrent.CountDownLatch;
20 > import java.util.concurrent.Executors;
21 > import java.util.concurrent.ExecutorService;
22 >
23 > import junit.framework.Test;
24  
25   public class ArrayBlockingQueueTest extends JSR166TestCase {
26  
27 +    public static class Fair extends BlockingQueueTest {
28 +        protected BlockingQueue emptyCollection() {
29 +            return new ArrayBlockingQueue(SIZE, true);
30 +        }
31 +    }
32 +
33 +    public static class NonFair extends BlockingQueueTest {
34 +        protected BlockingQueue emptyCollection() {
35 +            return new ArrayBlockingQueue(SIZE, false);
36 +        }
37 +    }
38 +
39      public static void main(String[] args) {
40 <        junit.textui.TestRunner.run (suite());  
40 >        main(suite(), args);
41      }
42  
43      public static Test suite() {
44 <        return new TestSuite(ArrayBlockingQueueTest.class);
44 >        class Implementation implements CollectionImplementation {
45 >            public Class<?> klazz() { return ArrayBlockingQueue.class; }
46 >            public Collection emptyCollection() { return new ArrayBlockingQueue(SIZE, false); }
47 >            public Object makeElement(int i) { return i; }
48 >            public boolean isConcurrent() { return true; }
49 >            public boolean permitsNulls() { return false; }
50 >        }
51 >        return newTestSuite(ArrayBlockingQueueTest.class,
52 >                            new Fair().testSuite(),
53 >                            new NonFair().testSuite(),
54 >                            CollectionTest.testSuite(new Implementation()));
55      }
56  
57      /**
58 <     * Create a queue of given size containing consecutive
59 <     * Integers 0 ... n.
58 >     * Returns a new queue of given size containing consecutive
59 >     * Integers 0 ... n - 1.
60       */
61 <    private ArrayBlockingQueue populatedQueue(int n) {
62 <        ArrayBlockingQueue q = new ArrayBlockingQueue(n);
61 >    private ArrayBlockingQueue<Integer> populatedQueue(int n) {
62 >        ArrayBlockingQueue<Integer> q = new ArrayBlockingQueue<Integer>(n);
63          assertTrue(q.isEmpty());
64 <        for(int i = 0; i < n; i++)
65 <            assertTrue(q.offer(new Integer(i)));
64 >        for (int i = 0; i < n; i++)
65 >            assertTrue(q.offer(new Integer(i)));
66          assertFalse(q.isEmpty());
67          assertEquals(0, q.remainingCapacity());
68 <        assertEquals(n, q.size());
68 >        assertEquals(n, q.size());
69 >        assertEquals((Integer) 0, q.peek());
70          return q;
71      }
72 <
73 <    public void testConstructor1(){
72 >
73 >    /**
74 >     * A new queue has the indicated capacity
75 >     */
76 >    public void testConstructor1() {
77          assertEquals(SIZE, new ArrayBlockingQueue(SIZE).remainingCapacity());
78      }
79  
80 <    public void testConstructor2(){
80 >    /**
81 >     * Constructor throws IAE if capacity argument nonpositive
82 >     */
83 >    public void testConstructor2() {
84          try {
85 <            ArrayBlockingQueue q = new ArrayBlockingQueue(0);
86 <            fail("Cannot make zero-sized");
87 <        }
47 <        catch (IllegalArgumentException success) {}
85 >            new ArrayBlockingQueue(0);
86 >            shouldThrow();
87 >        } catch (IllegalArgumentException success) {}
88      }
89  
90 <    public void testConstructor3(){
91 <
90 >    /**
91 >     * Initializing from null Collection throws NPE
92 >     */
93 >    public void testConstructor3() {
94          try {
95 <            ArrayBlockingQueue q = new ArrayBlockingQueue(1, true, null);
96 <            fail("Cannot make from null collection");
97 <        }
56 <        catch (NullPointerException success) {}
95 >            new ArrayBlockingQueue(1, true, null);
96 >            shouldThrow();
97 >        } catch (NullPointerException success) {}
98      }
99  
100 <    public void testConstructor4(){
100 >    /**
101 >     * Initializing from Collection of null elements throws NPE
102 >     */
103 >    public void testConstructor4() {
104 >        Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
105          try {
106 <            Integer[] ints = new Integer[SIZE];
107 <            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, false, Arrays.asList(ints));
108 <            fail("Cannot make with null elements");
64 <        }
65 <        catch (NullPointerException success) {}
106 >            new ArrayBlockingQueue(SIZE, false, elements);
107 >            shouldThrow();
108 >        } catch (NullPointerException success) {}
109      }
110  
111 <    public void testConstructor5(){
112 <        try {
113 <            Integer[] ints = new Integer[SIZE];
114 <            for (int i = 0; i < SIZE-1; ++i)
115 <                ints[i] = new Integer(i);
116 <            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, false, Arrays.asList(ints));
117 <            fail("Cannot make with null elements");
118 <        }
119 <        catch (NullPointerException success) {}
111 >    /**
112 >     * Initializing from Collection with some null elements throws NPE
113 >     */
114 >    public void testConstructor5() {
115 >        Integer[] ints = new Integer[SIZE];
116 >        for (int i = 0; i < SIZE - 1; ++i)
117 >            ints[i] = i;
118 >        Collection<Integer> elements = Arrays.asList(ints);
119 >        try {
120 >            new ArrayBlockingQueue(SIZE, false, elements);
121 >            shouldThrow();
122 >        } catch (NullPointerException success) {}
123      }
124  
125 <    public void testConstructor6(){
126 <        try {
127 <            Integer[] ints = new Integer[SIZE];
128 <            for (int i = 0; i < SIZE; ++i)
129 <                ints[i] = new Integer(i);
130 <            ArrayBlockingQueue q = new ArrayBlockingQueue(1, false, Arrays.asList(ints));
131 <            fail("Cannot make with insufficient capacity");
132 <        }
133 <        catch (IllegalArgumentException success) {}
125 >    /**
126 >     * Initializing from too large collection throws IAE
127 >     */
128 >    public void testConstructor6() {
129 >        Integer[] ints = new Integer[SIZE];
130 >        for (int i = 0; i < SIZE; ++i)
131 >            ints[i] = i;
132 >        Collection<Integer> elements = Arrays.asList(ints);
133 >        try {
134 >            new ArrayBlockingQueue(SIZE - 1, false, elements);
135 >            shouldThrow();
136 >        } catch (IllegalArgumentException success) {}
137      }
138  
139 <    public void testConstructor7(){
140 <        try {
141 <            Integer[] ints = new Integer[SIZE];
142 <            for (int i = 0; i < SIZE; ++i)
143 <                ints[i] = new Integer(i);
144 <            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, true, Arrays.asList(ints));
145 <            for (int i = 0; i < SIZE; ++i)
146 <                assertEquals(ints[i], q.poll());
147 <        }
148 <        finally {}
139 >    /**
140 >     * Queue contains all elements of collection used to initialize
141 >     */
142 >    public void testConstructor7() {
143 >        Integer[] ints = new Integer[SIZE];
144 >        for (int i = 0; i < SIZE; ++i)
145 >            ints[i] = i;
146 >        Collection<Integer> elements = Arrays.asList(ints);
147 >        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, true, elements);
148 >        for (int i = 0; i < SIZE; ++i)
149 >            assertEquals(ints[i], q.poll());
150      }
151  
152 +    /**
153 +     * Queue transitions from empty to full when elements added
154 +     */
155      public void testEmptyFull() {
156          ArrayBlockingQueue q = new ArrayBlockingQueue(2);
157          assertTrue(q.isEmpty());
158 <        assertEquals("should have room for 2", 2, q.remainingCapacity());
158 >        assertEquals(2, q.remainingCapacity());
159          q.add(one);
160          assertFalse(q.isEmpty());
161          q.add(two);
162          assertFalse(q.isEmpty());
163 <        assertEquals("queue should be full", 0, q.remainingCapacity());
164 <        assertFalse("offer should be rejected", q.offer(three));
163 >        assertEquals(0, q.remainingCapacity());
164 >        assertFalse(q.offer(three));
165      }
166  
167 <    public void testRemainingCapacity(){
168 <        ArrayBlockingQueue q = populatedQueue(SIZE);
167 >    /**
168 >     * remainingCapacity decreases on add, increases on remove
169 >     */
170 >    public void testRemainingCapacity() {
171 >        BlockingQueue q = populatedQueue(SIZE);
172          for (int i = 0; i < SIZE; ++i) {
173              assertEquals(i, q.remainingCapacity());
174 <            assertEquals(SIZE-i, q.size());
175 <            q.remove();
174 >            assertEquals(SIZE, q.size() + q.remainingCapacity());
175 >            assertEquals(i, q.remove());
176          }
177          for (int i = 0; i < SIZE; ++i) {
178 <            assertEquals(SIZE-i, q.remainingCapacity());
179 <            assertEquals(i, q.size());
180 <            q.add(new Integer(i));
178 >            assertEquals(SIZE - i, q.remainingCapacity());
179 >            assertEquals(SIZE, q.size() + q.remainingCapacity());
180 >            assertTrue(q.add(i));
181          }
182      }
183  
184 <    public void testOfferNull(){
185 <        try {
186 <            ArrayBlockingQueue q = new ArrayBlockingQueue(1);
187 <            q.offer(null);
132 <            fail("should throw NPE");
133 <        } catch (NullPointerException success) { }  
134 <    }
135 <
136 <    public void testOffer(){
184 >    /**
185 >     * Offer succeeds if not full; fails if full
186 >     */
187 >    public void testOffer() {
188          ArrayBlockingQueue q = new ArrayBlockingQueue(1);
189          assertTrue(q.offer(zero));
190          assertFalse(q.offer(one));
191      }
192  
193 <    public void testAdd(){
194 <        try {
195 <            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
196 <            for (int i = 0; i < SIZE; ++i) {
197 <                assertTrue(q.add(new Integer(i)));
198 <            }
199 <            assertEquals(0, q.remainingCapacity());
193 >    /**
194 >     * add succeeds if not full; throws ISE if full
195 >     */
196 >    public void testAdd() {
197 >        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
198 >        for (int i = 0; i < SIZE; ++i) {
199 >            assertTrue(q.add(new Integer(i)));
200 >        }
201 >        assertEquals(0, q.remainingCapacity());
202 >        try {
203              q.add(new Integer(SIZE));
204 <        } catch (IllegalStateException success){
205 <        }  
204 >            shouldThrow();
205 >        } catch (IllegalStateException success) {}
206      }
207  
208 <    public void testAddAll1(){
209 <        try {
210 <            ArrayBlockingQueue q = new ArrayBlockingQueue(1);
211 <            q.addAll(null);
212 <            fail("Cannot add null collection");
159 <        }
160 <        catch (NullPointerException success) {}
161 <    }
162 <    public void testAddAll2(){
208 >    /**
209 >     * addAll(this) throws IAE
210 >     */
211 >    public void testAddAllSelf() {
212 >        ArrayBlockingQueue q = populatedQueue(SIZE);
213          try {
214 <            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
215 <            Integer[] ints = new Integer[SIZE];
216 <            q.addAll(Arrays.asList(ints));
167 <            fail("Cannot add null elements");
168 <        }
169 <        catch (NullPointerException success) {}
214 >            q.addAll(q);
215 >            shouldThrow();
216 >        } catch (IllegalArgumentException success) {}
217      }
218 <    public void testAddAll3(){
218 >
219 >    /**
220 >     * addAll of a collection with any null elements throws NPE after
221 >     * possibly adding some elements
222 >     */
223 >    public void testAddAll3() {
224 >        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
225 >        Integer[] ints = new Integer[SIZE];
226 >        for (int i = 0; i < SIZE - 1; ++i)
227 >            ints[i] = new Integer(i);
228          try {
173            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
174            Integer[] ints = new Integer[SIZE];
175            for (int i = 0; i < SIZE-1; ++i)
176                ints[i] = new Integer(i);
229              q.addAll(Arrays.asList(ints));
230 <            fail("Cannot add null elements");
231 <        }
180 <        catch (NullPointerException success) {}
230 >            shouldThrow();
231 >        } catch (NullPointerException success) {}
232      }
233 <    public void testAddAll4(){
233 >
234 >    /**
235 >     * addAll throws ISE if not enough room
236 >     */
237 >    public void testAddAll4() {
238 >        ArrayBlockingQueue q = new ArrayBlockingQueue(1);
239 >        Integer[] ints = new Integer[SIZE];
240 >        for (int i = 0; i < SIZE; ++i)
241 >            ints[i] = new Integer(i);
242          try {
184            ArrayBlockingQueue q = new ArrayBlockingQueue(1);
185            Integer[] ints = new Integer[SIZE];
186            for (int i = 0; i < SIZE; ++i)
187                ints[i] = new Integer(i);
243              q.addAll(Arrays.asList(ints));
244 <            fail("Cannot add with insufficient capacity");
245 <        }
191 <        catch (IllegalStateException success) {}
192 <    }
193 <    public void testAddAll5(){
194 <        try {
195 <            Integer[] empty = new Integer[0];
196 <            Integer[] ints = new Integer[SIZE];
197 <            for (int i = 0; i < SIZE; ++i)
198 <                ints[i] = new Integer(i);
199 <            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
200 <            assertFalse(q.addAll(Arrays.asList(empty)));
201 <            assertTrue(q.addAll(Arrays.asList(ints)));
202 <            for (int i = 0; i < SIZE; ++i)
203 <                assertEquals(ints[i], q.poll());
204 <        }
205 <        finally {}
206 <    }
207 <
208 <     public void testPutNull() {
209 <        try {
210 <            ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
211 <            q.put(null);
212 <            fail("put should throw NPE");
213 <        }
214 <        catch (NullPointerException success){
215 <        }  
216 <        catch (InterruptedException ie) {
217 <            fail("Unexpected exception");
218 <        }
219 <     }
220 <
221 <     public void testPut() {
222 <         try {
223 <             ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
224 <             for (int i = 0; i < SIZE; ++i) {
225 <                 Integer I = new Integer(i);
226 <                 q.put(I);
227 <                 assertTrue(q.contains(I));
228 <             }
229 <             assertEquals(0, q.remainingCapacity());
230 <         }
231 <        catch (InterruptedException ie) {
232 <            fail("Unexpected exception");
233 <        }
244 >            shouldThrow();
245 >        } catch (IllegalStateException success) {}
246      }
247  
248 <    public void testBlockingPut(){
249 <        Thread t = new Thread(new Runnable() {
250 <                public void run() {
251 <                    int added = 0;
252 <                    try {
253 <                        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
254 <                        for (int i = 0; i < SIZE; ++i) {
255 <                            q.put(new Integer(i));
256 <                            ++added;
257 <                        }
258 <                        q.put(new Integer(SIZE));
259 <                        threadFail("put should block");
260 <                    } catch (InterruptedException ie){
249 <                        threadAssertEquals(added, SIZE);
250 <                    }  
251 <                }});
252 <        try {
253 <            t.start();
254 <           Thread.sleep(SHORT_DELAY_MS);
255 <           t.interrupt();
256 <           t.join();
257 <        }
258 <        catch (InterruptedException ie) {
259 <            fail("Unexpected exception");
260 <        }
248 >    /**
249 >     * Queue contains all elements, in traversal order, of successful addAll
250 >     */
251 >    public void testAddAll5() {
252 >        Integer[] empty = new Integer[0];
253 >        Integer[] ints = new Integer[SIZE];
254 >        for (int i = 0; i < SIZE; ++i)
255 >            ints[i] = new Integer(i);
256 >        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
257 >        assertFalse(q.addAll(Arrays.asList(empty)));
258 >        assertTrue(q.addAll(Arrays.asList(ints)));
259 >        for (int i = 0; i < SIZE; ++i)
260 >            assertEquals(ints[i], q.poll());
261      }
262  
263 <    public void testPutWithTake() {
264 <        final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
265 <        Thread t = new Thread(new Runnable() {
266 <                public void run(){
267 <                    int added = 0;
268 <                    try {
269 <                        q.put(new Object());
270 <                        ++added;
271 <                        q.put(new Object());
272 <                        ++added;
273 <                        q.put(new Object());
274 <                        ++added;
275 <                        q.put(new Object());
276 <                        ++added;
277 <                        threadFail("Should block");
278 <                    } catch (InterruptedException e){
279 <                        threadAssertTrue(added >= 2);
280 <                    }
281 <                }
282 <            });
283 <        try {
284 <            t.start();
285 <            Thread.sleep(SHORT_DELAY_MS);
286 <            q.take();
287 <            t.interrupt();
288 <            t.join();
289 <        } catch (Exception e){
290 <            fail("Unexpected exception");
263 >    /**
264 >     * all elements successfully put are contained
265 >     */
266 >    public void testPut() throws InterruptedException {
267 >        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
268 >        for (int i = 0; i < SIZE; ++i) {
269 >            Integer x = new Integer(i);
270 >            q.put(x);
271 >            assertTrue(q.contains(x));
272          }
273 +        assertEquals(0, q.remainingCapacity());
274      }
275  
276 <    public void testTimedOffer() {
277 <        final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
278 <        Thread t = new Thread(new Runnable() {
279 <                public void run(){
280 <                    try {
281 <                        q.put(new Object());
282 <                        q.put(new Object());
283 <                        threadAssertFalse(q.offer(new Object(), SHORT_DELAY_MS/2, TimeUnit.MILLISECONDS));
284 <                        q.offer(new Object(), LONG_DELAY_MS, TimeUnit.MILLISECONDS);
285 <                        threadFail("Should block");
286 <                    } catch (InterruptedException success){}
287 <                }
288 <            });
289 <        
290 <        try {
291 <            t.start();
292 <            Thread.sleep(SHORT_DELAY_MS);
293 <            t.interrupt();
294 <            t.join();
295 <        } catch (Exception e){
296 <            fail("Unexpected exception");
297 <        }
276 >    /**
277 >     * put blocks interruptibly if full
278 >     */
279 >    public void testBlockingPut() throws InterruptedException {
280 >        final ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
281 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
282 >        Thread t = newStartedThread(new CheckedRunnable() {
283 >            public void realRun() throws InterruptedException {
284 >                for (int i = 0; i < SIZE; ++i)
285 >                    q.put(i);
286 >                assertEquals(SIZE, q.size());
287 >                assertEquals(0, q.remainingCapacity());
288 >
289 >                Thread.currentThread().interrupt();
290 >                try {
291 >                    q.put(99);
292 >                    shouldThrow();
293 >                } catch (InterruptedException success) {}
294 >                assertFalse(Thread.interrupted());
295 >
296 >                pleaseInterrupt.countDown();
297 >                try {
298 >                    q.put(99);
299 >                    shouldThrow();
300 >                } catch (InterruptedException success) {}
301 >                assertFalse(Thread.interrupted());
302 >            }});
303 >
304 >        await(pleaseInterrupt);
305 >        assertThreadStaysAlive(t);
306 >        t.interrupt();
307 >        awaitTermination(t);
308 >        assertEquals(SIZE, q.size());
309 >        assertEquals(0, q.remainingCapacity());
310      }
311  
312 <    public void testTake(){
313 <        try {
314 <            ArrayBlockingQueue q = populatedQueue(SIZE);
315 <            for (int i = 0; i < SIZE; ++i) {
316 <                assertEquals(i, ((Integer)q.take()).intValue());
317 <            }
318 <        } catch (InterruptedException e){
319 <            fail("Unexpected exception");
320 <        }  
312 >    /**
313 >     * put blocks interruptibly waiting for take when full
314 >     */
315 >    public void testPutWithTake() throws InterruptedException {
316 >        final int capacity = 2;
317 >        final ArrayBlockingQueue q = new ArrayBlockingQueue(capacity);
318 >        final CountDownLatch pleaseTake = new CountDownLatch(1);
319 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
320 >        Thread t = newStartedThread(new CheckedRunnable() {
321 >            public void realRun() throws InterruptedException {
322 >                for (int i = 0; i < capacity; i++)
323 >                    q.put(i);
324 >                pleaseTake.countDown();
325 >                q.put(86);
326 >
327 >                pleaseInterrupt.countDown();
328 >                try {
329 >                    q.put(99);
330 >                    shouldThrow();
331 >                } catch (InterruptedException success) {}
332 >                assertFalse(Thread.interrupted());
333 >            }});
334 >
335 >        await(pleaseTake);
336 >        assertEquals(0, q.remainingCapacity());
337 >        assertEquals(0, q.take());
338 >
339 >        await(pleaseInterrupt);
340 >        assertThreadStaysAlive(t);
341 >        t.interrupt();
342 >        awaitTermination(t);
343 >        assertEquals(0, q.remainingCapacity());
344      }
345  
346 <    public void testTakeFromEmpty() {
346 >    /**
347 >     * timed offer times out if full and elements not taken
348 >     */
349 >    public void testTimedOffer() throws InterruptedException {
350          final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
351 <        Thread t = new Thread(new Runnable() {
352 <                public void run(){
353 <                    try {
354 <                        q.take();
355 <                        threadFail("Should block");
356 <                    } catch (InterruptedException success){ }                
357 <                }
358 <            });
359 <        try {
360 <            t.start();
361 <            Thread.sleep(SHORT_DELAY_MS);
362 <            t.interrupt();
363 <            t.join();
364 <        } catch (Exception e){
365 <            fail("Unexpected exception");
366 <        }
351 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
352 >        Thread t = newStartedThread(new CheckedRunnable() {
353 >            public void realRun() throws InterruptedException {
354 >                q.put(new Object());
355 >                q.put(new Object());
356 >                long startTime = System.nanoTime();
357 >                assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
358 >                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
359 >                pleaseInterrupt.countDown();
360 >                try {
361 >                    q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
362 >                    shouldThrow();
363 >                } catch (InterruptedException success) {}
364 >            }});
365 >
366 >        await(pleaseInterrupt);
367 >        assertThreadStaysAlive(t);
368 >        t.interrupt();
369 >        awaitTermination(t);
370      }
371  
372 <    public void testBlockingTake(){
373 <        Thread t = new Thread(new Runnable() {
374 <                public void run() {
375 <                    try {
376 <                        ArrayBlockingQueue q = populatedQueue(SIZE);
377 <                        for (int i = 0; i < SIZE; ++i) {
378 <                            threadAssertEquals(i, ((Integer)q.take()).intValue());
356 <                        }
357 <                        q.take();
358 <                        threadFail("take should block");
359 <                    } catch (InterruptedException success){
360 <                    }  
361 <                }});
362 <        try {
363 <            t.start();
364 <            Thread.sleep(SHORT_DELAY_MS);
365 <            t.interrupt();
366 <            t.join();
367 <        }
368 <        catch (InterruptedException ie) {
369 <            fail("Unexpected exception");
372 >    /**
373 >     * take retrieves elements in FIFO order
374 >     */
375 >    public void testTake() throws InterruptedException {
376 >        ArrayBlockingQueue q = populatedQueue(SIZE);
377 >        for (int i = 0; i < SIZE; ++i) {
378 >            assertEquals(i, q.take());
379          }
380      }
381  
382 +    /**
383 +     * Take removes existing elements until empty, then blocks interruptibly
384 +     */
385 +    public void testBlockingTake() throws InterruptedException {
386 +        final ArrayBlockingQueue q = populatedQueue(SIZE);
387 +        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
388 +        Thread t = newStartedThread(new CheckedRunnable() {
389 +            public void realRun() throws InterruptedException {
390 +                for (int i = 0; i < SIZE; ++i) {
391 +                    assertEquals(i, q.take());
392 +                }
393 +
394 +                Thread.currentThread().interrupt();
395 +                try {
396 +                    q.take();
397 +                    shouldThrow();
398 +                } catch (InterruptedException success) {}
399 +                assertFalse(Thread.interrupted());
400  
401 <    public void testPoll(){
401 >                pleaseInterrupt.countDown();
402 >                try {
403 >                    q.take();
404 >                    shouldThrow();
405 >                } catch (InterruptedException success) {}
406 >                assertFalse(Thread.interrupted());
407 >            }});
408 >
409 >        await(pleaseInterrupt);
410 >        assertThreadStaysAlive(t);
411 >        t.interrupt();
412 >        awaitTermination(t);
413 >    }
414 >
415 >    /**
416 >     * poll succeeds unless empty
417 >     */
418 >    public void testPoll() {
419          ArrayBlockingQueue q = populatedQueue(SIZE);
420          for (int i = 0; i < SIZE; ++i) {
421 <            assertEquals(i, ((Integer)q.poll()).intValue());
421 >            assertEquals(i, q.poll());
422          }
423 <        assertNull(q.poll());
423 >        assertNull(q.poll());
424      }
425  
426 <    public void testTimedPoll0() {
427 <        try {
428 <            ArrayBlockingQueue q = populatedQueue(SIZE);
429 <            for (int i = 0; i < SIZE; ++i) {
430 <                assertEquals(i, ((Integer)q.poll(0, TimeUnit.MILLISECONDS)).intValue());
431 <            }
432 <            assertNull(q.poll(0, TimeUnit.MILLISECONDS));
433 <        } catch (InterruptedException e){
434 <            fail("Unexpected exception");
435 <        }  
426 >    /**
427 >     * timed poll with zero timeout succeeds when non-empty, else times out
428 >     */
429 >    public void testTimedPoll0() throws InterruptedException {
430 >        ArrayBlockingQueue q = populatedQueue(SIZE);
431 >        for (int i = 0; i < SIZE; ++i) {
432 >            assertEquals(i, q.poll(0, MILLISECONDS));
433 >        }
434 >        assertNull(q.poll(0, MILLISECONDS));
435 >        checkEmpty(q);
436      }
437  
438 <    public void testTimedPoll() {
439 <        try {
440 <            ArrayBlockingQueue q = populatedQueue(SIZE);
441 <            for (int i = 0; i < SIZE; ++i) {
442 <                assertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue());
443 <            }
444 <            assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
445 <        } catch (InterruptedException e){
446 <            fail("Unexpected exception");
447 <        }  
448 <    }
449 <
450 <    public void testInterruptedTimedPoll(){
451 <        Thread t = new Thread(new Runnable() {
408 <                public void run() {
409 <                    try {
410 <                        ArrayBlockingQueue q = populatedQueue(SIZE);
411 <                        for (int i = 0; i < SIZE; ++i) {
412 <                            threadAssertEquals(i, ((Integer)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)).intValue());
413 <                        }
414 <                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
415 <                    } catch (InterruptedException success){
416 <                    }  
417 <                }});
418 <        try {
419 <            t.start();
420 <            Thread.sleep(SHORT_DELAY_MS);
421 <            t.interrupt();
422 <            t.join();
423 <        }
424 <        catch (InterruptedException ie) {
425 <            fail("Unexpected exception");
426 <        }
438 >    /**
439 >     * timed poll with nonzero timeout succeeds when non-empty, else times out
440 >     */
441 >    public void testTimedPoll() throws InterruptedException {
442 >        ArrayBlockingQueue q = populatedQueue(SIZE);
443 >        for (int i = 0; i < SIZE; ++i) {
444 >            long startTime = System.nanoTime();
445 >            assertEquals(i, q.poll(LONG_DELAY_MS, MILLISECONDS));
446 >            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
447 >        }
448 >        long startTime = System.nanoTime();
449 >        assertNull(q.poll(timeoutMillis(), MILLISECONDS));
450 >        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
451 >        checkEmpty(q);
452      }
453  
454 <    public void testTimedPollWithOffer(){
455 <        final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
456 <        Thread t = new Thread(new Runnable() {
457 <                public void run(){
458 <                    try {
459 <                        threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
460 <                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
461 <                        q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
462 <                        threadFail("Should block");
463 <                    } catch (InterruptedException success) { }                
454 >    /**
455 >     * Interrupted timed poll throws InterruptedException instead of
456 >     * returning timeout status
457 >     */
458 >    public void testInterruptedTimedPoll() throws InterruptedException {
459 >        final BlockingQueue<Integer> q = populatedQueue(SIZE);
460 >        final CountDownLatch aboutToWait = new CountDownLatch(1);
461 >        Thread t = newStartedThread(new CheckedRunnable() {
462 >            public void realRun() throws InterruptedException {
463 >                long startTime = System.nanoTime();
464 >                for (int i = 0; i < SIZE; ++i) {
465 >                    assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
466                  }
467 <            });
468 <        try {
469 <            t.start();
470 <            Thread.sleep(SMALL_DELAY_MS);
471 <            assertTrue(q.offer(zero, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
472 <            t.interrupt();
473 <            t.join();
474 <        } catch (Exception e){
475 <            fail("Unexpected exception");
476 <        }
477 <    }  
478 <
467 >                aboutToWait.countDown();
468 >                try {
469 >                    q.poll(LONG_DELAY_MS, MILLISECONDS);
470 >                    shouldThrow();
471 >                } catch (InterruptedException success) {
472 >                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
473 >                }
474 >            }});
475 >
476 >        await(aboutToWait);
477 >        waitForThreadToEnterWaitState(t);
478 >        t.interrupt();
479 >        awaitTermination(t);
480 >        checkEmpty(q);
481 >    }
482  
483 <    public void testPeek(){
483 >    /**
484 >     * peek returns next element, or null if empty
485 >     */
486 >    public void testPeek() {
487          ArrayBlockingQueue q = populatedQueue(SIZE);
488          for (int i = 0; i < SIZE; ++i) {
489 <            assertEquals(i, ((Integer)q.peek()).intValue());
490 <            q.poll();
489 >            assertEquals(i, q.peek());
490 >            assertEquals(i, q.poll());
491              assertTrue(q.peek() == null ||
492 <                       i != ((Integer)q.peek()).intValue());
492 >                       !q.peek().equals(i));
493          }
494 <        assertNull(q.peek());
494 >        assertNull(q.peek());
495      }
496  
497 <    public void testElement(){
497 >    /**
498 >     * element returns next element, or throws NSEE if empty
499 >     */
500 >    public void testElement() {
501          ArrayBlockingQueue q = populatedQueue(SIZE);
502          for (int i = 0; i < SIZE; ++i) {
503 <            assertEquals(i, ((Integer)q.element()).intValue());
504 <            q.poll();
503 >            assertEquals(i, q.element());
504 >            assertEquals(i, q.poll());
505          }
506          try {
507              q.element();
508 <            fail("no such element");
509 <        }
474 <        catch (NoSuchElementException success) {}
508 >            shouldThrow();
509 >        } catch (NoSuchElementException success) {}
510      }
511  
512 <    public void testRemove(){
512 >    /**
513 >     * remove removes next element, or throws NSEE if empty
514 >     */
515 >    public void testRemove() {
516          ArrayBlockingQueue q = populatedQueue(SIZE);
517          for (int i = 0; i < SIZE; ++i) {
518 <            assertEquals(i, ((Integer)q.remove()).intValue());
518 >            assertEquals(i, q.remove());
519          }
520          try {
521              q.remove();
522 <            fail("remove should throw");
523 <        } catch (NoSuchElementException success){
486 <        }  
522 >            shouldThrow();
523 >        } catch (NoSuchElementException success) {}
524      }
525  
526 <    public void testRemoveElement(){
527 <        ArrayBlockingQueue q = populatedQueue(SIZE);
528 <        for (int i = 1; i < SIZE; i+=2) {
529 <            assertTrue(q.remove(new Integer(i)));
493 <        }
494 <        for (int i = 0; i < SIZE; i+=2) {
495 <            assertTrue(q.remove(new Integer(i)));
496 <            assertFalse(q.remove(new Integer(i+1)));
497 <        }
498 <        assertTrue(q.isEmpty());
499 <    }
500 <        
501 <    public void testContains(){
526 >    /**
527 >     * contains(x) reports true when elements added but not yet removed
528 >     */
529 >    public void testContains() {
530          ArrayBlockingQueue q = populatedQueue(SIZE);
531          for (int i = 0; i < SIZE; ++i) {
532              assertTrue(q.contains(new Integer(i)));
533 <            q.poll();
533 >            assertEquals(i, q.poll());
534              assertFalse(q.contains(new Integer(i)));
535          }
536      }
537  
538 <    public void testClear(){
538 >    /**
539 >     * clear removes all elements
540 >     */
541 >    public void testClear() {
542          ArrayBlockingQueue q = populatedQueue(SIZE);
543          q.clear();
544          assertTrue(q.isEmpty());
# Line 515 | Line 546 | public class ArrayBlockingQueueTest exte
546          assertEquals(SIZE, q.remainingCapacity());
547          q.add(one);
548          assertFalse(q.isEmpty());
549 +        assertTrue(q.contains(one));
550          q.clear();
551          assertTrue(q.isEmpty());
552      }
553  
554 <    public void testContainsAll(){
554 >    /**
555 >     * containsAll(c) is true when c contains a subset of elements
556 >     */
557 >    public void testContainsAll() {
558          ArrayBlockingQueue q = populatedQueue(SIZE);
559          ArrayBlockingQueue p = new ArrayBlockingQueue(SIZE);
560          for (int i = 0; i < SIZE; ++i) {
# Line 530 | Line 565 | public class ArrayBlockingQueueTest exte
565          assertTrue(p.containsAll(q));
566      }
567  
568 <    public void testRetainAll(){
568 >    /**
569 >     * retainAll(c) retains only those elements of c and reports true if changed
570 >     */
571 >    public void testRetainAll() {
572          ArrayBlockingQueue q = populatedQueue(SIZE);
573          ArrayBlockingQueue p = populatedQueue(SIZE);
574          for (int i = 0; i < SIZE; ++i) {
# Line 541 | Line 579 | public class ArrayBlockingQueueTest exte
579                  assertTrue(changed);
580  
581              assertTrue(q.containsAll(p));
582 <            assertEquals(SIZE-i, q.size());
582 >            assertEquals(SIZE - i, q.size());
583              p.remove();
584          }
585      }
586  
587 <    public void testRemoveAll(){
587 >    /**
588 >     * removeAll(c) removes only those elements of c and reports true if changed
589 >     */
590 >    public void testRemoveAll() {
591          for (int i = 1; i < SIZE; ++i) {
592              ArrayBlockingQueue q = populatedQueue(SIZE);
593              ArrayBlockingQueue p = populatedQueue(i);
594              assertTrue(q.removeAll(p));
595 <            assertEquals(SIZE-i, q.size());
595 >            assertEquals(SIZE - i, q.size());
596              for (int j = 0; j < i; ++j) {
597 <                Integer I = (Integer)(p.remove());
598 <                assertFalse(q.contains(I));
597 >                Integer x = (Integer)(p.remove());
598 >                assertFalse(q.contains(x));
599 >            }
600 >        }
601 >    }
602 >
603 >    void checkToArray(ArrayBlockingQueue q) {
604 >        int size = q.size();
605 >        Object[] o = q.toArray();
606 >        assertEquals(size, o.length);
607 >        Iterator it = q.iterator();
608 >        for (int i = 0; i < size; i++) {
609 >            Integer x = (Integer) it.next();
610 >            assertEquals((Integer)o[0] + i, (int) x);
611 >            assertSame(o[i], x);
612 >        }
613 >    }
614 >
615 >    /**
616 >     * toArray() contains all elements in FIFO order
617 >     */
618 >    public void testToArray() {
619 >        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
620 >        for (int i = 0; i < SIZE; i++) {
621 >            checkToArray(q);
622 >            q.add(i);
623 >        }
624 >        // Provoke wraparound
625 >        for (int i = 0; i < SIZE; i++) {
626 >            checkToArray(q);
627 >            assertEquals(i, q.poll());
628 >            checkToArray(q);
629 >            q.add(SIZE + i);
630 >        }
631 >        for (int i = 0; i < SIZE; i++) {
632 >            checkToArray(q);
633 >            assertEquals(SIZE + i, q.poll());
634 >        }
635 >    }
636 >
637 >    void checkToArray2(ArrayBlockingQueue q) {
638 >        int size = q.size();
639 >        Integer[] a1 = (size == 0) ? null : new Integer[size - 1];
640 >        Integer[] a2 = new Integer[size];
641 >        Integer[] a3 = new Integer[size + 2];
642 >        if (size > 0) Arrays.fill(a1, 42);
643 >        Arrays.fill(a2, 42);
644 >        Arrays.fill(a3, 42);
645 >        Integer[] b1 = (size == 0) ? null : (Integer[]) q.toArray(a1);
646 >        Integer[] b2 = (Integer[]) q.toArray(a2);
647 >        Integer[] b3 = (Integer[]) q.toArray(a3);
648 >        assertSame(a2, b2);
649 >        assertSame(a3, b3);
650 >        Iterator it = q.iterator();
651 >        for (int i = 0; i < size; i++) {
652 >            Integer x = (Integer) it.next();
653 >            assertSame(b1[i], x);
654 >            assertEquals(b1[0] + i, (int) x);
655 >            assertSame(b2[i], x);
656 >            assertSame(b3[i], x);
657 >        }
658 >        assertNull(a3[size]);
659 >        assertEquals(42, (int) a3[size + 1]);
660 >        if (size > 0) {
661 >            assertNotSame(a1, b1);
662 >            assertEquals(size, b1.length);
663 >            for (int i = 0; i < a1.length; i++) {
664 >                assertEquals(42, (int) a1[i]);
665              }
666          }
667      }
668  
669 +    /**
670 +     * toArray(a) contains all elements in FIFO order
671 +     */
672 +    public void testToArray2() {
673 +        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
674 +        for (int i = 0; i < SIZE; i++) {
675 +            checkToArray2(q);
676 +            q.add(i);
677 +        }
678 +        // Provoke wraparound
679 +        for (int i = 0; i < SIZE; i++) {
680 +            checkToArray2(q);
681 +            assertEquals(i, q.poll());
682 +            checkToArray2(q);
683 +            q.add(SIZE + i);
684 +        }
685 +        for (int i = 0; i < SIZE; i++) {
686 +            checkToArray2(q);
687 +            assertEquals(SIZE + i, q.poll());
688 +        }
689 +    }
690  
691 <    public void testToArray(){
691 >    /**
692 >     * toArray(incompatible array type) throws ArrayStoreException
693 >     */
694 >    public void testToArray1_BadArg() {
695          ArrayBlockingQueue q = populatedQueue(SIZE);
696 <        Object[] o = q.toArray();
697 <        try {
698 <        for(int i = 0; i < o.length; i++)
699 <            assertEquals(o[i], q.take());
569 <        } catch (InterruptedException e){
570 <            fail("Unexpected exception");
571 <        }    
572 <    }
573 <
574 <    public void testToArray2(){
575 <        ArrayBlockingQueue q = populatedQueue(SIZE);
576 <        Integer[] ints = new Integer[SIZE];
577 <        ints = (Integer[])q.toArray(ints);
578 <        try {
579 <            for(int i = 0; i < ints.length; i++)
580 <                assertEquals(ints[i], q.take());
581 <        } catch (InterruptedException e){
582 <            fail("Unexpected exception");
583 <        }    
584 <    }
585 <    
586 <    public void testIterator(){
587 <        ArrayBlockingQueue q = populatedQueue(SIZE);
588 <        Iterator it = q.iterator();
589 <        try {
590 <            while(it.hasNext()){
591 <                assertEquals(it.next(), q.take());
592 <            }
593 <        } catch (InterruptedException e){
594 <            fail("Unexpected exception");
595 <        }    
696 >        try {
697 >            q.toArray(new String[10]);
698 >            shouldThrow();
699 >        } catch (ArrayStoreException success) {}
700      }
701  
702 <    public void testIteratorOrdering() {
702 >    /**
703 >     * iterator iterates through all elements
704 >     */
705 >    public void testIterator() throws InterruptedException {
706 >        ArrayBlockingQueue q = populatedQueue(SIZE);
707 >        Iterator it = q.iterator();
708 >        int i;
709 >        for (i = 0; it.hasNext(); i++)
710 >            assertTrue(q.contains(it.next()));
711 >        assertEquals(i, SIZE);
712 >        assertIteratorExhausted(it);
713 >
714 >        it = q.iterator();
715 >        for (i = 0; it.hasNext(); i++)
716 >            assertEquals(it.next(), q.take());
717 >        assertEquals(i, SIZE);
718 >        assertIteratorExhausted(it);
719 >    }
720 >
721 >    /**
722 >     * iterator of empty collection has no elements
723 >     */
724 >    public void testEmptyIterator() {
725 >        assertIteratorExhausted(new ArrayBlockingQueue(SIZE).iterator());
726 >    }
727  
728 +    /**
729 +     * iterator.remove removes current element
730 +     */
731 +    public void testIteratorRemove() {
732          final ArrayBlockingQueue q = new ArrayBlockingQueue(3);
733 +        q.add(two);
734 +        q.add(one);
735 +        q.add(three);
736 +
737 +        Iterator it = q.iterator();
738 +        it.next();
739 +        it.remove();
740 +
741 +        it = q.iterator();
742 +        assertSame(it.next(), one);
743 +        assertSame(it.next(), three);
744 +        assertFalse(it.hasNext());
745 +    }
746  
747 +    /**
748 +     * iterator ordering is FIFO
749 +     */
750 +    public void testIteratorOrdering() {
751 +        final ArrayBlockingQueue q = new ArrayBlockingQueue(3);
752          q.add(one);
753          q.add(two);
754          q.add(three);
# Line 607 | Line 757 | public class ArrayBlockingQueueTest exte
757  
758          int k = 0;
759          for (Iterator it = q.iterator(); it.hasNext();) {
760 <            int i = ((Integer)(it.next())).intValue();
611 <            assertEquals("items should come out in order", ++k, i);
760 >            assertEquals(++k, it.next());
761          }
762 <
614 <        assertEquals("should go through 3 elements", 3, k);
762 >        assertEquals(3, k);
763      }
764  
765 <    public void testWeaklyConsistentIteration () {
766 <
765 >    /**
766 >     * Modifications do not cause iterators to fail
767 >     */
768 >    public void testWeaklyConsistentIteration() {
769          final ArrayBlockingQueue q = new ArrayBlockingQueue(3);
620
770          q.add(one);
771          q.add(two);
772          q.add(three);
773 <
774 <        try {
775 <            for (Iterator it = q.iterator(); it.hasNext();) {
627 <                q.remove();
628 <                it.next();
629 <            }
630 <        }
631 <        catch (ConcurrentModificationException e) {
632 <            fail("weakly consistent iterator; should not get CME");
773 >        for (Iterator it = q.iterator(); it.hasNext();) {
774 >            q.remove();
775 >            it.next();
776          }
777 <
635 <        assertEquals("queue should be empty again", 0, q.size());
777 >        assertEquals(0, q.size());
778      }
779  
780 <
781 <    public void testToString(){
780 >    /**
781 >     * toString contains toStrings of elements
782 >     */
783 >    public void testToString() {
784          ArrayBlockingQueue q = populatedQueue(SIZE);
785          String s = q.toString();
786          for (int i = 0; i < SIZE; ++i) {
787 <            assertTrue(s.indexOf(String.valueOf(i)) >= 0);
787 >            assertTrue(s.contains(String.valueOf(i)));
788          }
789 <    }        
646 <
789 >    }
790  
791 +    /**
792 +     * offer transfers elements across Executor tasks
793 +     */
794      public void testOfferInExecutor() {
649
795          final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
651
796          q.add(one);
797          q.add(two);
798 +        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
799 +        final ExecutorService executor = Executors.newFixedThreadPool(2);
800 +        try (PoolCleaner cleaner = cleaner(executor)) {
801 +            executor.execute(new CheckedRunnable() {
802 +                public void realRun() throws InterruptedException {
803 +                    assertFalse(q.offer(three));
804 +                    threadsStarted.await();
805 +                    assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
806 +                    assertEquals(0, q.remainingCapacity());
807 +                }});
808  
809 <        ExecutorService executor = Executors.newFixedThreadPool(2);
810 <
811 <        executor.execute(new Runnable() {
812 <            public void run() {
813 <                threadAssertFalse(q.offer(three));
814 <                try {
815 <                    threadAssertTrue(q.offer(three, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
662 <                    threadAssertEquals(0, q.remainingCapacity());
663 <                }
664 <                catch (InterruptedException e) {
665 <                    threadFail("should not be interrupted");
666 <                }
667 <            }
668 <        });
669 <
670 <        executor.execute(new Runnable() {
671 <            public void run() {
672 <                try {
673 <                    Thread.sleep(SMALL_DELAY_MS);
674 <                    threadAssertEquals(one, q.take());
675 <                }
676 <                catch (InterruptedException e) {
677 <                    threadFail("should not be interrupted");
678 <                }
679 <            }
680 <        });
681 <        
682 <        joinPool(executor);
683 <
809 >            executor.execute(new CheckedRunnable() {
810 >                public void realRun() throws InterruptedException {
811 >                    threadsStarted.await();
812 >                    assertEquals(0, q.remainingCapacity());
813 >                    assertSame(one, q.take());
814 >                }});
815 >        }
816      }
817  
818 +    /**
819 +     * timed poll retrieves elements across Executor threads
820 +     */
821      public void testPollInExecutor() {
687
822          final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
823 +        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
824 +        final ExecutorService executor = Executors.newFixedThreadPool(2);
825 +        try (PoolCleaner cleaner = cleaner(executor)) {
826 +            executor.execute(new CheckedRunnable() {
827 +                public void realRun() throws InterruptedException {
828 +                    assertNull(q.poll());
829 +                    threadsStarted.await();
830 +                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
831 +                    checkEmpty(q);
832 +                }});
833  
834 <        ExecutorService executor = Executors.newFixedThreadPool(2);
835 <
836 <        executor.execute(new Runnable() {
693 <            public void run() {
694 <                threadAssertNull(q.poll());
695 <                try {
696 <                    threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
697 <                    threadAssertTrue(q.isEmpty());
698 <                }
699 <                catch (InterruptedException e) {
700 <                    threadFail("should not be interrupted");
701 <                }
702 <            }
703 <        });
704 <
705 <        executor.execute(new Runnable() {
706 <            public void run() {
707 <                try {
708 <                    Thread.sleep(SMALL_DELAY_MS);
834 >            executor.execute(new CheckedRunnable() {
835 >                public void realRun() throws InterruptedException {
836 >                    threadsStarted.await();
837                      q.put(one);
838 <                }
839 <                catch (InterruptedException e) {
840 <                    threadFail("should not be interrupted");
713 <                }
714 <            }
715 <        });
716 <        
717 <        joinPool(executor);
838 >                }});
839 >        }
840 >    }
841  
842 +    /**
843 +     * A deserialized serialized queue has same elements in same order
844 +     */
845 +    public void testSerialization() throws Exception {
846 +        Queue x = populatedQueue(SIZE);
847 +        Queue y = serialClone(x);
848 +
849 +        assertNotSame(x, y);
850 +        assertEquals(x.size(), y.size());
851 +        assertEquals(x.toString(), y.toString());
852 +        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
853 +        while (!x.isEmpty()) {
854 +            assertFalse(y.isEmpty());
855 +            assertEquals(x.remove(), y.remove());
856 +        }
857 +        assertTrue(y.isEmpty());
858      }
859  
860 <    public void testSerialization() {
860 >    /**
861 >     * drainTo(c) empties queue into another collection c
862 >     */
863 >    public void testDrainTo() {
864          ArrayBlockingQueue q = populatedQueue(SIZE);
865 +        ArrayList l = new ArrayList();
866 +        q.drainTo(l);
867 +        assertEquals(0, q.size());
868 +        assertEquals(SIZE, l.size());
869 +        for (int i = 0; i < SIZE; ++i)
870 +            assertEquals(l.get(i), new Integer(i));
871 +        q.add(zero);
872 +        q.add(one);
873 +        assertFalse(q.isEmpty());
874 +        assertTrue(q.contains(zero));
875 +        assertTrue(q.contains(one));
876 +        l.clear();
877 +        q.drainTo(l);
878 +        assertEquals(0, q.size());
879 +        assertEquals(2, l.size());
880 +        for (int i = 0; i < 2; ++i)
881 +            assertEquals(l.get(i), new Integer(i));
882 +    }
883  
884 <        try {
885 <            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
886 <            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
887 <            out.writeObject(q);
888 <            out.close();
884 >    /**
885 >     * drainTo empties full queue, unblocking a waiting put.
886 >     */
887 >    public void testDrainToWithActivePut() throws InterruptedException {
888 >        final ArrayBlockingQueue q = populatedQueue(SIZE);
889 >        Thread t = new Thread(new CheckedRunnable() {
890 >            public void realRun() throws InterruptedException {
891 >                q.put(new Integer(SIZE + 1));
892 >            }});
893 >
894 >        t.start();
895 >        ArrayList l = new ArrayList();
896 >        q.drainTo(l);
897 >        assertTrue(l.size() >= SIZE);
898 >        for (int i = 0; i < SIZE; ++i)
899 >            assertEquals(l.get(i), new Integer(i));
900 >        t.join();
901 >        assertTrue(q.size() + l.size() >= SIZE);
902 >    }
903  
904 <            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
905 <            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
906 <            ArrayBlockingQueue r = (ArrayBlockingQueue)in.readObject();
907 <            assertEquals(q.size(), r.size());
908 <            while (!q.isEmpty())
909 <                assertEquals(q.remove(), r.remove());
910 <        } catch(Exception e){
911 <            fail("unexpected exception");
904 >    /**
905 >     * drainTo(c, n) empties first min(n, size) elements of queue into c
906 >     */
907 >    public void testDrainToN() {
908 >        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE * 2);
909 >        for (int i = 0; i < SIZE + 2; ++i) {
910 >            for (int j = 0; j < SIZE; j++)
911 >                assertTrue(q.offer(new Integer(j)));
912 >            ArrayList l = new ArrayList();
913 >            q.drainTo(l, i);
914 >            int k = (i < SIZE) ? i : SIZE;
915 >            assertEquals(k, l.size());
916 >            assertEquals(SIZE - k, q.size());
917 >            for (int j = 0; j < k; ++j)
918 >                assertEquals(l.get(j), new Integer(j));
919 >            do {} while (q.poll() != null);
920          }
921      }
922  
923 <
923 >    /**
924 >     * remove(null), contains(null) always return false
925 >     */
926 >    public void testNeverContainsNull() {
927 >        Collection<?>[] qs = {
928 >            new ArrayBlockingQueue<Object>(10),
929 >            populatedQueue(2),
930 >        };
931 >
932 >        for (Collection<?> q : qs) {
933 >            assertFalse(q.contains(null));
934 >            assertFalse(q.remove(null));
935 >        }
936 >    }
937   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines