ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentLinkedDequeTest.java
Revision: 1.40
Committed: Wed Jan 27 02:55:18 2021 UTC (3 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.39: +2 -1 lines
Log Message:
Suppress all new errorprone "errors"

File Contents

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