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