1/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 */
22
23/*
24 * This file is available under and governed by the GNU General Public
25 * License version 2 only, as published by the Free Software Foundation.
26 * However, the following notice accompanied the original version of this
27 * file:
28 *
29 * Written by Doug Lea with assistance from members of JCP JSR-166
30 * Expert Group and released to the public domain, as explained at
31 * http://creativecommons.org/publicdomain/zero/1.0/
32 * Other contributors include Andrew Wright, Jeffrey Hayes,
33 * Pat Fisher, Mike Judd.
34 */
35
36import static java.util.concurrent.TimeUnit.MILLISECONDS;
37
38import java.util.ArrayList;
39import java.util.Arrays;
40import java.util.Collection;
41import java.util.Comparator;
42import java.util.Iterator;
43import java.util.NoSuchElementException;
44import java.util.Queue;
45import java.util.concurrent.BlockingQueue;
46import java.util.concurrent.CountDownLatch;
47import java.util.concurrent.Executors;
48import java.util.concurrent.ExecutorService;
49import java.util.concurrent.PriorityBlockingQueue;
50
51import junit.framework.Test;
52
53public class PriorityBlockingQueueTest extends JSR166TestCase {
54
55    public static class Generic extends BlockingQueueTest {
56        protected BlockingQueue emptyCollection() {
57            return new PriorityBlockingQueue();
58        }
59    }
60
61    public static class InitialCapacity extends BlockingQueueTest {
62        protected BlockingQueue emptyCollection() {
63            return new PriorityBlockingQueue(SIZE);
64        }
65    }
66
67    public static void main(String[] args) {
68        main(suite(), args);
69    }
70
71    public static Test suite() {
72        class Implementation implements CollectionImplementation {
73            public Class<?> klazz() { return PriorityBlockingQueue.class; }
74            public Collection emptyCollection() { return new PriorityBlockingQueue(); }
75            public Object makeElement(int i) { return i; }
76            public boolean isConcurrent() { return true; }
77            public boolean permitsNulls() { return false; }
78        }
79        return newTestSuite(PriorityBlockingQueueTest.class,
80                            new Generic().testSuite(),
81                            new InitialCapacity().testSuite(),
82                            CollectionTest.testSuite(new Implementation()));
83    }
84
85    /** Sample Comparator */
86    static class MyReverseComparator implements Comparator {
87        public int compare(Object x, Object y) {
88            return ((Comparable)y).compareTo(x);
89        }
90    }
91
92    /**
93     * Returns a new queue of given size containing consecutive
94     * Integers 0 ... n - 1.
95     */
96    private PriorityBlockingQueue<Integer> populatedQueue(int n) {
97        PriorityBlockingQueue<Integer> q =
98            new PriorityBlockingQueue<Integer>(n);
99        assertTrue(q.isEmpty());
100        for (int i = n - 1; i >= 0; i -= 2)
101            assertTrue(q.offer(new Integer(i)));
102        for (int i = (n & 1); i < n; i += 2)
103            assertTrue(q.offer(new Integer(i)));
104        assertFalse(q.isEmpty());
105        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
106        assertEquals(n, q.size());
107        assertEquals((Integer) 0, q.peek());
108        return q;
109    }
110
111    /**
112     * A new queue has unbounded capacity
113     */
114    public void testConstructor1() {
115        assertEquals(Integer.MAX_VALUE,
116                     new PriorityBlockingQueue(SIZE).remainingCapacity());
117    }
118
119    /**
120     * Constructor throws IAE if capacity argument nonpositive
121     */
122    public void testConstructor2() {
123        try {
124            new PriorityBlockingQueue(0);
125            shouldThrow();
126        } catch (IllegalArgumentException success) {}
127    }
128
129    /**
130     * Initializing from null Collection throws NPE
131     */
132    public void testConstructor3() {
133        try {
134            new PriorityBlockingQueue(null);
135            shouldThrow();
136        } catch (NullPointerException success) {}
137    }
138
139    /**
140     * Initializing from Collection of null elements throws NPE
141     */
142    public void testConstructor4() {
143        Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
144        try {
145            new PriorityBlockingQueue(elements);
146            shouldThrow();
147        } catch (NullPointerException success) {}
148    }
149
150    /**
151     * Initializing from Collection with some null elements throws NPE
152     */
153    public void testConstructor5() {
154        Integer[] ints = new Integer[SIZE];
155        for (int i = 0; i < SIZE - 1; ++i)
156            ints[i] = i;
157        Collection<Integer> elements = Arrays.asList(ints);
158        try {
159            new PriorityBlockingQueue(elements);
160            shouldThrow();
161        } catch (NullPointerException success) {}
162    }
163
164    /**
165     * Queue contains all elements of collection used to initialize
166     */
167    public void testConstructor6() {
168        Integer[] ints = new Integer[SIZE];
169        for (int i = 0; i < SIZE; ++i)
170            ints[i] = i;
171        PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints));
172        for (int i = 0; i < SIZE; ++i)
173            assertEquals(ints[i], q.poll());
174    }
175
176    /**
177     * The comparator used in constructor is used
178     */
179    public void testConstructor7() {
180        MyReverseComparator cmp = new MyReverseComparator();
181        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE, cmp);
182        assertEquals(cmp, q.comparator());
183        Integer[] ints = new Integer[SIZE];
184        for (int i = 0; i < SIZE; ++i)
185            ints[i] = new Integer(i);
186        q.addAll(Arrays.asList(ints));
187        for (int i = SIZE - 1; i >= 0; --i)
188            assertEquals(ints[i], q.poll());
189    }
190
191    /**
192     * isEmpty is true before add, false after
193     */
194    public void testEmpty() {
195        PriorityBlockingQueue q = new PriorityBlockingQueue(2);
196        assertTrue(q.isEmpty());
197        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
198        q.add(one);
199        assertFalse(q.isEmpty());
200        q.add(two);
201        q.remove();
202        q.remove();
203        assertTrue(q.isEmpty());
204    }
205
206    /**
207     * remainingCapacity() always returns Integer.MAX_VALUE
208     */
209    public void testRemainingCapacity() {
210        BlockingQueue q = populatedQueue(SIZE);
211        for (int i = 0; i < SIZE; ++i) {
212            assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
213            assertEquals(SIZE - i, q.size());
214            assertEquals(i, q.remove());
215        }
216        for (int i = 0; i < SIZE; ++i) {
217            assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
218            assertEquals(i, q.size());
219            assertTrue(q.add(i));
220        }
221    }
222
223    /**
224     * Offer of comparable element succeeds
225     */
226    public void testOffer() {
227        PriorityBlockingQueue q = new PriorityBlockingQueue(1);
228        assertTrue(q.offer(zero));
229        assertTrue(q.offer(one));
230    }
231
232    /**
233     * Offer of non-Comparable throws CCE
234     */
235    public void testOfferNonComparable() {
236        PriorityBlockingQueue q = new PriorityBlockingQueue(1);
237        try {
238            q.offer(new Object());
239            shouldThrow();
240        } catch (ClassCastException success) {
241            assertTrue(q.isEmpty());
242            assertEquals(0, q.size());
243            assertNull(q.poll());
244        }
245    }
246
247    /**
248     * add of comparable succeeds
249     */
250    public void testAdd() {
251        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
252        for (int i = 0; i < SIZE; ++i) {
253            assertEquals(i, q.size());
254            assertTrue(q.add(new Integer(i)));
255        }
256    }
257
258    /**
259     * addAll(this) throws IAE
260     */
261    public void testAddAllSelf() {
262        PriorityBlockingQueue q = populatedQueue(SIZE);
263        try {
264            q.addAll(q);
265            shouldThrow();
266        } catch (IllegalArgumentException success) {}
267    }
268
269    /**
270     * addAll of a collection with any null elements throws NPE after
271     * possibly adding some elements
272     */
273    public void testAddAll3() {
274        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
275        Integer[] ints = new Integer[SIZE];
276        for (int i = 0; i < SIZE - 1; ++i)
277            ints[i] = new Integer(i);
278        try {
279            q.addAll(Arrays.asList(ints));
280            shouldThrow();
281        } catch (NullPointerException success) {}
282    }
283
284    /**
285     * Queue contains all elements of successful addAll
286     */
287    public void testAddAll5() {
288        Integer[] empty = new Integer[0];
289        Integer[] ints = new Integer[SIZE];
290        for (int i = SIZE - 1; i >= 0; --i)
291            ints[i] = new Integer(i);
292        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
293        assertFalse(q.addAll(Arrays.asList(empty)));
294        assertTrue(q.addAll(Arrays.asList(ints)));
295        for (int i = 0; i < SIZE; ++i)
296            assertEquals(ints[i], q.poll());
297    }
298
299    /**
300     * all elements successfully put are contained
301     */
302    public void testPut() {
303        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
304        for (int i = 0; i < SIZE; ++i) {
305            Integer x = new Integer(i);
306            q.put(x);
307            assertTrue(q.contains(x));
308        }
309        assertEquals(SIZE, q.size());
310    }
311
312    /**
313     * put doesn't block waiting for take
314     */
315    public void testPutWithTake() throws InterruptedException {
316        final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
317        final int size = 4;
318        Thread t = newStartedThread(new CheckedRunnable() {
319            public void realRun() {
320                for (int i = 0; i < size; i++)
321                    q.put(new Integer(0));
322            }});
323
324        awaitTermination(t);
325        assertEquals(size, q.size());
326        q.take();
327    }
328
329    /**
330     * timed offer does not time out
331     */
332    public void testTimedOffer() throws InterruptedException {
333        final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
334        Thread t = newStartedThread(new CheckedRunnable() {
335            public void realRun() {
336                q.put(new Integer(0));
337                q.put(new Integer(0));
338                assertTrue(q.offer(new Integer(0), SHORT_DELAY_MS, MILLISECONDS));
339                assertTrue(q.offer(new Integer(0), LONG_DELAY_MS, MILLISECONDS));
340            }});
341
342        awaitTermination(t);
343    }
344
345    /**
346     * take retrieves elements in priority order
347     */
348    public void testTake() throws InterruptedException {
349        PriorityBlockingQueue q = populatedQueue(SIZE);
350        for (int i = 0; i < SIZE; ++i) {
351            assertEquals(i, q.take());
352        }
353    }
354
355    /**
356     * Take removes existing elements until empty, then blocks interruptibly
357     */
358    public void testBlockingTake() throws InterruptedException {
359        final PriorityBlockingQueue q = populatedQueue(SIZE);
360        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
361        Thread t = newStartedThread(new CheckedRunnable() {
362            public void realRun() throws InterruptedException {
363                for (int i = 0; i < SIZE; ++i) {
364                    assertEquals(i, q.take());
365                }
366
367                Thread.currentThread().interrupt();
368                try {
369                    q.take();
370                    shouldThrow();
371                } catch (InterruptedException success) {}
372                assertFalse(Thread.interrupted());
373
374                pleaseInterrupt.countDown();
375                try {
376                    q.take();
377                    shouldThrow();
378                } catch (InterruptedException success) {}
379                assertFalse(Thread.interrupted());
380            }});
381
382        await(pleaseInterrupt);
383        assertThreadStaysAlive(t);
384        t.interrupt();
385        awaitTermination(t);
386    }
387
388    /**
389     * poll succeeds unless empty
390     */
391    public void testPoll() {
392        PriorityBlockingQueue q = populatedQueue(SIZE);
393        for (int i = 0; i < SIZE; ++i) {
394            assertEquals(i, q.poll());
395        }
396        assertNull(q.poll());
397    }
398
399    /**
400     * timed poll with zero timeout succeeds when non-empty, else times out
401     */
402    public void testTimedPoll0() throws InterruptedException {
403        PriorityBlockingQueue q = populatedQueue(SIZE);
404        for (int i = 0; i < SIZE; ++i) {
405            assertEquals(i, q.poll(0, MILLISECONDS));
406        }
407        assertNull(q.poll(0, MILLISECONDS));
408    }
409
410    /**
411     * timed poll with nonzero timeout succeeds when non-empty, else times out
412     */
413    public void testTimedPoll() throws InterruptedException {
414        PriorityBlockingQueue<Integer> q = populatedQueue(SIZE);
415        for (int i = 0; i < SIZE; ++i) {
416            long startTime = System.nanoTime();
417            assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
418            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
419        }
420        long startTime = System.nanoTime();
421        assertNull(q.poll(timeoutMillis(), MILLISECONDS));
422        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
423        checkEmpty(q);
424    }
425
426    /**
427     * Interrupted timed poll throws InterruptedException instead of
428     * returning timeout status
429     */
430    public void testInterruptedTimedPoll() throws InterruptedException {
431        final BlockingQueue<Integer> q = populatedQueue(SIZE);
432        final CountDownLatch aboutToWait = new CountDownLatch(1);
433        Thread t = newStartedThread(new CheckedRunnable() {
434            public void realRun() throws InterruptedException {
435                long startTime = System.nanoTime();
436                for (int i = 0; i < SIZE; ++i) {
437                    assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
438                }
439                aboutToWait.countDown();
440                try {
441                    q.poll(LONG_DELAY_MS, MILLISECONDS);
442                    shouldThrow();
443                } catch (InterruptedException success) {
444                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
445                }
446            }});
447
448        aboutToWait.await();
449        waitForThreadToEnterWaitState(t);
450        t.interrupt();
451        awaitTermination(t);
452    }
453
454    /**
455     * peek returns next element, or null if empty
456     */
457    public void testPeek() {
458        PriorityBlockingQueue 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     */
471    public void testElement() {
472        PriorityBlockingQueue 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     */
486    public void testRemove() {
487        PriorityBlockingQueue 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     */
500    public void testContains() {
501        PriorityBlockingQueue q = populatedQueue(SIZE);
502        for (int i = 0; i < SIZE; ++i) {
503            assertTrue(q.contains(new Integer(i)));
504            q.poll();
505            assertFalse(q.contains(new Integer(i)));
506        }
507    }
508
509    /**
510     * clear removes all elements
511     */
512    public void testClear() {
513        PriorityBlockingQueue q = populatedQueue(SIZE);
514        q.clear();
515        assertTrue(q.isEmpty());
516        assertEquals(0, q.size());
517        q.add(one);
518        assertFalse(q.isEmpty());
519        assertTrue(q.contains(one));
520        q.clear();
521        assertTrue(q.isEmpty());
522    }
523
524    /**
525     * containsAll(c) is true when c contains a subset of elements
526     */
527    public void testContainsAll() {
528        PriorityBlockingQueue q = populatedQueue(SIZE);
529        PriorityBlockingQueue p = new PriorityBlockingQueue(SIZE);
530        for (int i = 0; i < SIZE; ++i) {
531            assertTrue(q.containsAll(p));
532            assertFalse(p.containsAll(q));
533            p.add(new Integer(i));
534        }
535        assertTrue(p.containsAll(q));
536    }
537
538    /**
539     * retainAll(c) retains only those elements of c and reports true if changed
540     */
541    public void testRetainAll() {
542        PriorityBlockingQueue q = populatedQueue(SIZE);
543        PriorityBlockingQueue p = populatedQueue(SIZE);
544        for (int i = 0; i < SIZE; ++i) {
545            boolean changed = q.retainAll(p);
546            if (i == 0)
547                assertFalse(changed);
548            else
549                assertTrue(changed);
550
551            assertTrue(q.containsAll(p));
552            assertEquals(SIZE - i, q.size());
553            p.remove();
554        }
555    }
556
557    /**
558     * removeAll(c) removes only those elements of c and reports true if changed
559     */
560    public void testRemoveAll() {
561        for (int i = 1; i < SIZE; ++i) {
562            PriorityBlockingQueue q = populatedQueue(SIZE);
563            PriorityBlockingQueue p = populatedQueue(i);
564            assertTrue(q.removeAll(p));
565            assertEquals(SIZE - i, q.size());
566            for (int j = 0; j < i; ++j) {
567                Integer x = (Integer)(p.remove());
568                assertFalse(q.contains(x));
569            }
570        }
571    }
572
573    /**
574     * toArray contains all elements
575     */
576    public void testToArray() throws InterruptedException {
577        PriorityBlockingQueue q = populatedQueue(SIZE);
578        Object[] o = q.toArray();
579        Arrays.sort(o);
580        for (int i = 0; i < o.length; i++)
581            assertSame(o[i], q.take());
582    }
583
584    /**
585     * toArray(a) contains all elements
586     */
587    public void testToArray2() throws InterruptedException {
588        PriorityBlockingQueue<Integer> q = populatedQueue(SIZE);
589        Integer[] ints = new Integer[SIZE];
590        Integer[] array = q.toArray(ints);
591        assertSame(ints, array);
592        Arrays.sort(ints);
593        for (int i = 0; i < ints.length; i++)
594            assertSame(ints[i], q.take());
595    }
596
597    /**
598     * toArray(incompatible array type) throws ArrayStoreException
599     */
600    public void testToArray1_BadArg() {
601        PriorityBlockingQueue q = populatedQueue(SIZE);
602        try {
603            q.toArray(new String[10]);
604            shouldThrow();
605        } catch (ArrayStoreException success) {}
606    }
607
608    /**
609     * iterator iterates through all elements
610     */
611    public void testIterator() {
612        PriorityBlockingQueue q = populatedQueue(SIZE);
613        Iterator it = q.iterator();
614        int i;
615        for (i = 0; it.hasNext(); i++)
616            assertTrue(q.contains(it.next()));
617        assertEquals(i, SIZE);
618        assertIteratorExhausted(it);
619    }
620
621    /**
622     * iterator of empty collection has no elements
623     */
624    public void testEmptyIterator() {
625        assertIteratorExhausted(new PriorityBlockingQueue().iterator());
626    }
627
628    /**
629     * iterator.remove removes current element
630     */
631    public void testIteratorRemove() {
632        final PriorityBlockingQueue q = new PriorityBlockingQueue(3);
633        q.add(new Integer(2));
634        q.add(new Integer(1));
635        q.add(new Integer(3));
636
637        Iterator it = q.iterator();
638        it.next();
639        it.remove();
640
641        it = q.iterator();
642        assertEquals(it.next(), new Integer(2));
643        assertEquals(it.next(), new Integer(3));
644        assertFalse(it.hasNext());
645    }
646
647    /**
648     * toString contains toStrings of elements
649     */
650    public void testToString() {
651        PriorityBlockingQueue q = populatedQueue(SIZE);
652        String s = q.toString();
653        for (int i = 0; i < SIZE; ++i) {
654            assertTrue(s.contains(String.valueOf(i)));
655        }
656    }
657
658    /**
659     * timed poll transfers elements across Executor tasks
660     */
661    public void testPollInExecutor() {
662        final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
663        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
664        final ExecutorService executor = Executors.newFixedThreadPool(2);
665        try (PoolCleaner cleaner = cleaner(executor)) {
666            executor.execute(new CheckedRunnable() {
667                public void realRun() throws InterruptedException {
668                    assertNull(q.poll());
669                    threadsStarted.await();
670                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
671                    checkEmpty(q);
672                }});
673
674            executor.execute(new CheckedRunnable() {
675                public void realRun() throws InterruptedException {
676                    threadsStarted.await();
677                    q.put(one);
678                }});
679        }
680    }
681
682    /**
683     * A deserialized serialized queue has same elements
684     */
685    public void testSerialization() throws Exception {
686        Queue x = populatedQueue(SIZE);
687        Queue y = serialClone(x);
688
689        assertNotSame(x, y);
690        assertEquals(x.size(), y.size());
691        while (!x.isEmpty()) {
692            assertFalse(y.isEmpty());
693            assertEquals(x.remove(), y.remove());
694        }
695        assertTrue(y.isEmpty());
696    }
697
698    /**
699     * drainTo(c) empties queue into another collection c
700     */
701    public void testDrainTo() {
702        PriorityBlockingQueue q = populatedQueue(SIZE);
703        ArrayList l = new ArrayList();
704        q.drainTo(l);
705        assertEquals(0, q.size());
706        assertEquals(SIZE, l.size());
707        for (int i = 0; i < SIZE; ++i)
708            assertEquals(l.get(i), new Integer(i));
709        q.add(zero);
710        q.add(one);
711        assertFalse(q.isEmpty());
712        assertTrue(q.contains(zero));
713        assertTrue(q.contains(one));
714        l.clear();
715        q.drainTo(l);
716        assertEquals(0, q.size());
717        assertEquals(2, l.size());
718        for (int i = 0; i < 2; ++i)
719            assertEquals(l.get(i), new Integer(i));
720    }
721
722    /**
723     * drainTo empties queue
724     */
725    public void testDrainToWithActivePut() throws InterruptedException {
726        final PriorityBlockingQueue q = populatedQueue(SIZE);
727        Thread t = new Thread(new CheckedRunnable() {
728            public void realRun() {
729                q.put(new Integer(SIZE + 1));
730            }});
731
732        t.start();
733        ArrayList l = new ArrayList();
734        q.drainTo(l);
735        assertTrue(l.size() >= SIZE);
736        for (int i = 0; i < SIZE; ++i)
737            assertEquals(l.get(i), new Integer(i));
738        t.join();
739        assertTrue(q.size() + l.size() >= SIZE);
740    }
741
742    /**
743     * drainTo(c, n) empties first min(n, size) elements of queue into c
744     */
745    public void testDrainToN() {
746        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE * 2);
747        for (int i = 0; i < SIZE + 2; ++i) {
748            for (int j = 0; j < SIZE; j++)
749                assertTrue(q.offer(new Integer(j)));
750            ArrayList l = new ArrayList();
751            q.drainTo(l, i);
752            int k = (i < SIZE) ? i : SIZE;
753            assertEquals(k, l.size());
754            assertEquals(SIZE - k, q.size());
755            for (int j = 0; j < k; ++j)
756                assertEquals(l.get(j), new Integer(j));
757            do {} while (q.poll() != null);
758        }
759    }
760
761    /**
762     * remove(null), contains(null) always return false
763     */
764    public void testNeverContainsNull() {
765        Collection<?>[] qs = {
766            new PriorityBlockingQueue<Object>(),
767            populatedQueue(2),
768        };
769
770        for (Collection<?> q : qs) {
771            assertFalse(q.contains(null));
772            assertFalse(q.remove(null));
773        }
774    }
775
776}
777