Home | History | Annotate | Download | only in jsr166
      1 /*
      2  * Written by Doug Lea and Martin Buchholz with assistance from members
      3  * of JCP JSR-166 Expert Group and released to the public domain, as
      4  * explained at http://creativecommons.org/publicdomain/zero/1.0/
      5  *
      6  * Other contributors include Andrew Wright, Jeffrey Hayes,
      7  * Pat Fisher, Mike Judd.
      8  */
      9 
     10 package jsr166;
     11 
     12 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     13 
     14 import java.util.ArrayList;
     15 import java.util.Arrays;
     16 import java.util.Collection;
     17 import java.util.Queue;
     18 import java.util.concurrent.BlockingQueue;
     19 import java.util.concurrent.CountDownLatch;
     20 
     21 import junit.framework.Test;
     22 import junit.framework.TestSuite;
     23 
     24 /**
     25  * Contains "contract" tests applicable to all BlockingQueue implementations.
     26  */
     27 public abstract class BlockingQueueTest extends JSR166TestCase {
     28     /*
     29      * This is the start of an attempt to refactor the tests for the
     30      * various related implementations of related interfaces without
     31      * too much duplicated code.  junit does not really support such
     32      * testing.  Here subclasses of TestCase not only contain tests,
     33      * but also configuration information that describes the
     34      * implementation class, most importantly how to instantiate
     35      * instances.
     36      */
     37 
     38     /** Like suite(), but non-static */
     39     // android-note: Explicitly instantiated.
     40     //
     41     // public Test testSuite() {
     42     //     // TODO: filter the returned tests using the configuration
     43     //     // information provided by the subclass via protected methods.
     44     //     return new TestSuite(this.getClass());
     45     // }
     46 
     47     //----------------------------------------------------------------
     48     // Configuration methods
     49     //----------------------------------------------------------------
     50 
     51     /** Returns an empty instance of the implementation class. */
     52     protected abstract BlockingQueue emptyCollection();
     53 
     54     /**
     55      * Returns an element suitable for insertion in the collection.
     56      * Override for collections with unusual element types.
     57      */
     58     protected Object makeElement(int i) {
     59         return Integer.valueOf(i);
     60     }
     61 
     62     //----------------------------------------------------------------
     63     // Tests
     64     //----------------------------------------------------------------
     65 
     66     /**
     67      * offer(null) throws NullPointerException
     68      */
     69     public void testOfferNull() {
     70         final Queue q = emptyCollection();
     71         try {
     72             q.offer(null);
     73             shouldThrow();
     74         } catch (NullPointerException success) {}
     75     }
     76 
     77     /**
     78      * add(null) throws NullPointerException
     79      */
     80     public void testAddNull() {
     81         final Collection q = emptyCollection();
     82         try {
     83             q.add(null);
     84             shouldThrow();
     85         } catch (NullPointerException success) {}
     86     }
     87 
     88     /**
     89      * timed offer(null) throws NullPointerException
     90      */
     91     public void testTimedOfferNull() throws InterruptedException {
     92         final BlockingQueue q = emptyCollection();
     93         long startTime = System.nanoTime();
     94         try {
     95             q.offer(null, LONG_DELAY_MS, MILLISECONDS);
     96             shouldThrow();
     97         } catch (NullPointerException success) {}
     98         assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
     99     }
    100 
    101     /**
    102      * put(null) throws NullPointerException
    103      */
    104     public void testPutNull() throws InterruptedException {
    105         final BlockingQueue q = emptyCollection();
    106         try {
    107             q.put(null);
    108             shouldThrow();
    109         } catch (NullPointerException success) {}
    110     }
    111 
    112     /**
    113      * put(null) throws NullPointerException
    114      */
    115     public void testAddAllNull() throws InterruptedException {
    116         final Collection q = emptyCollection();
    117         try {
    118             q.addAll(null);
    119             shouldThrow();
    120         } catch (NullPointerException success) {}
    121     }
    122 
    123     /**
    124      * addAll of a collection with null elements throws NullPointerException
    125      */
    126     public void testAddAllNullElements() {
    127         final Collection q = emptyCollection();
    128         final Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
    129         try {
    130             q.addAll(elements);
    131             shouldThrow();
    132         } catch (NullPointerException success) {}
    133     }
    134 
    135     /**
    136      * toArray(null) throws NullPointerException
    137      */
    138     public void testToArray_NullArray() {
    139         final Collection q = emptyCollection();
    140         try {
    141             q.toArray(null);
    142             shouldThrow();
    143         } catch (NullPointerException success) {}
    144     }
    145 
    146     /**
    147      * drainTo(null) throws NullPointerException
    148      */
    149     public void testDrainToNull() {
    150         final BlockingQueue q = emptyCollection();
    151         try {
    152             q.drainTo(null);
    153             shouldThrow();
    154         } catch (NullPointerException success) {}
    155     }
    156 
    157     /**
    158      * drainTo(this) throws IllegalArgumentException
    159      */
    160     public void testDrainToSelf() {
    161         final BlockingQueue q = emptyCollection();
    162         try {
    163             q.drainTo(q);
    164             shouldThrow();
    165         } catch (IllegalArgumentException success) {}
    166     }
    167 
    168     /**
    169      * drainTo(null, n) throws NullPointerException
    170      */
    171     public void testDrainToNullN() {
    172         final BlockingQueue q = emptyCollection();
    173         try {
    174             q.drainTo(null, 0);
    175             shouldThrow();
    176         } catch (NullPointerException success) {}
    177     }
    178 
    179     /**
    180      * drainTo(this, n) throws IllegalArgumentException
    181      */
    182     public void testDrainToSelfN() {
    183         final BlockingQueue q = emptyCollection();
    184         try {
    185             q.drainTo(q, 0);
    186             shouldThrow();
    187         } catch (IllegalArgumentException success) {}
    188     }
    189 
    190     /**
    191      * drainTo(c, n) returns 0 and does nothing when n <= 0
    192      */
    193     public void testDrainToNonPositiveMaxElements() {
    194         final BlockingQueue q = emptyCollection();
    195         final int[] ns = { 0, -1, -42, Integer.MIN_VALUE };
    196         for (int n : ns)
    197             assertEquals(0, q.drainTo(new ArrayList(), n));
    198         if (q.remainingCapacity() > 0) {
    199             // Not SynchronousQueue, that is
    200             Object one = makeElement(1);
    201             q.add(one);
    202             ArrayList c = new ArrayList();
    203             for (int n : ns)
    204                 assertEquals(0, q.drainTo(new ArrayList(), n));
    205             assertEquals(1, q.size());
    206             assertSame(one, q.poll());
    207             assertTrue(c.isEmpty());
    208         }
    209     }
    210 
    211     /**
    212      * timed poll before a delayed offer times out; after offer succeeds;
    213      * on interruption throws
    214      */
    215     public void testTimedPollWithOffer() throws InterruptedException {
    216         final BlockingQueue q = emptyCollection();
    217         final CheckedBarrier barrier = new CheckedBarrier(2);
    218         final Object zero = makeElement(0);
    219         Thread t = newStartedThread(new CheckedRunnable() {
    220             public void realRun() throws InterruptedException {
    221                 long startTime = System.nanoTime();
    222                 assertNull(q.poll(timeoutMillis(), MILLISECONDS));
    223                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    224 
    225                 barrier.await();
    226 
    227                 assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
    228 
    229                 Thread.currentThread().interrupt();
    230                 try {
    231                     q.poll(LONG_DELAY_MS, MILLISECONDS);
    232                     shouldThrow();
    233                 } catch (InterruptedException success) {}
    234                 assertFalse(Thread.interrupted());
    235 
    236                 barrier.await();
    237                 try {
    238                     q.poll(LONG_DELAY_MS, MILLISECONDS);
    239                     shouldThrow();
    240                 } catch (InterruptedException success) {}
    241                 assertFalse(Thread.interrupted());
    242 
    243                 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
    244             }});
    245 
    246         barrier.await();
    247         long startTime = System.nanoTime();
    248         assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS));
    249         assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
    250 
    251         barrier.await();
    252         assertThreadStaysAlive(t);
    253         t.interrupt();
    254         awaitTermination(t);
    255     }
    256 
    257     /**
    258      * take() blocks interruptibly when empty
    259      */
    260     public void testTakeFromEmptyBlocksInterruptibly() {
    261         final BlockingQueue q = emptyCollection();
    262         final CountDownLatch threadStarted = new CountDownLatch(1);
    263         Thread t = newStartedThread(new CheckedRunnable() {
    264             public void realRun() {
    265                 threadStarted.countDown();
    266                 try {
    267                     q.take();
    268                     shouldThrow();
    269                 } catch (InterruptedException success) {}
    270                 assertFalse(Thread.interrupted());
    271             }});
    272 
    273         await(threadStarted);
    274         assertThreadStaysAlive(t);
    275         t.interrupt();
    276         awaitTermination(t);
    277     }
    278 
    279     /**
    280      * take() throws InterruptedException immediately if interrupted
    281      * before waiting
    282      */
    283     public void testTakeFromEmptyAfterInterrupt() {
    284         final BlockingQueue q = emptyCollection();
    285         Thread t = newStartedThread(new CheckedRunnable() {
    286             public void realRun() {
    287                 Thread.currentThread().interrupt();
    288                 try {
    289                     q.take();
    290                     shouldThrow();
    291                 } catch (InterruptedException success) {}
    292                 assertFalse(Thread.interrupted());
    293             }});
    294 
    295         awaitTermination(t);
    296     }
    297 
    298     /**
    299      * timed poll() blocks interruptibly when empty
    300      */
    301     public void testTimedPollFromEmptyBlocksInterruptibly() {
    302         final BlockingQueue q = emptyCollection();
    303         final CountDownLatch threadStarted = new CountDownLatch(1);
    304         Thread t = newStartedThread(new CheckedRunnable() {
    305             public void realRun() {
    306                 threadStarted.countDown();
    307                 try {
    308                     q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
    309                     shouldThrow();
    310                 } catch (InterruptedException success) {}
    311                 assertFalse(Thread.interrupted());
    312             }});
    313 
    314         await(threadStarted);
    315         assertThreadStaysAlive(t);
    316         t.interrupt();
    317         awaitTermination(t);
    318     }
    319 
    320     /**
    321      * timed poll() throws InterruptedException immediately if
    322      * interrupted before waiting
    323      */
    324     public void testTimedPollFromEmptyAfterInterrupt() {
    325         final BlockingQueue q = emptyCollection();
    326         Thread t = newStartedThread(new CheckedRunnable() {
    327             public void realRun() {
    328                 Thread.currentThread().interrupt();
    329                 try {
    330                     q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
    331                     shouldThrow();
    332                 } catch (InterruptedException success) {}
    333                 assertFalse(Thread.interrupted());
    334             }});
    335 
    336         awaitTermination(t);
    337     }
    338 
    339     /**
    340      * remove(x) removes x and returns true if present
    341      * TODO: move to superclass CollectionTest.java
    342      */
    343     public void testRemoveElement() {
    344         final BlockingQueue q = emptyCollection();
    345         final int size = Math.min(q.remainingCapacity(), SIZE);
    346         final Object[] elts = new Object[size];
    347         assertFalse(q.contains(makeElement(99)));
    348         assertFalse(q.remove(makeElement(99)));
    349         checkEmpty(q);
    350         for (int i = 0; i < size; i++)
    351             q.add(elts[i] = makeElement(i));
    352         for (int i = 1; i < size; i += 2) {
    353             for (int pass = 0; pass < 2; pass++) {
    354                 assertEquals((pass == 0), q.contains(elts[i]));
    355                 assertEquals((pass == 0), q.remove(elts[i]));
    356                 assertFalse(q.contains(elts[i]));
    357                 assertTrue(q.contains(elts[i - 1]));
    358                 if (i < size - 1)
    359                     assertTrue(q.contains(elts[i + 1]));
    360             }
    361         }
    362         if (size > 0)
    363             assertTrue(q.contains(elts[0]));
    364         for (int i = size - 2; i >= 0; i -= 2) {
    365             assertTrue(q.contains(elts[i]));
    366             assertFalse(q.contains(elts[i + 1]));
    367             assertTrue(q.remove(elts[i]));
    368             assertFalse(q.contains(elts[i]));
    369             assertFalse(q.remove(elts[i + 1]));
    370             assertFalse(q.contains(elts[i + 1]));
    371         }
    372         checkEmpty(q);
    373     }
    374 
    375     /** For debugging. */
    376     public void XXXXtestFails() {
    377         fail(emptyCollection().getClass().toString());
    378     }
    379 
    380 }
    381