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.Deque;
14 import java.util.Iterator;
15 import java.util.NoSuchElementException;
16 import java.util.Queue;
17 import java.util.Random;
18 import java.util.concurrent.ConcurrentLinkedDeque;
19 
20 import junit.framework.Test;
21 import junit.framework.TestSuite;
22 
23 public class ConcurrentLinkedDequeTest extends JSR166TestCase {
24 
25     // android-note: Removed because the CTS runner does a bad job of
26     // retrying tests that have suite() declarations.
27     //
28     // public static void main(String[] args) {
29     //     main(suite(), args);
30     // }
31     // public static Test suite() {
32     //     return new TestSuite(ConcurrentLinkedDequeTest.class);
33     // }
34 
35     /**
36      * Returns a new deque of given size containing consecutive
37      * Integers 0 ... n.
38      */
populatedDeque(int n)39     private ConcurrentLinkedDeque<Integer> populatedDeque(int n) {
40         ConcurrentLinkedDeque<Integer> q = new ConcurrentLinkedDeque<Integer>();
41         assertTrue(q.isEmpty());
42         for (int i = 0; i < n; ++i)
43             assertTrue(q.offer(new Integer(i)));
44         assertFalse(q.isEmpty());
45         assertEquals(n, q.size());
46         return q;
47     }
48 
49     /**
50      * new deque is empty
51      */
testConstructor1()52     public void testConstructor1() {
53         assertTrue(new ConcurrentLinkedDeque().isEmpty());
54         assertEquals(0, new ConcurrentLinkedDeque().size());
55     }
56 
57     /**
58      * Initializing from null Collection throws NPE
59      */
testConstructor3()60     public void testConstructor3() {
61         try {
62             new ConcurrentLinkedDeque((Collection)null);
63             shouldThrow();
64         } catch (NullPointerException success) {}
65     }
66 
67     /**
68      * Initializing from Collection of null elements throws NPE
69      */
testConstructor4()70     public void testConstructor4() {
71         try {
72             new ConcurrentLinkedDeque(Arrays.asList(new Integer[SIZE]));
73             shouldThrow();
74         } catch (NullPointerException success) {}
75     }
76 
77     /**
78      * Initializing from Collection with some null elements throws NPE
79      */
testConstructor5()80     public void testConstructor5() {
81         Integer[] ints = new Integer[SIZE];
82         for (int i = 0; i < SIZE - 1; ++i)
83             ints[i] = new Integer(i);
84         try {
85             new ConcurrentLinkedDeque(Arrays.asList(ints));
86             shouldThrow();
87         } catch (NullPointerException success) {}
88     }
89 
90     /**
91      * Deque contains all elements of collection used to initialize
92      */
testConstructor6()93     public void testConstructor6() {
94         Integer[] ints = new Integer[SIZE];
95         for (int i = 0; i < SIZE; ++i)
96             ints[i] = new Integer(i);
97         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque(Arrays.asList(ints));
98         for (int i = 0; i < SIZE; ++i)
99             assertEquals(ints[i], q.poll());
100     }
101 
102     /**
103      * isEmpty is true before add, false after
104      */
testEmpty()105     public void testEmpty() {
106         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
107         assertTrue(q.isEmpty());
108         q.add(one);
109         assertFalse(q.isEmpty());
110         q.add(two);
111         q.remove();
112         q.remove();
113         assertTrue(q.isEmpty());
114     }
115 
116     /**
117      * size() changes when elements added and removed
118      */
testSize()119     public void testSize() {
120         ConcurrentLinkedDeque q = populatedDeque(SIZE);
121         for (int i = 0; i < SIZE; ++i) {
122             assertEquals(SIZE - i, q.size());
123             q.remove();
124         }
125         for (int i = 0; i < SIZE; ++i) {
126             assertEquals(i, q.size());
127             q.add(new Integer(i));
128         }
129     }
130 
131     /**
132      * push(null) throws NPE
133      */
testPushNull()134     public void testPushNull() {
135         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
136         try {
137             q.push(null);
138             shouldThrow();
139         } catch (NullPointerException success) {}
140     }
141 
142     /**
143      * peekFirst() returns element inserted with push
144      */
testPush()145     public void testPush() {
146         ConcurrentLinkedDeque q = populatedDeque(3);
147         q.pollLast();
148         q.push(four);
149         assertSame(four, q.peekFirst());
150     }
151 
152     /**
153      * pop() removes first element, or throws NSEE if empty
154      */
testPop()155     public void testPop() {
156         ConcurrentLinkedDeque q = populatedDeque(SIZE);
157         for (int i = 0; i < SIZE; ++i) {
158             assertEquals(i, q.pop());
159         }
160         try {
161             q.pop();
162             shouldThrow();
163         } catch (NoSuchElementException success) {}
164     }
165 
166     /**
167      * offer(null) throws NPE
168      */
testOfferNull()169     public void testOfferNull() {
170         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
171         try {
172             q.offer(null);
173             shouldThrow();
174         } catch (NullPointerException success) {}
175     }
176 
177     /**
178      * offerFirst(null) throws NPE
179      */
testOfferFirstNull()180     public void testOfferFirstNull() {
181         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
182         try {
183             q.offerFirst(null);
184             shouldThrow();
185         } catch (NullPointerException success) {}
186     }
187 
188     /**
189      * offerLast(null) throws NPE
190      */
testOfferLastNull()191     public void testOfferLastNull() {
192         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
193         try {
194             q.offerLast(null);
195             shouldThrow();
196         } catch (NullPointerException success) {}
197     }
198 
199     /**
200      * offer(x) succeeds
201      */
testOffer()202     public void testOffer() {
203         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
204         assertTrue(q.offer(zero));
205         assertTrue(q.offer(one));
206         assertSame(zero, q.peekFirst());
207         assertSame(one, q.peekLast());
208     }
209 
210     /**
211      * offerFirst(x) succeeds
212      */
testOfferFirst()213     public void testOfferFirst() {
214         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
215         assertTrue(q.offerFirst(zero));
216         assertTrue(q.offerFirst(one));
217         assertSame(one, q.peekFirst());
218         assertSame(zero, q.peekLast());
219     }
220 
221     /**
222      * offerLast(x) succeeds
223      */
testOfferLast()224     public void testOfferLast() {
225         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
226         assertTrue(q.offerLast(zero));
227         assertTrue(q.offerLast(one));
228         assertSame(zero, q.peekFirst());
229         assertSame(one, q.peekLast());
230     }
231 
232     /**
233      * add(null) throws NPE
234      */
testAddNull()235     public void testAddNull() {
236         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
237         try {
238             q.add(null);
239             shouldThrow();
240         } catch (NullPointerException success) {}
241     }
242 
243     /**
244      * addFirst(null) throws NPE
245      */
testAddFirstNull()246     public void testAddFirstNull() {
247         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
248         try {
249             q.addFirst(null);
250             shouldThrow();
251         } catch (NullPointerException success) {}
252     }
253 
254     /**
255      * addLast(null) throws NPE
256      */
testAddLastNull()257     public void testAddLastNull() {
258         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
259         try {
260             q.addLast(null);
261             shouldThrow();
262         } catch (NullPointerException success) {}
263     }
264 
265     /**
266      * add(x) succeeds
267      */
testAdd()268     public void testAdd() {
269         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
270         assertTrue(q.add(zero));
271         assertTrue(q.add(one));
272         assertSame(zero, q.peekFirst());
273         assertSame(one, q.peekLast());
274     }
275 
276     /**
277      * addFirst(x) succeeds
278      */
testAddFirst()279     public void testAddFirst() {
280         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
281         q.addFirst(zero);
282         q.addFirst(one);
283         assertSame(one, q.peekFirst());
284         assertSame(zero, q.peekLast());
285     }
286 
287     /**
288      * addLast(x) succeeds
289      */
testAddLast()290     public void testAddLast() {
291         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
292         q.addLast(zero);
293         q.addLast(one);
294         assertSame(zero, q.peekFirst());
295         assertSame(one, q.peekLast());
296     }
297 
298     /**
299      * addAll(null) throws NPE
300      */
testAddAll1()301     public void testAddAll1() {
302         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
303         try {
304             q.addAll(null);
305             shouldThrow();
306         } catch (NullPointerException success) {}
307     }
308 
309     /**
310      * addAll(this) throws IAE
311      */
testAddAllSelf()312     public void testAddAllSelf() {
313         ConcurrentLinkedDeque q = populatedDeque(SIZE);
314         try {
315             q.addAll(q);
316             shouldThrow();
317         } catch (IllegalArgumentException success) {}
318     }
319 
320     /**
321      * addAll of a collection with null elements throws NPE
322      */
testAddAll2()323     public void testAddAll2() {
324         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
325         try {
326             q.addAll(Arrays.asList(new Integer[SIZE]));
327             shouldThrow();
328         } catch (NullPointerException success) {}
329     }
330 
331     /**
332      * addAll of a collection with any null elements throws NPE after
333      * possibly adding some elements
334      */
testAddAll3()335     public void testAddAll3() {
336         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
337         Integer[] ints = new Integer[SIZE];
338         for (int i = 0; i < SIZE - 1; ++i)
339             ints[i] = new Integer(i);
340         try {
341             q.addAll(Arrays.asList(ints));
342             shouldThrow();
343         } catch (NullPointerException success) {}
344     }
345 
346     /**
347      * Deque contains all elements, in traversal order, of successful addAll
348      */
testAddAll5()349     public void testAddAll5() {
350         Integer[] empty = new Integer[0];
351         Integer[] ints = new Integer[SIZE];
352         for (int i = 0; i < SIZE; ++i)
353             ints[i] = new Integer(i);
354         ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
355         assertFalse(q.addAll(Arrays.asList(empty)));
356         assertTrue(q.addAll(Arrays.asList(ints)));
357         for (int i = 0; i < SIZE; ++i)
358             assertEquals(ints[i], q.poll());
359     }
360 
361     /**
362      * pollFirst() succeeds unless empty
363      */
testPollFirst()364     public void testPollFirst() {
365         ConcurrentLinkedDeque q = populatedDeque(SIZE);
366         for (int i = 0; i < SIZE; ++i) {
367             assertEquals(i, q.pollFirst());
368         }
369         assertNull(q.pollFirst());
370     }
371 
372     /**
373      * pollLast() succeeds unless empty
374      */
testPollLast()375     public void testPollLast() {
376         ConcurrentLinkedDeque q = populatedDeque(SIZE);
377         for (int i = SIZE - 1; i >= 0; --i) {
378             assertEquals(i, q.pollLast());
379         }
380         assertNull(q.pollLast());
381     }
382 
383     /**
384      * poll() succeeds unless empty
385      */
testPoll()386     public void testPoll() {
387         ConcurrentLinkedDeque q = populatedDeque(SIZE);
388         for (int i = 0; i < SIZE; ++i) {
389             assertEquals(i, q.poll());
390         }
391         assertNull(q.poll());
392     }
393 
394     /**
395      * peek() returns next element, or null if empty
396      */
testPeek()397     public void testPeek() {
398         ConcurrentLinkedDeque q = populatedDeque(SIZE);
399         for (int i = 0; i < SIZE; ++i) {
400             assertEquals(i, q.peek());
401             assertEquals(i, q.poll());
402             assertTrue(q.peek() == null ||
403                        !q.peek().equals(i));
404         }
405         assertNull(q.peek());
406     }
407 
408     /**
409      * element() returns first element, or throws NSEE if empty
410      */
testElement()411     public void testElement() {
412         ConcurrentLinkedDeque q = populatedDeque(SIZE);
413         for (int i = 0; i < SIZE; ++i) {
414             assertEquals(i, q.element());
415             assertEquals(i, q.poll());
416         }
417         try {
418             q.element();
419             shouldThrow();
420         } catch (NoSuchElementException success) {}
421     }
422 
423     /**
424      * remove() removes next element, or throws NSEE if empty
425      */
testRemove()426     public void testRemove() {
427         ConcurrentLinkedDeque q = populatedDeque(SIZE);
428         for (int i = 0; i < SIZE; ++i) {
429             assertEquals(i, q.remove());
430         }
431         try {
432             q.remove();
433             shouldThrow();
434         } catch (NoSuchElementException success) {}
435     }
436 
437     /**
438      * remove(x) removes x and returns true if present
439      */
testRemoveElement()440     public void testRemoveElement() {
441         ConcurrentLinkedDeque q = populatedDeque(SIZE);
442         for (int i = 1; i < SIZE; i += 2) {
443             assertTrue(q.contains(i));
444             assertTrue(q.remove(i));
445             assertFalse(q.contains(i));
446             assertTrue(q.contains(i - 1));
447         }
448         for (int i = 0; i < SIZE; i += 2) {
449             assertTrue(q.contains(i));
450             assertTrue(q.remove(i));
451             assertFalse(q.contains(i));
452             assertFalse(q.remove(i + 1));
453             assertFalse(q.contains(i + 1));
454         }
455         assertTrue(q.isEmpty());
456     }
457 
458     /**
459      * peekFirst() returns next element, or null if empty
460      */
testPeekFirst()461     public void testPeekFirst() {
462         ConcurrentLinkedDeque q = populatedDeque(SIZE);
463         for (int i = 0; i < SIZE; ++i) {
464             assertEquals(i, q.peekFirst());
465             assertEquals(i, q.pollFirst());
466             assertTrue(q.peekFirst() == null ||
467                        !q.peekFirst().equals(i));
468         }
469         assertNull(q.peekFirst());
470     }
471 
472     /**
473      * peekLast() returns next element, or null if empty
474      */
testPeekLast()475     public void testPeekLast() {
476         ConcurrentLinkedDeque q = populatedDeque(SIZE);
477         for (int i = SIZE - 1; i >= 0; --i) {
478             assertEquals(i, q.peekLast());
479             assertEquals(i, q.pollLast());
480             assertTrue(q.peekLast() == null ||
481                        !q.peekLast().equals(i));
482         }
483         assertNull(q.peekLast());
484     }
485 
486     /**
487      * getFirst() returns first element, or throws NSEE if empty
488      */
testFirstElement()489     public void testFirstElement() {
490         ConcurrentLinkedDeque q = populatedDeque(SIZE);
491         for (int i = 0; i < SIZE; ++i) {
492             assertEquals(i, q.getFirst());
493             assertEquals(i, q.pollFirst());
494         }
495         try {
496             q.getFirst();
497             shouldThrow();
498         } catch (NoSuchElementException success) {}
499     }
500 
501     /**
502      * getLast() returns last element, or throws NSEE if empty
503      */
testLastElement()504     public void testLastElement() {
505         ConcurrentLinkedDeque q = populatedDeque(SIZE);
506         for (int i = SIZE - 1; i >= 0; --i) {
507             assertEquals(i, q.getLast());
508             assertEquals(i, q.pollLast());
509         }
510         try {
511             q.getLast();
512             shouldThrow();
513         } catch (NoSuchElementException success) {}
514         assertNull(q.peekLast());
515     }
516 
517     /**
518      * removeFirst() removes first element, or throws NSEE if empty
519      */
testRemoveFirst()520     public void testRemoveFirst() {
521         ConcurrentLinkedDeque q = populatedDeque(SIZE);
522         for (int i = 0; i < SIZE; ++i) {
523             assertEquals(i, q.removeFirst());
524         }
525         try {
526             q.removeFirst();
527             shouldThrow();
528         } catch (NoSuchElementException success) {}
529         assertNull(q.peekFirst());
530     }
531 
532     /**
533      * removeLast() removes last element, or throws NSEE if empty
534      */
testRemoveLast()535     public void testRemoveLast() {
536         ConcurrentLinkedDeque q = populatedDeque(SIZE);
537         for (int i = SIZE - 1; i >= 0; --i) {
538             assertEquals(i, q.removeLast());
539         }
540         try {
541             q.removeLast();
542             shouldThrow();
543         } catch (NoSuchElementException success) {}
544         assertNull(q.peekLast());
545     }
546 
547     /**
548      * removeFirstOccurrence(x) removes x and returns true if present
549      */
testRemoveFirstOccurrence()550     public void testRemoveFirstOccurrence() {
551         ConcurrentLinkedDeque q = populatedDeque(SIZE);
552         for (int i = 1; i < SIZE; i += 2) {
553             assertTrue(q.removeFirstOccurrence(new Integer(i)));
554         }
555         for (int i = 0; i < SIZE; i += 2) {
556             assertTrue(q.removeFirstOccurrence(new Integer(i)));
557             assertFalse(q.removeFirstOccurrence(new Integer(i + 1)));
558         }
559         assertTrue(q.isEmpty());
560     }
561 
562     /**
563      * removeLastOccurrence(x) removes x and returns true if present
564      */
testRemoveLastOccurrence()565     public void testRemoveLastOccurrence() {
566         ConcurrentLinkedDeque q = populatedDeque(SIZE);
567         for (int i = 1; i < SIZE; i += 2) {
568             assertTrue(q.removeLastOccurrence(new Integer(i)));
569         }
570         for (int i = 0; i < SIZE; i += 2) {
571             assertTrue(q.removeLastOccurrence(new Integer(i)));
572             assertFalse(q.removeLastOccurrence(new Integer(i + 1)));
573         }
574         assertTrue(q.isEmpty());
575     }
576 
577     /**
578      * contains(x) reports true when elements added but not yet removed
579      */
testContains()580     public void testContains() {
581         ConcurrentLinkedDeque q = populatedDeque(SIZE);
582         for (int i = 0; i < SIZE; ++i) {
583             assertTrue(q.contains(new Integer(i)));
584             q.poll();
585             assertFalse(q.contains(new Integer(i)));
586         }
587     }
588 
589     /**
590      * clear() removes all elements
591      */
testClear()592     public void testClear() {
593         ConcurrentLinkedDeque q = populatedDeque(SIZE);
594         q.clear();
595         assertTrue(q.isEmpty());
596         assertEquals(0, q.size());
597         q.add(one);
598         assertFalse(q.isEmpty());
599         q.clear();
600         assertTrue(q.isEmpty());
601     }
602 
603     /**
604      * containsAll(c) is true when c contains a subset of elements
605      */
testContainsAll()606     public void testContainsAll() {
607         ConcurrentLinkedDeque q = populatedDeque(SIZE);
608         ConcurrentLinkedDeque p = new ConcurrentLinkedDeque();
609         for (int i = 0; i < SIZE; ++i) {
610             assertTrue(q.containsAll(p));
611             assertFalse(p.containsAll(q));
612             p.add(new Integer(i));
613         }
614         assertTrue(p.containsAll(q));
615     }
616 
617     /**
618      * retainAll(c) retains only those elements of c and reports true if change
619      */
testRetainAll()620     public void testRetainAll() {
621         ConcurrentLinkedDeque q = populatedDeque(SIZE);
622         ConcurrentLinkedDeque p = populatedDeque(SIZE);
623         for (int i = 0; i < SIZE; ++i) {
624             boolean changed = q.retainAll(p);
625             if (i == 0)
626                 assertFalse(changed);
627             else
628                 assertTrue(changed);
629 
630             assertTrue(q.containsAll(p));
631             assertEquals(SIZE - i, q.size());
632             p.remove();
633         }
634     }
635 
636     /**
637      * removeAll(c) removes only those elements of c and reports true if changed
638      */
testRemoveAll()639     public void testRemoveAll() {
640         for (int i = 1; i < SIZE; ++i) {
641             ConcurrentLinkedDeque q = populatedDeque(SIZE);
642             ConcurrentLinkedDeque p = populatedDeque(i);
643             assertTrue(q.removeAll(p));
644             assertEquals(SIZE - i, q.size());
645             for (int j = 0; j < i; ++j) {
646                 Integer x = (Integer)(p.remove());
647                 assertFalse(q.contains(x));
648             }
649         }
650     }
651 
652     /**
653      * toArray() contains all elements in FIFO order
654      */
testToArray()655     public void testToArray() {
656         ConcurrentLinkedDeque q = populatedDeque(SIZE);
657         Object[] o = q.toArray();
658         for (int i = 0; i < o.length; i++)
659             assertSame(o[i], q.poll());
660     }
661 
662     /**
663      * toArray(a) contains all elements in FIFO order
664      */
testToArray2()665     public void testToArray2() {
666         ConcurrentLinkedDeque<Integer> q = populatedDeque(SIZE);
667         Integer[] ints = new Integer[SIZE];
668         Integer[] array = q.toArray(ints);
669         assertSame(ints, array);
670         for (int i = 0; i < ints.length; i++)
671             assertSame(ints[i], q.poll());
672     }
673 
674     /**
675      * toArray(null) throws NullPointerException
676      */
testToArray_NullArg()677     public void testToArray_NullArg() {
678         ConcurrentLinkedDeque q = populatedDeque(SIZE);
679         try {
680             q.toArray(null);
681             shouldThrow();
682         } catch (NullPointerException success) {}
683     }
684 
685     /**
686      * toArray(incompatible array type) throws ArrayStoreException
687      */
testToArray1_BadArg()688     public void testToArray1_BadArg() {
689         ConcurrentLinkedDeque q = populatedDeque(SIZE);
690         try {
691             q.toArray(new String[10]);
692             shouldThrow();
693         } catch (ArrayStoreException success) {}
694     }
695 
696     /**
697      * Iterator iterates through all elements
698      */
testIterator()699     public void testIterator() {
700         ConcurrentLinkedDeque q = populatedDeque(SIZE);
701         Iterator it = q.iterator();
702         int i;
703         for (i = 0; it.hasNext(); i++)
704             assertTrue(q.contains(it.next()));
705         assertEquals(i, SIZE);
706         assertIteratorExhausted(it);
707     }
708 
709     /**
710      * iterator of empty collection has no elements
711      */
testEmptyIterator()712     public void testEmptyIterator() {
713         Deque c = new ConcurrentLinkedDeque();
714         assertIteratorExhausted(c.iterator());
715         assertIteratorExhausted(c.descendingIterator());
716     }
717 
718     /**
719      * Iterator ordering is FIFO
720      */
testIteratorOrdering()721     public void testIteratorOrdering() {
722         final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
723         q.add(one);
724         q.add(two);
725         q.add(three);
726 
727         int k = 0;
728         for (Iterator it = q.iterator(); it.hasNext();) {
729             assertEquals(++k, it.next());
730         }
731 
732         assertEquals(3, k);
733     }
734 
735     /**
736      * Modifications do not cause iterators to fail
737      */
testWeaklyConsistentIteration()738     public void testWeaklyConsistentIteration() {
739         final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
740         q.add(one);
741         q.add(two);
742         q.add(three);
743 
744         for (Iterator it = q.iterator(); it.hasNext();) {
745             q.remove();
746             it.next();
747         }
748 
749         assertEquals("deque should be empty again", 0, q.size());
750     }
751 
752     /**
753      * iterator.remove() removes current element
754      */
testIteratorRemove()755     public void testIteratorRemove() {
756         final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
757         final Random rng = new Random();
758         for (int iters = 0; iters < 100; ++iters) {
759             int max = rng.nextInt(5) + 2;
760             int split = rng.nextInt(max - 1) + 1;
761             for (int j = 1; j <= max; ++j)
762                 q.add(new Integer(j));
763             Iterator it = q.iterator();
764             for (int j = 1; j <= split; ++j)
765                 assertEquals(it.next(), new Integer(j));
766             it.remove();
767             assertEquals(it.next(), new Integer(split + 1));
768             for (int j = 1; j <= split; ++j)
769                 q.remove(new Integer(j));
770             it = q.iterator();
771             for (int j = split + 1; j <= max; ++j) {
772                 assertEquals(it.next(), new Integer(j));
773                 it.remove();
774             }
775             assertFalse(it.hasNext());
776             assertTrue(q.isEmpty());
777         }
778     }
779 
780     /**
781      * Descending iterator iterates through all elements
782      */
testDescendingIterator()783     public void testDescendingIterator() {
784         ConcurrentLinkedDeque q = populatedDeque(SIZE);
785         int i = 0;
786         Iterator it = q.descendingIterator();
787         while (it.hasNext()) {
788             assertTrue(q.contains(it.next()));
789             ++i;
790         }
791         assertEquals(i, SIZE);
792         assertFalse(it.hasNext());
793         try {
794             it.next();
795             shouldThrow();
796         } catch (NoSuchElementException success) {}
797     }
798 
799     /**
800      * Descending iterator ordering is reverse FIFO
801      */
testDescendingIteratorOrdering()802     public void testDescendingIteratorOrdering() {
803         final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
804         for (int iters = 0; iters < 100; ++iters) {
805             q.add(new Integer(3));
806             q.add(new Integer(2));
807             q.add(new Integer(1));
808             int k = 0;
809             for (Iterator it = q.descendingIterator(); it.hasNext();) {
810                 assertEquals(++k, it.next());
811             }
812 
813             assertEquals(3, k);
814             q.remove();
815             q.remove();
816             q.remove();
817         }
818     }
819 
820     /**
821      * descendingIterator.remove() removes current element
822      */
testDescendingIteratorRemove()823     public void testDescendingIteratorRemove() {
824         final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
825         final Random rng = new Random();
826         for (int iters = 0; iters < 100; ++iters) {
827             int max = rng.nextInt(5) + 2;
828             int split = rng.nextInt(max - 1) + 1;
829             for (int j = max; j >= 1; --j)
830                 q.add(new Integer(j));
831             Iterator it = q.descendingIterator();
832             for (int j = 1; j <= split; ++j)
833                 assertEquals(it.next(), new Integer(j));
834             it.remove();
835             assertEquals(it.next(), new Integer(split + 1));
836             for (int j = 1; j <= split; ++j)
837                 q.remove(new Integer(j));
838             it = q.descendingIterator();
839             for (int j = split + 1; j <= max; ++j) {
840                 assertEquals(it.next(), new Integer(j));
841                 it.remove();
842             }
843             assertFalse(it.hasNext());
844             assertTrue(q.isEmpty());
845         }
846     }
847 
848     /**
849      * toString() contains toStrings of elements
850      */
testToString()851     public void testToString() {
852         ConcurrentLinkedDeque q = populatedDeque(SIZE);
853         String s = q.toString();
854         for (int i = 0; i < SIZE; ++i) {
855             assertTrue(s.contains(String.valueOf(i)));
856         }
857     }
858 
859     /**
860      * A deserialized serialized deque has same elements in same order
861      */
testSerialization()862     public void testSerialization() throws Exception {
863         Queue x = populatedDeque(SIZE);
864         Queue y = serialClone(x);
865 
866         assertNotSame(x, y);
867         assertEquals(x.size(), y.size());
868         assertEquals(x.toString(), y.toString());
869         assertTrue(Arrays.equals(x.toArray(), y.toArray()));
870         while (!x.isEmpty()) {
871             assertFalse(y.isEmpty());
872             assertEquals(x.remove(), y.remove());
873         }
874         assertTrue(y.isEmpty());
875     }
876 
877     /**
878      * contains(null) always return false.
879      * remove(null) always throws NullPointerException.
880      */
testNeverContainsNull()881     public void testNeverContainsNull() {
882         Deque<?>[] qs = {
883             new ConcurrentLinkedDeque<Object>(),
884             populatedDeque(2),
885         };
886 
887         for (Deque<?> q : qs) {
888             assertFalse(q.contains(null));
889             try {
890                 assertFalse(q.remove(null));
891                 shouldThrow();
892             } catch (NullPointerException success) {}
893             try {
894                 assertFalse(q.removeFirstOccurrence(null));
895                 shouldThrow();
896             } catch (NullPointerException success) {}
897             try {
898                 assertFalse(q.removeLastOccurrence(null));
899                 shouldThrow();
900             } catch (NullPointerException success) {}
901         }
902     }
903 }
904