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