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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines