--- jsr166/src/test/tck/AbstractExecutorServiceTest.java 2010/10/09 19:30:34 1.27 +++ jsr166/src/test/tck/AbstractExecutorServiceTest.java 2015/10/04 18:18:48 1.40 @@ -1,22 +1,37 @@ /* * 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 + * http://creativecommons.org/publicdomain/zero/1.0/ * Other contributors include Andrew Wright, Jeffrey Hayes, * Pat Fisher, Mike Judd. */ - -import junit.framework.*; -import java.util.*; -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.math.BigInteger; -import java.security.*; + +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.AbstractExecutorService; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import junit.framework.Test; +import junit.framework.TestSuite; public class AbstractExecutorServiceTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { return new TestSuite(AbstractExecutorServiceTest.class); @@ -46,14 +61,18 @@ public class AbstractExecutorServiceTest */ public void testExecuteRunnable() throws Exception { ExecutorService e = new DirectExecutorService(); - TrackedShortRunnable task = new TrackedShortRunnable(); - assertFalse(task.done); - Future future = e.submit(task); - future.get(); - assertTrue(task.done); + final AtomicBoolean done = new AtomicBoolean(false); + Future future = e.submit(new CheckedRunnable() { + public void realRun() { + done.set(true); + }}); + assertNull(future.get()); + assertNull(future.get(0, MILLISECONDS)); + assertTrue(done.get()); + assertTrue(future.isDone()); + assertFalse(future.isCancelled()); } - /** * Completed submit(callable) returns result */ @@ -84,7 +103,6 @@ public class AbstractExecutorServiceTest assertSame(TEST_STRING, result); } - /** * A submitted privileged action runs to completion */ @@ -150,87 +168,39 @@ public class AbstractExecutorServiceTest * execute(null runnable) throws NPE */ public void testExecuteNullRunnable() { + ExecutorService e = new DirectExecutorService(); try { - ExecutorService e = new DirectExecutorService(); e.submit((Runnable) null); shouldThrow(); } catch (NullPointerException success) {} } - /** * submit(null callable) throws NPE */ public void testSubmitNullCallable() { + ExecutorService e = new DirectExecutorService(); try { - ExecutorService e = new DirectExecutorService(); e.submit((Callable) null); shouldThrow(); } catch (NullPointerException success) {} } /** - * submit(runnable) throws RejectedExecutionException if - * executor is saturated. - */ - public void testExecute1() { - ThreadPoolExecutor p = - new ThreadPoolExecutor(1, 1, - 60, TimeUnit.SECONDS, - new ArrayBlockingQueue(1)); - try { - for (int i = 0; i < 2; ++i) - p.submit(new MediumRunnable()); - for (int i = 0; i < 2; ++i) { - try { - p.submit(new MediumRunnable()); - shouldThrow(); - } catch (RejectedExecutionException success) {} - } - } finally { - joinPool(p); - } - } - - /** - * submit(callable) throws RejectedExecutionException - * if executor is saturated. - */ - public void testExecute2() { - ThreadPoolExecutor p = - new ThreadPoolExecutor(1, 1, - 60, TimeUnit.SECONDS, - new ArrayBlockingQueue(1)); - try { - for (int i = 0; i < 2; ++i) - p.submit(new MediumRunnable()); - for (int i = 0; i < 2; ++i) { - try { - p.submit(new SmallCallable()); - shouldThrow(); - } catch (RejectedExecutionException success) {} - } - } finally { - joinPool(p); - } - } - - - /** * submit(callable).get() throws InterruptedException if interrupted */ public void testInterruptedSubmit() throws InterruptedException { final CountDownLatch submitted = new CountDownLatch(1); final CountDownLatch quittingTime = new CountDownLatch(1); - final ExecutorService p - = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, - new ArrayBlockingQueue(10)); final Callable awaiter = new CheckedCallable() { public Void realCall() throws InterruptedException { quittingTime.await(); return null; }}; - try { + final ExecutorService p + = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, + new ArrayBlockingQueue(10)); + try (PoolCleaner cleaner = cleaner(p)) { Thread t = new Thread(new CheckedInterruptedRunnable() { public void realRun() throws Exception { Future future = p.submit(awaiter); @@ -241,83 +211,54 @@ public class AbstractExecutorServiceTest submitted.await(); t.interrupt(); t.join(); - } finally { quittingTime.countDown(); - joinPool(p); } } /** - * get of submitted callable throws InterruptedException if callable - * interrupted - */ - public void testSubmitIE() throws InterruptedException { - final ThreadPoolExecutor p = - new ThreadPoolExecutor(1, 1, - 60, TimeUnit.SECONDS, - new ArrayBlockingQueue(10)); - - Thread t = new Thread(new CheckedInterruptedRunnable() { - public void realRun() throws Exception { - p.submit(new SmallCallable()).get(); - }}); - - t.start(); - Thread.sleep(SHORT_DELAY_MS); - t.interrupt(); - t.join(); - joinPool(p); - } - - /** * get of submit(callable) throws ExecutionException if callable * throws exception */ public void testSubmitEE() throws InterruptedException { - ThreadPoolExecutor p = + final ThreadPoolExecutor p = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new ArrayBlockingQueue(10)); - - Callable c = new Callable() { - public Object call() { return 5/0; }}; - - try { - p.submit(c).get(); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof ArithmeticException); + try (PoolCleaner cleaner = cleaner(p)) { + Callable c = new Callable() { + public Object call() { throw new ArithmeticException(); }}; + try { + p.submit(c).get(); + shouldThrow(); + } catch (ExecutionException success) { + assertTrue(success.getCause() instanceof ArithmeticException); + } } - joinPool(p); } /** * invokeAny(null) throws NPE */ - public void testInvokeAny1() - throws InterruptedException, ExecutionException { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAny(null); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + public void testInvokeAny1() throws Exception { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + try { + e.invokeAny(null); + shouldThrow(); + } catch (NullPointerException success) {} } } /** * invokeAny(empty collection) throws IAE */ - public void testInvokeAny2() - throws InterruptedException, ExecutionException { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAny(new ArrayList>()); - shouldThrow(); - } catch (IllegalArgumentException success) { - } finally { - joinPool(e); + public void testInvokeAny2() throws Exception { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + try { + e.invokeAny(new ArrayList>()); + shouldThrow(); + } catch (IllegalArgumentException success) {} } } @@ -325,17 +266,16 @@ public class AbstractExecutorServiceTest * invokeAny(c) throws NPE if c has null elements */ public void testInvokeAny3() throws Exception { - ExecutorService e = new DirectExecutorService(); - List> l = new ArrayList>(); - l.add(new Callable() { - public Integer call() { return 5/0; }}); - l.add(null); - try { - e.invokeAny(l); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + List> l = new ArrayList>(); + l.add(new Callable() { + public Long call() { throw new ArithmeticException(); }}); + l.add(null); + try { + e.invokeAny(l); + shouldThrow(); + } catch (NullPointerException success) {} } } @@ -343,16 +283,16 @@ public class AbstractExecutorServiceTest * invokeAny(c) throws ExecutionException if no task in c completes */ public void testInvokeAny4() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - List> l = new ArrayList>(); - l.add(new NPETask()); - try { - e.invokeAny(l); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof NullPointerException); - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + List> l = new ArrayList>(); + l.add(new NPETask()); + try { + e.invokeAny(l); + shouldThrow(); + } catch (ExecutionException success) { + assertTrue(success.getCause() instanceof NullPointerException); + } } } @@ -360,15 +300,13 @@ public class AbstractExecutorServiceTest * invokeAny(c) returns result of some task in c if at least one completes */ public void testInvokeAny5() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { List> l = new ArrayList>(); l.add(new StringTask()); l.add(new StringTask()); String result = e.invokeAny(l); assertSame(TEST_STRING, result); - } finally { - joinPool(e); } } @@ -376,13 +314,12 @@ public class AbstractExecutorServiceTest * invokeAll(null) throws NPE */ public void testInvokeAll1() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAll(null); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + try { + e.invokeAll(null); + shouldThrow(); + } catch (NullPointerException success) {} } } @@ -390,12 +327,10 @@ public class AbstractExecutorServiceTest * invokeAll(empty collection) returns empty collection */ public void testInvokeAll2() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { List> r = e.invokeAll(new ArrayList>()); assertTrue(r.isEmpty()); - } finally { - joinPool(e); } } @@ -403,16 +338,15 @@ public class AbstractExecutorServiceTest * invokeAll(c) throws NPE if c has null elements */ public void testInvokeAll3() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - List> l = new ArrayList>(); - l.add(new StringTask()); - l.add(null); - try { - e.invokeAll(l); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + List> l = new ArrayList>(); + l.add(new StringTask()); + l.add(null); + try { + e.invokeAll(l); + shouldThrow(); + } catch (NullPointerException success) {} } } @@ -420,8 +354,8 @@ public class AbstractExecutorServiceTest * get of returned element of invokeAll(c) throws exception on failed task */ public void testInvokeAll4() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { List> l = new ArrayList>(); l.add(new NPETask()); List> futures = e.invokeAll(l); @@ -432,8 +366,6 @@ public class AbstractExecutorServiceTest } catch (ExecutionException success) { assertTrue(success.getCause() instanceof NullPointerException); } - } finally { - joinPool(e); } } @@ -441,8 +373,8 @@ public class AbstractExecutorServiceTest * invokeAll(c) returns results of all completed tasks in c */ public void testInvokeAll5() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { List> l = new ArrayList>(); l.add(new StringTask()); l.add(new StringTask()); @@ -450,23 +382,19 @@ public class AbstractExecutorServiceTest assertEquals(2, futures.size()); for (Future future : futures) assertSame(TEST_STRING, future.get()); - } finally { - joinPool(e); } } - /** * timed invokeAny(null) throws NPE */ public void testTimedInvokeAny1() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + try { + e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (NullPointerException success) {} } } @@ -474,15 +402,14 @@ public class AbstractExecutorServiceTest * timed invokeAny(null time unit) throws NPE */ public void testTimedInvokeAnyNullTimeUnit() throws Exception { - ExecutorService e = new DirectExecutorService(); - List> l = new ArrayList>(); - l.add(new StringTask()); - try { - e.invokeAny(l, MEDIUM_DELAY_MS, null); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + List> l = new ArrayList>(); + l.add(new StringTask()); + try { + e.invokeAny(l, MEDIUM_DELAY_MS, null); + shouldThrow(); + } catch (NullPointerException success) {} } } @@ -490,13 +417,13 @@ public class AbstractExecutorServiceTest * timed invokeAny(empty collection) throws IAE */ public void testTimedInvokeAny2() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAny(new ArrayList>(), MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (IllegalArgumentException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + try { + e.invokeAny(new ArrayList>(), + MEDIUM_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (IllegalArgumentException success) {} } } @@ -504,17 +431,16 @@ public class AbstractExecutorServiceTest * timed invokeAny(c) throws NPE if c has null elements */ public void testTimedInvokeAny3() throws Exception { - ExecutorService e = new DirectExecutorService(); - List> l = new ArrayList>(); - l.add(new Callable() { - public Integer call() { return 5/0; }}); - l.add(null); - try { - e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + List> l = new ArrayList>(); + l.add(new Callable() { + public Long call() { throw new ArithmeticException(); }}); + l.add(null); + try { + e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (NullPointerException success) {} } } @@ -522,16 +448,16 @@ public class AbstractExecutorServiceTest * timed invokeAny(c) throws ExecutionException if no task completes */ public void testTimedInvokeAny4() throws Exception { - ExecutorService e = new DirectExecutorService(); - List> l = new ArrayList>(); - l.add(new NPETask()); - try { - e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (ExecutionException success) { - assertTrue(success.getCause() instanceof NullPointerException); - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + List> l = new ArrayList>(); + l.add(new NPETask()); + try { + e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (ExecutionException success) { + assertTrue(success.getCause() instanceof NullPointerException); + } } } @@ -539,15 +465,13 @@ public class AbstractExecutorServiceTest * timed invokeAny(c) returns result of some task in c */ public void testTimedInvokeAny5() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { List> l = new ArrayList>(); l.add(new StringTask()); l.add(new StringTask()); String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); assertSame(TEST_STRING, result); - } finally { - joinPool(e); } } @@ -555,13 +479,12 @@ public class AbstractExecutorServiceTest * timed invokeAll(null) throws NPE */ public void testTimedInvokeAll1() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { - e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + try { + e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (NullPointerException success) {} } } @@ -569,15 +492,14 @@ public class AbstractExecutorServiceTest * timed invokeAll(null time unit) throws NPE */ public void testTimedInvokeAllNullTimeUnit() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - List> l = new ArrayList>(); - l.add(new StringTask()); - try { - e.invokeAll(l, MEDIUM_DELAY_MS, null); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + List> l = new ArrayList>(); + l.add(new StringTask()); + try { + e.invokeAll(l, MEDIUM_DELAY_MS, null); + shouldThrow(); + } catch (NullPointerException success) {} } } @@ -585,12 +507,10 @@ public class AbstractExecutorServiceTest * timed invokeAll(empty collection) returns empty collection */ public void testTimedInvokeAll2() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { List> r = e.invokeAll(new ArrayList>(), MEDIUM_DELAY_MS, MILLISECONDS); assertTrue(r.isEmpty()); - } finally { - joinPool(e); } } @@ -598,16 +518,15 @@ public class AbstractExecutorServiceTest * timed invokeAll(c) throws NPE if c has null elements */ public void testTimedInvokeAll3() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - List> l = new ArrayList>(); - l.add(new StringTask()); - l.add(null); - try { - e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (NullPointerException success) { - } finally { - joinPool(e); + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + List> l = new ArrayList>(); + l.add(new StringTask()); + l.add(null); + try { + e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (NullPointerException success) {} } } @@ -615,8 +534,8 @@ public class AbstractExecutorServiceTest * get of returned element of invokeAll(c) throws exception on failed task */ public void testTimedInvokeAll4() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { List> l = new ArrayList>(); l.add(new NPETask()); List> futures = @@ -628,8 +547,6 @@ public class AbstractExecutorServiceTest } catch (ExecutionException success) { assertTrue(success.getCause() instanceof NullPointerException); } - } finally { - joinPool(e); } } @@ -637,45 +554,51 @@ public class AbstractExecutorServiceTest * timed invokeAll(c) returns results of all completed tasks in c */ public void testTimedInvokeAll5() throws Exception { - ExecutorService e = new DirectExecutorService(); - try { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { List> l = new ArrayList>(); l.add(new StringTask()); l.add(new StringTask()); List> futures = - e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); + e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS); assertEquals(2, futures.size()); for (Future future : futures) assertSame(TEST_STRING, future.get()); - } finally { - joinPool(e); } } /** * timed invokeAll cancels tasks not completed by timeout */ - public void testTimedInvokeAll6() throws InterruptedException { - ExecutorService e = new DirectExecutorService(); - try { - List> l = new ArrayList>(); - l.add(new StringTask()); - l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING)); - l.add(new StringTask()); - List> futures = - e.invokeAll(l, SMALL_DELAY_MS, MILLISECONDS); - assertEquals(3, futures.size()); - Iterator> it = futures.iterator(); - Future f1 = it.next(); - Future f2 = it.next(); - Future f3 = it.next(); - assertTrue(f1.isDone()); - assertFalse(f1.isCancelled()); - assertTrue(f2.isDone()); - assertTrue(f3.isDone()); - assertTrue(f3.isCancelled()); - } finally { - joinPool(e); + public void testTimedInvokeAll6() throws Exception { + final ExecutorService e = new DirectExecutorService(); + try (PoolCleaner cleaner = cleaner(e)) { + for (long timeout = timeoutMillis();;) { + List> tasks = new ArrayList<>(); + tasks.add(new StringTask("0")); + tasks.add(Executors.callable(possiblyInterruptedRunnable(timeout), + TEST_STRING)); + tasks.add(new StringTask("2")); + long startTime = System.nanoTime(); + List> futures = + e.invokeAll(tasks, timeout, MILLISECONDS); + assertEquals(tasks.size(), futures.size()); + assertTrue(millisElapsedSince(startTime) >= timeout); + for (Future future : futures) + assertTrue(future.isDone()); + try { + assertEquals("0", futures.get(0).get()); + assertEquals(TEST_STRING, futures.get(1).get()); + } catch (CancellationException retryWithLongerTimeout) { + // unusual delay before starting second task + timeout *= 2; + if (timeout >= LONG_DELAY_MS / 2) + fail("expected exactly one task to be cancelled"); + continue; + } + assertTrue(futures.get(2).isCancelled()); + break; + } } }