--- jsr166/src/test/tck/ExecutorCompletionServiceTest.java 2016/05/03 23:06:12 1.23 +++ jsr166/src/test/tck/ExecutorCompletionServiceTest.java 2016/05/21 22:30:16 1.24 @@ -11,9 +11,13 @@ import static java.util.concurrent.TimeU import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; +import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.RunnableFuture; @@ -33,7 +37,7 @@ public class ExecutorCompletionServiceTe } /** - * Creating a new ECS with null Executor throw NPE + * new ExecutorCompletionService(null) throws NullPointerException */ public void testConstructorNPE() { try { @@ -43,110 +47,157 @@ public class ExecutorCompletionServiceTe } /** - * Creating a new ECS with null queue throw NPE + * new ExecutorCompletionService(e, null) throws NullPointerException */ public void testConstructorNPE2() { + final Executor e = ForkJoinPool.commonPool(); try { - ExecutorService e = Executors.newCachedThreadPool(); new ExecutorCompletionService(e, null); shouldThrow(); } catch (NullPointerException success) {} } /** - * Submitting a null callable throws NPE + * ecs.submit(null) throws NullPointerException */ - public void testSubmitNPE() { - final ExecutorService e = Executors.newCachedThreadPool(); - final ExecutorCompletionService ecs = new ExecutorCompletionService(e); - try (PoolCleaner cleaner = cleaner(e)) { - Callable c = null; - try { - ecs.submit(c); - shouldThrow(); - } catch (NullPointerException success) {} - } + public void testSubmitNullCallable() { + final ExecutorCompletionService ecs = + new ExecutorCompletionService(ForkJoinPool.commonPool()); + try { + ecs.submit((Callable) null); + shouldThrow(); + } catch (NullPointerException success) {} } /** - * Submitting a null runnable throws NPE + * ecs.submit(null, val) throws NullPointerException */ - public void testSubmitNPE2() { - final ExecutorService e = Executors.newCachedThreadPool(); - final ExecutorCompletionService ecs = new ExecutorCompletionService(e); - try (PoolCleaner cleaner = cleaner(e)) { - Runnable r = null; - try { - ecs.submit(r, Boolean.TRUE); - shouldThrow(); - } catch (NullPointerException success) {} - } + public void testSubmitNullRunnable() { + final ExecutorCompletionService ecs = + new ExecutorCompletionService(ForkJoinPool.commonPool()); + try { + ecs.submit((Runnable) null, Boolean.TRUE); + shouldThrow(); + } catch (NullPointerException success) {} } /** * A taken submitted task is completed */ - public void testTake() throws InterruptedException { - final ExecutorService e = Executors.newCachedThreadPool(); - final ExecutorCompletionService ecs = new ExecutorCompletionService(e); - try (PoolCleaner cleaner = cleaner(e)) { - Callable c = new StringTask(); - ecs.submit(c); - Future f = ecs.take(); - assertTrue(f.isDone()); - } + public void testTake() + throws InterruptedException, ExecutionException { + final ExecutorCompletionService ecs = + new ExecutorCompletionService(ForkJoinPool.commonPool()); + ecs.submit(new StringTask()); + Future f = ecs.take(); + assertTrue(f.isDone()); + assertSame(TEST_STRING, f.get()); } /** * Take returns the same future object returned by submit */ public void testTake2() throws InterruptedException { - final ExecutorService e = Executors.newCachedThreadPool(); - final ExecutorCompletionService ecs = new ExecutorCompletionService(e); - try (PoolCleaner cleaner = cleaner(e)) { - Callable c = new StringTask(); - Future f1 = ecs.submit(c); - Future f2 = ecs.take(); - assertSame(f1, f2); + final ExecutorCompletionService ecs = + new ExecutorCompletionService(ForkJoinPool.commonPool()); + Future f1 = ecs.submit(new StringTask()); + Future f2 = ecs.take(); + assertSame(f1, f2); + } + + /** + * poll returns non-null when the returned task is completed + */ + public void testPoll1() + throws InterruptedException, ExecutionException { + final ExecutorCompletionService ecs = + new ExecutorCompletionService(ForkJoinPool.commonPool()); + assertNull(ecs.poll()); + ecs.submit(new StringTask()); + + long startTime = System.nanoTime(); + Future f; + while ((f = ecs.poll()) == null) { + if (millisElapsedSince(startTime) > LONG_DELAY_MS) + fail("timed out"); + Thread.yield(); } + assertTrue(f.isDone()); + assertSame(TEST_STRING, f.get()); } /** - * If poll returns non-null, the returned task is completed + * timed poll returns non-null when the returned task is completed */ - public void testPoll1() throws Exception { - final ExecutorService e = Executors.newCachedThreadPool(); - final ExecutorCompletionService ecs = new ExecutorCompletionService(e); - try (PoolCleaner cleaner = cleaner(e)) { - assertNull(ecs.poll()); - Callable c = new StringTask(); - ecs.submit(c); - - long startTime = System.nanoTime(); - Future f; - while ((f = ecs.poll()) == null) { - if (millisElapsedSince(startTime) > LONG_DELAY_MS) - fail("timed out"); - Thread.yield(); - } - assertTrue(f.isDone()); - assertSame(TEST_STRING, f.get()); + public void testPoll2() + throws InterruptedException, ExecutionException { + final ExecutorCompletionService ecs = + new ExecutorCompletionService(ForkJoinPool.commonPool()); + assertNull(ecs.poll()); + ecs.submit(new StringTask()); + + long startTime = System.nanoTime(); + Future f; + while ((f = ecs.poll(SHORT_DELAY_MS, MILLISECONDS)) == null) { + if (millisElapsedSince(startTime) > LONG_DELAY_MS) + fail("timed out"); + Thread.yield(); } + assertTrue(f.isDone()); + assertSame(TEST_STRING, f.get()); + } + + /** + * poll returns null before the returned task is completed + */ + public void testPollReturnsNull() + throws InterruptedException, ExecutionException { + final ExecutorCompletionService ecs = + new ExecutorCompletionService(ForkJoinPool.commonPool()); + final CountDownLatch proceed = new CountDownLatch(1); + ecs.submit(new Callable() { public String call() throws Exception { + proceed.await(); + return TEST_STRING; + }}); + assertNull(ecs.poll()); + assertNull(ecs.poll(0L, MILLISECONDS)); + assertNull(ecs.poll(Long.MIN_VALUE, MILLISECONDS)); + long startTime = System.nanoTime(); + assertNull(ecs.poll(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + proceed.countDown(); + assertSame(TEST_STRING, ecs.take().get()); } /** - * If timed poll returns non-null, the returned task is completed + * successful and failed tasks are both returned */ - public void testPoll2() throws InterruptedException { + public void testTaskAssortment() + throws InterruptedException, ExecutionException { final ExecutorService e = Executors.newCachedThreadPool(); - final ExecutorCompletionService ecs = new ExecutorCompletionService(e); + final CompletionService cs = new ExecutorCompletionService(e); + final ArithmeticException ex = new ArithmeticException(); try (PoolCleaner cleaner = cleaner(e)) { - assertNull(ecs.poll()); - Callable c = new StringTask(); - ecs.submit(c); - Future f = ecs.poll(SHORT_DELAY_MS, MILLISECONDS); - if (f != null) - assertTrue(f.isDone()); + for (int i = 0; i < 2; i++) { + cs.submit(new StringTask()); + cs.submit(callableThrowing(ex)); + cs.submit(runnableThrowing(ex), null); + } + int normalCompletions = 0; + int exceptionalCompletions = 0; + for (int i = 0; i < 3 * 2; i++) { + try { + if (cs.take().get() == TEST_STRING) + normalCompletions++; + } + catch (ExecutionException expected) { + assertTrue(expected.getCause() instanceof ArithmeticException); + exceptionalCompletions++; + } + } + assertEquals(2 * 1, normalCompletions); + assertEquals(2 * 2, exceptionalCompletions); + assertNull(cs.poll()); } } @@ -158,7 +209,7 @@ public class ExecutorCompletionServiceTe final AtomicBoolean done = new AtomicBoolean(false); class MyCallableFuture extends FutureTask { MyCallableFuture(Callable c) { super(c); } - protected void done() { done.set(true); } + @Override protected void done() { done.set(true); } } final ExecutorService e = new ThreadPoolExecutor(1, 1, @@ -167,15 +218,14 @@ public class ExecutorCompletionServiceTe protected RunnableFuture newTaskFor(Callable c) { return new MyCallableFuture(c); }}; - CompletionService ecs = - new ExecutorCompletionService<>(e); + CompletionService cs = new ExecutorCompletionService<>(e); try (PoolCleaner cleaner = cleaner(e)) { - assertNull(ecs.poll()); + assertNull(cs.poll()); Callable c = new StringTask(); - Future f1 = ecs.submit(c); + Future f1 = cs.submit(c); assertTrue("submit must return MyCallableFuture", f1 instanceof MyCallableFuture); - Future f2 = ecs.take(); + Future f2 = cs.take(); assertSame("submit and take must return same objects", f1, f2); assertTrue("completed task must have set done", done.get()); } @@ -189,7 +239,7 @@ public class ExecutorCompletionServiceTe final AtomicBoolean done = new AtomicBoolean(false); class MyRunnableFuture extends FutureTask { MyRunnableFuture(Runnable t, V r) { super(t, r); } - protected void done() { done.set(true); } + @Override protected void done() { done.set(true); } } final ExecutorService e = new ThreadPoolExecutor(1, 1, @@ -198,15 +248,14 @@ public class ExecutorCompletionServiceTe protected RunnableFuture newTaskFor(Runnable t, T r) { return new MyRunnableFuture(t, r); }}; - final CompletionService ecs = - new ExecutorCompletionService<>(e); + CompletionService cs = new ExecutorCompletionService<>(e); try (PoolCleaner cleaner = cleaner(e)) { - assertNull(ecs.poll()); + assertNull(cs.poll()); Runnable r = new NoOpRunnable(); - Future f1 = ecs.submit(r, null); + Future f1 = cs.submit(r, null); assertTrue("submit must return MyRunnableFuture", f1 instanceof MyRunnableFuture); - Future f2 = ecs.take(); + Future f2 = cs.take(); assertSame("submit and take must return same objects", f1, f2); assertTrue("completed task must have set done", done.get()); }