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.Iterator; 14 import java.util.NoSuchElementException; 15 import java.util.Queue; 16 import java.util.concurrent.ConcurrentLinkedQueue; 17 18 import junit.framework.Test; 19 import junit.framework.TestSuite; 20 21 public class ConcurrentLinkedQueueTest extends JSR166TestCase { 22 23 // android-note: Removed because the CTS runner does a bad job of 24 // retrying tests that have suite() declarations. 25 // 26 // public static void main(String[] args) { 27 // main(suite(), args); 28 // } 29 // public static Test suite() { 30 // return new TestSuite(ConcurrentLinkedQueueTest.class); 31 // } 32 33 /** 34 * Returns a new queue of given size containing consecutive 35 * Integers 0 ... n. 36 */ populatedQueue(int n)37 private ConcurrentLinkedQueue<Integer> populatedQueue(int n) { 38 ConcurrentLinkedQueue<Integer> q = new ConcurrentLinkedQueue<Integer>(); 39 assertTrue(q.isEmpty()); 40 for (int i = 0; i < n; ++i) 41 assertTrue(q.offer(new Integer(i))); 42 assertFalse(q.isEmpty()); 43 assertEquals(n, q.size()); 44 return q; 45 } 46 47 /** 48 * new queue is empty 49 */ testConstructor1()50 public void testConstructor1() { 51 assertEquals(0, new ConcurrentLinkedQueue().size()); 52 } 53 54 /** 55 * Initializing from null Collection throws NPE 56 */ testConstructor3()57 public void testConstructor3() { 58 try { 59 new ConcurrentLinkedQueue((Collection)null); 60 shouldThrow(); 61 } catch (NullPointerException success) {} 62 } 63 64 /** 65 * Initializing from Collection of null elements throws NPE 66 */ testConstructor4()67 public void testConstructor4() { 68 try { 69 new ConcurrentLinkedQueue(Arrays.asList(new Integer[SIZE])); 70 shouldThrow(); 71 } catch (NullPointerException success) {} 72 } 73 74 /** 75 * Initializing from Collection with some null elements throws NPE 76 */ testConstructor5()77 public void testConstructor5() { 78 Integer[] ints = new Integer[SIZE]; 79 for (int i = 0; i < SIZE - 1; ++i) 80 ints[i] = new Integer(i); 81 try { 82 new ConcurrentLinkedQueue(Arrays.asList(ints)); 83 shouldThrow(); 84 } catch (NullPointerException success) {} 85 } 86 87 /** 88 * Queue contains all elements of collection used to initialize 89 */ testConstructor6()90 public void testConstructor6() { 91 Integer[] ints = new Integer[SIZE]; 92 for (int i = 0; i < SIZE; ++i) 93 ints[i] = new Integer(i); 94 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints)); 95 for (int i = 0; i < SIZE; ++i) 96 assertEquals(ints[i], q.poll()); 97 } 98 99 /** 100 * isEmpty is true before add, false after 101 */ testEmpty()102 public void testEmpty() { 103 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 104 assertTrue(q.isEmpty()); 105 q.add(one); 106 assertFalse(q.isEmpty()); 107 q.add(two); 108 q.remove(); 109 q.remove(); 110 assertTrue(q.isEmpty()); 111 } 112 113 /** 114 * size changes when elements added and removed 115 */ testSize()116 public void testSize() { 117 ConcurrentLinkedQueue q = populatedQueue(SIZE); 118 for (int i = 0; i < SIZE; ++i) { 119 assertEquals(SIZE - i, q.size()); 120 q.remove(); 121 } 122 for (int i = 0; i < SIZE; ++i) { 123 assertEquals(i, q.size()); 124 q.add(new Integer(i)); 125 } 126 } 127 128 /** 129 * offer(null) throws NPE 130 */ testOfferNull()131 public void testOfferNull() { 132 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 133 try { 134 q.offer(null); 135 shouldThrow(); 136 } catch (NullPointerException success) {} 137 } 138 139 /** 140 * add(null) throws NPE 141 */ testAddNull()142 public void testAddNull() { 143 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 144 try { 145 q.add(null); 146 shouldThrow(); 147 } catch (NullPointerException success) {} 148 } 149 150 /** 151 * Offer returns true 152 */ testOffer()153 public void testOffer() { 154 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 155 assertTrue(q.offer(zero)); 156 assertTrue(q.offer(one)); 157 } 158 159 /** 160 * add returns true 161 */ testAdd()162 public void testAdd() { 163 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 164 for (int i = 0; i < SIZE; ++i) { 165 assertEquals(i, q.size()); 166 assertTrue(q.add(new Integer(i))); 167 } 168 } 169 170 /** 171 * addAll(null) throws NPE 172 */ testAddAll1()173 public void testAddAll1() { 174 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 175 try { 176 q.addAll(null); 177 shouldThrow(); 178 } catch (NullPointerException success) {} 179 } 180 181 /** 182 * addAll(this) throws IAE 183 */ testAddAllSelf()184 public void testAddAllSelf() { 185 ConcurrentLinkedQueue q = populatedQueue(SIZE); 186 try { 187 q.addAll(q); 188 shouldThrow(); 189 } catch (IllegalArgumentException success) {} 190 } 191 192 /** 193 * addAll of a collection with null elements throws NPE 194 */ testAddAll2()195 public void testAddAll2() { 196 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 197 try { 198 q.addAll(Arrays.asList(new Integer[SIZE])); 199 shouldThrow(); 200 } catch (NullPointerException success) {} 201 } 202 203 /** 204 * addAll of a collection with any null elements throws NPE after 205 * possibly adding some elements 206 */ testAddAll3()207 public void testAddAll3() { 208 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 209 Integer[] ints = new Integer[SIZE]; 210 for (int i = 0; i < SIZE - 1; ++i) 211 ints[i] = new Integer(i); 212 try { 213 q.addAll(Arrays.asList(ints)); 214 shouldThrow(); 215 } catch (NullPointerException success) {} 216 } 217 218 /** 219 * Queue contains all elements, in traversal order, of successful addAll 220 */ testAddAll5()221 public void testAddAll5() { 222 Integer[] empty = new Integer[0]; 223 Integer[] ints = new Integer[SIZE]; 224 for (int i = 0; i < SIZE; ++i) 225 ints[i] = new Integer(i); 226 ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 227 assertFalse(q.addAll(Arrays.asList(empty))); 228 assertTrue(q.addAll(Arrays.asList(ints))); 229 for (int i = 0; i < SIZE; ++i) 230 assertEquals(ints[i], q.poll()); 231 } 232 233 /** 234 * poll succeeds unless empty 235 */ testPoll()236 public void testPoll() { 237 ConcurrentLinkedQueue q = populatedQueue(SIZE); 238 for (int i = 0; i < SIZE; ++i) { 239 assertEquals(i, q.poll()); 240 } 241 assertNull(q.poll()); 242 } 243 244 /** 245 * peek returns next element, or null if empty 246 */ testPeek()247 public void testPeek() { 248 ConcurrentLinkedQueue q = populatedQueue(SIZE); 249 for (int i = 0; i < SIZE; ++i) { 250 assertEquals(i, q.peek()); 251 assertEquals(i, q.poll()); 252 assertTrue(q.peek() == null || 253 !q.peek().equals(i)); 254 } 255 assertNull(q.peek()); 256 } 257 258 /** 259 * element returns next element, or throws NSEE if empty 260 */ testElement()261 public void testElement() { 262 ConcurrentLinkedQueue q = populatedQueue(SIZE); 263 for (int i = 0; i < SIZE; ++i) { 264 assertEquals(i, q.element()); 265 assertEquals(i, q.poll()); 266 } 267 try { 268 q.element(); 269 shouldThrow(); 270 } catch (NoSuchElementException success) {} 271 } 272 273 /** 274 * remove removes next element, or throws NSEE if empty 275 */ testRemove()276 public void testRemove() { 277 ConcurrentLinkedQueue q = populatedQueue(SIZE); 278 for (int i = 0; i < SIZE; ++i) { 279 assertEquals(i, q.remove()); 280 } 281 try { 282 q.remove(); 283 shouldThrow(); 284 } catch (NoSuchElementException success) {} 285 } 286 287 /** 288 * remove(x) removes x and returns true if present 289 */ testRemoveElement()290 public void testRemoveElement() { 291 ConcurrentLinkedQueue q = populatedQueue(SIZE); 292 for (int i = 1; i < SIZE; i += 2) { 293 assertTrue(q.contains(i)); 294 assertTrue(q.remove(i)); 295 assertFalse(q.contains(i)); 296 assertTrue(q.contains(i - 1)); 297 } 298 for (int i = 0; i < SIZE; i += 2) { 299 assertTrue(q.contains(i)); 300 assertTrue(q.remove(i)); 301 assertFalse(q.contains(i)); 302 assertFalse(q.remove(i + 1)); 303 assertFalse(q.contains(i + 1)); 304 } 305 assertTrue(q.isEmpty()); 306 } 307 308 /** 309 * contains(x) reports true when elements added but not yet removed 310 */ testContains()311 public void testContains() { 312 ConcurrentLinkedQueue q = populatedQueue(SIZE); 313 for (int i = 0; i < SIZE; ++i) { 314 assertTrue(q.contains(new Integer(i))); 315 q.poll(); 316 assertFalse(q.contains(new Integer(i))); 317 } 318 } 319 320 /** 321 * clear removes all elements 322 */ testClear()323 public void testClear() { 324 ConcurrentLinkedQueue q = populatedQueue(SIZE); 325 q.clear(); 326 assertTrue(q.isEmpty()); 327 assertEquals(0, q.size()); 328 q.add(one); 329 assertFalse(q.isEmpty()); 330 q.clear(); 331 assertTrue(q.isEmpty()); 332 } 333 334 /** 335 * containsAll(c) is true when c contains a subset of elements 336 */ testContainsAll()337 public void testContainsAll() { 338 ConcurrentLinkedQueue q = populatedQueue(SIZE); 339 ConcurrentLinkedQueue p = new ConcurrentLinkedQueue(); 340 for (int i = 0; i < SIZE; ++i) { 341 assertTrue(q.containsAll(p)); 342 assertFalse(p.containsAll(q)); 343 p.add(new Integer(i)); 344 } 345 assertTrue(p.containsAll(q)); 346 } 347 348 /** 349 * retainAll(c) retains only those elements of c and reports true if change 350 */ testRetainAll()351 public void testRetainAll() { 352 ConcurrentLinkedQueue q = populatedQueue(SIZE); 353 ConcurrentLinkedQueue p = populatedQueue(SIZE); 354 for (int i = 0; i < SIZE; ++i) { 355 boolean changed = q.retainAll(p); 356 if (i == 0) 357 assertFalse(changed); 358 else 359 assertTrue(changed); 360 361 assertTrue(q.containsAll(p)); 362 assertEquals(SIZE - i, q.size()); 363 p.remove(); 364 } 365 } 366 367 /** 368 * removeAll(c) removes only those elements of c and reports true if changed 369 */ testRemoveAll()370 public void testRemoveAll() { 371 for (int i = 1; i < SIZE; ++i) { 372 ConcurrentLinkedQueue q = populatedQueue(SIZE); 373 ConcurrentLinkedQueue p = populatedQueue(i); 374 assertTrue(q.removeAll(p)); 375 assertEquals(SIZE - i, q.size()); 376 for (int j = 0; j < i; ++j) { 377 Integer x = (Integer)(p.remove()); 378 assertFalse(q.contains(x)); 379 } 380 } 381 } 382 383 /** 384 * toArray contains all elements in FIFO order 385 */ testToArray()386 public void testToArray() { 387 ConcurrentLinkedQueue q = populatedQueue(SIZE); 388 Object[] o = q.toArray(); 389 for (int i = 0; i < o.length; i++) 390 assertSame(o[i], q.poll()); 391 } 392 393 /** 394 * toArray(a) contains all elements in FIFO order 395 */ testToArray2()396 public void testToArray2() { 397 ConcurrentLinkedQueue<Integer> q = populatedQueue(SIZE); 398 Integer[] ints = new Integer[SIZE]; 399 Integer[] array = q.toArray(ints); 400 assertSame(ints, array); 401 for (int i = 0; i < ints.length; i++) 402 assertSame(ints[i], q.poll()); 403 } 404 405 /** 406 * toArray(null) throws NullPointerException 407 */ testToArray_NullArg()408 public void testToArray_NullArg() { 409 ConcurrentLinkedQueue q = populatedQueue(SIZE); 410 try { 411 q.toArray(null); 412 shouldThrow(); 413 } catch (NullPointerException success) {} 414 } 415 416 /** 417 * toArray(incompatible array type) throws ArrayStoreException 418 */ testToArray1_BadArg()419 public void testToArray1_BadArg() { 420 ConcurrentLinkedQueue q = populatedQueue(SIZE); 421 try { 422 q.toArray(new String[10]); 423 shouldThrow(); 424 } catch (ArrayStoreException success) {} 425 } 426 427 /** 428 * iterator iterates through all elements 429 */ testIterator()430 public void testIterator() { 431 ConcurrentLinkedQueue q = populatedQueue(SIZE); 432 Iterator it = q.iterator(); 433 int i; 434 for (i = 0; it.hasNext(); i++) 435 assertTrue(q.contains(it.next())); 436 assertEquals(i, SIZE); 437 assertIteratorExhausted(it); 438 } 439 440 /** 441 * iterator of empty collection has no elements 442 */ testEmptyIterator()443 public void testEmptyIterator() { 444 assertIteratorExhausted(new ConcurrentLinkedQueue().iterator()); 445 } 446 447 /** 448 * iterator ordering is FIFO 449 */ testIteratorOrdering()450 public void testIteratorOrdering() { 451 final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 452 q.add(one); 453 q.add(two); 454 q.add(three); 455 456 int k = 0; 457 for (Iterator it = q.iterator(); it.hasNext();) { 458 assertEquals(++k, it.next()); 459 } 460 461 assertEquals(3, k); 462 } 463 464 /** 465 * Modifications do not cause iterators to fail 466 */ testWeaklyConsistentIteration()467 public void testWeaklyConsistentIteration() { 468 final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 469 q.add(one); 470 q.add(two); 471 q.add(three); 472 473 for (Iterator it = q.iterator(); it.hasNext();) { 474 q.remove(); 475 it.next(); 476 } 477 478 assertEquals("queue should be empty again", 0, q.size()); 479 } 480 481 /** 482 * iterator.remove removes current element 483 */ testIteratorRemove()484 public void testIteratorRemove() { 485 final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); 486 q.add(one); 487 q.add(two); 488 q.add(three); 489 Iterator it = q.iterator(); 490 it.next(); 491 it.remove(); 492 it = q.iterator(); 493 assertSame(it.next(), two); 494 assertSame(it.next(), three); 495 assertFalse(it.hasNext()); 496 } 497 498 /** 499 * toString contains toStrings of elements 500 */ testToString()501 public void testToString() { 502 ConcurrentLinkedQueue q = populatedQueue(SIZE); 503 String s = q.toString(); 504 for (int i = 0; i < SIZE; ++i) { 505 assertTrue(s.contains(String.valueOf(i))); 506 } 507 } 508 509 /** 510 * A deserialized serialized queue has same elements in same order 511 */ testSerialization()512 public void testSerialization() throws Exception { 513 Queue x = populatedQueue(SIZE); 514 Queue y = serialClone(x); 515 516 assertNotSame(x, y); 517 assertEquals(x.size(), y.size()); 518 assertEquals(x.toString(), y.toString()); 519 assertTrue(Arrays.equals(x.toArray(), y.toArray())); 520 while (!x.isEmpty()) { 521 assertFalse(y.isEmpty()); 522 assertEquals(x.remove(), y.remove()); 523 } 524 assertTrue(y.isEmpty()); 525 } 526 527 /** 528 * remove(null), contains(null) always return false 529 */ testNeverContainsNull()530 public void testNeverContainsNull() { 531 Collection<?>[] qs = { 532 new ConcurrentLinkedQueue<Object>(), 533 populatedQueue(2), 534 }; 535 536 for (Collection<?> q : qs) { 537 assertFalse(q.contains(null)); 538 assertFalse(q.remove(null)); 539 } 540 } 541 } 542