ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentLinkedDequeTest.java
Revision: 1.30
Committed: Tue Oct 10 05:54:41 2017 UTC (6 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.29: +77 -0 lines
Log Message:
8188900: ConcurrentLinkedDeque linearizability

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