Home | History | Annotate | Download | only in jsr166
      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 
     53     protected BlockingQueue emptyCollection() {
     54         return new DelayQueue();
     55     }
     56 
     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;
     68         PDelay(int i) { pseudodelay = i; }
     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         }
     74         public int compareTo(Delayed y) {
     75             return compareTo((PDelay)y);
     76         }
     77         public boolean equals(Object other) {
     78             return (other instanceof PDelay) &&
     79                 this.pseudodelay == ((PDelay)other).pseudodelay;
     80         }
     81         // suppress [overrides] javac warning
     82         public int hashCode() { return pseudodelay; }
     83         public long getDelay(TimeUnit ignore) {
     84             return Integer.MIN_VALUE + pseudodelay;
     85         }
     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;
     96         NanoDelay(long i) {
     97             trigger = System.nanoTime() + i;
     98         }
     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 
    107         public int compareTo(Delayed y) {
    108             return compareTo((NanoDelay)y);
    109         }
    110 
    111         public boolean equals(Object other) {
    112             return equals((NanoDelay)other);
    113         }
    114         public boolean equals(NanoDelay other) {
    115             return other.trigger == trigger;
    116         }
    117 
    118         // suppress [overrides] javac warning
    119         public int hashCode() { return (int) trigger; }
    120 
    121         public long getDelay(TimeUnit unit) {
    122             long n = trigger - System.nanoTime();
    123             return unit.convert(n, TimeUnit.NANOSECONDS);
    124         }
    125 
    126         public long getTriggerTime() {
    127             return trigger;
    128         }
    129 
    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      */
    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      */
    155     public void testConstructor1() {
    156         assertEquals(Integer.MAX_VALUE, new DelayQueue().remainingCapacity());
    157     }
    158 
    159     /**
    160      * Initializing from null Collection throws NPE
    161      */
    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      */
    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      */
    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      */
    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         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      */
    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      */
    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         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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    638     public void testEmptyIterator() {
    639         assertIteratorExhausted(new DelayQueue().iterator());
    640     }
    641 
    642     /**
    643      * iterator.remove removes current element
    644      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    803     public void testNeverContainsNull() {
    804         Collection<?> q = populatedQueue(SIZE);
    805         assertFalse(q.contains(null));
    806         assertFalse(q.remove(null));
    807     }
    808 }
    809