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