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