--- jsr166/src/test/tck/DelayQueueTest.java 2003/09/20 18:20:07 1.4 +++ jsr166/src/test/tck/DelayQueueTest.java 2009/11/21 02:33:20 1.19 @@ -1,34 +1,36 @@ /* - * Written by members of JCP JSR-166 Expert Group and released to the - * public domain. Use, modify, and redistribute this code in any way - * without acknowledgement. Other contributors include Andrew Wright, - * Jeffrey Hayes, Pat Fischer, Mike Judd. + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. */ import junit.framework.*; import java.util.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import java.util.concurrent.*; public class DelayQueueTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run (suite()); + junit.textui.TestRunner.run (suite()); } public static Test suite() { - return new TestSuite(DelayQueueTest.class); + return new TestSuite(DelayQueueTest.class); } private static final int NOCAP = Integer.MAX_VALUE; /** - * A delayed implmentation for testing. - * Most Q/BQ tests use Pseudodelays, where delays are all elapsed + * A delayed implementation for testing. + * Most tests use Pseudodelays, where delays are all elapsed * (so, no blocking solely for delays) but are still ordered - */ - static class PDelay implements Delayed { + */ + static class PDelay implements Delayed { int pseudodelay; PDelay(int i) { pseudodelay = Integer.MIN_VALUE + i; } - public int compareTo(Object y) { + public int compareTo(PDelay y) { int i = pseudodelay; int j = ((PDelay)y).pseudodelay; if (i < j) return -1; @@ -36,7 +38,7 @@ public class DelayQueueTest extends JSR1 return 0; } - public int compareTo(PDelay y) { + public int compareTo(Delayed y) { int i = pseudodelay; int j = ((PDelay)y).pseudodelay; if (i < j) return -1; @@ -68,12 +70,12 @@ public class DelayQueueTest extends JSR1 /** * Delayed implementation that actually delays */ - static class NanoDelay implements Delayed { + static class NanoDelay implements Delayed { long trigger; - NanoDelay(long i) { + NanoDelay(long i) { trigger = System.nanoTime() + i; } - public int compareTo(Object y) { + public int compareTo(NanoDelay y) { long i = trigger; long j = ((NanoDelay)y).trigger; if (i < j) return -1; @@ -81,7 +83,7 @@ public class DelayQueueTest extends JSR1 return 0; } - public int compareTo(NanoDelay y) { + public int compareTo(Delayed y) { long i = trigger; long j = ((NanoDelay)y).trigger; if (i < j) return -1; @@ -118,25 +120,25 @@ public class DelayQueueTest extends JSR1 private DelayQueue populatedQueue(int n) { DelayQueue q = new DelayQueue(); assertTrue(q.isEmpty()); - for(int i = n-1; i >= 0; i-=2) - assertTrue(q.offer(new PDelay(i))); - for(int i = (n & 1); i < n; i+=2) - assertTrue(q.offer(new PDelay(i))); + for (int i = n-1; i >= 0; i-=2) + assertTrue(q.offer(new PDelay(i))); + for (int i = (n & 1); i < n; i+=2) + assertTrue(q.offer(new PDelay(i))); assertFalse(q.isEmpty()); assertEquals(NOCAP, q.remainingCapacity()); - assertEquals(n, q.size()); + assertEquals(n, q.size()); return q; } - + /** - * + * A new queue has unbounded capacity */ public void testConstructor1() { assertEquals(NOCAP, new DelayQueue().remainingCapacity()); } /** - * + * Initializing from null Collection throws NPE */ public void testConstructor3() { try { @@ -147,7 +149,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * Initializing from Collection of null elements throws NPE */ public void testConstructor4() { try { @@ -159,7 +161,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * Initializing from Collection with some null elements throws NPE */ public void testConstructor5() { try { @@ -173,7 +175,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * Queue contains all elements of collection used to initialize */ public void testConstructor6() { try { @@ -188,7 +190,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * isEmpty is true before add, false after */ public void testEmpty() { DelayQueue q = new DelayQueue(); @@ -203,7 +205,8 @@ public class DelayQueueTest extends JSR1 } /** - * + * remainingCapacity does not change when elementa added or removed, + * but size does */ public void testRemainingCapacity() { DelayQueue q = populatedQueue(SIZE); @@ -220,18 +223,29 @@ public class DelayQueueTest extends JSR1 } /** - * + * offer(null) throws NPE */ public void testOfferNull() { - try { + try { DelayQueue q = new DelayQueue(); q.offer(null); shouldThrow(); - } catch (NullPointerException success) { } + } catch (NullPointerException success) { } + } + + /** + * add(null) throws NPE + */ + public void testAddNull() { + try { + DelayQueue q = new DelayQueue(); + q.add(null); + shouldThrow(); + } catch (NullPointerException success) { } } /** - * + * offer non-null succeeds */ public void testOffer() { DelayQueue q = new DelayQueue(); @@ -240,7 +254,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * add succeeds */ public void testAdd() { DelayQueue q = new DelayQueue(); @@ -251,7 +265,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * addAll(null) throws NPE */ public void testAddAll1() { try { @@ -261,8 +275,22 @@ public class DelayQueueTest extends JSR1 } catch (NullPointerException success) {} } + + + /** + * addAll(this) throws IAE + */ + public void testAddAllSelf() { + try { + DelayQueue q = populatedQueue(SIZE); + q.addAll(q); + shouldThrow(); + } + catch (IllegalArgumentException success) {} + } + /** - * + * addAll of a collection with null elements throws NPE */ public void testAddAll2() { try { @@ -274,7 +302,8 @@ public class DelayQueueTest extends JSR1 catch (NullPointerException success) {} } /** - * + * addAll of a collection with any null elements throws NPE after + * possibly adding some elements */ public void testAddAll3() { try { @@ -289,7 +318,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * Queue contains all elements of successful addAll */ public void testAddAll5() { try { @@ -307,20 +336,20 @@ public class DelayQueueTest extends JSR1 } /** - * + * put(null) throws NPE */ public void testPutNull() { - try { + try { DelayQueue q = new DelayQueue(); q.put(null); shouldThrow(); - } - catch (NullPointerException success){ - } + } + catch (NullPointerException success) { + } } /** - * + * all elements successfully put are contained */ public void testPut() { try { @@ -337,7 +366,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * put doesn't block waiting for take */ public void testPutWithTake() { final DelayQueue q = new DelayQueue(); @@ -364,13 +393,13 @@ public class DelayQueueTest extends JSR1 q.take(); t.interrupt(); t.join(); - } catch (Exception e){ + } catch (Exception e) { unexpectedException(); } } /** - * + * timed offer does not time out */ public void testTimedOffer() { final DelayQueue q = new DelayQueue(); @@ -379,38 +408,38 @@ public class DelayQueueTest extends JSR1 try { q.put(new PDelay(0)); q.put(new PDelay(0)); - threadAssertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); - threadAssertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, MILLISECONDS)); + threadAssertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, MILLISECONDS)); } finally { } } }); - + try { t.start(); Thread.sleep(SMALL_DELAY_MS); t.interrupt(); t.join(); - } catch (Exception e){ + } catch (Exception e) { unexpectedException(); } } /** - * + * take retrieves elements in priority order */ public void testTake() { - try { + try { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { assertEquals(new PDelay(i), ((PDelay)q.take())); } - } catch (InterruptedException e){ - unexpectedException(); - } + } catch (InterruptedException e) { + unexpectedException(); + } } /** - * + * take blocks interruptibly when empty */ public void testTakeFromEmpty() { final DelayQueue q = new DelayQueue(); @@ -418,8 +447,8 @@ public class DelayQueueTest extends JSR1 public void run() { try { q.take(); - threadShouldThrow(); - } catch (InterruptedException success){ } + threadShouldThrow(); + } catch (InterruptedException success) { } } }); try { @@ -427,13 +456,13 @@ public class DelayQueueTest extends JSR1 Thread.sleep(SHORT_DELAY_MS); t.interrupt(); t.join(); - } catch (Exception e){ + } catch (Exception e) { unexpectedException(); } } /** - * + * Take removes existing elements until empty, then blocks interruptibly */ public void testBlockingTake() { Thread t = new Thread(new Runnable() { @@ -445,64 +474,65 @@ public class DelayQueueTest extends JSR1 } q.take(); threadShouldThrow(); - } catch (InterruptedException success){ - } + } catch (InterruptedException success) { + } }}); t.start(); - try { - Thread.sleep(SHORT_DELAY_MS); + try { + Thread.sleep(SHORT_DELAY_MS); t.interrupt(); t.join(); } catch (InterruptedException ie) { - unexpectedException(); + unexpectedException(); } } /** - * + * poll succeeds unless empty */ public void testPoll() { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { assertEquals(new PDelay(i), ((PDelay)q.poll())); } - assertNull(q.poll()); + assertNull(q.poll()); } /** - * + * timed pool with zero timeout succeeds when non-empty, else times out */ public void testTimedPoll0() { try { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(new PDelay(i), ((PDelay)q.poll(0, TimeUnit.MILLISECONDS))); + assertEquals(new PDelay(i), ((PDelay)q.poll(0, MILLISECONDS))); } - assertNull(q.poll(0, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e){ - unexpectedException(); - } + assertNull(q.poll(0, MILLISECONDS)); + } catch (InterruptedException e) { + unexpectedException(); + } } /** - * + * timed pool with nonzero timeout succeeds when non-empty, else times out */ public void testTimedPoll() { try { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS))); + assertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, MILLISECONDS))); } - assertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException e){ - unexpectedException(); - } + assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS)); + } catch (InterruptedException e) { + unexpectedException(); + } } /** - * + * Interrupted timed poll throws InterruptedException instead of + * returning timeout status */ public void testInterruptedTimedPoll() { Thread t = new Thread(new Runnable() { @@ -510,66 +540,69 @@ public class DelayQueueTest extends JSR1 try { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { - threadAssertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS))); + threadAssertEquals(new PDelay(i), ((PDelay)q.poll(SHORT_DELAY_MS, MILLISECONDS))); } - threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); - } catch (InterruptedException success){ - } + threadAssertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS)); + } catch (InterruptedException success) { + } }}); t.start(); - try { - Thread.sleep(SHORT_DELAY_MS); + try { + Thread.sleep(SHORT_DELAY_MS); t.interrupt(); t.join(); } catch (InterruptedException ie) { - unexpectedException(); + unexpectedException(); } } /** - * + * timed poll before a delayed offer fails; after offer succeeds; + * on interruption throws */ public void testTimedPollWithOffer() { final DelayQueue q = new DelayQueue(); Thread t = new Thread(new Runnable() { public void run() { try { - threadAssertNull(q.poll(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); - q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); - q.poll(LONG_DELAY_MS, TimeUnit.MILLISECONDS); - threadFail("Should block"); - } catch (InterruptedException success) { } + threadAssertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS)); + q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(LONG_DELAY_MS, MILLISECONDS); + threadFail("Should block"); + } catch (InterruptedException success) { } } }); try { t.start(); Thread.sleep(SMALL_DELAY_MS); - assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); + assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, MILLISECONDS)); t.interrupt(); t.join(); - } catch (Exception e){ + } catch (Exception e) { unexpectedException(); } - } + } /** - * + * peek returns next element, or null if empty */ public void testPeek() { DelayQueue q = populatedQueue(SIZE); for (int i = 0; i < SIZE; ++i) { assertEquals(new PDelay(i), ((PDelay)q.peek())); q.poll(); - assertTrue(q.peek() == null || - i != ((PDelay)q.peek()).intValue()); + if (q.isEmpty()) + assertNull(q.peek()); + else + assertTrue(i != ((PDelay)q.peek()).intValue()); } - assertNull(q.peek()); + assertNull(q.peek()); } /** - * + * element returns next element, or throws NSEE if empty */ public void testElement() { DelayQueue q = populatedQueue(SIZE); @@ -585,7 +618,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * remove removes next element, or throws NSEE if empty */ public void testRemove() { DelayQueue q = populatedQueue(SIZE); @@ -595,12 +628,12 @@ public class DelayQueueTest extends JSR1 try { q.remove(); shouldThrow(); - } catch (NoSuchElementException success){ - } + } catch (NoSuchElementException success) { + } } /** - * + * remove(x) removes x and returns true if present */ public void testRemoveElement() { DelayQueue q = populatedQueue(SIZE); @@ -613,9 +646,9 @@ public class DelayQueueTest extends JSR1 } assertTrue(q.isEmpty()); } - + /** - * + * contains(x) reports true when elements added but not yet removed */ public void testContains() { DelayQueue q = populatedQueue(SIZE); @@ -627,7 +660,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * clear removes all elements */ public void testClear() { DelayQueue q = populatedQueue(SIZE); @@ -635,14 +668,16 @@ public class DelayQueueTest extends JSR1 assertTrue(q.isEmpty()); assertEquals(0, q.size()); assertEquals(NOCAP, q.remainingCapacity()); - q.add(new PDelay(1)); + PDelay x = new PDelay(1); + q.add(x); assertFalse(q.isEmpty()); + assertTrue(q.contains(x)); q.clear(); assertTrue(q.isEmpty()); } /** - * + * containsAll(c) is true when c contains a subset of elements */ public void testContainsAll() { DelayQueue q = populatedQueue(SIZE); @@ -656,7 +691,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * retainAll(c) retains only those elements of c and reports true if changed */ public void testRetainAll() { DelayQueue q = populatedQueue(SIZE); @@ -675,7 +710,7 @@ public class DelayQueueTest extends JSR1 } /** - * + * removeAll(c) removes only those elements of c and reports true if changed */ public void testRemoveAll() { for (int i = 1; i < SIZE; ++i) { @@ -691,44 +726,67 @@ public class DelayQueueTest extends JSR1 } /** - * + * toArray contains all elements */ public void testToArray() { DelayQueue q = populatedQueue(SIZE); - Object[] o = q.toArray(); + Object[] o = q.toArray(); Arrays.sort(o); - try { - for(int i = 0; i < o.length; i++) - assertEquals(o[i], q.take()); - } catch (InterruptedException e){ - unexpectedException(); - } + try { + for (int i = 0; i < o.length; i++) + assertEquals(o[i], q.take()); + } catch (InterruptedException e) { + unexpectedException(); + } } /** - * + * toArray(a) contains all elements */ public void testToArray2() { DelayQueue q = populatedQueue(SIZE); - PDelay[] ints = new PDelay[SIZE]; - ints = (PDelay[])q.toArray(ints); + PDelay[] ints = new PDelay[SIZE]; + ints = (PDelay[])q.toArray(ints); Arrays.sort(ints); - try { - for(int i = 0; i < ints.length; i++) - assertEquals(ints[i], q.take()); - } catch (InterruptedException e){ - unexpectedException(); - } + try { + for (int i = 0; i < ints.length; i++) + assertEquals(ints[i], q.take()); + } catch (InterruptedException e) { + unexpectedException(); + } } - + + /** - * + * toArray(null) throws NPE + */ + public void testToArray_BadArg() { + try { + DelayQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(null); + shouldThrow(); + } catch (NullPointerException success) {} + } + + /** + * toArray with incompatible array type throws CCE + */ + public void testToArray1_BadArg() { + try { + DelayQueue q = populatedQueue(SIZE); + Object o[] = q.toArray(new String[10] ); + shouldThrow(); + } catch (ArrayStoreException success) {} + } + + /** + * iterator iterates through all elements */ public void testIterator() { DelayQueue q = populatedQueue(SIZE); int i = 0; - Iterator it = q.iterator(); - while(it.hasNext()) { + Iterator it = q.iterator(); + while (it.hasNext()) { assertTrue(q.contains(it.next())); ++i; } @@ -736,20 +794,16 @@ public class DelayQueueTest extends JSR1 } /** - * + * iterator.remove removes current element */ public void testIteratorRemove () { - final DelayQueue q = new DelayQueue(); - q.add(new PDelay(2)); q.add(new PDelay(1)); q.add(new PDelay(3)); - Iterator it = q.iterator(); it.next(); it.remove(); - it = q.iterator(); assertEquals(it.next(), new PDelay(2)); assertEquals(it.next(), new PDelay(3)); @@ -758,7 +812,7 @@ public class DelayQueueTest extends JSR1 /** - * + * toString contains toStrings of elements */ public void testToString() { DelayQueue q = populatedQueue(SIZE); @@ -766,22 +820,19 @@ public class DelayQueueTest extends JSR1 for (int i = 0; i < SIZE; ++i) { assertTrue(s.indexOf(String.valueOf(Integer.MIN_VALUE+i)) >= 0); } - } + } /** - * + * offer transfers elements across Executor tasks */ public void testPollInExecutor() { - final DelayQueue q = new DelayQueue(); - ExecutorService executor = Executors.newFixedThreadPool(2); - executor.execute(new Runnable() { public void run() { threadAssertNull(q.poll()); try { - threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS)); + threadAssertTrue(null != q.poll(MEDIUM_DELAY_MS, MILLISECONDS)); threadAssertTrue(q.isEmpty()); } catch (InterruptedException e) { @@ -801,14 +852,13 @@ public class DelayQueueTest extends JSR1 } } }); - joinPool(executor); } /** - * + * Delayed actions do not occur until their delay elapses */ public void testDelay() { DelayQueue q = new DelayQueue(); @@ -826,14 +876,159 @@ public class DelayQueueTest extends JSR1 NanoDelay e = (NanoDelay)(q.take()); long tt = e.getTriggerTime(); assertTrue(tt <= System.nanoTime()); - if (i != 0) + if (i != 0) assertTrue(tt >= last); last = tt; } } - catch(InterruptedException ie) { + catch (InterruptedException ie) { + unexpectedException(); + } + } + + /** + * peek of a non-empty queue returns non-null even if not expired + */ + public void testPeekDelayed() { + DelayQueue q = new DelayQueue(); + q.add(new NanoDelay(Long.MAX_VALUE)); + assert(q.peek() != null); + } + + + /** + * poll of a non-empty queue returns null if no expired elements. + */ + public void testPollDelayed() { + DelayQueue q = new DelayQueue(); + q.add(new NanoDelay(Long.MAX_VALUE)); + assertNull(q.poll()); + } + + /** + * timed poll of a non-empty queue returns null if no expired elements. + */ + public void testTimedPollDelayed() { + DelayQueue q = new DelayQueue(); + q.add(new NanoDelay(LONG_DELAY_MS * 1000000L)); + try { + assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS)); + } catch (Exception ex) { unexpectedException(); } } + /** + * drainTo(null) throws NPE + */ + public void testDrainToNull() { + DelayQueue q = populatedQueue(SIZE); + try { + q.drainTo(null); + shouldThrow(); + } catch (NullPointerException success) { + } + } + + /** + * drainTo(this) throws IAE + */ + public void testDrainToSelf() { + DelayQueue q = populatedQueue(SIZE); + try { + q.drainTo(q); + shouldThrow(); + } catch (IllegalArgumentException success) { + } + } + + /** + * drainTo(c) empties queue into another collection c + */ + public void testDrainTo() { + DelayQueue q = new DelayQueue(); + PDelay[] elems = new PDelay[SIZE]; + for (int i = 0; i < SIZE; ++i) { + elems[i] = new PDelay(i); + q.add(elems[i]); + } + ArrayList l = new ArrayList(); + q.drainTo(l); + assertEquals(q.size(), 0); + for (int i = 0; i < SIZE; ++i) + assertEquals(l.get(i), elems[i]); + q.add(elems[0]); + q.add(elems[1]); + assertFalse(q.isEmpty()); + assertTrue(q.contains(elems[0])); + assertTrue(q.contains(elems[1])); + l.clear(); + q.drainTo(l); + assertEquals(q.size(), 0); + assertEquals(l.size(), 2); + for (int i = 0; i < 2; ++i) + assertEquals(l.get(i), elems[i]); + } + + /** + * drainTo empties queue + */ + public void testDrainToWithActivePut() { + final DelayQueue q = populatedQueue(SIZE); + Thread t = new Thread(new Runnable() { + public void run() { + q.put(new PDelay(SIZE+1)); + } + }); + try { + t.start(); + ArrayList l = new ArrayList(); + q.drainTo(l); + assertTrue(l.size() >= SIZE); + t.join(); + assertTrue(q.size() + l.size() >= SIZE); + } catch (Exception e) { + unexpectedException(); + } + } + + /** + * drainTo(null, n) throws NPE + */ + public void testDrainToNullN() { + DelayQueue q = populatedQueue(SIZE); + try { + q.drainTo(null, 0); + shouldThrow(); + } catch (NullPointerException success) { + } + } + + /** + * drainTo(this, n) throws IAE + */ + public void testDrainToSelfN() { + DelayQueue q = populatedQueue(SIZE); + try { + q.drainTo(q, 0); + shouldThrow(); + } catch (IllegalArgumentException success) { + } + } + + /** + * drainTo(c, n) empties first max {n, size} elements of queue into c + */ + public void testDrainToN() { + for (int i = 0; i < SIZE + 2; ++i) { + DelayQueue q = populatedQueue(SIZE); + ArrayList l = new ArrayList(); + q.drainTo(l, i); + int k = (i < SIZE)? i : SIZE; + assertEquals(q.size(), SIZE-k); + assertEquals(l.size(), k); + } + } + + }