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