ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ArrayBlockingQueueTest.java
Revision: 1.100
Committed: Wed Jan 27 02:55:18 2021 UTC (3 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.99: +1 -0 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 static java.util.concurrent.TimeUnit.MILLISECONDS;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.Iterator;
16 import java.util.NoSuchElementException;
17 import java.util.Queue;
18 import java.util.concurrent.ArrayBlockingQueue;
19 import java.util.concurrent.BlockingQueue;
20 import java.util.concurrent.CountDownLatch;
21 import java.util.concurrent.Executors;
22 import java.util.concurrent.ExecutorService;
23 import java.util.concurrent.ThreadLocalRandom;
24
25 import junit.framework.Test;
26
27 public class ArrayBlockingQueueTest extends JSR166TestCase {
28
29 public static void main(String[] args) {
30 main(suite(), args);
31 }
32
33 public static Test suite() {
34 class Implementation implements CollectionImplementation {
35 public Class<?> klazz() { return ArrayBlockingQueue.class; }
36 public Collection emptyCollection() {
37 boolean fair = randomBoolean();
38 return populatedQueue(0, SIZE, 2 * SIZE, fair);
39 }
40 public Object makeElement(int i) { return JSR166TestCase.itemFor(i); }
41 public boolean isConcurrent() { return true; }
42 public boolean permitsNulls() { return false; }
43 }
44
45 return newTestSuite(
46 ArrayBlockingQueueTest.class,
47 new Fair().testSuite(),
48 new NonFair().testSuite(),
49 CollectionTest.testSuite(new Implementation()));
50 }
51
52 public static class Fair extends BlockingQueueTest {
53 protected BlockingQueue<Item> emptyCollection() {
54 return populatedQueue(0, SIZE, 2 * SIZE, true);
55 }
56 }
57
58 public static class NonFair extends BlockingQueueTest {
59 protected BlockingQueue<Item> emptyCollection() {
60 return populatedQueue(0, SIZE, 2 * SIZE, false);
61 }
62 }
63
64 /**
65 * Returns a new queue of given size containing consecutive
66 * Items 0 ... n - 1.
67 */
68 static ArrayBlockingQueue<Item> populatedQueue(int n) {
69 return populatedQueue(n, n, n, false);
70 }
71
72 /**
73 * Returns a new queue of given size containing consecutive
74 * Items 0 ... n - 1, with given capacity range and fairness.
75 */
76 static ArrayBlockingQueue<Item> populatedQueue(
77 int size, int minCapacity, int maxCapacity, boolean fair) {
78 ThreadLocalRandom rnd = ThreadLocalRandom.current();
79 int capacity = rnd.nextInt(minCapacity, maxCapacity + 1);
80 ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(capacity);
81 assertTrue(q.isEmpty());
82 // shuffle circular array elements so they wrap
83 {
84 int n = rnd.nextInt(capacity);
85 for (int i = 0; i < n; i++) q.add(fortytwo);
86 for (int i = 0; i < n; i++) q.remove();
87 }
88 for (int i = 0; i < size; i++)
89 mustOffer(q, i);
90 mustEqual(size == 0, q.isEmpty());
91 mustEqual(capacity - size, q.remainingCapacity());
92 mustEqual(size, q.size());
93 if (size > 0)
94 mustEqual(0, q.peek());
95 return q;
96 }
97
98 /**
99 * A new queue has the indicated capacity
100 */
101 public void testConstructor1() {
102 mustEqual(SIZE, new ArrayBlockingQueue<Item>(SIZE).remainingCapacity());
103 }
104
105 /**
106 * Constructor throws IllegalArgumentException if capacity argument nonpositive
107 */
108 public void testConstructor_nonPositiveCapacity() {
109 for (int i : new int[] { 0, -1, Integer.MIN_VALUE }) {
110 try {
111 new ArrayBlockingQueue<Item>(i);
112 shouldThrow();
113 } catch (IllegalArgumentException success) {}
114 for (boolean fair : new boolean[] { true, false }) {
115 try {
116 new ArrayBlockingQueue<Item>(i, fair);
117 shouldThrow();
118 } catch (IllegalArgumentException success) {}
119 }
120 }
121 }
122
123 /**
124 * Initializing from null Collection throws NPE
125 */
126 public void testConstructor_nullCollection() {
127 try {
128 new ArrayBlockingQueue<Item>(1, true, null);
129 shouldThrow();
130 } catch (NullPointerException success) {}
131 }
132
133 /**
134 * Initializing from Collection of null elements throws NPE
135 */
136 public void testConstructor4() {
137 Collection<Item> elements = Arrays.asList(new Item[SIZE]);
138 try {
139 new ArrayBlockingQueue<Item>(SIZE, false, elements);
140 shouldThrow();
141 } catch (NullPointerException success) {}
142 }
143
144 /**
145 * Initializing from Collection with some null elements throws NPE
146 */
147 public void testConstructor5() {
148 Item[] items = new Item[2]; items[0] = zero;
149 Collection<Item> elements = Arrays.asList(items);
150 try {
151 new ArrayBlockingQueue<Item>(SIZE, false, elements);
152 shouldThrow();
153 } catch (NullPointerException success) {}
154 }
155
156 /**
157 * Initializing from too large collection throws IllegalArgumentException
158 */
159 public void testConstructor_collectionTooLarge() {
160 // just barely fits - succeeds
161 new ArrayBlockingQueue<Object>(SIZE, false,
162 Collections.nCopies(SIZE, ""));
163 try {
164 new ArrayBlockingQueue<Object>(SIZE - 1, false,
165 Collections.nCopies(SIZE, ""));
166 shouldThrow();
167 } catch (IllegalArgumentException success) {}
168 }
169
170 /**
171 * Queue contains all elements of collection used to initialize
172 */
173 public void testConstructor7() {
174 Item[] items = defaultItems;
175 Collection<Item> elements = Arrays.asList(items);
176 ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(SIZE, true, elements);
177 for (int i = 0; i < SIZE; ++i)
178 mustEqual(items[i], q.poll());
179 }
180
181 /**
182 * Queue transitions from empty to full when elements added
183 */
184 public void testEmptyFull() {
185 BlockingQueue<Item> q = populatedQueue(0, 2, 2, false);
186 assertTrue(q.isEmpty());
187 mustEqual(2, q.remainingCapacity());
188 q.add(one);
189 assertFalse(q.isEmpty());
190 assertTrue(q.offer(two));
191 assertFalse(q.isEmpty());
192 mustEqual(0, q.remainingCapacity());
193 assertFalse(q.offer(three));
194 }
195
196 /**
197 * remainingCapacity decreases on add, increases on remove
198 */
199 public void testRemainingCapacity() {
200 int size = ThreadLocalRandom.current().nextInt(1, SIZE);
201 BlockingQueue<Item> q = populatedQueue(size, size, 2 * size, false);
202 int spare = q.remainingCapacity();
203 int capacity = spare + size;
204 for (int i = 0; i < size; i++) {
205 mustEqual(spare + i, q.remainingCapacity());
206 mustEqual(capacity, q.size() + q.remainingCapacity());
207 mustEqual(i, q.remove());
208 }
209 for (int i = 0; i < size; i++) {
210 mustEqual(capacity - i, q.remainingCapacity());
211 mustEqual(capacity, q.size() + q.remainingCapacity());
212 mustAdd(q, i);
213 }
214 }
215
216 /**
217 * Offer succeeds if not full; fails if full
218 */
219 public void testOffer() {
220 ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(1);
221 assertTrue(q.offer(zero));
222 assertFalse(q.offer(one));
223 }
224
225 /**
226 * add succeeds if not full; throws IllegalStateException if full
227 */
228 public void testAdd() {
229 ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(SIZE);
230 for (int i = 0; i < SIZE; i++) assertTrue(q.add(itemFor(i)));
231 mustEqual(0, q.remainingCapacity());
232 try {
233 q.add(itemFor(SIZE));
234 shouldThrow();
235 } catch (IllegalStateException success) {}
236 }
237
238 /**
239 * addAll(this) throws IllegalArgumentException
240 */
241 public void testAddAllSelf() {
242 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
243 try {
244 q.addAll(q);
245 shouldThrow();
246 } catch (IllegalArgumentException success) {}
247 }
248
249 /**
250 * addAll of a collection with any null elements throws NPE after
251 * possibly adding some elements
252 */
253 public void testAddAll3() {
254 ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(SIZE);
255 Item[] items = new Item[2]; items[0] = zero;
256 try {
257 q.addAll(Arrays.asList(items));
258 shouldThrow();
259 } catch (NullPointerException success) {}
260 }
261
262 /**
263 * addAll throws IllegalStateException if not enough room
264 */
265 public void testAddAll_insufficientSpace() {
266 int size = ThreadLocalRandom.current().nextInt(1, SIZE);
267 ArrayBlockingQueue<Item> q = populatedQueue(0, size, size, false);
268 // Just fits:
269 q.addAll(populatedQueue(size, size, 2 * size, false));
270 mustEqual(0, q.remainingCapacity());
271 mustEqual(size, q.size());
272 mustEqual(0, q.peek());
273 try {
274 q = populatedQueue(0, size, size, false);
275 q.addAll(Collections.nCopies(size + 1, fortytwo));
276 shouldThrow();
277 } catch (IllegalStateException success) {}
278 }
279
280 /**
281 * Queue contains all elements, in traversal order, of successful addAll
282 */
283 public void testAddAll5() {
284 Item[] empty = new Item[0];
285 Item[] items = defaultItems;
286 ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(SIZE);
287 assertFalse(q.addAll(Arrays.asList(empty)));
288 assertTrue(q.addAll(Arrays.asList(items)));
289 for (int i = 0; i < SIZE; ++i)
290 mustEqual(items[i], q.poll());
291 }
292
293 /**
294 * all elements successfully put are contained
295 */
296 public void testPut() throws InterruptedException {
297 ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(SIZE);
298 for (int i = 0; i < SIZE; ++i) {
299 Item x = itemFor(i);
300 q.put(x);
301 mustContain(q, x);
302 }
303 mustEqual(0, q.remainingCapacity());
304 }
305
306 /**
307 * put blocks interruptibly if full
308 */
309 public void testBlockingPut() throws InterruptedException {
310 final ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(SIZE);
311 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
312 Thread t = newStartedThread(new CheckedRunnable() {
313 public void realRun() throws InterruptedException {
314 for (int i = 0; i < SIZE; ++i)
315 q.put(itemFor(i));
316 mustEqual(SIZE, q.size());
317 mustEqual(0, q.remainingCapacity());
318
319 Thread.currentThread().interrupt();
320 try {
321 q.put(ninetynine);
322 shouldThrow();
323 } catch (InterruptedException success) {}
324 assertFalse(Thread.interrupted());
325
326 pleaseInterrupt.countDown();
327 try {
328 q.put(ninetynine);
329 shouldThrow();
330 } catch (InterruptedException success) {}
331 assertFalse(Thread.interrupted());
332 }});
333
334 await(pleaseInterrupt);
335 if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING);
336 t.interrupt();
337 awaitTermination(t);
338 mustEqual(SIZE, q.size());
339 mustEqual(0, q.remainingCapacity());
340 }
341
342 /**
343 * put blocks interruptibly waiting for take when full
344 */
345 public void testPutWithTake() throws InterruptedException {
346 final int capacity = 2;
347 final ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(capacity);
348 final CountDownLatch pleaseTake = new CountDownLatch(1);
349 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
350 Thread t = newStartedThread(new CheckedRunnable() {
351 public void realRun() throws InterruptedException {
352 for (int i = 0; i < capacity; i++)
353 q.put(itemFor(i));
354 pleaseTake.countDown();
355 q.put(eightysix);
356
357 Thread.currentThread().interrupt();
358 try {
359 q.put(ninetynine);
360 shouldThrow();
361 } catch (InterruptedException success) {}
362 assertFalse(Thread.interrupted());
363
364 pleaseInterrupt.countDown();
365 try {
366 q.put(ninetynine);
367 shouldThrow();
368 } catch (InterruptedException success) {}
369 assertFalse(Thread.interrupted());
370 }});
371
372 await(pleaseTake);
373 mustEqual(0, q.remainingCapacity());
374 mustEqual(0, q.take());
375
376 await(pleaseInterrupt);
377 if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING);
378 t.interrupt();
379 awaitTermination(t);
380 mustEqual(0, q.remainingCapacity());
381 }
382
383 /**
384 * timed offer times out if full and elements not taken
385 */
386 public void testTimedOffer() {
387 final ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(2);
388 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
389 Thread t = newStartedThread(new CheckedRunnable() {
390 public void realRun() throws InterruptedException {
391 q.put(one);
392 q.put(two);
393 long startTime = System.nanoTime();
394 assertFalse(q.offer(zero, timeoutMillis(), MILLISECONDS));
395 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
396
397 Thread.currentThread().interrupt();
398 try {
399 q.offer(three, randomTimeout(), randomTimeUnit());
400 shouldThrow();
401 } catch (InterruptedException success) {}
402 assertFalse(Thread.interrupted());
403
404 pleaseInterrupt.countDown();
405 try {
406 q.offer(four, LONGER_DELAY_MS, MILLISECONDS);
407 shouldThrow();
408 } catch (InterruptedException success) {}
409 assertFalse(Thread.interrupted());
410 }});
411
412 await(pleaseInterrupt);
413 if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING);
414 t.interrupt();
415 awaitTermination(t);
416 }
417
418 /**
419 * take retrieves elements in FIFO order
420 */
421 public void testTake() throws InterruptedException {
422 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
423 for (int i = 0; i < SIZE; ++i) {
424 mustEqual(i, q.take());
425 }
426 }
427
428 /**
429 * Take removes existing elements until empty, then blocks interruptibly
430 */
431 public void testBlockingTake() throws InterruptedException {
432 final ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
433 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
434 Thread t = newStartedThread(new CheckedRunnable() {
435 public void realRun() throws InterruptedException {
436 for (int i = 0; i < SIZE; i++) mustEqual(i, q.take());
437
438 Thread.currentThread().interrupt();
439 try {
440 q.take();
441 shouldThrow();
442 } catch (InterruptedException success) {}
443 assertFalse(Thread.interrupted());
444
445 pleaseInterrupt.countDown();
446 try {
447 q.take();
448 shouldThrow();
449 } catch (InterruptedException success) {}
450 assertFalse(Thread.interrupted());
451 }});
452
453 await(pleaseInterrupt);
454 if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING);
455 t.interrupt();
456 awaitTermination(t);
457 }
458
459 /**
460 * poll succeeds unless empty
461 */
462 public void testPoll() {
463 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
464 for (int i = 0; i < SIZE; ++i) {
465 mustEqual(i, q.poll());
466 }
467 assertNull(q.poll());
468 }
469
470 /**
471 * timed poll with zero timeout succeeds when non-empty, else times out
472 */
473 public void testTimedPoll0() throws InterruptedException {
474 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
475 for (int i = 0; i < SIZE; ++i) {
476 mustEqual(i, q.poll(0, MILLISECONDS));
477 }
478 assertNull(q.poll(0, MILLISECONDS));
479 checkEmpty(q);
480 }
481
482 /**
483 * timed poll with nonzero timeout succeeds when non-empty, else times out
484 */
485 public void testTimedPoll() throws InterruptedException {
486 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
487 for (int i = 0; i < SIZE; ++i) {
488 long startTime = System.nanoTime();
489 mustEqual(i, q.poll(LONG_DELAY_MS, MILLISECONDS));
490 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
491 }
492 long startTime = System.nanoTime();
493 assertNull(q.poll(timeoutMillis(), MILLISECONDS));
494 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
495 checkEmpty(q);
496 }
497
498 /**
499 * Interrupted timed poll throws InterruptedException instead of
500 * returning timeout status
501 */
502 public void testInterruptedTimedPoll() throws InterruptedException {
503 final BlockingQueue<Item> q = populatedQueue(SIZE);
504 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
505 Thread t = newStartedThread(new CheckedRunnable() {
506 public void realRun() throws InterruptedException {
507 for (int i = 0; i < SIZE; i++)
508 mustEqual(i, q.poll(LONG_DELAY_MS, MILLISECONDS));
509
510 Thread.currentThread().interrupt();
511 try {
512 q.poll(randomTimeout(), randomTimeUnit());
513 shouldThrow();
514 } catch (InterruptedException success) {}
515 assertFalse(Thread.interrupted());
516
517 pleaseInterrupt.countDown();
518 try {
519 q.poll(LONGER_DELAY_MS, MILLISECONDS);
520 shouldThrow();
521 } catch (InterruptedException success) {}
522 assertFalse(Thread.interrupted());
523 }});
524
525 await(pleaseInterrupt);
526 if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING);
527 t.interrupt();
528 awaitTermination(t);
529 checkEmpty(q);
530 }
531
532 /**
533 * peek returns next element, or null if empty
534 */
535 public void testPeek() {
536 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
537 for (int i = 0; i < SIZE; ++i) {
538 mustEqual(i, q.peek());
539 mustEqual(i, q.poll());
540 assertTrue(q.peek() == null ||
541 !q.peek().equals(i));
542 }
543 assertNull(q.peek());
544 }
545
546 /**
547 * element returns next element, or throws NSEE if empty
548 */
549 public void testElement() {
550 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
551 for (int i = 0; i < SIZE; ++i) {
552 mustEqual(i, q.element());
553 mustEqual(i, q.poll());
554 }
555 try {
556 q.element();
557 shouldThrow();
558 } catch (NoSuchElementException success) {}
559 }
560
561 /**
562 * remove removes next element, or throws NSEE if empty
563 */
564 public void testRemove() {
565 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
566 for (int i = 0; i < SIZE; ++i) {
567 mustEqual(i, q.remove());
568 }
569 try {
570 q.remove();
571 shouldThrow();
572 } catch (NoSuchElementException success) {}
573 }
574
575 /**
576 * contains(x) reports true when elements added but not yet removed
577 */
578 public void testContains() {
579 int size = ThreadLocalRandom.current().nextInt(1, SIZE);
580 ArrayBlockingQueue<Item> q = populatedQueue(size, size, 2 * size, false);
581 assertFalse(q.contains(null));
582 for (int i = 0; i < size; ++i) {
583 mustContain(q, i);
584 mustEqual(i, q.poll());
585 mustNotContain(q, i);
586 }
587 }
588
589 /**
590 * clear removes all elements
591 */
592 public void testClear() {
593 int size = ThreadLocalRandom.current().nextInt(1, 5);
594 ArrayBlockingQueue<Item> q = populatedQueue(size, size, 2 * size, false);
595 int capacity = size + q.remainingCapacity();
596 q.clear();
597 assertTrue(q.isEmpty());
598 mustEqual(0, q.size());
599 mustEqual(capacity, q.remainingCapacity());
600 q.add(one);
601 assertFalse(q.isEmpty());
602 mustContain(q, one);
603 q.clear();
604 assertTrue(q.isEmpty());
605 }
606
607 /**
608 * containsAll(c) is true when c contains a subset of elements
609 */
610 public void testContainsAll() {
611 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
612 ArrayBlockingQueue<Item> p = new ArrayBlockingQueue<>(SIZE);
613 for (int i = 0; i < SIZE; ++i) {
614 assertTrue(q.containsAll(p));
615 assertFalse(p.containsAll(q));
616 mustAdd(p, i);
617 }
618 assertTrue(p.containsAll(q));
619 }
620
621 /**
622 * retainAll(c) retains only those elements of c and reports true if changed
623 */
624 public void testRetainAll() {
625 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
626 ArrayBlockingQueue<Item> p = populatedQueue(SIZE);
627 for (int i = 0; i < SIZE; ++i) {
628 boolean changed = q.retainAll(p);
629 if (i == 0)
630 assertFalse(changed);
631 else
632 assertTrue(changed);
633
634 assertTrue(q.containsAll(p));
635 mustEqual(SIZE - i, q.size());
636 p.remove();
637 }
638 }
639
640 /**
641 * removeAll(c) removes only those elements of c and reports true if changed
642 */
643 public void testRemoveAll() {
644 for (int i = 1; i < SIZE; ++i) {
645 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
646 ArrayBlockingQueue<Item> p = populatedQueue(i);
647 assertTrue(q.removeAll(p));
648 mustEqual(SIZE - i, q.size());
649 for (int j = 0; j < i; ++j) {
650 Item x = p.remove();
651 mustNotContain(q, x);
652 }
653 }
654 }
655
656 void checkToArray(ArrayBlockingQueue<Item> q) {
657 int size = q.size();
658 Object[] a1 = q.toArray();
659 mustEqual(size, a1.length);
660 Item[] a2 = q.toArray(new Item[0]);
661 mustEqual(size, a2.length);
662 Item[] a3 = q.toArray(new Item[Math.max(0, size - 1)]);
663 mustEqual(size, a3.length);
664 Item[] a4 = new Item[size];
665 assertSame(a4, q.toArray(a4));
666 Item[] a5 = new Item[size + 1];
667 Arrays.fill(a5, fortytwo);
668 assertSame(a5, q.toArray(a5));
669 Item[] a6 = new Item[size + 2];
670 Arrays.fill(a6, fortytwo);
671 assertSame(a6, q.toArray(a6));
672 Object[][] as = { a1, a2, a3, a4, a5, a6 };
673 for (Object[] a : as) {
674 if (a.length > size) assertNull(a[size]);
675 if (a.length > size + 1) mustEqual(fortytwo, a[size + 1]);
676 }
677 Iterator<? extends Item> it = q.iterator();
678 Item s = q.peek();
679 for (int i = 0; i < size; i++) {
680 Item x = (Item) it.next();
681 mustEqual(s.value + i, x);
682 for (Object[] a : as)
683 mustEqual(a[i], x);
684 }
685 }
686
687 /**
688 * toArray() and toArray(a) contain all elements in FIFO order
689 */
690 public void testToArray() {
691 final ThreadLocalRandom rnd = ThreadLocalRandom.current();
692 final int size = rnd.nextInt(6);
693 final int capacity = Math.max(1, size + rnd.nextInt(size + 1));
694 ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(capacity);
695 for (int i = 0; i < size; i++) {
696 checkToArray(q);
697 mustAdd(q, i);
698 }
699 // Provoke wraparound
700 int added = size * 2;
701 for (int i = 0; i < added; i++) {
702 checkToArray(q);
703 mustEqual(i, q.poll());
704 q.add(new Item(size + i));
705 }
706 for (int i = 0; i < size; i++) {
707 checkToArray(q);
708 mustEqual((added + i), q.poll());
709 }
710 }
711
712 /**
713 * toArray(incompatible array type) throws ArrayStoreException
714 */
715 @SuppressWarnings("CollectionToArraySafeParameter")
716 public void testToArray_incompatibleArrayType() {
717 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
718 try {
719 q.toArray(new String[10]);
720 shouldThrow();
721 } catch (ArrayStoreException success) {}
722 try {
723 q.toArray(new String[0]);
724 shouldThrow();
725 } catch (ArrayStoreException success) {}
726 }
727
728 /**
729 * iterator iterates through all elements
730 */
731 public void testIterator() throws InterruptedException {
732 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
733 Iterator<? extends Item> it = q.iterator();
734 int i;
735 for (i = 0; it.hasNext(); i++)
736 mustContain(q, it.next());
737 mustEqual(i, SIZE);
738 assertIteratorExhausted(it);
739
740 it = q.iterator();
741 for (i = 0; it.hasNext(); i++)
742 mustEqual(it.next(), q.take());
743 mustEqual(i, SIZE);
744 assertIteratorExhausted(it);
745 }
746
747 /**
748 * iterator of empty collection has no elements
749 */
750 public void testEmptyIterator() {
751 assertIteratorExhausted(new ArrayBlockingQueue<>(SIZE).iterator());
752 }
753
754 /**
755 * iterator.remove removes current element
756 */
757 public void testIteratorRemove() {
758 final ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(3);
759 q.add(two);
760 q.add(one);
761 q.add(three);
762
763 Iterator<? extends Item> it = q.iterator();
764 it.next();
765 it.remove();
766
767 it = q.iterator();
768 assertSame(it.next(), one);
769 assertSame(it.next(), three);
770 assertFalse(it.hasNext());
771 }
772
773 /**
774 * iterator ordering is FIFO
775 */
776 public void testIteratorOrdering() {
777 final ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(3);
778 q.add(one);
779 q.add(two);
780 q.add(three);
781
782 assertEquals("queue should be full", 0, q.remainingCapacity());
783
784 int k = 0;
785 for (Iterator<? extends Item> it = q.iterator(); it.hasNext();) {
786 mustEqual(++k, it.next());
787 }
788 mustEqual(3, k);
789 }
790
791 /**
792 * Modifications do not cause iterators to fail
793 */
794 public void testWeaklyConsistentIteration() {
795 final ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(3);
796 q.add(one);
797 q.add(two);
798 q.add(three);
799 for (Iterator<? extends Item> it = q.iterator(); it.hasNext();) {
800 q.remove();
801 it.next();
802 }
803 mustEqual(0, q.size());
804 }
805
806 /**
807 * toString contains toStrings of elements
808 */
809 public void testToString() {
810 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
811 String s = q.toString();
812 for (int i = 0; i < SIZE; ++i) {
813 assertTrue(s.contains(String.valueOf(i)));
814 }
815 }
816
817 /**
818 * offer transfers elements across Executor tasks
819 */
820 public void testOfferInExecutor() {
821 final ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(2);
822 q.add(one);
823 q.add(two);
824 final CheckedBarrier threadsStarted = new CheckedBarrier(2);
825 final ExecutorService executor = Executors.newFixedThreadPool(2);
826 try (PoolCleaner cleaner = cleaner(executor)) {
827 executor.execute(new CheckedRunnable() {
828 public void realRun() throws InterruptedException {
829 assertFalse(q.offer(three));
830 threadsStarted.await();
831 assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
832 mustEqual(0, q.remainingCapacity());
833 }});
834
835 executor.execute(new CheckedRunnable() {
836 public void realRun() throws InterruptedException {
837 threadsStarted.await();
838 mustEqual(0, q.remainingCapacity());
839 assertSame(one, q.take());
840 }});
841 }
842 }
843
844 /**
845 * timed poll retrieves elements across Executor threads
846 */
847 public void testPollInExecutor() {
848 final ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(2);
849 final CheckedBarrier threadsStarted = new CheckedBarrier(2);
850 final ExecutorService executor = Executors.newFixedThreadPool(2);
851 try (PoolCleaner cleaner = cleaner(executor)) {
852 executor.execute(new CheckedRunnable() {
853 public void realRun() throws InterruptedException {
854 assertNull(q.poll());
855 threadsStarted.await();
856 assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
857 checkEmpty(q);
858 }});
859
860 executor.execute(new CheckedRunnable() {
861 public void realRun() throws InterruptedException {
862 threadsStarted.await();
863 q.put(one);
864 }});
865 }
866 }
867
868 /**
869 * A deserialized/reserialized queue has same elements in same order
870 */
871 public void testSerialization() throws Exception {
872 Queue<Item> x = populatedQueue(SIZE);
873 Queue<Item> y = serialClone(x);
874
875 assertNotSame(x, y);
876 mustEqual(x.size(), y.size());
877 mustEqual(x.toString(), y.toString());
878 assertTrue(Arrays.equals(x.toArray(), y.toArray()));
879 while (!x.isEmpty()) {
880 assertFalse(y.isEmpty());
881 mustEqual(x.remove(), y.remove());
882 }
883 assertTrue(y.isEmpty());
884 }
885
886 /**
887 * drainTo(c) empties queue into another collection c
888 */
889 public void testDrainTo() {
890 ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
891 ArrayList<Item> l = new ArrayList<>();
892 q.drainTo(l);
893 mustEqual(0, q.size());
894 mustEqual(SIZE, l.size());
895 for (int i = 0; i < SIZE; ++i)
896 mustEqual(l.get(i), i);
897 q.add(zero);
898 q.add(one);
899 assertFalse(q.isEmpty());
900 mustContain(q, zero);
901 mustContain(q, one);
902 l.clear();
903 q.drainTo(l);
904 mustEqual(0, q.size());
905 mustEqual(2, l.size());
906 for (int i = 0; i < 2; ++i)
907 mustEqual(l.get(i), i);
908 }
909
910 /**
911 * drainTo empties full queue, unblocking a waiting put.
912 */
913 public void testDrainToWithActivePut() throws InterruptedException {
914 final ArrayBlockingQueue<Item> q = populatedQueue(SIZE);
915 Thread t = new Thread(new CheckedRunnable() {
916 public void realRun() throws InterruptedException {
917 q.put(new Item(SIZE + 1));
918 }});
919
920 t.start();
921 ArrayList<Item> l = new ArrayList<>();
922 q.drainTo(l);
923 assertTrue(l.size() >= SIZE);
924 for (int i = 0; i < SIZE; ++i)
925 mustEqual(l.get(i), i);
926 t.join();
927 assertTrue(q.size() + l.size() >= SIZE);
928 }
929
930 /**
931 * drainTo(c, n) empties first min(n, size) elements of queue into c
932 */
933 public void testDrainToN() {
934 ArrayBlockingQueue<Item> q = new ArrayBlockingQueue<>(SIZE * 2);
935 for (int i = 0; i < SIZE + 2; ++i) {
936 for (int j = 0; j < SIZE; j++)
937 mustOffer(q, j);
938 ArrayList<Item> l = new ArrayList<>();
939 q.drainTo(l, i);
940 int k = (i < SIZE) ? i : SIZE;
941 mustEqual(k, l.size());
942 mustEqual(SIZE - k, q.size());
943 for (int j = 0; j < k; ++j)
944 mustEqual(l.get(j), j);
945 do {} while (q.poll() != null);
946 }
947 }
948
949 /**
950 * remove(null), contains(null) always return false
951 */
952 public void testNeverContainsNull() {
953 Collection<?>[] qs = {
954 populatedQueue(0, 1, 10, false),
955 populatedQueue(2, 2, 10, true),
956 };
957
958 for (Collection<?> q : qs) {
959 assertFalse(q.contains(null));
960 assertFalse(q.remove(null));
961 }
962 }
963 }