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.concurrent.BlockingQueue;
19 import java.util.concurrent.CountDownLatch;
20 import java.util.concurrent.Delayed;
21 import java.util.concurrent.DelayQueue;
22 import java.util.concurrent.Executors;
23 import java.util.concurrent.ExecutorService;
24 import java.util.concurrent.TimeUnit;
25 
26 import junit.framework.Test;
27 
28 public class DelayQueueTest extends JSR166TestCase {
29 
30     // Android-changed: Extend BlockingQueueTest directly instead of creating
31     // an inner class and its associated suite.
32     //
33     // public static class Generic extends BlockingQueueTest {
34     //     protected BlockingQueue emptyCollection() {
35     //         return new DelayQueue();
36     //     }
37     //     protected PDelay makeElement(int i) {
38     //         return new PDelay(i);
39     //     }
40     // }
41 
42     // android-note: Removed because the CTS runner does a bad job of
43     // retrying tests that have suite() declarations.
44     //
45     // public static void main(String[] args) {
46     //     main(suite(), args);
47     // }
48     // public static Test suite() {
49     //     return newTestSuite(DelayQueueTest.class,
50     //                         new Generic().testSuite());
51     // }
52 
emptyCollection()53     protected BlockingQueue emptyCollection() {
54         return new DelayQueue();
55     }
56 
makeElement(int i)57     protected PDelay makeElement(int i) {
58         return new PDelay(i);
59     }
60 
61     /**
62      * A delayed implementation for testing.
63      * Most tests use Pseudodelays, where delays are all elapsed
64      * (so, no blocking solely for delays) but are still ordered
65      */
66     static class PDelay implements Delayed {
67         int pseudodelay;
PDelay(int i)68         PDelay(int i) { pseudodelay = i; }
compareTo(PDelay other)69         public int compareTo(PDelay other) {
70             int a = this.pseudodelay;
71             int b = other.pseudodelay;
72             return (a < b) ? -1 : (a > b) ? 1 : 0;
73         }
compareTo(Delayed y)74         public int compareTo(Delayed y) {
75             return compareTo((PDelay)y);
76         }
equals(Object other)77         public boolean equals(Object other) {
78             return (other instanceof PDelay) &&
79                 this.pseudodelay == ((PDelay)other).pseudodelay;
80         }
81         // suppress [overrides] javac warning
hashCode()82         public int hashCode() { return pseudodelay; }
getDelay(TimeUnit ignore)83         public long getDelay(TimeUnit ignore) {
84             return Integer.MIN_VALUE + pseudodelay;
85         }
toString()86         public String toString() {
87             return String.valueOf(pseudodelay);
88         }
89     }
90 
91     /**
92      * Delayed implementation that actually delays
93      */
94     static class NanoDelay implements Delayed {
95         long trigger;
NanoDelay(long i)96         NanoDelay(long i) {
97             trigger = System.nanoTime() + i;
98         }
compareTo(NanoDelay y)99         public int compareTo(NanoDelay y) {
100             long i = trigger;
101             long j = y.trigger;
102             if (i < j) return -1;
103             if (i > j) return 1;
104             return 0;
105         }
106 
compareTo(Delayed y)107         public int compareTo(Delayed y) {
108             return compareTo((NanoDelay)y);
109         }
110 
equals(Object other)111         public boolean equals(Object other) {
112             return equals((NanoDelay)other);
113         }
equals(NanoDelay other)114         public boolean equals(NanoDelay other) {
115             return other.trigger == trigger;
116         }
117 
118         // suppress [overrides] javac warning
hashCode()119         public int hashCode() { return (int) trigger; }
120 
getDelay(TimeUnit unit)121         public long getDelay(TimeUnit unit) {
122             long n = trigger - System.nanoTime();
123             return unit.convert(n, TimeUnit.NANOSECONDS);
124         }
125 
getTriggerTime()126         public long getTriggerTime() {
127             return trigger;
128         }
129 
toString()130         public String toString() {
131             return String.valueOf(trigger);
132         }
133     }
134 
135     /**
136      * Returns a new queue of given size containing consecutive
137      * PDelays 0 ... n.
138      */
populatedQueue(int n)139     private DelayQueue<PDelay> populatedQueue(int n) {
140         DelayQueue<PDelay> q = new DelayQueue<PDelay>();
141         assertTrue(q.isEmpty());
142         for (int i = n - 1; i >= 0; i -= 2)
143             assertTrue(q.offer(new PDelay(i)));
144         for (int i = (n & 1); i < n; i += 2)
145             assertTrue(q.offer(new PDelay(i)));
146         assertFalse(q.isEmpty());
147         assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
148         assertEquals(n, q.size());
149         return q;
150     }
151 
152     /**
153      * A new queue has unbounded capacity
154      */
testConstructor1()155     public void testConstructor1() {
156         assertEquals(Integer.MAX_VALUE, new DelayQueue().remainingCapacity());
157     }
158 
159     /**
160      * Initializing from null Collection throws NPE
161      */
testConstructor3()162     public void testConstructor3() {
163         try {
164             new DelayQueue(null);
165             shouldThrow();
166         } catch (NullPointerException success) {}
167     }
168 
169     /**
170      * Initializing from Collection of null elements throws NPE
171      */
testConstructor4()172     public void testConstructor4() {
173         try {
174             new DelayQueue(Arrays.asList(new PDelay[SIZE]));
175             shouldThrow();
176         } catch (NullPointerException success) {}
177     }
178 
179     /**
180      * Initializing from Collection with some null elements throws NPE
181      */
testConstructor5()182     public void testConstructor5() {
183         PDelay[] a = new PDelay[SIZE];
184         for (int i = 0; i < SIZE - 1; ++i)
185             a[i] = new PDelay(i);
186         try {
187             new DelayQueue(Arrays.asList(a));
188             shouldThrow();
189         } catch (NullPointerException success) {}
190     }
191 
192     /**
193      * Queue contains all elements of collection used to initialize
194      */
testConstructor6()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      */
testEmpty()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      */
testRemainingCapacity()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      */
testOffer()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      */
testAdd()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      */
testAddAllSelf()259     public void testAddAllSelf() {
260         DelayQueue q = populatedQueue(SIZE);
261         try {
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      */
testAddAll3()271     public void testAddAll3() {
272         DelayQueue q = new DelayQueue();
273         PDelay[] a = new PDelay[SIZE];
274         for (int i = 0; i < SIZE - 1; ++i)
275             a[i] = new PDelay(i);
276         try {
277             q.addAll(Arrays.asList(a));
278             shouldThrow();
279         } catch (NullPointerException success) {}
280     }
281 
282     /**
283      * Queue contains all elements of successful addAll
284      */
testAddAll5()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      */
testPut()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      */
testPutWithTake()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      */
testTimedOffer()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      */
testTake()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      */
testBlockingTake()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      */
testPoll()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      */
testTimedPoll0()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      */
testTimedPoll()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      */
testInterruptedTimedPoll()428     public void testInterruptedTimedPoll() throws InterruptedException {
429         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
430         final DelayQueue q = populatedQueue(SIZE);
431         Thread t = newStartedThread(new CheckedRunnable() {
432             public void realRun() throws InterruptedException {
433                 long startTime = System.nanoTime();
434                 for (int i = 0; i < SIZE; ++i) {
435                     assertEquals(new PDelay(i),
436                                  ((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS)));
437                 }
438 
439                 Thread.currentThread().interrupt();
440                 try {
441                     q.poll(LONG_DELAY_MS, MILLISECONDS);
442                     shouldThrow();
443                 } catch (InterruptedException success) {}
444                 assertFalse(Thread.interrupted());
445 
446                 pleaseInterrupt.countDown();
447                 try {
448                     q.poll(LONG_DELAY_MS, MILLISECONDS);
449                     shouldThrow();
450                 } catch (InterruptedException success) {}
451                 assertFalse(Thread.interrupted());
452                 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
453             }});
454 
455         await(pleaseInterrupt);
456         assertThreadStaysAlive(t);
457         t.interrupt();
458         awaitTermination(t);
459         checkEmpty(q);
460     }
461 
462     /**
463      * peek returns next element, or null if empty
464      */
testPeek()465     public void testPeek() {
466         DelayQueue q = populatedQueue(SIZE);
467         for (int i = 0; i < SIZE; ++i) {
468             assertEquals(new PDelay(i), q.peek());
469             assertEquals(new PDelay(i), q.poll());
470             if (q.isEmpty())
471                 assertNull(q.peek());
472             else
473                 assertFalse(new PDelay(i).equals(q.peek()));
474         }
475         assertNull(q.peek());
476     }
477 
478     /**
479      * element returns next element, or throws NSEE if empty
480      */
testElement()481     public void testElement() {
482         DelayQueue q = populatedQueue(SIZE);
483         for (int i = 0; i < SIZE; ++i) {
484             assertEquals(new PDelay(i), q.element());
485             q.poll();
486         }
487         try {
488             q.element();
489             shouldThrow();
490         } catch (NoSuchElementException success) {}
491     }
492 
493     /**
494      * remove removes next element, or throws NSEE if empty
495      */
testRemove()496     public void testRemove() {
497         DelayQueue q = populatedQueue(SIZE);
498         for (int i = 0; i < SIZE; ++i) {
499             assertEquals(new PDelay(i), q.remove());
500         }
501         try {
502             q.remove();
503             shouldThrow();
504         } catch (NoSuchElementException success) {}
505     }
506 
507     /**
508      * contains(x) reports true when elements added but not yet removed
509      */
testContains()510     public void testContains() {
511         DelayQueue q = populatedQueue(SIZE);
512         for (int i = 0; i < SIZE; ++i) {
513             assertTrue(q.contains(new PDelay(i)));
514             q.poll();
515             assertFalse(q.contains(new PDelay(i)));
516         }
517     }
518 
519     /**
520      * clear removes all elements
521      */
testClear()522     public void testClear() {
523         DelayQueue q = populatedQueue(SIZE);
524         q.clear();
525         assertTrue(q.isEmpty());
526         assertEquals(0, q.size());
527         assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
528         PDelay x = new PDelay(1);
529         q.add(x);
530         assertFalse(q.isEmpty());
531         assertTrue(q.contains(x));
532         q.clear();
533         assertTrue(q.isEmpty());
534     }
535 
536     /**
537      * containsAll(c) is true when c contains a subset of elements
538      */
testContainsAll()539     public void testContainsAll() {
540         DelayQueue q = populatedQueue(SIZE);
541         DelayQueue p = new DelayQueue();
542         for (int i = 0; i < SIZE; ++i) {
543             assertTrue(q.containsAll(p));
544             assertFalse(p.containsAll(q));
545             p.add(new PDelay(i));
546         }
547         assertTrue(p.containsAll(q));
548     }
549 
550     /**
551      * retainAll(c) retains only those elements of c and reports true if changed
552      */
testRetainAll()553     public void testRetainAll() {
554         DelayQueue q = populatedQueue(SIZE);
555         DelayQueue p = populatedQueue(SIZE);
556         for (int i = 0; i < SIZE; ++i) {
557             boolean changed = q.retainAll(p);
558             if (i == 0)
559                 assertFalse(changed);
560             else
561                 assertTrue(changed);
562 
563             assertTrue(q.containsAll(p));
564             assertEquals(SIZE - i, q.size());
565             p.remove();
566         }
567     }
568 
569     /**
570      * removeAll(c) removes only those elements of c and reports true if changed
571      */
testRemoveAll()572     public void testRemoveAll() {
573         for (int i = 1; i < SIZE; ++i) {
574             DelayQueue q = populatedQueue(SIZE);
575             DelayQueue p = populatedQueue(i);
576             assertTrue(q.removeAll(p));
577             assertEquals(SIZE - i, q.size());
578             for (int j = 0; j < i; ++j) {
579                 PDelay x = (PDelay)(p.remove());
580                 assertFalse(q.contains(x));
581             }
582         }
583     }
584 
585     /**
586      * toArray contains all elements
587      */
testToArray()588     public void testToArray() throws InterruptedException {
589         DelayQueue q = populatedQueue(SIZE);
590         Object[] o = q.toArray();
591         Arrays.sort(o);
592         for (int i = 0; i < o.length; i++)
593             assertSame(o[i], q.take());
594     }
595 
596     /**
597      * toArray(a) contains all elements
598      */
testToArray2()599     public void testToArray2() {
600         DelayQueue<PDelay> q = populatedQueue(SIZE);
601         PDelay[] ints = new PDelay[SIZE];
602         PDelay[] array = q.toArray(ints);
603         assertSame(ints, array);
604         Arrays.sort(ints);
605         for (int i = 0; i < ints.length; i++)
606             assertSame(ints[i], q.remove());
607     }
608 
609     /**
610      * toArray(incompatible array type) throws ArrayStoreException
611      */
testToArray1_BadArg()612     public void testToArray1_BadArg() {
613         DelayQueue q = populatedQueue(SIZE);
614         try {
615             q.toArray(new String[10]);
616             shouldThrow();
617         } catch (ArrayStoreException success) {}
618     }
619 
620     /**
621      * iterator iterates through all elements
622      */
testIterator()623     public void testIterator() {
624         DelayQueue q = populatedQueue(SIZE);
625         int i = 0;
626         Iterator it = q.iterator();
627         while (it.hasNext()) {
628             assertTrue(q.contains(it.next()));
629             ++i;
630         }
631         assertEquals(i, SIZE);
632         assertIteratorExhausted(it);
633     }
634 
635     /**
636      * iterator of empty collection has no elements
637      */
testEmptyIterator()638     public void testEmptyIterator() {
639         assertIteratorExhausted(new DelayQueue().iterator());
640     }
641 
642     /**
643      * iterator.remove removes current element
644      */
testIteratorRemove()645     public void testIteratorRemove() {
646         final DelayQueue q = new DelayQueue();
647         q.add(new PDelay(2));
648         q.add(new PDelay(1));
649         q.add(new PDelay(3));
650         Iterator it = q.iterator();
651         it.next();
652         it.remove();
653         it = q.iterator();
654         assertEquals(new PDelay(2), it.next());
655         assertEquals(new PDelay(3), it.next());
656         assertFalse(it.hasNext());
657     }
658 
659     /**
660      * toString contains toStrings of elements
661      */
testToString()662     public void testToString() {
663         DelayQueue q = populatedQueue(SIZE);
664         String s = q.toString();
665         for (Object e : q)
666             assertTrue(s.contains(e.toString()));
667     }
668 
669     /**
670      * timed poll transfers elements across Executor tasks
671      */
testPollInExecutor()672     public void testPollInExecutor() {
673         final DelayQueue q = new DelayQueue();
674         final CheckedBarrier threadsStarted = new CheckedBarrier(2);
675         final ExecutorService executor = Executors.newFixedThreadPool(2);
676         try (PoolCleaner cleaner = cleaner(executor)) {
677             executor.execute(new CheckedRunnable() {
678                 public void realRun() throws InterruptedException {
679                     assertNull(q.poll());
680                     threadsStarted.await();
681                     assertNotNull(q.poll(LONG_DELAY_MS, MILLISECONDS));
682                     checkEmpty(q);
683                 }});
684 
685             executor.execute(new CheckedRunnable() {
686                 public void realRun() throws InterruptedException {
687                     threadsStarted.await();
688                     q.put(new PDelay(1));
689                 }});
690         }
691     }
692 
693     /**
694      * Delayed actions do not occur until their delay elapses
695      */
testDelay()696     public void testDelay() throws InterruptedException {
697         DelayQueue<NanoDelay> q = new DelayQueue<NanoDelay>();
698         for (int i = 0; i < SIZE; ++i)
699             q.add(new NanoDelay(1000000L * (SIZE - i)));
700 
701         long last = 0;
702         for (int i = 0; i < SIZE; ++i) {
703             NanoDelay e = q.take();
704             long tt = e.getTriggerTime();
705             assertTrue(System.nanoTime() - tt >= 0);
706             if (i != 0)
707                 assertTrue(tt >= last);
708             last = tt;
709         }
710         assertTrue(q.isEmpty());
711     }
712 
713     /**
714      * peek of a non-empty queue returns non-null even if not expired
715      */
testPeekDelayed()716     public void testPeekDelayed() {
717         DelayQueue q = new DelayQueue();
718         q.add(new NanoDelay(Long.MAX_VALUE));
719         assertNotNull(q.peek());
720     }
721 
722     /**
723      * poll of a non-empty queue returns null if no expired elements.
724      */
testPollDelayed()725     public void testPollDelayed() {
726         DelayQueue q = new DelayQueue();
727         q.add(new NanoDelay(Long.MAX_VALUE));
728         assertNull(q.poll());
729     }
730 
731     /**
732      * timed poll of a non-empty queue returns null if no expired elements.
733      */
testTimedPollDelayed()734     public void testTimedPollDelayed() throws InterruptedException {
735         DelayQueue q = new DelayQueue();
736         q.add(new NanoDelay(LONG_DELAY_MS * 1000000L));
737         assertNull(q.poll(timeoutMillis(), MILLISECONDS));
738     }
739 
740     /**
741      * drainTo(c) empties queue into another collection c
742      */
testDrainTo()743     public void testDrainTo() {
744         DelayQueue q = new DelayQueue();
745         PDelay[] elems = new PDelay[SIZE];
746         for (int i = 0; i < SIZE; ++i) {
747             elems[i] = new PDelay(i);
748             q.add(elems[i]);
749         }
750         ArrayList l = new ArrayList();
751         q.drainTo(l);
752         assertEquals(0, q.size());
753         for (int i = 0; i < SIZE; ++i)
754             assertEquals(elems[i], l.get(i));
755         q.add(elems[0]);
756         q.add(elems[1]);
757         assertFalse(q.isEmpty());
758         assertTrue(q.contains(elems[0]));
759         assertTrue(q.contains(elems[1]));
760         l.clear();
761         q.drainTo(l);
762         assertEquals(0, q.size());
763         assertEquals(2, l.size());
764         for (int i = 0; i < 2; ++i)
765             assertEquals(elems[i], l.get(i));
766     }
767 
768     /**
769      * drainTo empties queue
770      */
testDrainToWithActivePut()771     public void testDrainToWithActivePut() throws InterruptedException {
772         final DelayQueue q = populatedQueue(SIZE);
773         Thread t = new Thread(new CheckedRunnable() {
774             public void realRun() {
775                 q.put(new PDelay(SIZE + 1));
776             }});
777 
778         t.start();
779         ArrayList l = new ArrayList();
780         q.drainTo(l);
781         assertTrue(l.size() >= SIZE);
782         t.join();
783         assertTrue(q.size() + l.size() >= SIZE);
784     }
785 
786     /**
787      * drainTo(c, n) empties first min(n, size) elements of queue into c
788      */
testDrainToN()789     public void testDrainToN() {
790         for (int i = 0; i < SIZE + 2; ++i) {
791             DelayQueue q = populatedQueue(SIZE);
792             ArrayList l = new ArrayList();
793             q.drainTo(l, i);
794             int k = (i < SIZE) ? i : SIZE;
795             assertEquals(SIZE - k, q.size());
796             assertEquals(k, l.size());
797         }
798     }
799 
800     /**
801      * remove(null), contains(null) always return false
802      */
testNeverContainsNull()803     public void testNeverContainsNull() {
804         Collection<?> q = populatedQueue(SIZE);
805         assertFalse(q.contains(null));
806         assertFalse(q.remove(null));
807     }
808 }
809