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