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