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