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