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/licenses/publicdomain
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
9 package tests.api.java.util.concurrent; // android-added
11 import junit.framework.*;
13 import static java.util.concurrent.TimeUnit.MILLISECONDS;
14 import java.util.concurrent.*;
16 public class DelayQueueTest extends JSR166TestCase {
17 public static Test suite() {
18 return new TestSuite(DelayQueueTest.class);
21 private static final int NOCAP = Integer.MAX_VALUE;
24 * A delayed implementation for testing.
25 * Most tests use Pseudodelays, where delays are all elapsed
26 * (so, no blocking solely for delays) but are still ordered
28 static class PDelay implements Delayed {
30 PDelay(int i) { pseudodelay = Integer.MIN_VALUE + i; }
31 public int compareTo(PDelay y) {
33 int j = y.pseudodelay;
39 public int compareTo(Delayed y) {
40 return compareTo((PDelay)y);
43 public boolean equals(Object other) {
44 return equals((PDelay)other);
46 public boolean equals(PDelay other) {
47 return other.pseudodelay == pseudodelay;
51 public long getDelay(TimeUnit ignore) {
54 public int intValue() {
58 public String toString() {
59 return String.valueOf(pseudodelay);
65 * Delayed implementation that actually delays
67 static class NanoDelay implements Delayed {
70 trigger = System.nanoTime() + i;
72 public int compareTo(NanoDelay y) {
80 public int compareTo(Delayed y) {
81 return compareTo((NanoDelay)y);
84 public boolean equals(Object other) {
85 return equals((NanoDelay)other);
87 public boolean equals(NanoDelay other) {
88 return other.trigger == trigger;
91 public long getDelay(TimeUnit unit) {
92 long n = trigger - System.nanoTime();
93 return unit.convert(n, TimeUnit.NANOSECONDS);
96 public long getTriggerTime() {
100 public String toString() {
101 return String.valueOf(trigger);
107 * Create a queue of given size containing consecutive
110 private DelayQueue populatedQueue(int n) {
111 DelayQueue q = new DelayQueue();
112 assertTrue(q.isEmpty());
113 for (int i = n-1; i >= 0; i-=2)
114 assertTrue(q.offer(new PDelay(i)));
115 for (int i = (n & 1); i < n; i+=2)
116 assertTrue(q.offer(new PDelay(i)));
117 assertFalse(q.isEmpty());
118 assertEquals(NOCAP, q.remainingCapacity());
119 assertEquals(n, q.size());
124 * A new queue has unbounded capacity
126 public void testConstructor1() {
127 assertEquals(NOCAP, new DelayQueue().remainingCapacity());
131 * Initializing from null Collection throws NPE
133 public void testConstructor3() {
135 DelayQueue q = new DelayQueue(null);
137 } catch (NullPointerException success) {}
141 * Initializing from Collection of null elements throws NPE
143 public void testConstructor4() {
145 PDelay[] ints = new PDelay[SIZE];
146 DelayQueue q = new DelayQueue(Arrays.asList(ints));
148 } catch (NullPointerException success) {}
152 * Initializing from Collection with some null elements throws NPE
154 public void testConstructor5() {
156 PDelay[] ints = new PDelay[SIZE];
157 for (int i = 0; i < SIZE-1; ++i)
158 ints[i] = new PDelay(i);
159 DelayQueue q = new DelayQueue(Arrays.asList(ints));
161 } catch (NullPointerException success) {}
165 * Queue contains all elements of collection used to initialize
167 public void testConstructor6() {
168 PDelay[] ints = new PDelay[SIZE];
169 for (int i = 0; i < SIZE; ++i)
170 ints[i] = new PDelay(i);
171 DelayQueue q = new DelayQueue(Arrays.asList(ints));
172 for (int i = 0; i < SIZE; ++i)
173 assertEquals(ints[i], q.poll());
177 * isEmpty is true before add, false after
179 public void testEmpty() {
180 DelayQueue q = new DelayQueue();
181 assertTrue(q.isEmpty());
182 assertEquals(NOCAP, q.remainingCapacity());
183 q.add(new PDelay(1));
184 assertFalse(q.isEmpty());
185 q.add(new PDelay(2));
188 assertTrue(q.isEmpty());
192 * remainingCapacity does not change when elements added or removed,
195 public void testRemainingCapacity() {
196 DelayQueue q = populatedQueue(SIZE);
197 for (int i = 0; i < SIZE; ++i) {
198 assertEquals(NOCAP, q.remainingCapacity());
199 assertEquals(SIZE-i, q.size());
202 for (int i = 0; i < SIZE; ++i) {
203 assertEquals(NOCAP, q.remainingCapacity());
204 assertEquals(i, q.size());
205 q.add(new PDelay(i));
210 * offer(null) throws NPE
212 public void testOfferNull() {
214 DelayQueue q = new DelayQueue();
217 } catch (NullPointerException success) {}
221 * add(null) throws NPE
223 public void testAddNull() {
225 DelayQueue q = new DelayQueue();
228 } catch (NullPointerException success) {}
232 * offer non-null succeeds
234 public void testOffer() {
235 DelayQueue q = new DelayQueue();
236 assertTrue(q.offer(new PDelay(0)));
237 assertTrue(q.offer(new PDelay(1)));
243 public void testAdd() {
244 DelayQueue q = new DelayQueue();
245 for (int i = 0; i < SIZE; ++i) {
246 assertEquals(i, q.size());
247 assertTrue(q.add(new PDelay(i)));
252 * addAll(null) throws NPE
254 public void testAddAll1() {
256 DelayQueue q = new DelayQueue();
259 } catch (NullPointerException success) {}
264 * addAll(this) throws IAE
266 public void testAddAllSelf() {
268 DelayQueue q = populatedQueue(SIZE);
271 } catch (IllegalArgumentException success) {}
275 * addAll of a collection with null elements throws NPE
277 public void testAddAll2() {
279 DelayQueue q = new DelayQueue();
280 PDelay[] ints = new PDelay[SIZE];
281 q.addAll(Arrays.asList(ints));
283 } catch (NullPointerException success) {}
286 * addAll of a collection with any null elements throws NPE after
287 * possibly adding some elements
289 public void testAddAll3() {
291 DelayQueue q = new DelayQueue();
292 PDelay[] ints = new PDelay[SIZE];
293 for (int i = 0; i < SIZE-1; ++i)
294 ints[i] = new PDelay(i);
295 q.addAll(Arrays.asList(ints));
297 } catch (NullPointerException success) {}
301 * Queue contains all elements of successful addAll
303 public void testAddAll5() {
304 PDelay[] empty = new PDelay[0];
305 PDelay[] ints = new PDelay[SIZE];
306 for (int i = SIZE-1; i >= 0; --i)
307 ints[i] = new PDelay(i);
308 DelayQueue q = new DelayQueue();
309 assertFalse(q.addAll(Arrays.asList(empty)));
310 assertTrue(q.addAll(Arrays.asList(ints)));
311 for (int i = 0; i < SIZE; ++i)
312 assertEquals(ints[i], q.poll());
316 * put(null) throws NPE
318 public void testPutNull() {
320 DelayQueue q = new DelayQueue();
323 } catch (NullPointerException success) {}
327 * all elements successfully put are contained
329 public void testPut() {
330 DelayQueue q = new DelayQueue();
331 for (int i = 0; i < SIZE; ++i) {
332 PDelay I = new PDelay(i);
334 assertTrue(q.contains(I));
336 assertEquals(SIZE, q.size());
340 * put doesn't block waiting for take
342 public void testPutWithTake() throws InterruptedException {
343 final DelayQueue q = new DelayQueue();
344 Thread t = new Thread(new CheckedRunnable() {
345 public void realRun() {
346 q.put(new PDelay(0));
347 q.put(new PDelay(0));
348 q.put(new PDelay(0));
349 q.put(new PDelay(0));
353 Thread.sleep(SHORT_DELAY_MS);
360 * timed offer does not time out
362 public void testTimedOffer() throws InterruptedException {
363 final DelayQueue q = new DelayQueue();
364 Thread t = new Thread(new CheckedRunnable() {
365 public void realRun() throws InterruptedException {
366 q.put(new PDelay(0));
367 q.put(new PDelay(0));
368 assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, MILLISECONDS));
369 assertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, MILLISECONDS));
373 Thread.sleep(SMALL_DELAY_MS);
379 * take retrieves elements in priority order
381 public void testTake() throws InterruptedException {
382 DelayQueue q = populatedQueue(SIZE);
383 for (int i = 0; i < SIZE; ++i) {
384 assertEquals(new PDelay(i), ((PDelay)q.take()));
389 * take blocks interruptibly when empty
391 public void testTakeFromEmpty() throws InterruptedException {
392 final DelayQueue q = new DelayQueue();
393 Thread t = new ThreadShouldThrow(InterruptedException.class) {
394 public void realRun() throws InterruptedException {
399 Thread.sleep(SHORT_DELAY_MS);
405 * Take removes existing elements until empty, then blocks interruptibly
407 public void testBlockingTake() throws InterruptedException {
408 final DelayQueue q = populatedQueue(SIZE);
409 Thread t = new Thread(new CheckedRunnable() {
410 public void realRun() throws InterruptedException {
411 for (int i = 0; i < SIZE; ++i) {
412 assertEquals(new PDelay(i), ((PDelay)q.take()));
417 } catch (InterruptedException success) {}
421 Thread.sleep(SHORT_DELAY_MS);
428 * poll succeeds unless empty
430 public void testPoll() {
431 DelayQueue q = populatedQueue(SIZE);
432 for (int i = 0; i < SIZE; ++i) {
433 assertEquals(new PDelay(i), ((PDelay)q.poll()));
435 assertNull(q.poll());
439 * timed pool with zero timeout succeeds when non-empty, else times out
441 public void testTimedPoll0() throws InterruptedException {
442 DelayQueue q = populatedQueue(SIZE);
443 for (int i = 0; i < SIZE; ++i) {
444 assertEquals(new PDelay(i), ((PDelay)q.poll(0, MILLISECONDS)));
446 assertNull(q.poll(0, MILLISECONDS));
450 * timed pool with nonzero timeout succeeds when non-empty, else times out
452 public void testTimedPoll() throws InterruptedException {
453 DelayQueue q = populatedQueue(SIZE);
454 for (int i = 0; i < SIZE; ++i) {
455 assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, MILLISECONDS)));
457 assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
461 * Interrupted timed poll throws InterruptedException instead of
462 * returning timeout status
464 public void testInterruptedTimedPoll() throws InterruptedException {
465 Thread t = new Thread(new CheckedRunnable() {
466 public void realRun() throws InterruptedException {
467 DelayQueue q = populatedQueue(SIZE);
468 for (int i = 0; i < SIZE; ++i) {
469 assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, MILLISECONDS)));
472 q.poll(SMALL_DELAY_MS, MILLISECONDS);
474 } catch (InterruptedException success) {}
478 Thread.sleep(SHORT_DELAY_MS);
484 * timed poll before a delayed offer fails; after offer succeeds;
485 * on interruption throws
487 public void testTimedPollWithOffer() throws InterruptedException {
488 final DelayQueue q = new DelayQueue();
489 final PDelay pdelay = new PDelay(0);
490 Thread t = new Thread(new CheckedRunnable() {
491 public void realRun() throws InterruptedException {
492 assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
493 assertSame(pdelay, q.poll(LONG_DELAY_MS, MILLISECONDS));
495 q.poll(LONG_DELAY_MS, MILLISECONDS);
497 } catch (InterruptedException success) {}
501 Thread.sleep(SMALL_DELAY_MS);
502 assertTrue(q.offer(pdelay, SHORT_DELAY_MS, MILLISECONDS));
509 * peek returns next element, or null if empty
511 public void testPeek() {
512 DelayQueue q = populatedQueue(SIZE);
513 for (int i = 0; i < SIZE; ++i) {
514 assertEquals(new PDelay(i), ((PDelay)q.peek()));
515 assertEquals(new PDelay(i), ((PDelay)q.poll()));
517 assertNull(q.peek());
519 assertFalse(new PDelay(i).equals(q.peek()));
521 assertNull(q.peek());
525 * element returns next element, or throws NSEE if empty
527 public void testElement() {
528 DelayQueue q = populatedQueue(SIZE);
529 for (int i = 0; i < SIZE; ++i) {
530 assertEquals(new PDelay(i), ((PDelay)q.element()));
536 } catch (NoSuchElementException success) {}
540 * remove removes next element, or throws NSEE if empty
542 public void testRemove() {
543 DelayQueue q = populatedQueue(SIZE);
544 for (int i = 0; i < SIZE; ++i) {
545 assertEquals(new PDelay(i), ((PDelay)q.remove()));
550 } catch (NoSuchElementException success) {}
554 * remove(x) removes x and returns true if present
556 public void testRemoveElement() {
557 DelayQueue q = populatedQueue(SIZE);
558 for (int i = 1; i < SIZE; i+=2) {
559 assertTrue(q.remove(new PDelay(i)));
561 for (int i = 0; i < SIZE; i+=2) {
562 assertTrue(q.remove(new PDelay(i)));
563 assertFalse(q.remove(new PDelay(i+1)));
565 assertTrue(q.isEmpty());
569 * contains(x) reports true when elements added but not yet removed
571 public void testContains() {
572 DelayQueue q = populatedQueue(SIZE);
573 for (int i = 0; i < SIZE; ++i) {
574 assertTrue(q.contains(new PDelay(i)));
576 assertFalse(q.contains(new PDelay(i)));
581 * clear removes all elements
583 public void testClear() {
584 DelayQueue q = populatedQueue(SIZE);
586 assertTrue(q.isEmpty());
587 assertEquals(0, q.size());
588 assertEquals(NOCAP, q.remainingCapacity());
589 PDelay x = new PDelay(1);
591 assertFalse(q.isEmpty());
592 assertTrue(q.contains(x));
594 assertTrue(q.isEmpty());
598 * containsAll(c) is true when c contains a subset of elements
600 public void testContainsAll() {
601 DelayQueue q = populatedQueue(SIZE);
602 DelayQueue p = new DelayQueue();
603 for (int i = 0; i < SIZE; ++i) {
604 assertTrue(q.containsAll(p));
605 assertFalse(p.containsAll(q));
606 p.add(new PDelay(i));
608 assertTrue(p.containsAll(q));
612 * retainAll(c) retains only those elements of c and reports true if changed
614 public void testRetainAll() {
615 DelayQueue q = populatedQueue(SIZE);
616 DelayQueue p = populatedQueue(SIZE);
617 for (int i = 0; i < SIZE; ++i) {
618 boolean changed = q.retainAll(p);
620 assertFalse(changed);
624 assertTrue(q.containsAll(p));
625 assertEquals(SIZE-i, q.size());
631 * removeAll(c) removes only those elements of c and reports true if changed
633 public void testRemoveAll() {
634 for (int i = 1; i < SIZE; ++i) {
635 DelayQueue q = populatedQueue(SIZE);
636 DelayQueue p = populatedQueue(i);
637 assertTrue(q.removeAll(p));
638 assertEquals(SIZE-i, q.size());
639 for (int j = 0; j < i; ++j) {
640 PDelay I = (PDelay)(p.remove());
641 assertFalse(q.contains(I));
647 * toArray contains all elements
649 public void testToArray() throws InterruptedException {
650 DelayQueue q = populatedQueue(SIZE);
651 Object[] o = q.toArray();
653 for (int i = 0; i < o.length; i++)
654 assertEquals(o[i], q.take());
658 * toArray(a) contains all elements
660 public void testToArray2() throws InterruptedException {
661 DelayQueue q = populatedQueue(SIZE);
662 PDelay[] ints = new PDelay[SIZE];
663 ints = (PDelay[])q.toArray(ints);
665 for (int i = 0; i < ints.length; i++)
666 assertEquals(ints[i], q.take());
671 * toArray(null) throws NPE
673 public void testToArray_BadArg() {
674 DelayQueue q = populatedQueue(SIZE);
676 Object o[] = q.toArray(null);
678 } catch (NullPointerException success) {}
682 * toArray with incompatible array type throws CCE
684 public void testToArray1_BadArg() {
685 DelayQueue q = populatedQueue(SIZE);
687 Object o[] = q.toArray(new String[10]);
689 } catch (ArrayStoreException success) {}
693 * iterator iterates through all elements
695 public void testIterator() {
696 DelayQueue q = populatedQueue(SIZE);
698 Iterator it = q.iterator();
699 while (it.hasNext()) {
700 assertTrue(q.contains(it.next()));
703 assertEquals(i, SIZE);
707 * iterator.remove removes current element
709 public void testIteratorRemove () {
710 final DelayQueue q = new DelayQueue();
711 q.add(new PDelay(2));
712 q.add(new PDelay(1));
713 q.add(new PDelay(3));
714 Iterator it = q.iterator();
718 assertEquals(it.next(), new PDelay(2));
719 assertEquals(it.next(), new PDelay(3));
720 assertFalse(it.hasNext());
725 * toString contains toStrings of elements
727 public void testToString() {
728 DelayQueue q = populatedQueue(SIZE);
729 String s = q.toString();
730 for (int i = 0; i < SIZE; ++i) {
731 assertTrue(s.indexOf(String.valueOf(Integer.MIN_VALUE+i)) >= 0);
736 * offer transfers elements across Executor tasks
738 public void testPollInExecutor() {
739 final DelayQueue q = new DelayQueue();
740 ExecutorService executor = Executors.newFixedThreadPool(2);
741 executor.execute(new CheckedRunnable() {
742 public void realRun() throws InterruptedException {
743 assertNull(q.poll());
744 assertTrue(null != q.poll(MEDIUM_DELAY_MS, MILLISECONDS));
745 assertTrue(q.isEmpty());
748 executor.execute(new CheckedRunnable() {
749 public void realRun() throws InterruptedException {
750 Thread.sleep(SHORT_DELAY_MS);
751 q.put(new PDelay(1));
759 * Delayed actions do not occur until their delay elapses
761 public void testDelay() throws InterruptedException {
762 DelayQueue q = new DelayQueue();
763 NanoDelay[] elements = new NanoDelay[SIZE];
764 for (int i = 0; i < SIZE; ++i) {
765 elements[i] = new NanoDelay(1000000000L + 1000000L * (SIZE - i));
767 for (int i = 0; i < SIZE; ++i) {
772 for (int i = 0; i < SIZE; ++i) {
773 NanoDelay e = (NanoDelay)(q.take());
774 long tt = e.getTriggerTime();
775 assertTrue(tt <= System.nanoTime());
777 assertTrue(tt >= last);
783 * peek of a non-empty queue returns non-null even if not expired
785 public void testPeekDelayed() {
786 DelayQueue q = new DelayQueue();
787 q.add(new NanoDelay(Long.MAX_VALUE));
788 assert(q.peek() != null);
793 * poll of a non-empty queue returns null if no expired elements.
795 public void testPollDelayed() {
796 DelayQueue q = new DelayQueue();
797 q.add(new NanoDelay(Long.MAX_VALUE));
798 assertNull(q.poll());
802 * timed poll of a non-empty queue returns null if no expired elements.
804 public void testTimedPollDelayed() throws InterruptedException {
805 DelayQueue q = new DelayQueue();
806 q.add(new NanoDelay(LONG_DELAY_MS * 1000000L));
807 assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS));
811 * drainTo(null) throws NPE
813 public void testDrainToNull() {
814 DelayQueue q = populatedQueue(SIZE);
818 } catch (NullPointerException success) {}
822 * drainTo(this) throws IAE
824 public void testDrainToSelf() {
825 DelayQueue q = populatedQueue(SIZE);
829 } catch (IllegalArgumentException success) {}
833 * drainTo(c) empties queue into another collection c
835 public void testDrainTo() {
836 DelayQueue q = new DelayQueue();
837 PDelay[] elems = new PDelay[SIZE];
838 for (int i = 0; i < SIZE; ++i) {
839 elems[i] = new PDelay(i);
842 ArrayList l = new ArrayList();
844 assertEquals(q.size(), 0);
845 for (int i = 0; i < SIZE; ++i)
846 assertEquals(l.get(i), elems[i]);
849 assertFalse(q.isEmpty());
850 assertTrue(q.contains(elems[0]));
851 assertTrue(q.contains(elems[1]));
854 assertEquals(q.size(), 0);
855 assertEquals(l.size(), 2);
856 for (int i = 0; i < 2; ++i)
857 assertEquals(l.get(i), elems[i]);
861 * drainTo empties queue
863 public void testDrainToWithActivePut() throws InterruptedException {
864 final DelayQueue q = populatedQueue(SIZE);
865 Thread t = new Thread(new CheckedRunnable() {
866 public void realRun() {
867 q.put(new PDelay(SIZE+1));
871 ArrayList l = new ArrayList();
873 assertTrue(l.size() >= SIZE);
875 assertTrue(q.size() + l.size() >= SIZE);
879 * drainTo(null, n) throws NPE
881 public void testDrainToNullN() {
882 DelayQueue q = populatedQueue(SIZE);
886 } catch (NullPointerException success) {}
890 * drainTo(this, n) throws IAE
892 public void testDrainToSelfN() {
893 DelayQueue q = populatedQueue(SIZE);
897 } catch (IllegalArgumentException success) {}
901 * drainTo(c, n) empties first max {n, size} elements of queue into c
903 public void testDrainToN() {
904 for (int i = 0; i < SIZE + 2; ++i) {
905 DelayQueue q = populatedQueue(SIZE);
906 ArrayList l = new ArrayList();
908 int k = (i < SIZE)? i : SIZE;
909 assertEquals(q.size(), SIZE-k);
910 assertEquals(l.size(), k);