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