• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // android-changed: Extend BlockingQueueTest directly.
29 public 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 
emptyCollection()52     protected BlockingQueue emptyCollection() {
53         return new DelayQueue();
54     }
55 
makeElement(int i)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;
PDelay(int i)67         PDelay(int i) { pseudodelay = i; }
compareTo(PDelay other)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         }
compareTo(Delayed y)73         public int compareTo(Delayed y) {
74             return compareTo((PDelay)y);
75         }
equals(Object other)76         public boolean equals(Object other) {
77             return (other instanceof PDelay) &&
78                 this.pseudodelay == ((PDelay)other).pseudodelay;
79         }
80         // suppress [overrides] javac warning
hashCode()81         public int hashCode() { return pseudodelay; }
getDelay(TimeUnit ignore)82         public long getDelay(TimeUnit ignore) {
83             return Integer.MIN_VALUE + pseudodelay;
84         }
toString()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;
NanoDelay(long i)95         NanoDelay(long i) {
96             trigger = System.nanoTime() + i;
97         }
compareTo(NanoDelay y)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 
compareTo(Delayed y)106         public int compareTo(Delayed y) {
107             return compareTo((NanoDelay)y);
108         }
109 
equals(Object other)110         public boolean equals(Object other) {
111             return equals((NanoDelay)other);
112         }
equals(NanoDelay other)113         public boolean equals(NanoDelay other) {
114             return other.trigger == trigger;
115         }
116 
117         // suppress [overrides] javac warning
hashCode()118         public int hashCode() { return (int) trigger; }
119 
getDelay(TimeUnit unit)120         public long getDelay(TimeUnit unit) {
121             long n = trigger - System.nanoTime();
122             return unit.convert(n, TimeUnit.NANOSECONDS);
123         }
124 
getTriggerTime()125         public long getTriggerTime() {
126             return trigger;
127         }
128 
toString()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      */
populatedQueue(int n)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      */
testConstructor1()154     public void testConstructor1() {
155         assertEquals(Integer.MAX_VALUE, new DelayQueue().remainingCapacity());
156     }
157 
158     /**
159      * Initializing from null Collection throws NPE
160      */
testConstructor3()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      */
testConstructor4()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      */
testConstructor5()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      */
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         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      */
testAddAll3()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      */
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         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      */
testPeek()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      */
testElement()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      */
testRemove()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      */
testContains()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      */
testClear()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      */
testContainsAll()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      */
testRetainAll()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      */
testRemoveAll()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      */
testToArray()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      */
testToArray2()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      */
testToArray1_BadArg()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      */
testIterator()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      */
testEmptyIterator()634     public void testEmptyIterator() {
635         assertIteratorExhausted(new DelayQueue().iterator());
636     }
637 
638     /**
639      * iterator.remove removes current element
640      */
testIteratorRemove()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      */
testToString()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      */
testPollInExecutor()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      */
testDelay()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      */
testPeekDelayed()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      */
testPollDelayed()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      */
testTimedPollDelayed()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      */
testDrainTo()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      */
testDrainToWithActivePut()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      */
testDrainToN()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      */
testNeverContainsNull()799     public void testNeverContainsNull() {
800         Collection<?> q = populatedQueue(SIZE);
801         assertFalse(q.contains(null));
802         assertFalse(q.remove(null));
803     }
804 }
805