ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/DelayQueueTest.java
Revision: 1.5
Committed: Thu Sep 25 11:02:41 2003 UTC (20 years, 7 months ago) by dl
Branch: MAIN
Changes since 1.4: +47 -51 lines
Log Message:
improve tck javadocs; rename and add a few tests

File Contents

# Content
1 /*
2 * Written by members of JCP JSR-166 Expert Group and released to the
3 * public domain. Use, modify, and redistribute this code in any way
4 * without acknowledgement. Other contributors include Andrew Wright,
5 * Jeffrey Hayes, Pat Fischer, Mike Judd.
6 */
7
8 import junit.framework.*;
9 import java.util.*;
10 import java.util.concurrent.*;
11
12 public class DelayQueueTest extends JSR166TestCase {
13 public static void main(String[] args) {
14 junit.textui.TestRunner.run (suite());
15 }
16
17 public static Test suite() {
18 return new TestSuite(DelayQueueTest.class);
19 }
20
21 private static final int NOCAP = Integer.MAX_VALUE;
22
23 /**
24 * A delayed implmentation for testing.
25 * Most tests use Pseudodelays, where delays are all elapsed
26 * (so, no blocking solely for delays) but are still ordered
27 */
28 static class PDelay implements Delayed {
29 int pseudodelay;
30 PDelay(int i) { pseudodelay = Integer.MIN_VALUE + i; }
31 public int compareTo(Object y) {
32 int i = pseudodelay;
33 int j = ((PDelay)y).pseudodelay;
34 if (i < j) return -1;
35 if (i > j) return 1;
36 return 0;
37 }
38
39 public int compareTo(PDelay y) {
40 int i = pseudodelay;
41 int j = ((PDelay)y).pseudodelay;
42 if (i < j) return -1;
43 if (i > j) return 1;
44 return 0;
45 }
46
47 public boolean equals(Object other) {
48 return ((PDelay)other).pseudodelay == pseudodelay;
49 }
50 public boolean equals(PDelay other) {
51 return ((PDelay)other).pseudodelay == pseudodelay;
52 }
53
54
55 public long getDelay(TimeUnit ignore) {
56 return pseudodelay;
57 }
58 public int intValue() {
59 return pseudodelay;
60 }
61
62 public String toString() {
63 return String.valueOf(pseudodelay);
64 }
65 }
66
67
68 /**
69 * Delayed implementation that actually delays
70 */
71 static class NanoDelay implements Delayed {
72 long trigger;
73 NanoDelay(long i) {
74 trigger = System.nanoTime() + i;
75 }
76 public int compareTo(Object y) {
77 long i = trigger;
78 long j = ((NanoDelay)y).trigger;
79 if (i < j) return -1;
80 if (i > j) return 1;
81 return 0;
82 }
83
84 public int compareTo(NanoDelay y) {
85 long i = trigger;
86 long j = ((NanoDelay)y).trigger;
87 if (i < j) return -1;
88 if (i > j) return 1;
89 return 0;
90 }
91
92 public boolean equals(Object other) {
93 return ((NanoDelay)other).trigger == trigger;
94 }
95 public boolean equals(NanoDelay other) {
96 return ((NanoDelay)other).trigger == trigger;
97 }
98
99 public long getDelay(TimeUnit unit) {
100 long n = trigger - System.nanoTime();
101 return unit.convert(n, TimeUnit.NANOSECONDS);
102 }
103
104 public long getTriggerTime() {
105 return trigger;
106 }
107
108 public String toString() {
109 return String.valueOf(trigger);
110 }
111 }
112
113
114 /**
115 * Create a queue of given size containing consecutive
116 * PDelays 0 ... n.
117 */
118 private DelayQueue populatedQueue(int n) {
119 DelayQueue q = new DelayQueue();
120 assertTrue(q.isEmpty());
121 for(int i = n-1; i >= 0; i-=2)
122 assertTrue(q.offer(new PDelay(i)));
123 for(int i = (n & 1); i < n; i+=2)
124 assertTrue(q.offer(new PDelay(i)));
125 assertFalse(q.isEmpty());
126 assertEquals(NOCAP, q.remainingCapacity());
127 assertEquals(n, q.size());
128 return q;
129 }
130
131 /**
132 * A new queue has unbounded capacity
133 */
134 public void testConstructor1() {
135 assertEquals(NOCAP, new DelayQueue().remainingCapacity());
136 }
137
138 /**
139 * Initializing from null Collection throws NPE
140 */
141 public void testConstructor3() {
142 try {
143 DelayQueue q = new DelayQueue(null);
144 shouldThrow();
145 }
146 catch (NullPointerException success) {}
147 }
148
149 /**
150 * Initializing from Collection of null elements throws NPE
151 */
152 public void testConstructor4() {
153 try {
154 PDelay[] ints = new PDelay[SIZE];
155 DelayQueue q = new DelayQueue(Arrays.asList(ints));
156 shouldThrow();
157 }
158 catch (NullPointerException success) {}
159 }
160
161 /**
162 * Initializing from Collection with some null elements throws NPE
163 */
164 public void testConstructor5() {
165 try {
166 PDelay[] ints = new PDelay[SIZE];
167 for (int i = 0; i < SIZE-1; ++i)
168 ints[i] = new PDelay(i);
169 DelayQueue q = new DelayQueue(Arrays.asList(ints));
170 shouldThrow();
171 }
172 catch (NullPointerException success) {}
173 }
174
175 /**
176 * Queue contains all elements of collection used to initialize
177 */
178 public void testConstructor6() {
179 try {
180 PDelay[] ints = new PDelay[SIZE];
181 for (int i = 0; i < SIZE; ++i)
182 ints[i] = new PDelay(i);
183 DelayQueue q = new DelayQueue(Arrays.asList(ints));
184 for (int i = 0; i < SIZE; ++i)
185 assertEquals(ints[i], q.poll());
186 }
187 finally {}
188 }
189
190 /**
191 * isEmpty is true before add, false after
192 */
193 public void testEmpty() {
194 DelayQueue q = new DelayQueue();
195 assertTrue(q.isEmpty());
196 assertEquals(NOCAP, q.remainingCapacity());
197 q.add(new PDelay(1));
198 assertFalse(q.isEmpty());
199 q.add(new PDelay(2));
200 q.remove();
201 q.remove();
202 assertTrue(q.isEmpty());
203 }
204
205 /**
206 * remainingCapacity does not change when elementa added or removed,
207 * but size does
208 */
209 public void testRemainingCapacity() {
210 DelayQueue q = populatedQueue(SIZE);
211 for (int i = 0; i < SIZE; ++i) {
212 assertEquals(NOCAP, q.remainingCapacity());
213 assertEquals(SIZE-i, q.size());
214 q.remove();
215 }
216 for (int i = 0; i < SIZE; ++i) {
217 assertEquals(NOCAP, q.remainingCapacity());
218 assertEquals(i, q.size());
219 q.add(new PDelay(i));
220 }
221 }
222
223 /**
224 * offer(null) throws NPE
225 */
226 public void testOfferNull() {
227 try {
228 DelayQueue q = new DelayQueue();
229 q.offer(null);
230 shouldThrow();
231 } catch (NullPointerException success) { }
232 }
233
234 /**
235 * offer non-null succeeds
236 */
237 public void testOffer() {
238 DelayQueue q = new DelayQueue();
239 assertTrue(q.offer(new PDelay(0)));
240 assertTrue(q.offer(new PDelay(1)));
241 }
242
243 /**
244 * add succeeds
245 */
246 public void testAdd() {
247 DelayQueue q = new DelayQueue();
248 for (int i = 0; i < SIZE; ++i) {
249 assertEquals(i, q.size());
250 assertTrue(q.add(new PDelay(i)));
251 }
252 }
253
254 /**
255 * addAll(null) throws NPE
256 */
257 public void testAddAll1() {
258 try {
259 DelayQueue q = new DelayQueue();
260 q.addAll(null);
261 shouldThrow();
262 }
263 catch (NullPointerException success) {}
264 }
265 /**
266 * addAll of a collection with null elements throws NPE
267 */
268 public void testAddAll2() {
269 try {
270 DelayQueue q = new DelayQueue();
271 PDelay[] ints = new PDelay[SIZE];
272 q.addAll(Arrays.asList(ints));
273 shouldThrow();
274 }
275 catch (NullPointerException success) {}
276 }
277 /**
278 * addAll of a collection with any null elements throws NPE after
279 * possibly adding some elements
280 */
281 public void testAddAll3() {
282 try {
283 DelayQueue q = new DelayQueue();
284 PDelay[] ints = new PDelay[SIZE];
285 for (int i = 0; i < SIZE-1; ++i)
286 ints[i] = new PDelay(i);
287 q.addAll(Arrays.asList(ints));
288 shouldThrow();
289 }
290 catch (NullPointerException success) {}
291 }
292
293 /**
294 * Queue contains all elements of successful addAll
295 */
296 public void testAddAll5() {
297 try {
298 PDelay[] empty = new PDelay[0];
299 PDelay[] ints = new PDelay[SIZE];
300 for (int i = SIZE-1; i >= 0; --i)
301 ints[i] = new PDelay(i);
302 DelayQueue q = new DelayQueue();
303 assertFalse(q.addAll(Arrays.asList(empty)));
304 assertTrue(q.addAll(Arrays.asList(ints)));
305 for (int i = 0; i < SIZE; ++i)
306 assertEquals(ints[i], q.poll());
307 }
308 finally {}
309 }
310
311 /**
312 * put(null) throws NPE
313 */
314 public void testPutNull() {
315 try {
316 DelayQueue q = new DelayQueue();
317 q.put(null);
318 shouldThrow();
319 }
320 catch (NullPointerException success){
321 }
322 }
323
324 /**
325 * all elements successfully put are contained
326 */
327 public void testPut() {
328 try {
329 DelayQueue q = new DelayQueue();
330 for (int i = 0; i < SIZE; ++i) {
331 PDelay I = new PDelay(i);
332 q.put(I);
333 assertTrue(q.contains(I));
334 }
335 assertEquals(SIZE, q.size());
336 }
337 finally {
338 }
339 }
340
341 /**
342 * put doesn't block waiting for take
343 */
344 public void testPutWithTake() {
345 final DelayQueue q = new DelayQueue();
346 Thread t = new Thread(new Runnable() {
347 public void run() {
348 int added = 0;
349 try {
350 q.put(new PDelay(0));
351 ++added;
352 q.put(new PDelay(0));
353 ++added;
354 q.put(new PDelay(0));
355 ++added;
356 q.put(new PDelay(0));
357 ++added;
358 threadAssertTrue(added == 4);
359 } finally {
360 }
361 }
362 });
363 try {
364 t.start();
365 Thread.sleep(SHORT_DELAY_MS);
366 q.take();
367 t.interrupt();
368 t.join();
369 } catch (Exception e){
370 unexpectedException();
371 }
372 }
373
374 /**
375 * timed offer does not time out
376 */
377 public void testTimedOffer() {
378 final DelayQueue q = new DelayQueue();
379 Thread t = new Thread(new Runnable() {
380 public void run() {
381 try {
382 q.put(new PDelay(0));
383 q.put(new PDelay(0));
384 threadAssertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
385 threadAssertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, TimeUnit.MILLISECONDS));
386 } finally { }
387 }
388 });
389
390 try {
391 t.start();
392 Thread.sleep(SMALL_DELAY_MS);
393 t.interrupt();
394 t.join();
395 } catch (Exception e){
396 unexpectedException();
397 }
398 }
399
400 /**
401 * take retrieves elements in priority order
402 */
403 public void testTake() {
404 try {
405 DelayQueue q = populatedQueue(SIZE);
406 for (int i = 0; i < SIZE; ++i) {
407 assertEquals(new PDelay(i), ((PDelay)q.take()));
408 }
409 } catch (InterruptedException e){
410 unexpectedException();
411 }
412 }
413
414 /**
415 * take blocks interruptibly when empty
416 */
417 public void testTakeFromEmpty() {
418 final DelayQueue q = new DelayQueue();
419 Thread t = new Thread(new Runnable() {
420 public void run() {
421 try {
422 q.take();
423 threadShouldThrow();
424 } catch (InterruptedException success){ }
425 }
426 });
427 try {
428 t.start();
429 Thread.sleep(SHORT_DELAY_MS);
430 t.interrupt();
431 t.join();
432 } catch (Exception e){
433 unexpectedException();
434 }
435 }
436
437 /**
438 * Take removes existing elements until empty, then blocks interruptibly
439 */
440 public void testBlockingTake() {
441 Thread t = new Thread(new Runnable() {
442 public void run() {
443 try {
444 DelayQueue q = populatedQueue(SIZE);
445 for (int i = 0; i < SIZE; ++i) {
446 threadAssertEquals(new PDelay(i), ((PDelay)q.take()));
447 }
448 q.take();
449 threadShouldThrow();
450 } catch (InterruptedException success){
451 }
452 }});
453 t.start();
454 try {
455 Thread.sleep(SHORT_DELAY_MS);
456 t.interrupt();
457 t.join();
458 }
459 catch (InterruptedException ie) {
460 unexpectedException();
461 }
462 }
463
464
465 /**
466 * poll succeeds unless empty
467 */
468 public void testPoll() {
469 DelayQueue q = populatedQueue(SIZE);
470 for (int i = 0; i < SIZE; ++i) {
471 assertEquals(new PDelay(i), ((PDelay)q.poll()));
472 }
473 assertNull(q.poll());
474 }
475
476 /**
477 * timed pool with zero timeout succeeds when non-empty, else times out
478 */
479 public void testTimedPoll0() {
480 try {
481 DelayQueue q = populatedQueue(SIZE);
482 for (int i = 0; i < SIZE; ++i) {
483 assertEquals(new PDelay(i), ((PDelay)q.poll(0, TimeUnit.MILLISECONDS)));
484 }
485 assertNull(q.poll(0, TimeUnit.MILLISECONDS));
486 } catch (InterruptedException e){
487 unexpectedException();
488 }
489 }
490
491 /**
492 * timed pool with nonzero timeout succeeds when non-empty, else times out
493 */
494 public void testTimedPoll() {
495 try {
496 DelayQueue q = populatedQueue(SIZE);
497 for (int i = 0; i < SIZE; ++i) {
498 assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)));
499 }
500 assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
501 } catch (InterruptedException e){
502 unexpectedException();
503 }
504 }
505
506 /**
507 * Interrupted timed poll throws InterruptedException instead of
508 * returning timeout status
509 */
510 public void testInterruptedTimedPoll() {
511 Thread t = new Thread(new Runnable() {
512 public void run() {
513 try {
514 DelayQueue q = populatedQueue(SIZE);
515 for (int i = 0; i < SIZE; ++i) {
516 threadAssertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)));
517 }
518 threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
519 } catch (InterruptedException success){
520 }
521 }});
522 t.start();
523 try {
524 Thread.sleep(SHORT_DELAY_MS);
525 t.interrupt();
526 t.join();
527 }
528 catch (InterruptedException ie) {
529 unexpectedException();
530 }
531 }
532
533 /**
534 * timed poll before a delayed offer fails; after offer succeeds;
535 * on interruption throws
536 */
537 public void testTimedPollWithOffer() {
538 final DelayQueue q = new DelayQueue();
539 Thread t = new Thread(new Runnable() {
540 public void run() {
541 try {
542 threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
543 q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
544 q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS);
545 threadFail("Should block");
546 } catch (InterruptedException success) { }
547 }
548 });
549 try {
550 t.start();
551 Thread.sleep(SMALL_DELAY_MS);
552 assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
553 t.interrupt();
554 t.join();
555 } catch (Exception e){
556 unexpectedException();
557 }
558 }
559
560
561 /**
562 * peek returns next element, or null if empty
563 */
564 public void testPeek() {
565 DelayQueue q = populatedQueue(SIZE);
566 for (int i = 0; i < SIZE; ++i) {
567 assertEquals(new PDelay(i), ((PDelay)q.peek()));
568 q.poll();
569 assertTrue(q.peek() == null ||
570 i != ((PDelay)q.peek()).intValue());
571 }
572 assertNull(q.peek());
573 }
574
575 /**
576 * element returns next element, or throws NSEE if empty
577 */
578 public void testElement() {
579 DelayQueue q = populatedQueue(SIZE);
580 for (int i = 0; i < SIZE; ++i) {
581 assertEquals(new PDelay(i), ((PDelay)q.element()));
582 q.poll();
583 }
584 try {
585 q.element();
586 shouldThrow();
587 }
588 catch (NoSuchElementException success) {}
589 }
590
591 /**
592 * remove removes next element, or throws NSEE if empty
593 */
594 public void testRemove() {
595 DelayQueue q = populatedQueue(SIZE);
596 for (int i = 0; i < SIZE; ++i) {
597 assertEquals(new PDelay(i), ((PDelay)q.remove()));
598 }
599 try {
600 q.remove();
601 shouldThrow();
602 } catch (NoSuchElementException success){
603 }
604 }
605
606 /**
607 * remove(x) removes x and returns true if present
608 */
609 public void testRemoveElement() {
610 DelayQueue q = populatedQueue(SIZE);
611 for (int i = 1; i < SIZE; i+=2) {
612 assertTrue(q.remove(new PDelay(i)));
613 }
614 for (int i = 0; i < SIZE; i+=2) {
615 assertTrue(q.remove(new PDelay(i)));
616 assertFalse(q.remove(new PDelay(i+1)));
617 }
618 assertTrue(q.isEmpty());
619 }
620
621 /**
622 * contains(x) reports true when elements added but not yet removed
623 */
624 public void testContains() {
625 DelayQueue q = populatedQueue(SIZE);
626 for (int i = 0; i < SIZE; ++i) {
627 assertTrue(q.contains(new PDelay(i)));
628 q.poll();
629 assertFalse(q.contains(new PDelay(i)));
630 }
631 }
632
633 /**
634 * clear removes all elements
635 */
636 public void testClear() {
637 DelayQueue q = populatedQueue(SIZE);
638 q.clear();
639 assertTrue(q.isEmpty());
640 assertEquals(0, q.size());
641 assertEquals(NOCAP, q.remainingCapacity());
642 q.add(new PDelay(1));
643 assertFalse(q.isEmpty());
644 q.clear();
645 assertTrue(q.isEmpty());
646 }
647
648 /**
649 * containsAll(c) is true when c contains a subset of elements
650 */
651 public void testContainsAll() {
652 DelayQueue q = populatedQueue(SIZE);
653 DelayQueue p = new DelayQueue();
654 for (int i = 0; i < SIZE; ++i) {
655 assertTrue(q.containsAll(p));
656 assertFalse(p.containsAll(q));
657 p.add(new PDelay(i));
658 }
659 assertTrue(p.containsAll(q));
660 }
661
662 /**
663 * retainAll(c) retains only those elements of c and reports true if changed
664 */
665 public void testRetainAll() {
666 DelayQueue q = populatedQueue(SIZE);
667 DelayQueue p = populatedQueue(SIZE);
668 for (int i = 0; i < SIZE; ++i) {
669 boolean changed = q.retainAll(p);
670 if (i == 0)
671 assertFalse(changed);
672 else
673 assertTrue(changed);
674
675 assertTrue(q.containsAll(p));
676 assertEquals(SIZE-i, q.size());
677 p.remove();
678 }
679 }
680
681 /**
682 * removeAll(c) removes only those elements of c and reports true if changed
683 */
684 public void testRemoveAll() {
685 for (int i = 1; i < SIZE; ++i) {
686 DelayQueue q = populatedQueue(SIZE);
687 DelayQueue p = populatedQueue(i);
688 assertTrue(q.removeAll(p));
689 assertEquals(SIZE-i, q.size());
690 for (int j = 0; j < i; ++j) {
691 PDelay I = (PDelay)(p.remove());
692 assertFalse(q.contains(I));
693 }
694 }
695 }
696
697 /**
698 * toArray contains all elements
699 */
700 public void testToArray() {
701 DelayQueue q = populatedQueue(SIZE);
702 Object[] o = q.toArray();
703 Arrays.sort(o);
704 try {
705 for(int i = 0; i < o.length; i++)
706 assertEquals(o[i], q.take());
707 } catch (InterruptedException e){
708 unexpectedException();
709 }
710 }
711
712 /**
713 * toArray(a) contains all elements
714 */
715 public void testToArray2() {
716 DelayQueue q = populatedQueue(SIZE);
717 PDelay[] ints = new PDelay[SIZE];
718 ints = (PDelay[])q.toArray(ints);
719 Arrays.sort(ints);
720 try {
721 for(int i = 0; i < ints.length; i++)
722 assertEquals(ints[i], q.take());
723 } catch (InterruptedException e){
724 unexpectedException();
725 }
726 }
727
728 /**
729 * iterator iterates through all elements
730 */
731 public void testIterator() {
732 DelayQueue q = populatedQueue(SIZE);
733 int i = 0;
734 Iterator it = q.iterator();
735 while(it.hasNext()) {
736 assertTrue(q.contains(it.next()));
737 ++i;
738 }
739 assertEquals(i, SIZE);
740 }
741
742 /**
743 * iterator.remove removes current element
744 */
745 public void testIteratorRemove () {
746 final DelayQueue q = new DelayQueue();
747 q.add(new PDelay(2));
748 q.add(new PDelay(1));
749 q.add(new PDelay(3));
750 Iterator it = q.iterator();
751 it.next();
752 it.remove();
753 it = q.iterator();
754 assertEquals(it.next(), new PDelay(2));
755 assertEquals(it.next(), new PDelay(3));
756 assertFalse(it.hasNext());
757 }
758
759
760 /**
761 * toString contains toStrings of elements
762 */
763 public void testToString() {
764 DelayQueue q = populatedQueue(SIZE);
765 String s = q.toString();
766 for (int i = 0; i < SIZE; ++i) {
767 assertTrue(s.indexOf(String.valueOf(Integer.MIN_VALUE+i)) >= 0);
768 }
769 }
770
771 /**
772 * offer transfers elements across Executor tasks
773 */
774 public void testPollInExecutor() {
775 final DelayQueue q = new DelayQueue();
776 ExecutorService executor = Executors.newFixedThreadPool(2);
777 executor.execute(new Runnable() {
778 public void run() {
779 threadAssertNull(q.poll());
780 try {
781 threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS));
782 threadAssertTrue(q.isEmpty());
783 }
784 catch (InterruptedException e) {
785 threadUnexpectedException();
786 }
787 }
788 });
789
790 executor.execute(new Runnable() {
791 public void run() {
792 try {
793 Thread.sleep(SHORT_DELAY_MS);
794 q.put(new PDelay(1));
795 }
796 catch (InterruptedException e) {
797 threadUnexpectedException();
798 }
799 }
800 });
801 joinPool(executor);
802
803 }
804
805
806 /**
807 * Dekayed actions do not occur until their delay elapses
808 */
809 public void testDelay() {
810 DelayQueue q = new DelayQueue();
811 NanoDelay[] elements = new NanoDelay[SIZE];
812 for (int i = 0; i < SIZE; ++i) {
813 elements[i] = new NanoDelay(1000000000L + 1000000L * (SIZE - i));
814 }
815 for (int i = 0; i < SIZE; ++i) {
816 q.add(elements[i]);
817 }
818
819 try {
820 long last = 0;
821 for (int i = 0; i < SIZE; ++i) {
822 NanoDelay e = (NanoDelay)(q.take());
823 long tt = e.getTriggerTime();
824 assertTrue(tt <= System.nanoTime());
825 if (i != 0)
826 assertTrue(tt >= last);
827 last = tt;
828 }
829 }
830 catch(InterruptedException ie) {
831 unexpectedException();
832 }
833 }
834
835 }