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 java.util.Arrays;
     12 import java.util.Collection;
     13 import java.util.Iterator;
     14 import java.util.NoSuchElementException;
     15 import java.util.Queue;
     16 import java.util.concurrent.ConcurrentLinkedQueue;
     17 
     18 import junit.framework.Test;
     19 import junit.framework.TestSuite;
     20 
     21 public class ConcurrentLinkedQueueTest extends JSR166TestCase {
     22 
     23     // android-note: Removed because the CTS runner does a bad job of
     24     // retrying tests that have suite() declarations.
     25     //
     26     // public static void main(String[] args) {
     27     //     main(suite(), args);
     28     // }
     29     // public static Test suite() {
     30     //     return new TestSuite(ConcurrentLinkedQueueTest.class);
     31     // }
     32 
     33     /**
     34      * Returns a new queue of given size containing consecutive
     35      * Integers 0 ... n.
     36      */
     37     private ConcurrentLinkedQueue<Integer> populatedQueue(int n) {
     38         ConcurrentLinkedQueue<Integer> q = new ConcurrentLinkedQueue<Integer>();
     39         assertTrue(q.isEmpty());
     40         for (int i = 0; i < n; ++i)
     41             assertTrue(q.offer(new Integer(i)));
     42         assertFalse(q.isEmpty());
     43         assertEquals(n, q.size());
     44         return q;
     45     }
     46 
     47     /**
     48      * new queue is empty
     49      */
     50     public void testConstructor1() {
     51         assertEquals(0, new ConcurrentLinkedQueue().size());
     52     }
     53 
     54     /**
     55      * Initializing from null Collection throws NPE
     56      */
     57     public void testConstructor3() {
     58         try {
     59             new ConcurrentLinkedQueue((Collection)null);
     60             shouldThrow();
     61         } catch (NullPointerException success) {}
     62     }
     63 
     64     /**
     65      * Initializing from Collection of null elements throws NPE
     66      */
     67     public void testConstructor4() {
     68         try {
     69             new ConcurrentLinkedQueue(Arrays.asList(new Integer[SIZE]));
     70             shouldThrow();
     71         } catch (NullPointerException success) {}
     72     }
     73 
     74     /**
     75      * Initializing from Collection with some null elements throws NPE
     76      */
     77     public void testConstructor5() {
     78         Integer[] ints = new Integer[SIZE];
     79         for (int i = 0; i < SIZE - 1; ++i)
     80             ints[i] = new Integer(i);
     81         try {
     82             new ConcurrentLinkedQueue(Arrays.asList(ints));
     83             shouldThrow();
     84         } catch (NullPointerException success) {}
     85     }
     86 
     87     /**
     88      * Queue contains all elements of collection used to initialize
     89      */
     90     public void testConstructor6() {
     91         Integer[] ints = new Integer[SIZE];
     92         for (int i = 0; i < SIZE; ++i)
     93             ints[i] = new Integer(i);
     94         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
     95         for (int i = 0; i < SIZE; ++i)
     96             assertEquals(ints[i], q.poll());
     97     }
     98 
     99     /**
    100      * isEmpty is true before add, false after
    101      */
    102     public void testEmpty() {
    103         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    104         assertTrue(q.isEmpty());
    105         q.add(one);
    106         assertFalse(q.isEmpty());
    107         q.add(two);
    108         q.remove();
    109         q.remove();
    110         assertTrue(q.isEmpty());
    111     }
    112 
    113     /**
    114      * size changes when elements added and removed
    115      */
    116     public void testSize() {
    117         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    118         for (int i = 0; i < SIZE; ++i) {
    119             assertEquals(SIZE - i, q.size());
    120             q.remove();
    121         }
    122         for (int i = 0; i < SIZE; ++i) {
    123             assertEquals(i, q.size());
    124             q.add(new Integer(i));
    125         }
    126     }
    127 
    128     /**
    129      * offer(null) throws NPE
    130      */
    131     public void testOfferNull() {
    132         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    133         try {
    134             q.offer(null);
    135             shouldThrow();
    136         } catch (NullPointerException success) {}
    137     }
    138 
    139     /**
    140      * add(null) throws NPE
    141      */
    142     public void testAddNull() {
    143         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    144         try {
    145             q.add(null);
    146             shouldThrow();
    147         } catch (NullPointerException success) {}
    148     }
    149 
    150     /**
    151      * Offer returns true
    152      */
    153     public void testOffer() {
    154         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    155         assertTrue(q.offer(zero));
    156         assertTrue(q.offer(one));
    157     }
    158 
    159     /**
    160      * add returns true
    161      */
    162     public void testAdd() {
    163         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    164         for (int i = 0; i < SIZE; ++i) {
    165             assertEquals(i, q.size());
    166             assertTrue(q.add(new Integer(i)));
    167         }
    168     }
    169 
    170     /**
    171      * addAll(null) throws NPE
    172      */
    173     public void testAddAll1() {
    174         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    175         try {
    176             q.addAll(null);
    177             shouldThrow();
    178         } catch (NullPointerException success) {}
    179     }
    180 
    181     /**
    182      * addAll(this) throws IAE
    183      */
    184     public void testAddAllSelf() {
    185         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    186         try {
    187             q.addAll(q);
    188             shouldThrow();
    189         } catch (IllegalArgumentException success) {}
    190     }
    191 
    192     /**
    193      * addAll of a collection with null elements throws NPE
    194      */
    195     public void testAddAll2() {
    196         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    197         try {
    198             q.addAll(Arrays.asList(new Integer[SIZE]));
    199             shouldThrow();
    200         } catch (NullPointerException success) {}
    201     }
    202 
    203     /**
    204      * addAll of a collection with any null elements throws NPE after
    205      * possibly adding some elements
    206      */
    207     public void testAddAll3() {
    208         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    209         Integer[] ints = new Integer[SIZE];
    210         for (int i = 0; i < SIZE - 1; ++i)
    211             ints[i] = new Integer(i);
    212         try {
    213             q.addAll(Arrays.asList(ints));
    214             shouldThrow();
    215         } catch (NullPointerException success) {}
    216     }
    217 
    218     /**
    219      * Queue contains all elements, in traversal order, of successful addAll
    220      */
    221     public void testAddAll5() {
    222         Integer[] empty = new Integer[0];
    223         Integer[] ints = new Integer[SIZE];
    224         for (int i = 0; i < SIZE; ++i)
    225             ints[i] = new Integer(i);
    226         ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    227         assertFalse(q.addAll(Arrays.asList(empty)));
    228         assertTrue(q.addAll(Arrays.asList(ints)));
    229         for (int i = 0; i < SIZE; ++i)
    230             assertEquals(ints[i], q.poll());
    231     }
    232 
    233     /**
    234      * poll succeeds unless empty
    235      */
    236     public void testPoll() {
    237         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    238         for (int i = 0; i < SIZE; ++i) {
    239             assertEquals(i, q.poll());
    240         }
    241         assertNull(q.poll());
    242     }
    243 
    244     /**
    245      * peek returns next element, or null if empty
    246      */
    247     public void testPeek() {
    248         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    249         for (int i = 0; i < SIZE; ++i) {
    250             assertEquals(i, q.peek());
    251             assertEquals(i, q.poll());
    252             assertTrue(q.peek() == null ||
    253                        !q.peek().equals(i));
    254         }
    255         assertNull(q.peek());
    256     }
    257 
    258     /**
    259      * element returns next element, or throws NSEE if empty
    260      */
    261     public void testElement() {
    262         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    263         for (int i = 0; i < SIZE; ++i) {
    264             assertEquals(i, q.element());
    265             assertEquals(i, q.poll());
    266         }
    267         try {
    268             q.element();
    269             shouldThrow();
    270         } catch (NoSuchElementException success) {}
    271     }
    272 
    273     /**
    274      * remove removes next element, or throws NSEE if empty
    275      */
    276     public void testRemove() {
    277         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    278         for (int i = 0; i < SIZE; ++i) {
    279             assertEquals(i, q.remove());
    280         }
    281         try {
    282             q.remove();
    283             shouldThrow();
    284         } catch (NoSuchElementException success) {}
    285     }
    286 
    287     /**
    288      * remove(x) removes x and returns true if present
    289      */
    290     public void testRemoveElement() {
    291         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    292         for (int i = 1; i < SIZE; i += 2) {
    293             assertTrue(q.contains(i));
    294             assertTrue(q.remove(i));
    295             assertFalse(q.contains(i));
    296             assertTrue(q.contains(i - 1));
    297         }
    298         for (int i = 0; i < SIZE; i += 2) {
    299             assertTrue(q.contains(i));
    300             assertTrue(q.remove(i));
    301             assertFalse(q.contains(i));
    302             assertFalse(q.remove(i + 1));
    303             assertFalse(q.contains(i + 1));
    304         }
    305         assertTrue(q.isEmpty());
    306     }
    307 
    308     /**
    309      * contains(x) reports true when elements added but not yet removed
    310      */
    311     public void testContains() {
    312         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    313         for (int i = 0; i < SIZE; ++i) {
    314             assertTrue(q.contains(new Integer(i)));
    315             q.poll();
    316             assertFalse(q.contains(new Integer(i)));
    317         }
    318     }
    319 
    320     /**
    321      * clear removes all elements
    322      */
    323     public void testClear() {
    324         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    325         q.clear();
    326         assertTrue(q.isEmpty());
    327         assertEquals(0, q.size());
    328         q.add(one);
    329         assertFalse(q.isEmpty());
    330         q.clear();
    331         assertTrue(q.isEmpty());
    332     }
    333 
    334     /**
    335      * containsAll(c) is true when c contains a subset of elements
    336      */
    337     public void testContainsAll() {
    338         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    339         ConcurrentLinkedQueue p = new ConcurrentLinkedQueue();
    340         for (int i = 0; i < SIZE; ++i) {
    341             assertTrue(q.containsAll(p));
    342             assertFalse(p.containsAll(q));
    343             p.add(new Integer(i));
    344         }
    345         assertTrue(p.containsAll(q));
    346     }
    347 
    348     /**
    349      * retainAll(c) retains only those elements of c and reports true if change
    350      */
    351     public void testRetainAll() {
    352         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    353         ConcurrentLinkedQueue p = populatedQueue(SIZE);
    354         for (int i = 0; i < SIZE; ++i) {
    355             boolean changed = q.retainAll(p);
    356             if (i == 0)
    357                 assertFalse(changed);
    358             else
    359                 assertTrue(changed);
    360 
    361             assertTrue(q.containsAll(p));
    362             assertEquals(SIZE - i, q.size());
    363             p.remove();
    364         }
    365     }
    366 
    367     /**
    368      * removeAll(c) removes only those elements of c and reports true if changed
    369      */
    370     public void testRemoveAll() {
    371         for (int i = 1; i < SIZE; ++i) {
    372             ConcurrentLinkedQueue q = populatedQueue(SIZE);
    373             ConcurrentLinkedQueue p = populatedQueue(i);
    374             assertTrue(q.removeAll(p));
    375             assertEquals(SIZE - i, q.size());
    376             for (int j = 0; j < i; ++j) {
    377                 Integer x = (Integer)(p.remove());
    378                 assertFalse(q.contains(x));
    379             }
    380         }
    381     }
    382 
    383     /**
    384      * toArray contains all elements in FIFO order
    385      */
    386     public void testToArray() {
    387         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    388         Object[] o = q.toArray();
    389         for (int i = 0; i < o.length; i++)
    390             assertSame(o[i], q.poll());
    391     }
    392 
    393     /**
    394      * toArray(a) contains all elements in FIFO order
    395      */
    396     public void testToArray2() {
    397         ConcurrentLinkedQueue<Integer> q = populatedQueue(SIZE);
    398         Integer[] ints = new Integer[SIZE];
    399         Integer[] array = q.toArray(ints);
    400         assertSame(ints, array);
    401         for (int i = 0; i < ints.length; i++)
    402             assertSame(ints[i], q.poll());
    403     }
    404 
    405     /**
    406      * toArray(null) throws NullPointerException
    407      */
    408     public void testToArray_NullArg() {
    409         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    410         try {
    411             q.toArray(null);
    412             shouldThrow();
    413         } catch (NullPointerException success) {}
    414     }
    415 
    416     /**
    417      * toArray(incompatible array type) throws ArrayStoreException
    418      */
    419     public void testToArray1_BadArg() {
    420         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    421         try {
    422             q.toArray(new String[10]);
    423             shouldThrow();
    424         } catch (ArrayStoreException success) {}
    425     }
    426 
    427     /**
    428      * iterator iterates through all elements
    429      */
    430     public void testIterator() {
    431         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    432         Iterator it = q.iterator();
    433         int i;
    434         for (i = 0; it.hasNext(); i++)
    435             assertTrue(q.contains(it.next()));
    436         assertEquals(i, SIZE);
    437         assertIteratorExhausted(it);
    438     }
    439 
    440     /**
    441      * iterator of empty collection has no elements
    442      */
    443     public void testEmptyIterator() {
    444         assertIteratorExhausted(new ConcurrentLinkedQueue().iterator());
    445     }
    446 
    447     /**
    448      * iterator ordering is FIFO
    449      */
    450     public void testIteratorOrdering() {
    451         final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    452         q.add(one);
    453         q.add(two);
    454         q.add(three);
    455 
    456         int k = 0;
    457         for (Iterator it = q.iterator(); it.hasNext();) {
    458             assertEquals(++k, it.next());
    459         }
    460 
    461         assertEquals(3, k);
    462     }
    463 
    464     /**
    465      * Modifications do not cause iterators to fail
    466      */
    467     public void testWeaklyConsistentIteration() {
    468         final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    469         q.add(one);
    470         q.add(two);
    471         q.add(three);
    472 
    473         for (Iterator it = q.iterator(); it.hasNext();) {
    474             q.remove();
    475             it.next();
    476         }
    477 
    478         assertEquals("queue should be empty again", 0, q.size());
    479     }
    480 
    481     /**
    482      * iterator.remove removes current element
    483      */
    484     public void testIteratorRemove() {
    485         final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
    486         q.add(one);
    487         q.add(two);
    488         q.add(three);
    489         Iterator it = q.iterator();
    490         it.next();
    491         it.remove();
    492         it = q.iterator();
    493         assertSame(it.next(), two);
    494         assertSame(it.next(), three);
    495         assertFalse(it.hasNext());
    496     }
    497 
    498     /**
    499      * toString contains toStrings of elements
    500      */
    501     public void testToString() {
    502         ConcurrentLinkedQueue q = populatedQueue(SIZE);
    503         String s = q.toString();
    504         for (int i = 0; i < SIZE; ++i) {
    505             assertTrue(s.contains(String.valueOf(i)));
    506         }
    507     }
    508 
    509     /**
    510      * A deserialized serialized queue has same elements in same order
    511      */
    512     public void testSerialization() throws Exception {
    513         Queue x = populatedQueue(SIZE);
    514         Queue y = serialClone(x);
    515 
    516         assertNotSame(x, y);
    517         assertEquals(x.size(), y.size());
    518         assertEquals(x.toString(), y.toString());
    519         assertTrue(Arrays.equals(x.toArray(), y.toArray()));
    520         while (!x.isEmpty()) {
    521             assertFalse(y.isEmpty());
    522             assertEquals(x.remove(), y.remove());
    523         }
    524         assertTrue(y.isEmpty());
    525     }
    526 
    527     /**
    528      * remove(null), contains(null) always return false
    529      */
    530     public void testNeverContainsNull() {
    531         Collection<?>[] qs = {
    532             new ConcurrentLinkedQueue<Object>(),
    533             populatedQueue(2),
    534         };
    535 
    536         for (Collection<?> q : qs) {
    537             assertFalse(q.contains(null));
    538             assertFalse(q.remove(null));
    539         }
    540     }
    541 }
    542