ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ArrayBlockingQueueTest.java
Revision: 1.94
Committed: Tue Aug 13 00:54:51 2019 UTC (4 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.93: +1 -1 lines
Log Message:
use randomBoolean()

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