--- jsr166/src/test/tck/CountedCompleterTest.java 2013/06/04 23:07:11 1.8 +++ jsr166/src/test/tck/CountedCompleterTest.java 2018/07/22 20:23:28 1.37 @@ -3,27 +3,26 @@ * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ -import java.util.concurrent.ExecutionException; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.HashSet; import java.util.concurrent.CancellationException; +import java.util.concurrent.CountedCompleter; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; -import java.util.concurrent.CountedCompleter; -import java.util.concurrent.ForkJoinWorkerThread; -import java.util.concurrent.RecursiveAction; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicReference; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.SECONDS; -import java.util.HashSet; -import junit.framework.*; + +import junit.framework.Test; +import junit.framework.TestSuite; public class CountedCompleterTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { @@ -49,7 +48,7 @@ public class CountedCompleterTest extend } private void testInvokeOnPool(ForkJoinPool pool, ForkJoinTask a) { - try { + try (PoolCleaner cleaner = cleaner(pool)) { assertFalse(a.isDone()); assertFalse(a.isCompletedNormally()); assertFalse(a.isCompletedAbnormally()); @@ -65,8 +64,6 @@ public class CountedCompleterTest extend assertFalse(a.isCancelled()); assertNull(a.getException()); assertNull(a.getRawResult()); - } finally { - joinPool(pool); } } @@ -79,7 +76,7 @@ public class CountedCompleterTest extend assertNull(a.getRawResult()); try { - a.get(0L, SECONDS); + a.get(randomExpiredTimeout(), randomTimeUnit()); shouldThrow(); } catch (TimeoutException success) { } catch (Throwable fail) { threadUnexpectedException(fail); } @@ -95,28 +92,30 @@ public class CountedCompleterTest extend { Thread.currentThread().interrupt(); - long t0 = System.nanoTime(); + long startTime = System.nanoTime(); assertNull(a.join()); - assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); Thread.interrupted(); } { Thread.currentThread().interrupt(); - long t0 = System.nanoTime(); + long startTime = System.nanoTime(); a.quietlyJoin(); // should be no-op - assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); Thread.interrupted(); } assertFalse(a.cancel(false)); assertFalse(a.cancel(true)); + + Object v1 = null, v2 = null; try { - assertNull(a.get()); - } catch (Throwable fail) { threadUnexpectedException(fail); } - try { - assertNull(a.get(5L, SECONDS)); + v1 = a.get(); + v2 = a.get(randomTimeout(), randomTimeUnit()); } catch (Throwable fail) { threadUnexpectedException(fail); } + assertNull(v1); + assertNull(v2); } void checkCancelled(CountedCompleter a) { @@ -138,9 +137,9 @@ public class CountedCompleterTest extend Thread.interrupted(); { - long t0 = System.nanoTime(); + long startTime = System.nanoTime(); a.quietlyJoin(); // should be no-op - assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); } try { @@ -150,7 +149,7 @@ public class CountedCompleterTest extend } catch (Throwable fail) { threadUnexpectedException(fail); } try { - a.get(5L, SECONDS); + a.get(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (CancellationException success) { } catch (Throwable fail) { threadUnexpectedException(fail); } @@ -176,9 +175,9 @@ public class CountedCompleterTest extend Thread.interrupted(); { - long t0 = System.nanoTime(); + long startTime = System.nanoTime(); a.quietlyJoin(); // should be no-op - assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); } try { @@ -189,7 +188,7 @@ public class CountedCompleterTest extend } catch (Throwable fail) { threadUnexpectedException(fail); } try { - a.get(5L, SECONDS); + a.get(randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (ExecutionException success) { assertSame(t.getClass(), success.getCause().getClass()); @@ -198,8 +197,8 @@ public class CountedCompleterTest extend try { a.invoke(); shouldThrow(); - } catch (Throwable ex) { - assertSame(t, ex); + } catch (Throwable success) { + assertSame(t, success); } } @@ -252,7 +251,9 @@ public class CountedCompleterTest extend } void checkCompletes(Object rawResult) { checkIncomplete(); + int pendingCount = getPendingCount(); complete(rawResult); + assertEquals(pendingCount, getPendingCount()); assertEquals(0, computeN()); assertEquals(1, onCompletionN()); assertEquals(0, onExceptionalCompletionN()); @@ -278,21 +279,29 @@ public class CountedCompleterTest extend final class NoopCC extends CheckedCC { NoopCC() { super(); } NoopCC(CountedCompleter p) { super(p); } + NoopCC(CountedCompleter p, int initialPendingCount) { + super(p, initialPendingCount); + } protected void realCompute() {} } /** * A newly constructed CountedCompleter is not completed; - * complete() causes completion. + * complete() causes completion. pendingCount is ignored. */ public void testComplete() { for (Object x : new Object[] { Boolean.TRUE, null }) { - new NoopCC() - .checkCompletes(x); - new NoopCC(new NoopCC()) - .checkCompletes(x); + for (int pendingCount : new int[] { 0, 42 }) { + testComplete(new NoopCC(), x, pendingCount); + testComplete(new NoopCC(new NoopCC()), x, pendingCount); + } } } + void testComplete(NoopCC cc, Object x, int pendingCount) { + cc.setPendingCount(pendingCount); + cc.checkCompletes(x); + assertEquals(pendingCount, cc.getPendingCount()); + } /** * completeExceptionally completes exceptionally @@ -305,14 +314,20 @@ public class CountedCompleterTest extend } /** - * completeExceptionally(null) throws NullPointerException + * completeExceptionally(null) surprisingly has the same effect as + * completeExceptionally(new RuntimeException()) */ public void testCompleteExceptionally_null() { + NoopCC a = new NoopCC(); + a.completeExceptionally(null); try { - new NoopCC() - .checkCompletesExceptionally(null); + a.invoke(); shouldThrow(); - } catch (NullPointerException success) {} + } catch (RuntimeException success) { + assertSame(success.getClass(), RuntimeException.class); + assertNull(success.getCause()); + a.checkCompletedExceptionally(success); + } } /** @@ -321,10 +336,15 @@ public class CountedCompleterTest extend public void testSetPendingCount() { NoopCC a = new NoopCC(); assertEquals(0, a.getPendingCount()); - a.setPendingCount(1); - assertEquals(1, a.getPendingCount()); - a.setPendingCount(27); - assertEquals(27, a.getPendingCount()); + int[] vals = { + -1, 0, 1, + Integer.MIN_VALUE, + Integer.MAX_VALUE, + }; + for (int val : vals) { + a.setPendingCount(val); + assertEquals(val, a.getPendingCount()); + } } /** @@ -337,21 +357,26 @@ public class CountedCompleterTest extend assertEquals(1, a.getPendingCount()); a.addToPendingCount(27); assertEquals(28, a.getPendingCount()); + a.addToPendingCount(-28); + assertEquals(0, a.getPendingCount()); } /** * decrementPendingCountUnlessZero decrements reported pending * count unless zero */ - public void testDecrementPendingCount() { - NoopCC a = new NoopCC(); - assertEquals(0, a.getPendingCount()); - a.addToPendingCount(1); + public void testDecrementPendingCountUnlessZero() { + NoopCC a = new NoopCC(null, 2); + assertEquals(2, a.getPendingCount()); + assertEquals(2, a.decrementPendingCountUnlessZero()); assertEquals(1, a.getPendingCount()); - a.decrementPendingCountUnlessZero(); + assertEquals(1, a.decrementPendingCountUnlessZero()); assertEquals(0, a.getPendingCount()); - a.decrementPendingCountUnlessZero(); + assertEquals(0, a.decrementPendingCountUnlessZero()); assertEquals(0, a.getPendingCount()); + a.setPendingCount(-1); + assertEquals(-1, a.decrementPendingCountUnlessZero()); + assertEquals(-2, a.getPendingCount()); } /** @@ -446,7 +471,9 @@ public class CountedCompleterTest extend NoopCC a = new NoopCC(); a.setPendingCount(1); assertNull(a.firstComplete()); - assertEquals(a, a.firstComplete()); + a.checkIncomplete(); + assertSame(a, a.firstComplete()); + a.checkIncomplete(); } /** @@ -459,16 +486,21 @@ public class CountedCompleterTest extend a.setPendingCount(1); b.setPendingCount(1); assertNull(b.firstComplete()); - CountedCompleter c = b.firstComplete(); - assertSame(b, c); - CountedCompleter d = c.nextComplete(); - assertNull(d); - CountedCompleter e = c.nextComplete(); - assertSame(a, e); + assertSame(b, b.firstComplete()); + assertNull(b.nextComplete()); + a.checkIncomplete(); + b.checkIncomplete(); + assertSame(a, b.nextComplete()); + assertSame(a, b.nextComplete()); + a.checkIncomplete(); + b.checkIncomplete(); + assertNull(a.nextComplete()); + b.checkIncomplete(); + checkCompletedNormally(a); } /** - * quietlyCompleteRoot completes root task + * quietlyCompleteRoot completes root task and only root task */ public void testQuietlyCompleteRoot() { NoopCC a = new NoopCC(); @@ -486,8 +518,9 @@ public class CountedCompleterTest extend // Invocation tests use some interdependent task classes // to better test propagation etc - - // Version of Fibonacci with different classes for left vs right forks + /** + * Version of Fibonacci with different classes for left vs right forks + */ abstract class CCF extends CheckedCC { int number; int rnumber; @@ -670,7 +703,7 @@ public class CountedCompleterTest extend CCF f = new LCCF(8); assertSame(f, f.fork()); try { - f.get(5L, null); + f.get(randomTimeout(), null); shouldThrow(); } catch (NullPointerException success) {} }}; @@ -702,6 +735,8 @@ public class CountedCompleterTest extend CCF f = new LCCF(8); assertSame(f, f.fork()); helpQuiesce(); + while (!f.isDone()) // wait out race + ; assertEquals(21, f.number); assertEquals(0, getQueuedTaskCount()); checkCompletedNormally(f); @@ -1123,7 +1158,7 @@ public class CountedCompleterTest extend } /** - * invokeAll(collection) throws exception if any task does + * invokeAll(collection) throws exception if any task does */ public void testAbnormalInvokeAllCollection() { ForkJoinTask a = new CheckedRecursiveAction() { @@ -1392,7 +1427,7 @@ public class CountedCompleterTest extend CCF f = new LCCF(8); assertSame(f, f.fork()); try { - f.get(5L, null); + f.get(randomTimeout(), null); shouldThrow(); } catch (NullPointerException success) {} }}; @@ -1788,7 +1823,7 @@ public class CountedCompleterTest extend } /** - * invokeAll(collection) throws exception if any task does + * invokeAll(collection) throws exception if any task does */ public void testAbnormalInvokeAllCollectionSingleton() { ForkJoinTask a = new CheckedRecursiveAction() {