ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentLinkedDequeTest.java
Revision: 1.1
Committed: Wed Aug 25 21:40:03 2010 UTC (13 years, 8 months ago) by jsr166
Branch: MAIN
Log Message:
Finish ConcurrentLinkedDeque feature

File Contents

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