ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ExecutorsTest.java (file contents):
Revision 1.27 by jsr166, Tue Dec 1 09:56:28 2009 UTC vs.
Revision 1.38 by jsr166, Thu Apr 14 22:55:08 2011 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   * Other contributors include Andrew Wright, Jeffrey Hayes,
6   * Pat Fisher, Mike Judd.
7   */
# Line 16 | Line 16 | import java.security.*;
16  
17   public class ExecutorsTest extends JSR166TestCase {
18      public static void main(String[] args) {
19 <        junit.textui.TestRunner.run (suite());
19 >        junit.textui.TestRunner.run(suite());
20      }
21      public static Test suite() {
22          return new TestSuite(ExecutorsTest.class);
23      }
24  
25    static class TimedCallable<T> implements Callable<T> {
26        private final ExecutorService exec;
27        private final Callable<T> func;
28        private final long msecs;
29
30        TimedCallable(ExecutorService exec, Callable<T> func, long msecs) {
31            this.exec = exec;
32            this.func = func;
33            this.msecs = msecs;
34        }
35
36        public T call() throws Exception {
37            Future<T> ftask = exec.submit(func);
38            try {
39                return ftask.get(msecs, MILLISECONDS);
40            } finally {
41                ftask.cancel(true);
42            }
43        }
44    }
45
46
47    private static class Fib implements Callable<BigInteger> {
48        private final BigInteger n;
49        Fib(long n) {
50            if (n < 0) throw new IllegalArgumentException("need non-negative arg, but got " + n);
51            this.n = BigInteger.valueOf(n);
52        }
53        public BigInteger call() {
54            BigInteger f1 = BigInteger.ONE;
55            BigInteger f2 = f1;
56            for (BigInteger i = BigInteger.ZERO; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
57                BigInteger t = f1.add(f2);
58                f1 = f2;
59                f2 = t;
60            }
61            return f1;
62        }
63    };
64
25      /**
26       * A newCachedThreadPool can execute runnables
27       */
# Line 221 | Line 181 | public class ExecutorsTest extends JSR16
181       * a newSingleThreadScheduledExecutor successfully runs delayed task
182       */
183      public void testNewSingleThreadScheduledExecutor() throws Exception {
184 <        TrackedCallable callable = new TrackedCallable();
185 <        ScheduledExecutorService p1 = Executors.newSingleThreadScheduledExecutor();
186 <        Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
187 <        assertFalse(callable.done);
188 <        Thread.sleep(MEDIUM_DELAY_MS);
189 <        assertTrue(callable.done);
190 <        assertEquals(Boolean.TRUE, f.get());
191 <        joinPool(p1);
184 >        ScheduledExecutorService p = Executors.newSingleThreadScheduledExecutor();
185 >        try {
186 >            final CountDownLatch done = new CountDownLatch(1);
187 >            final Runnable task = new CheckedRunnable() {
188 >                public void realRun() {
189 >                    done.countDown();
190 >                }};
191 >            Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
192 >                                  SHORT_DELAY_MS, MILLISECONDS);
193 >            assertFalse(f.isDone());
194 >            assertTrue(done.await(MEDIUM_DELAY_MS, MILLISECONDS));
195 >            assertSame(Boolean.TRUE, f.get(SMALL_DELAY_MS, MILLISECONDS));
196 >            assertSame(Boolean.TRUE, f.get());
197 >            assertTrue(f.isDone());
198 >        } finally {
199 >            joinPool(p);
200 >        }
201      }
202  
203      /**
204       * a newScheduledThreadPool successfully runs delayed task
205       */
206      public void testnewScheduledThreadPool() throws Exception {
207 <        TrackedCallable callable = new TrackedCallable();
208 <        ScheduledExecutorService p1 = Executors.newScheduledThreadPool(2);
209 <        Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
210 <        assertFalse(callable.done);
211 <        Thread.sleep(MEDIUM_DELAY_MS);
212 <        assertTrue(callable.done);
213 <        assertEquals(Boolean.TRUE, f.get());
214 <        joinPool(p1);
207 >        ScheduledExecutorService p = Executors.newScheduledThreadPool(2);
208 >        try {
209 >            final CountDownLatch done = new CountDownLatch(1);
210 >            final Runnable task = new CheckedRunnable() {
211 >                public void realRun() {
212 >                    done.countDown();
213 >                }};
214 >            Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
215 >                                  SHORT_DELAY_MS, MILLISECONDS);
216 >            assertFalse(f.isDone());
217 >            assertTrue(done.await(MEDIUM_DELAY_MS, MILLISECONDS));
218 >            assertSame(Boolean.TRUE, f.get(SMALL_DELAY_MS, MILLISECONDS));
219 >            assertSame(Boolean.TRUE, f.get());
220 >            assertTrue(f.isDone());
221 >        } finally {
222 >            joinPool(p);
223 >        }
224      }
225  
226      /**
227       * an unconfigurable newScheduledThreadPool successfully runs delayed task
228       */
229      public void testunconfigurableScheduledExecutorService() throws Exception {
230 <        TrackedCallable callable = new TrackedCallable();
231 <        ScheduledExecutorService p1 = Executors.unconfigurableScheduledExecutorService(Executors.newScheduledThreadPool(2));
232 <        Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
233 <        assertFalse(callable.done);
234 <        Thread.sleep(MEDIUM_DELAY_MS);
235 <        assertTrue(callable.done);
236 <        assertEquals(Boolean.TRUE, f.get());
237 <        joinPool(p1);
230 >        ScheduledExecutorService p =
231 >            Executors.unconfigurableScheduledExecutorService
232 >            (Executors.newScheduledThreadPool(2));
233 >        try {
234 >            final CountDownLatch done = new CountDownLatch(1);
235 >            final Runnable task = new CheckedRunnable() {
236 >                public void realRun() {
237 >                    done.countDown();
238 >                }};
239 >            Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
240 >                                  SHORT_DELAY_MS, MILLISECONDS);
241 >            assertFalse(f.isDone());
242 >            assertTrue(done.await(MEDIUM_DELAY_MS, MILLISECONDS));
243 >            assertSame(Boolean.TRUE, f.get(SMALL_DELAY_MS, MILLISECONDS));
244 >            assertSame(Boolean.TRUE, f.get());
245 >            assertTrue(f.isDone());
246 >        } finally {
247 >            joinPool(p);
248 >        }
249      }
250  
251      /**
252 <     *  timeouts from execute will time out if they compute too long.
252 >     * Future.get on submitted tasks will time out if they compute too long.
253       */
254      public void testTimedCallable() throws Exception {
255 <        int N = 10000;
256 <        ExecutorService executor = Executors.newSingleThreadExecutor();
257 <        List<Callable<BigInteger>> tasks = new ArrayList<Callable<BigInteger>>(N);
258 <        try {
259 <            long startTime = System.currentTimeMillis();
260 <
261 <            long i = 0;
262 <            while (tasks.size() < N) {
263 <                tasks.add(new TimedCallable<BigInteger>(executor, new Fib(i), 1));
264 <                i += 10;
265 <            }
266 <
267 <            int iters = 0;
279 <            BigInteger sum = BigInteger.ZERO;
280 <            for (Iterator<Callable<BigInteger>> it = tasks.iterator(); it.hasNext();) {
255 >        final Runnable sleeper = new CheckedInterruptedRunnable() {
256 >            public void realRun() throws InterruptedException {
257 >                Thread.sleep(LONG_DELAY_MS);
258 >            }};
259 >        for (ExecutorService executor :
260 >                 new ExecutorService[] {
261 >                     Executors.newSingleThreadExecutor(),
262 >                     Executors.newCachedThreadPool(),
263 >                     Executors.newFixedThreadPool(2),
264 >                     Executors.newScheduledThreadPool(2),
265 >                 }) {
266 >            try {
267 >                Future future = executor.submit(sleeper);
268                  try {
269 <                    ++iters;
270 <                    sum = sum.add(it.next().call());
271 <                }
272 <                catch (TimeoutException success) {
273 <                    assertTrue(iters > 0);
287 <                    return;
269 >                    future.get(SHORT_DELAY_MS, MILLISECONDS);
270 >                    shouldThrow();
271 >                } catch (TimeoutException success) {
272 >                } finally {
273 >                    future.cancel(true);
274                  }
275              }
276 <            // if by chance we didn't ever time out, total time must be small
277 <            long elapsed = System.currentTimeMillis() - startTime;
278 <            assertTrue(elapsed < N);
293 <        }
294 <        finally {
295 <            joinPool(executor);
276 >            finally {
277 >                joinPool(executor);
278 >            }
279          }
280      }
281  
# Line 303 | Line 286 | public class ExecutorsTest extends JSR16
286       */
287      public void testDefaultThreadFactory() throws Exception {
288          final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
289 <        Runnable r = new Runnable() {
290 <                public void run() {
291 <                    try {
292 <                        Thread current = Thread.currentThread();
293 <                        threadAssertTrue(!current.isDaemon());
294 <                        threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
295 <                        ThreadGroup g = current.getThreadGroup();
296 <                        SecurityManager s = System.getSecurityManager();
297 <                        if (s != null)
298 <                            threadAssertTrue(g == s.getThreadGroup());
299 <                        else
300 <                            threadAssertTrue(g == egroup);
301 <                        String name = current.getName();
302 <                        threadAssertTrue(name.endsWith("thread-1"));
303 <                    } catch (SecurityException ok) {
304 <                        // Also pass if not allowed to change setting
322 <                    }
289 >        Runnable r = new CheckedRunnable() {
290 >            public void realRun() {
291 >                try {
292 >                    Thread current = Thread.currentThread();
293 >                    assertTrue(!current.isDaemon());
294 >                    assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
295 >                    ThreadGroup g = current.getThreadGroup();
296 >                    SecurityManager s = System.getSecurityManager();
297 >                    if (s != null)
298 >                        assertTrue(g == s.getThreadGroup());
299 >                    else
300 >                        assertTrue(g == egroup);
301 >                    String name = current.getName();
302 >                    assertTrue(name.endsWith("thread-1"));
303 >                } catch (SecurityException ok) {
304 >                    // Also pass if not allowed to change setting
305                  }
306 <            };
306 >            }};
307          ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
308  
309          e.execute(r);
# Line 343 | Line 325 | public class ExecutorsTest extends JSR16
325       * access control context and context class loader
326       */
327      public void testPrivilegedThreadFactory() throws Exception {
328 <        Policy savedPolicy = null;
329 <        try {
330 <            savedPolicy = Policy.getPolicy();
331 <            AdjustablePolicy policy = new AdjustablePolicy();
332 <            policy.addPermission(new RuntimePermission("getContextClassLoader"));
333 <            policy.addPermission(new RuntimePermission("setContextClassLoader"));
334 <            Policy.setPolicy(policy);
353 <        } catch (AccessControlException ok) {
354 <            return;
355 <        }
356 <        final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
357 <        final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
358 <        final AccessControlContext thisacc = AccessController.getContext();
359 <        Runnable r = new Runnable() {
360 <                public void run() {
361 <                    try {
328 >        Runnable r = new CheckedRunnable() {
329 >            public void realRun() throws Exception {
330 >                final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
331 >                final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
332 >                final AccessControlContext thisacc = AccessController.getContext();
333 >                Runnable r = new CheckedRunnable() {
334 >                    public void realRun() {
335                          Thread current = Thread.currentThread();
336 <                        threadAssertTrue(!current.isDaemon());
337 <                        threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
336 >                        assertTrue(!current.isDaemon());
337 >                        assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
338                          ThreadGroup g = current.getThreadGroup();
339                          SecurityManager s = System.getSecurityManager();
340                          if (s != null)
341 <                            threadAssertTrue(g == s.getThreadGroup());
341 >                            assertTrue(g == s.getThreadGroup());
342                          else
343 <                            threadAssertTrue(g == egroup);
343 >                            assertTrue(g == egroup);
344                          String name = current.getName();
345 <                        threadAssertTrue(name.endsWith("thread-1"));
346 <                        threadAssertTrue(thisccl == current.getContextClassLoader());
347 <                        threadAssertTrue(thisacc.equals(AccessController.getContext()));
348 <                    } catch (SecurityException ok) {
349 <                        // Also pass if not allowed to change settings
350 <                    }
351 <                }
352 <            };
353 <        ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
345 >                        assertTrue(name.endsWith("thread-1"));
346 >                        assertSame(thisccl, current.getContextClassLoader());
347 >                        assertEquals(thisacc, AccessController.getContext());
348 >                    }};
349 >                ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
350 >                e.execute(r);
351 >                e.shutdown();
352 >                Thread.sleep(SHORT_DELAY_MS);
353 >                joinPool(e);
354 >            }};
355 >
356 >        runWithPermissions(r,
357 >                           new RuntimePermission("getClassLoader"),
358 >                           new RuntimePermission("setContextClassLoader"),
359 >                           new RuntimePermission("modifyThread"));
360 >    }
361  
362 <        Policy.setPolicy(savedPolicy);
363 <        e.execute(r);
364 <        try {
365 <            e.shutdown();
366 <        } catch (SecurityException ok) {
367 <        }
368 <        try {
369 <            Thread.sleep(SHORT_DELAY_MS);
370 <        } finally {
391 <            joinPool(e);
362 >    boolean haveCCLPermissions() {
363 >        SecurityManager sm = System.getSecurityManager();
364 >        if (sm != null) {
365 >            try {
366 >                sm.checkPermission(new RuntimePermission("setContextClassLoader"));
367 >                sm.checkPermission(new RuntimePermission("getClassLoader"));
368 >            } catch (AccessControlException e) {
369 >                return false;
370 >            }
371          }
372 +        return true;
373      }
374  
375      void checkCCL() {
# Line 413 | Line 393 | public class ExecutorsTest extends JSR16
393       * privilegedCallableUsingCurrentClassLoader throws ACE
394       */
395      public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
396 <        Policy savedPolicy = null;
397 <        try {
398 <            savedPolicy = Policy.getPolicy();
399 <            AdjustablePolicy policy = new AdjustablePolicy();
400 <            Policy.setPolicy(policy);
401 <        } catch (AccessControlException ok) {
402 <            return;
403 <        }
404 <
425 <        // Check if program still has too many permissions to run test
426 <        try {
427 <            checkCCL();
428 <            // too many privileges to test; so return
429 <            Policy.setPolicy(savedPolicy);
430 <            return;
431 <        } catch (AccessControlException ok) {
432 <        }
396 >        Runnable r = new CheckedRunnable() {
397 >            public void realRun() throws Exception {
398 >                if (System.getSecurityManager() == null)
399 >                    return;
400 >                try {
401 >                    Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
402 >                    shouldThrow();
403 >                } catch (AccessControlException success) {}
404 >            }};
405  
406 <        try {
435 <            Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
436 <            shouldThrow();
437 <        } catch (AccessControlException success) {
438 <        } finally {
439 <            Policy.setPolicy(savedPolicy);
440 <        }
406 >        runWithoutPermissions(r);
407      }
408  
409      /**
# Line 445 | Line 411 | public class ExecutorsTest extends JSR16
411       * privilegedCallableUsingCurrentClassLoader does not throw ACE
412       */
413      public void testprivilegedCallableUsingCCLWithPrivs() throws Exception {
414 <        Policy savedPolicy = null;
415 <        try {
416 <            savedPolicy = Policy.getPolicy();
417 <            AdjustablePolicy policy = new AdjustablePolicy();
418 <            policy.addPermission(new RuntimePermission("getContextClassLoader"));
419 <            policy.addPermission(new RuntimePermission("setContextClassLoader"));
420 <            Policy.setPolicy(policy);
421 <        } catch (AccessControlException ok) {
422 <            return;
423 <        }
458 <
459 <        try {
460 <            Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
461 <            task.call();
462 <        }
463 <        finally {
464 <            Policy.setPolicy(savedPolicy);
465 <        }
414 >        Runnable r = new CheckedRunnable() {
415 >            public void realRun() throws Exception {
416 >                Executors.privilegedCallableUsingCurrentClassLoader
417 >                    (new NoOpCallable())
418 >                    .call();
419 >            }};
420 >
421 >        runWithPermissions(r,
422 >                           new RuntimePermission("getClassLoader"),
423 >                           new RuntimePermission("setContextClassLoader"));
424      }
425  
426      /**
427       * Without permissions, calling privilegedCallable throws ACE
428       */
429      public void testprivilegedCallableWithNoPrivs() throws Exception {
430 <        Callable task;
431 <        Policy savedPolicy = null;
474 <        AdjustablePolicy policy = null;
475 <        AccessControlContext noprivAcc = null;
476 <        try {
477 <            savedPolicy = Policy.getPolicy();
478 <            policy = new AdjustablePolicy();
479 <            Policy.setPolicy(policy);
480 <            noprivAcc = AccessController.getContext();
481 <            task = Executors.privilegedCallable(new CheckCCL());
482 <            Policy.setPolicy(savedPolicy);
483 <        } catch (AccessControlException ok) {
484 <            return; // program has too few permissions to set up test
485 <        }
486 <
487 <        // Make sure that program doesn't have too many permissions
488 <        try {
489 <            AccessController.doPrivileged(new PrivilegedAction() {
490 <                    public Object run() {
491 <                        checkCCL();
492 <                        return null;
493 <                    }}, noprivAcc);
494 <            // too many permssions; skip test
495 <            return;
496 <        } catch (AccessControlException ok) {
497 <        }
430 >        // Avoid classloader-related SecurityExceptions in swingui.TestRunner
431 >        Executors.privilegedCallable(new CheckCCL());
432  
433 <        try {
434 <            task.call();
435 <            shouldThrow();
436 <        } catch (AccessControlException success) {}
433 >        Runnable r = new CheckedRunnable() {
434 >            public void realRun() throws Exception {
435 >                if (System.getSecurityManager() == null)
436 >                    return;
437 >                Callable task = Executors.privilegedCallable(new CheckCCL());
438 >                try {
439 >                    task.call();
440 >                    shouldThrow();
441 >                } catch (AccessControlException success) {}
442 >            }};
443 >
444 >        runWithoutPermissions(r);
445 >
446 >        // It seems rather difficult to test that the
447 >        // AccessControlContext of the privilegedCallable is used
448 >        // instead of its caller.  Below is a failed attempt to do
449 >        // that, which does not work because the AccessController
450 >        // cannot capture the internal state of the current Policy.
451 >        // It would be much more work to differentiate based on,
452 >        // e.g. CodeSource.
453 >
454 > //         final AccessControlContext[] noprivAcc = new AccessControlContext[1];
455 > //         final Callable[] task = new Callable[1];
456 >
457 > //         runWithPermissions
458 > //             (new CheckedRunnable() {
459 > //                 public void realRun() {
460 > //                     if (System.getSecurityManager() == null)
461 > //                         return;
462 > //                     noprivAcc[0] = AccessController.getContext();
463 > //                     task[0] = Executors.privilegedCallable(new CheckCCL());
464 > //                     try {
465 > //                         AccessController.doPrivileged(new PrivilegedAction<Void>() {
466 > //                                                           public Void run() {
467 > //                                                               checkCCL();
468 > //                                                               return null;
469 > //                                                           }}, noprivAcc[0]);
470 > //                         shouldThrow();
471 > //                     } catch (AccessControlException success) {}
472 > //                 }});
473 >
474 > //         runWithPermissions
475 > //             (new CheckedRunnable() {
476 > //                 public void realRun() throws Exception {
477 > //                     if (System.getSecurityManager() == null)
478 > //                         return;
479 > //                     // Verify that we have an underprivileged ACC
480 > //                     try {
481 > //                         AccessController.doPrivileged(new PrivilegedAction<Void>() {
482 > //                                                           public Void run() {
483 > //                                                               checkCCL();
484 > //                                                               return null;
485 > //                                                           }}, noprivAcc[0]);
486 > //                         shouldThrow();
487 > //                     } catch (AccessControlException success) {}
488 >
489 > //                     try {
490 > //                         task[0].call();
491 > //                         shouldThrow();
492 > //                     } catch (AccessControlException success) {}
493 > //                 }},
494 > //              new RuntimePermission("getClassLoader"),
495 > //              new RuntimePermission("setContextClassLoader"));
496      }
497  
498      /**
499       * With permissions, calling privilegedCallable succeeds
500       */
501      public void testprivilegedCallableWithPrivs() throws Exception {
502 <        Policy savedPolicy = null;
503 <        try {
504 <            savedPolicy = Policy.getPolicy();
505 <            AdjustablePolicy policy = new AdjustablePolicy();
506 <            policy.addPermission(new RuntimePermission("getContextClassLoader"));
507 <            policy.addPermission(new RuntimePermission("setContextClassLoader"));
508 <            Policy.setPolicy(policy);
509 <        } catch (AccessControlException ok) {
517 <            return;
518 <        }
519 <
520 <        Callable task = Executors.privilegedCallable(new CheckCCL());
521 <        try {
522 <            task.call();
523 <        } finally {
524 <            Policy.setPolicy(savedPolicy);
525 <        }
502 >        Runnable r = new CheckedRunnable() {
503 >            public void realRun() throws Exception {
504 >                Executors.privilegedCallable(new CheckCCL()).call();
505 >            }};
506 >
507 >        runWithPermissions(r,
508 >                           new RuntimePermission("getClassLoader"),
509 >                           new RuntimePermission("setContextClassLoader"));
510      }
511  
512      /**

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines