--- jsr166/src/test/tck/SynchronousQueueTest.java 2011/05/28 13:40:20 1.36 +++ jsr166/src/test/tck/SynchronousQueueTest.java 2019/08/11 22:29:27 1.63 @@ -6,11 +6,21 @@ * Pat Fisher, Mike Judd. */ -import junit.framework.*; -import java.util.*; -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.io.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadLocalRandom; + +import junit.framework.Test; public class SynchronousQueueTest extends JSR166TestCase { @@ -27,7 +37,7 @@ public class SynchronousQueueTest extend } public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { @@ -50,32 +60,6 @@ public class SynchronousQueueTest extend } /** - * offer(null) throws NullPointerException - */ - public void testOfferNull() { testOfferNull(false); } - public void testOfferNull_fair() { testOfferNull(true); } - public void testOfferNull(boolean fair) { - SynchronousQueue q = new SynchronousQueue(fair); - try { - q.offer(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * add(null) throws NullPointerException - */ - public void testAddNull() { testAddNull(false); } - public void testAddNull_fair() { testAddNull(true); } - public void testAddNull(boolean fair) { - SynchronousQueue q = new SynchronousQueue(fair); - try { - q.add(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** * offer fails if no active taker */ public void testOffer() { testOffer(false); } @@ -100,19 +84,6 @@ public class SynchronousQueueTest extend } /** - * addAll(null) throws NullPointerException - */ - public void testAddAll_null() { testAddAll_null(false); } - public void testAddAll_null_fair() { testAddAll_null(true); } - public void testAddAll_null(boolean fair) { - SynchronousQueue q = new SynchronousQueue(fair); - try { - q.addAll(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** * addAll(this) throws IllegalArgumentException */ public void testAddAll_self() { testAddAll_self(false); } @@ -126,21 +97,7 @@ public class SynchronousQueueTest extend } /** - * addAll of a collection with null elements throws NullPointerException - */ - public void testAddAll_null2() { testAddAll_null2(false); } - public void testAddAll_null2_fair() { testAddAll_null2(true); } - public void testAddAll_null2(boolean fair) { - SynchronousQueue q = new SynchronousQueue(fair); - Collection ints = Arrays.asList(new Integer[1]); - try { - q.addAll(ints); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll throws ISE if no active taker + * addAll throws IllegalStateException if no active taker */ public void testAddAll_ISE() { testAddAll_ISE(false); } public void testAddAll_ISE_fair() { testAddAll_ISE(true); } @@ -157,17 +114,6 @@ public class SynchronousQueueTest extend } /** - * put(null) throws NPE - */ - public void testPutNull() throws InterruptedException { - try { - SynchronousQueue q = new SynchronousQueue(); - q.put(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** * put blocks interruptibly if no active taker */ public void testBlockingPut() { testBlockingPut(false); } @@ -193,7 +139,7 @@ public class SynchronousQueueTest extend }}); await(pleaseInterrupt); - assertThreadStaysAlive(t); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertEquals(0, q.remainingCapacity()); @@ -213,6 +159,13 @@ public class SynchronousQueueTest extend pleaseTake.countDown(); q.put(one); + Thread.currentThread().interrupt(); + try { + q.put(99); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + pleaseInterrupt.countDown(); try { q.put(99); @@ -222,39 +175,50 @@ public class SynchronousQueueTest extend }}); await(pleaseTake); - assertEquals(q.remainingCapacity(), 0); + assertEquals(0, q.remainingCapacity()); try { assertSame(one, q.take()); } catch (InterruptedException e) { threadUnexpectedException(e); } await(pleaseInterrupt); - assertThreadStaysAlive(t); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); - assertEquals(q.remainingCapacity(), 0); + assertEquals(0, q.remainingCapacity()); } /** * timed offer times out if elements not taken */ - public void testTimedOffer() { testTimedOffer(false); } - public void testTimedOffer_fair() { testTimedOffer(true); } - public void testTimedOffer(boolean fair) { + public void testTimedOffer() { + final boolean fair = ThreadLocalRandom.current().nextBoolean(); final SynchronousQueue q = new SynchronousQueue(fair); final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { long startTime = System.nanoTime(); + assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + + Thread.currentThread().interrupt(); + try { + q.offer(new Object(), randomTimeout(), randomTimeUnit()); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + pleaseInterrupt.countDown(); try { - q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS); + q.offer(new Object(), LONG_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseInterrupt); - assertThreadStaysAlive(t); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -283,11 +247,10 @@ public class SynchronousQueueTest extend /** * timed poll with nonzero timeout times out if no active putter */ - public void testTimedPoll() { testTimedPoll(false); } - public void testTimedPoll_fair() { testTimedPoll(true); } - public void testTimedPoll(boolean fair) { + public void testTimedPoll() { + final boolean fair = ThreadLocalRandom.current().nextBoolean(); final SynchronousQueue q = new SynchronousQueue(fair); - long startTime = System.nanoTime(); + final long startTime = System.nanoTime(); try { assertNull(q.poll(timeoutMillis(), MILLISECONDS)); } catch (InterruptedException e) { threadUnexpectedException(e); } assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); @@ -297,9 +260,8 @@ public class SynchronousQueueTest extend * timed poll before a delayed offer times out, returning null; * after offer succeeds; on interruption throws */ - public void testTimedPollWithOffer() { testTimedPollWithOffer(false); } - public void testTimedPollWithOffer_fair() { testTimedPollWithOffer(true); } - public void testTimedPollWithOffer(boolean fair) { + public void testTimedPollWithOffer() { + final boolean fair = ThreadLocalRandom.current().nextBoolean(); final SynchronousQueue q = new SynchronousQueue(fair); final CountDownLatch pleaseOffer = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1); @@ -312,11 +274,10 @@ public class SynchronousQueueTest extend pleaseOffer.countDown(); startTime = System.nanoTime(); assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS)); - assertTrue(millisElapsedSince(startTime) < MEDIUM_DELAY_MS); Thread.currentThread().interrupt(); try { - q.poll(LONG_DELAY_MS, MILLISECONDS); + q.poll(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); @@ -327,16 +288,18 @@ public class SynchronousQueueTest extend shouldThrow(); } catch (InterruptedException success) {} assertFalse(Thread.interrupted()); + + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); await(pleaseOffer); long startTime = System.nanoTime(); try { assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); } catch (InterruptedException e) { threadUnexpectedException(e); } - assertTrue(millisElapsedSince(startTime) < MEDIUM_DELAY_MS); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); await(pleaseInterrupt); - assertThreadStaysAlive(t); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); awaitTermination(t); } @@ -378,17 +341,6 @@ public class SynchronousQueueTest extend } /** - * remove(x) returns false - */ - public void testRemoveElement() { testRemoveElement(false); } - public void testRemoveElement_fair() { testRemoveElement(true); } - public void testRemoveElement(boolean fair) { - final SynchronousQueue q = new SynchronousQueue(fair); - assertFalse(q.remove(zero)); - assertTrue(q.isEmpty()); - } - - /** * contains returns false */ public void testContains() { testContains(false); } @@ -456,18 +408,28 @@ public class SynchronousQueueTest extend public void testToArray(boolean fair) { final SynchronousQueue q = new SynchronousQueue(fair); Object[] o = q.toArray(); - assertEquals(o.length, 0); + assertEquals(0, o.length); } /** - * toArray(a) is nulled at position 0 + * toArray(Integer array) returns its argument with the first + * element (if present) nulled out */ public void testToArray2() { testToArray2(false); } public void testToArray2_fair() { testToArray2(true); } public void testToArray2(boolean fair) { - final SynchronousQueue q = new SynchronousQueue(fair); - Integer[] ints = new Integer[1]; - assertNull(ints[0]); + final SynchronousQueue q = new SynchronousQueue<>(fair); + Integer[] a; + + a = new Integer[0]; + assertSame(a, q.toArray(a)); + + a = new Integer[3]; + Arrays.fill(a, 42); + assertSame(a, q.toArray(a)); + assertNull(a[0]); + for (int i = 1; i < a.length; i++) + assertEquals(42, (int) a[i]); } /** @@ -478,7 +440,7 @@ public class SynchronousQueueTest extend public void testToArray_null(boolean fair) { final SynchronousQueue q = new SynchronousQueue(fair); try { - Object o[] = q.toArray(null); + Object[] o = q.toArray((Object[])null); shouldThrow(); } catch (NullPointerException success) {} } @@ -489,17 +451,11 @@ public class SynchronousQueueTest extend public void testIterator() { testIterator(false); } public void testIterator_fair() { testIterator(true); } public void testIterator(boolean fair) { - final SynchronousQueue q = new SynchronousQueue(fair); - Iterator it = q.iterator(); - assertFalse(it.hasNext()); - try { - Object x = it.next(); - shouldThrow(); - } catch (NoSuchElementException success) {} + assertIteratorExhausted(new SynchronousQueue(fair).iterator()); } /** - * iterator remove throws ISE + * iterator remove throws IllegalStateException */ public void testIteratorRemove() { testIteratorRemove(false); } public void testIteratorRemove_fair() { testIteratorRemove(true); } @@ -530,24 +486,24 @@ public class SynchronousQueueTest extend public void testOfferInExecutor_fair() { testOfferInExecutor(true); } public void testOfferInExecutor(boolean fair) { final SynchronousQueue q = new SynchronousQueue(fair); - ExecutorService executor = Executors.newFixedThreadPool(2); final CheckedBarrier threadsStarted = new CheckedBarrier(2); + final ExecutorService executor = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(executor)) { - executor.execute(new CheckedRunnable() { - public void realRun() throws InterruptedException { - assertFalse(q.offer(one)); - threadsStarted.await(); - assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS)); - assertEquals(0, q.remainingCapacity()); - }}); - - executor.execute(new CheckedRunnable() { - public void realRun() throws InterruptedException { - threadsStarted.await(); - assertSame(one, q.take()); - }}); - - joinPool(executor); + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertFalse(q.offer(one)); + threadsStarted.await(); + assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS)); + assertEquals(0, q.remainingCapacity()); + }}); + + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + threadsStarted.await(); + assertSame(one, q.take()); + }}); + } } /** @@ -558,62 +514,43 @@ public class SynchronousQueueTest extend public void testPollInExecutor(boolean fair) { final SynchronousQueue q = new SynchronousQueue(fair); final CheckedBarrier threadsStarted = new CheckedBarrier(2); - ExecutorService executor = Executors.newFixedThreadPool(2); - executor.execute(new CheckedRunnable() { - public void realRun() throws InterruptedException { - assertNull(q.poll()); - threadsStarted.await(); - assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS)); - assertTrue(q.isEmpty()); - }}); - - executor.execute(new CheckedRunnable() { - public void realRun() throws InterruptedException { - threadsStarted.await(); - q.put(one); - }}); - - joinPool(executor); - } - - /** - * a deserialized serialized queue is usable - */ - public void testSerialization() { testSerialization(false); } - public void testSerialization_fair() { testSerialization(true); } - public void testSerialization(boolean fair) { - final SynchronousQueue q = new SynchronousQueue(fair); - final SynchronousQueue r = serialClone(q); - assertTrue(q != r); - assertEquals(q.size(), r.size()); - while (!q.isEmpty()) - assertEquals(q.remove(), r.remove()); - } - - /** - * drainTo(null) throws NPE - */ - public void testDrainToNull() { testDrainToNull(false); } - public void testDrainToNull_fair() { testDrainToNull(true); } - public void testDrainToNull(boolean fair) { - final SynchronousQueue q = new SynchronousQueue(fair); - try { - q.drainTo(null); - shouldThrow(); - } catch (NullPointerException success) {} + final ExecutorService executor = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(executor)) { + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertNull(q.poll()); + threadsStarted.await(); + assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS)); + assertTrue(q.isEmpty()); + }}); + + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + threadsStarted.await(); + q.put(one); + }}); + } } /** - * drainTo(this) throws IAE + * a deserialized/reserialized queue is usable */ - public void testDrainToSelf() { testDrainToSelf(false); } - public void testDrainToSelf_fair() { testDrainToSelf(true); } - public void testDrainToSelf(boolean fair) { - final SynchronousQueue q = new SynchronousQueue(fair); - try { - q.drainTo(q); - shouldThrow(); - } catch (IllegalArgumentException success) {} + public void testSerialization() { + final SynchronousQueue x = new SynchronousQueue(); + final SynchronousQueue y = new SynchronousQueue(false); + final SynchronousQueue z = new SynchronousQueue(true); + assertSerialEquals(x, y); + assertNotSerialEquals(x, z); + SynchronousQueue[] qs = { x, y, z }; + for (SynchronousQueue q : qs) { + SynchronousQueue clone = serialClone(q); + assertNotSame(q, clone); + assertSerialEquals(q, clone); + assertTrue(clone.isEmpty()); + assertEquals(0, clone.size()); + assertEquals(0, clone.remainingCapacity()); + assertFalse(clone.offer(zero)); + } } /** @@ -625,8 +562,8 @@ public class SynchronousQueueTest extend final SynchronousQueue q = new SynchronousQueue(fair); ArrayList l = new ArrayList(); q.drainTo(l); - assertEquals(q.size(), 0); - assertEquals(l.size(), 0); + assertEquals(0, q.size()); + assertEquals(0, l.size()); } /** @@ -649,38 +586,12 @@ public class SynchronousQueueTest extend fail("timed out"); Thread.yield(); } - assertTrue(l.size() == 1); + assertEquals(1, l.size()); assertSame(one, l.get(0)); awaitTermination(t); } /** - * drainTo(null, n) throws NullPointerException - */ - public void testDrainToNullN() { testDrainToNullN(false); } - public void testDrainToNullN_fair() { testDrainToNullN(true); } - public void testDrainToNullN(boolean fair) { - final SynchronousQueue q = new SynchronousQueue(fair); - try { - q.drainTo(null, 0); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * drainTo(this, n) throws IllegalArgumentException - */ - public void testDrainToSelfN() { testDrainToSelfN(false); } - public void testDrainToSelfN_fair() { testDrainToSelfN(true); } - public void testDrainToSelfN(boolean fair) { - final SynchronousQueue q = new SynchronousQueue(fair); - try { - q.drainTo(q, 0); - shouldThrow(); - } catch (IllegalArgumentException success) {} - } - - /** * drainTo(c, n) empties up to n elements of queue into c */ public void testDrainToN() throws InterruptedException { @@ -696,10 +607,12 @@ public class SynchronousQueueTest extend }}); ArrayList l = new ArrayList(); - delay(SHORT_DELAY_MS); - q.drainTo(l, 1); + int drained; + while ((drained = q.drainTo(l, 1)) == 0) Thread.yield(); + assertEquals(1, drained); assertEquals(1, l.size()); - q.drainTo(l, 1); + while ((drained = q.drainTo(l, 1)) == 0) Thread.yield(); + assertEquals(1, drained); assertEquals(2, l.size()); assertTrue(l.contains(one)); assertTrue(l.contains(two)); @@ -707,4 +620,13 @@ public class SynchronousQueueTest extend awaitTermination(t2); } + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection q = new SynchronousQueue(); + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); + } + }