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