--- jsr166/src/test/tck/ExecutorsTest.java 2003/09/20 18:20:07 1.4 +++ jsr166/src/test/tck/ExecutorsTest.java 2003/12/09 19:09:24 1.9 @@ -10,25 +10,18 @@ import junit.framework.*; import java.util.*; import java.util.concurrent.*; import java.math.BigInteger; +import java.security.*; public class ExecutorsTest 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(ExecutorsTest.class); + return new TestSuite(ExecutorsTest.class); } private static final String TEST_STRING = "a test string"; - private static class MyTask implements Runnable { - public void run() { completed = true; } - public boolean isCompleted() { return completed; } - public void reset() { completed = false; } - private boolean completed = false; - } - private static class StringTask implements Callable { public String call() { return TEST_STRING; } } @@ -79,21 +72,381 @@ public class ExecutorsTest extends JSR16 } }; + /** + * A newCachedThreadPool can execute runnables + */ + public void testNewCachedThreadPool1() { + ExecutorService e = Executors.newCachedThreadPool(); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.shutdown(); + } + + /** + * A newCachedThreadPool with given ThreadFactory can execute runnables + */ + public void testNewCachedThreadPool2() { + ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.shutdown(); + } + + /** + * A newCachedThreadPool with null ThreadFactory throws NPE + */ + public void testNewCachedThreadPool3() { + try { + ExecutorService e = Executors.newCachedThreadPool(null); + shouldThrow(); + } + catch(NullPointerException success) { + } + } + + + /** + * A new SingleThreadExecutor can execute runnables + */ + public void testNewSingleThreadExecutor1() { + ExecutorService e = Executors.newSingleThreadExecutor(); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.shutdown(); + } + + /** + * A new SingleThreadExecutor with given ThreadFactory can execute runnables + */ + public void testNewSingleThreadExecutor2() { + ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.shutdown(); + } + + /** + * A new SingleThreadExecutor with null ThreadFactory throws NPE + */ + public void testNewSingleThreadExecutor3() { + try { + ExecutorService e = Executors.newSingleThreadExecutor(null); + shouldThrow(); + } + catch(NullPointerException success) { + } + } + + /** + * A new newFixedThreadPool can execute runnables + */ + public void testNewFixedThreadPool1() { + ExecutorService e = Executors.newFixedThreadPool(2); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.shutdown(); + } + + /** + * A new newFixedThreadPool with given ThreadFactory can execute runnables + */ + public void testNewFixedThreadPool2() { + ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.execute(new NoOpRunnable()); + e.shutdown(); + } + + /** + * A new newFixedThreadPool with null ThreadFactory throws NPE + */ + public void testNewFixedThreadPool3() { + try { + ExecutorService e = Executors.newFixedThreadPool(2, null); + shouldThrow(); + } + catch(NullPointerException success) { + } + } + + /** + * A new newFixedThreadPool with 0 threads throws IAE + */ + public void testNewFixedThreadPool4() { + try { + ExecutorService e = Executors.newFixedThreadPool(0); + shouldThrow(); + } + catch(IllegalArgumentException success) { + } + } + + /** + * execute of runnable runs it to completion + */ + public void testExecuteRunnable() { + try { + Executor e = new DirectExecutor(); + TrackedShortRunnable task = new TrackedShortRunnable(); + assertFalse(task.done); + Future future = Executors.execute(e, task); + future.get(); + assertTrue(task.done); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + } + + /** + * invoke of a runnable runs it to completion + */ + public void testInvokeRunnable() { + try { + Executor e = new DirectExecutor(); + TrackedShortRunnable task = new TrackedShortRunnable(); + assertFalse(task.done); + Executors.invoke(e, task); + assertTrue(task.done); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + } + + /** + * execute of a callable runs it to completion + */ + public void testExecuteCallable() { + try { + Executor e = new DirectExecutor(); + Future future = Executors.execute(e, new StringTask()); + String result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + } + + + /** + * execute of a privileged action runs it to completion + */ + public void testExecutePrivilegedAction() { + Policy savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + try { + Executor e = new DirectExecutor(); + Future future = Executors.execute(e, new PrivilegedAction() { + public Object run() { + return TEST_STRING; + }}); + + Object result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + finally { + Policy.setPolicy(savedPolicy); + } + } + + /** + * execute of a privileged exception action runs it to completion + */ + public void testExecutePrivilegedExceptionAction() { + Policy savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + try { + Executor e = new DirectExecutor(); + Future future = Executors.execute(e, new PrivilegedExceptionAction() { + public Object run() { + return TEST_STRING; + }}); + + Object result = future.get(); + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + finally { + Policy.setPolicy(savedPolicy); + } + } + + /** + * execute of a failed privileged exception action reports exception + */ + public void testExecuteFailedPrivilegedExceptionAction() { + Policy savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + try { + Executor e = new DirectExecutor(); + Future future = Executors.execute(e, new PrivilegedExceptionAction() { + public Object run() throws Exception { + throw new IndexOutOfBoundsException(); + }}); + + Object result = future.get(); + shouldThrow(); + } + catch (ExecutionException success) { + } + catch (InterruptedException ex) { + unexpectedException(); + } + finally { + Policy.setPolicy(savedPolicy); + } + } + + /** + * invoke of a collable runs it to completion + */ + public void testInvokeCallable() { + try { + Executor e = new DirectExecutor(); + String result = Executors.invoke(e, new StringTask()); + + assertSame(TEST_STRING, result); + } + catch (ExecutionException ex) { + unexpectedException(); + } + catch (InterruptedException ex) { + unexpectedException(); + } + } + + /** + * execute with null executor throws NPE + */ + public void testNullExecuteRunnable() { + try { + TrackedShortRunnable task = new TrackedShortRunnable(); + assertFalse(task.done); + Future future = Executors.execute(null, task); + shouldThrow(); + } + catch (NullPointerException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * execute with a null runnable throws NPE + */ + public void testExecuteNullRunnable() { + try { + Executor e = new DirectExecutor(); + TrackedShortRunnable task = null; + Future future = Executors.execute(e, task); + shouldThrow(); + } + catch (NullPointerException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * invoke of a null runnable throws NPE + */ + public void testInvokeNullRunnable() { + try { + Executor e = new DirectExecutor(); + TrackedShortRunnable task = null; + Executors.invoke(e, task); + shouldThrow(); + } + catch (NullPointerException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * execute of a null callable throws NPE + */ + public void testExecuteNullCallable() { + try { + Executor e = new DirectExecutor(); + StringTask t = null; + Future future = Executors.execute(e, t); + shouldThrow(); + } + catch (NullPointerException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } + /** + * invoke of a null callable throws NPE + */ + public void testInvokeNullCallable() { + try { + Executor e = new DirectExecutor(); + StringTask t = null; + String result = Executors.invoke(e, t); + shouldThrow(); + } + catch (NullPointerException success) { + } + catch (Exception ex) { + unexpectedException(); + } + } /** - * execute(Executor, Runnable) will throw - * RejectedExecutionException Attempting to execute a runnable on - * a full ThreadPool will cause such an exception here, up to 5 - * runnables are attempted on a pool capable on handling one - * until it throws an exception + * execute(Executor, Runnable) throws RejectedExecutionException + * if saturated. */ public void testExecute1() { ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(1)); try { for(int i = 0; i < 5; ++i){ - Executors.execute(p, new MediumRunnable(), Boolean.TRUE); + Executors.execute(p, new MediumRunnable()); } shouldThrow(); } catch(RejectedExecutionException success){} @@ -101,11 +454,8 @@ public class ExecutorsTest extends JSR16 } /** - * execute(Executor, Callable) will throw - * RejectedExecutionException Attempting to execute a callable on - * a full ThreadPool will cause such an exception here, up to 5 - * runnables are attempted on a pool capable on handling one - * until it throws an exception + * execute(Executor, Callable)throws RejectedExecutionException + * if saturated. */ public void testExecute2() { ThreadPoolExecutor p = new ThreadPoolExecutor(1,1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(1)); @@ -120,11 +470,10 @@ public class ExecutorsTest extends JSR16 /** - * invoke(Executor, Runnable) throws InterruptedException - * A single use of invoke starts that will wait long enough - * for the invoking thread to be interrupted + * invoke(Executor, Runnable) throws InterruptedException if + * caller interrupted. */ - public void testInvoke2() { + public void testInterruptedInvoke() { final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); Thread t = new Thread(new Runnable() { public void run() { @@ -156,10 +505,8 @@ public class ExecutorsTest extends JSR16 } /** - * invoke(Executor, Runnable) will throw - * ExecutionException An ExecutionException occurs when the - * underlying Runnable throws an exception, here the - * DivideByZeroException will cause an ExecutionException + * invoke(Executor, Runnable) throws ExecutionException if + * runnable throws exception. */ public void testInvoke3() { ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); @@ -185,9 +532,8 @@ public class ExecutorsTest extends JSR16 /** - * invoke(Executor, Callable) throws - * InterruptedException A single use of invoke starts that will - * wait long enough for the invoking thread to be interrupted + * invoke(Executor, Callable) throws InterruptedException if + * callable throws exception */ public void testInvoke5() { final ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); @@ -226,9 +572,8 @@ public class ExecutorsTest extends JSR16 } /** - * invoke(Executor, Callable) will throw ExecutionException - * An ExecutionException occurs when the underlying Runnable throws - * an exception, here the DivideByZeroException will cause an ExecutionException + * invoke(Executor, Callable) will throw ExecutionException + * if callable throws exception */ public void testInvoke6() { ThreadPoolExecutor p = new ThreadPoolExecutor(1,1,SHORT_DELAY_MS, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10)); @@ -246,87 +591,15 @@ public class ExecutorsTest extends JSR16 } shouldThrow(); - } catch(RejectedExecutionException e){} - catch(InterruptedException e2){} - catch(ExecutionException e3){} - joinPool(p); - } - - /** - * - */ - public void testExecuteRunnable () { - try { - Executor e = new DirectExecutor(); - MyTask task = new MyTask(); - assertFalse(task.isCompleted()); - Future future = Executors.execute(e, task, TEST_STRING); - String result = future.get(); - assertTrue(task.isCompleted()); - assertSame(TEST_STRING, result); - } - catch (ExecutionException ex) { - unexpectedException(); - } - catch (InterruptedException ex) { - unexpectedException(); - } - } - - /** - * - */ - public void testInvokeRunnable () { - try { - Executor e = new DirectExecutor(); - MyTask task = new MyTask(); - assertFalse(task.isCompleted()); - Executors.invoke(e, task); - assertTrue(task.isCompleted()); - } - catch (ExecutionException ex) { - unexpectedException(); - } - catch (InterruptedException ex) { - unexpectedException(); - } - } - - /** - * - */ - public void testExecuteCallable () { - try { - Executor e = new DirectExecutor(); - Future future = Executors.execute(e, new StringTask()); - String result = future.get(); - assertSame(TEST_STRING, result); - } - catch (ExecutionException ex) { - unexpectedException(); - } - catch (InterruptedException ex) { + } + catch(ExecutionException success){ + } catch(Exception e) { unexpectedException(); } + joinPool(p); } - /** - * - */ - public void testInvokeCallable () { - try { - Executor e = new DirectExecutor(); - String result = Executors.invoke(e, new StringTask()); - assertSame(TEST_STRING, result); - } - catch (ExecutionException ex) { - unexpectedException(); - } - catch (InterruptedException ex) { - unexpectedException(); - } - } /** * timeouts from execute will time out if they compute too long. @@ -369,6 +642,84 @@ public class ExecutorsTest extends JSR16 } + /** + * ThreadPoolExecutor using defaultThreadFactory has + * specified group, priority, daemon status, and name + */ + public void testDefaultThreadFactory() { + final ThreadGroup egroup = Thread.currentThread().getThreadGroup(); + Runnable r = new Runnable() { + public void run() { + Thread current = Thread.currentThread(); + threadAssertTrue(!current.isDaemon()); + threadAssertTrue(current.getPriority() == Thread.NORM_PRIORITY); + ThreadGroup g = current.getThreadGroup(); + SecurityManager s = System.getSecurityManager(); + if (s != null) + threadAssertTrue(g == s.getThreadGroup()); + else + threadAssertTrue(g == egroup); + String name = current.getName(); + threadAssertTrue(name.endsWith("thread-1")); + } + }; + ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory()); + + e.execute(r); + e.shutdown(); + try { + Thread.sleep(SHORT_DELAY_MS); + } catch (Exception eX) { + unexpectedException(); + } finally { + joinPool(e); + } + } + /** + * ThreadPoolExecutor using privilegedThreadFactory has + * specified group, priority, daemon status, name, + * access control context and context class loader + */ + public void testPrivilegedThreadFactory() { + Policy savedPolicy = Policy.getPolicy(); + AdjustablePolicy policy = new AdjustablePolicy(); + policy.addPermission(new RuntimePermission("getContextClassLoader")); + policy.addPermission(new RuntimePermission("setContextClassLoader")); + Policy.setPolicy(policy); + final ThreadGroup egroup = Thread.currentThread().getThreadGroup(); + final ClassLoader thisccl = Thread.currentThread().getContextClassLoader(); + final AccessControlContext thisacc = AccessController.getContext(); + Runnable r = new Runnable() { + public void run() { + Thread current = Thread.currentThread(); + threadAssertTrue(!current.isDaemon()); + threadAssertTrue(current.getPriority() == Thread.NORM_PRIORITY); + ThreadGroup g = current.getThreadGroup(); + SecurityManager s = System.getSecurityManager(); + if (s != null) + threadAssertTrue(g == s.getThreadGroup()); + else + threadAssertTrue(g == egroup); + String name = current.getName(); + threadAssertTrue(name.endsWith("thread-1")); + threadAssertTrue(thisccl == current.getContextClassLoader()); + threadAssertTrue(thisacc.equals(AccessController.getContext())); + } + }; + ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory()); + + Policy.setPolicy(savedPolicy); + e.execute(r); + e.shutdown(); + try { + Thread.sleep(SHORT_DELAY_MS); + } catch (Exception ex) { + unexpectedException(); + } finally { + joinPool(e); + } + + } }