ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.32
Committed: Mon Oct 4 03:34:21 2010 UTC (13 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.31: +3 -0 lines
Log Message:
Avoid classloader-related SecurityExceptions in swingui.TestRunner

File Contents

# Content
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
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9
10 import junit.framework.*;
11 import java.util.*;
12 import java.util.concurrent.*;
13 import static java.util.concurrent.TimeUnit.MILLISECONDS;
14 import java.math.BigInteger;
15 import java.security.*;
16
17 public class ExecutorsTest extends JSR166TestCase {
18 public static void main(String[] args) {
19 junit.textui.TestRunner.run(suite());
20 }
21 public static Test suite() {
22 return new TestSuite(ExecutorsTest.class);
23 }
24
25 /**
26 * A newCachedThreadPool can execute runnables
27 */
28 public void testNewCachedThreadPool1() {
29 ExecutorService e = Executors.newCachedThreadPool();
30 e.execute(new NoOpRunnable());
31 e.execute(new NoOpRunnable());
32 e.execute(new NoOpRunnable());
33 joinPool(e);
34 }
35
36 /**
37 * A newCachedThreadPool with given ThreadFactory can execute runnables
38 */
39 public void testNewCachedThreadPool2() {
40 ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory());
41 e.execute(new NoOpRunnable());
42 e.execute(new NoOpRunnable());
43 e.execute(new NoOpRunnable());
44 joinPool(e);
45 }
46
47 /**
48 * A newCachedThreadPool with null ThreadFactory throws NPE
49 */
50 public void testNewCachedThreadPool3() {
51 try {
52 ExecutorService e = Executors.newCachedThreadPool(null);
53 shouldThrow();
54 } catch (NullPointerException success) {}
55 }
56
57
58 /**
59 * A new SingleThreadExecutor can execute runnables
60 */
61 public void testNewSingleThreadExecutor1() {
62 ExecutorService e = Executors.newSingleThreadExecutor();
63 e.execute(new NoOpRunnable());
64 e.execute(new NoOpRunnable());
65 e.execute(new NoOpRunnable());
66 joinPool(e);
67 }
68
69 /**
70 * A new SingleThreadExecutor with given ThreadFactory can execute runnables
71 */
72 public void testNewSingleThreadExecutor2() {
73 ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory());
74 e.execute(new NoOpRunnable());
75 e.execute(new NoOpRunnable());
76 e.execute(new NoOpRunnable());
77 joinPool(e);
78 }
79
80 /**
81 * A new SingleThreadExecutor with null ThreadFactory throws NPE
82 */
83 public void testNewSingleThreadExecutor3() {
84 try {
85 ExecutorService e = Executors.newSingleThreadExecutor(null);
86 shouldThrow();
87 } catch (NullPointerException success) {}
88 }
89
90 /**
91 * A new SingleThreadExecutor cannot be casted to concrete implementation
92 */
93 public void testCastNewSingleThreadExecutor() {
94 ExecutorService e = Executors.newSingleThreadExecutor();
95 try {
96 ThreadPoolExecutor tpe = (ThreadPoolExecutor)e;
97 shouldThrow();
98 } catch (ClassCastException success) {
99 } finally {
100 joinPool(e);
101 }
102 }
103
104
105 /**
106 * A new newFixedThreadPool can execute runnables
107 */
108 public void testNewFixedThreadPool1() {
109 ExecutorService e = Executors.newFixedThreadPool(2);
110 e.execute(new NoOpRunnable());
111 e.execute(new NoOpRunnable());
112 e.execute(new NoOpRunnable());
113 joinPool(e);
114 }
115
116 /**
117 * A new newFixedThreadPool with given ThreadFactory can execute runnables
118 */
119 public void testNewFixedThreadPool2() {
120 ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory());
121 e.execute(new NoOpRunnable());
122 e.execute(new NoOpRunnable());
123 e.execute(new NoOpRunnable());
124 joinPool(e);
125 }
126
127 /**
128 * A new newFixedThreadPool with null ThreadFactory throws NPE
129 */
130 public void testNewFixedThreadPool3() {
131 try {
132 ExecutorService e = Executors.newFixedThreadPool(2, null);
133 shouldThrow();
134 } catch (NullPointerException success) {}
135 }
136
137 /**
138 * A new newFixedThreadPool with 0 threads throws IAE
139 */
140 public void testNewFixedThreadPool4() {
141 try {
142 ExecutorService e = Executors.newFixedThreadPool(0);
143 shouldThrow();
144 } catch (IllegalArgumentException success) {}
145 }
146
147
148 /**
149 * An unconfigurable newFixedThreadPool can execute runnables
150 */
151 public void testunconfigurableExecutorService() {
152 ExecutorService e = Executors.unconfigurableExecutorService(Executors.newFixedThreadPool(2));
153 e.execute(new NoOpRunnable());
154 e.execute(new NoOpRunnable());
155 e.execute(new NoOpRunnable());
156 joinPool(e);
157 }
158
159 /**
160 * unconfigurableExecutorService(null) throws NPE
161 */
162 public void testunconfigurableExecutorServiceNPE() {
163 try {
164 ExecutorService e = Executors.unconfigurableExecutorService(null);
165 shouldThrow();
166 } catch (NullPointerException success) {}
167 }
168
169 /**
170 * unconfigurableScheduledExecutorService(null) throws NPE
171 */
172 public void testunconfigurableScheduledExecutorServiceNPE() {
173 try {
174 ExecutorService e = Executors.unconfigurableScheduledExecutorService(null);
175 shouldThrow();
176 } catch (NullPointerException success) {}
177 }
178
179
180 /**
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);
192 }
193
194 /**
195 * a newScheduledThreadPool successfully runs delayed task
196 */
197 public void testnewScheduledThreadPool() throws Exception {
198 TrackedCallable callable = new TrackedCallable();
199 ScheduledExecutorService p1 = Executors.newScheduledThreadPool(2);
200 Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
201 assertFalse(callable.done);
202 Thread.sleep(MEDIUM_DELAY_MS);
203 assertTrue(callable.done);
204 assertEquals(Boolean.TRUE, f.get());
205 joinPool(p1);
206 }
207
208 /**
209 * an unconfigurable newScheduledThreadPool successfully runs delayed task
210 */
211 public void testunconfigurableScheduledExecutorService() throws Exception {
212 TrackedCallable callable = new TrackedCallable();
213 ScheduledExecutorService p1 = Executors.unconfigurableScheduledExecutorService(Executors.newScheduledThreadPool(2));
214 Future f = p1.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
215 assertFalse(callable.done);
216 Thread.sleep(MEDIUM_DELAY_MS);
217 assertTrue(callable.done);
218 assertEquals(Boolean.TRUE, f.get());
219 joinPool(p1);
220 }
221
222 /**
223 * Future.get on submitted tasks will time out if they compute too long.
224 */
225 public void testTimedCallable() throws Exception {
226 final Runnable sleeper =
227 new RunnableShouldThrow(InterruptedException.class) {
228 public void realRun() throws InterruptedException {
229 Thread.sleep(LONG_DELAY_MS);
230 }};
231 for (ExecutorService executor :
232 new ExecutorService[] {
233 Executors.newSingleThreadExecutor(),
234 Executors.newCachedThreadPool(),
235 Executors.newFixedThreadPool(2),
236 Executors.newScheduledThreadPool(2),
237 }) {
238 try {
239 Future future = executor.submit(sleeper);
240 try {
241 future.get(SHORT_DELAY_MS, MILLISECONDS);
242 shouldThrow();
243 } catch (TimeoutException success) {
244 } finally {
245 future.cancel(true);
246 }
247 }
248 finally {
249 joinPool(executor);
250 }
251 }
252 }
253
254
255 /**
256 * ThreadPoolExecutor using defaultThreadFactory has
257 * specified group, priority, daemon status, and name
258 */
259 public void testDefaultThreadFactory() throws Exception {
260 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
261 Runnable r = new CheckedRunnable() {
262 public void realRun() {
263 try {
264 Thread current = Thread.currentThread();
265 assertTrue(!current.isDaemon());
266 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
267 ThreadGroup g = current.getThreadGroup();
268 SecurityManager s = System.getSecurityManager();
269 if (s != null)
270 assertTrue(g == s.getThreadGroup());
271 else
272 assertTrue(g == egroup);
273 String name = current.getName();
274 assertTrue(name.endsWith("thread-1"));
275 } catch (SecurityException ok) {
276 // Also pass if not allowed to change setting
277 }
278 }};
279 ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
280
281 e.execute(r);
282 try {
283 e.shutdown();
284 } catch (SecurityException ok) {
285 }
286
287 try {
288 Thread.sleep(SHORT_DELAY_MS);
289 } finally {
290 joinPool(e);
291 }
292 }
293
294 /**
295 * ThreadPoolExecutor using privilegedThreadFactory has
296 * specified group, priority, daemon status, name,
297 * access control context and context class loader
298 */
299 public void testPrivilegedThreadFactory() throws Exception {
300 Runnable r = new CheckedRunnable() {
301 public void realRun() throws Exception {
302 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
303 final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
304 final AccessControlContext thisacc = AccessController.getContext();
305 Runnable r = new CheckedRunnable() {
306 public void realRun() {
307 Thread current = Thread.currentThread();
308 assertTrue(!current.isDaemon());
309 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
310 ThreadGroup g = current.getThreadGroup();
311 SecurityManager s = System.getSecurityManager();
312 if (s != null)
313 assertTrue(g == s.getThreadGroup());
314 else
315 assertTrue(g == egroup);
316 String name = current.getName();
317 assertTrue(name.endsWith("thread-1"));
318 assertSame(thisccl, current.getContextClassLoader());
319 assertEquals(thisacc, AccessController.getContext());
320 }};
321 ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
322 e.execute(r);
323 e.shutdown();
324 Thread.sleep(SHORT_DELAY_MS);
325 joinPool(e);
326 }};
327
328 runWithPermissions(r,
329 new RuntimePermission("getClassLoader"),
330 new RuntimePermission("setContextClassLoader"),
331 new RuntimePermission("modifyThread"));
332 }
333
334 boolean haveCCLPermissions() {
335 SecurityManager sm = System.getSecurityManager();
336 if (sm != null) {
337 try {
338 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
339 sm.checkPermission(new RuntimePermission("getClassLoader"));
340 } catch (AccessControlException e) {
341 return false;
342 }
343 }
344 return true;
345 }
346
347 void checkCCL() {
348 SecurityManager sm = System.getSecurityManager();
349 if (sm != null) {
350 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
351 sm.checkPermission(new RuntimePermission("getClassLoader"));
352 }
353 }
354
355 class CheckCCL implements Callable<Object> {
356 public Object call() {
357 checkCCL();
358 return null;
359 }
360 }
361
362
363 /**
364 * Without class loader permissions, creating
365 * privilegedCallableUsingCurrentClassLoader throws ACE
366 */
367 public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
368 Runnable r = new CheckedRunnable() {
369 public void realRun() throws Exception {
370 if (System.getSecurityManager() == null)
371 return;
372 try {
373 Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
374 shouldThrow();
375 } catch (AccessControlException success) {}
376 }};
377
378 runWithoutPermissions(r);
379 }
380
381 /**
382 * With class loader permissions, calling
383 * privilegedCallableUsingCurrentClassLoader does not throw ACE
384 */
385 public void testprivilegedCallableUsingCCLWithPrivs() throws Exception {
386 Runnable r = new CheckedRunnable() {
387 public void realRun() throws Exception {
388 Executors.privilegedCallableUsingCurrentClassLoader
389 (new NoOpCallable())
390 .call();
391 }};
392
393 runWithPermissions(r,
394 new RuntimePermission("getClassLoader"),
395 new RuntimePermission("setContextClassLoader"));
396 }
397
398 /**
399 * Without permissions, calling privilegedCallable throws ACE
400 */
401 public void testprivilegedCallableWithNoPrivs() throws Exception {
402 // Avoid classloader-related SecurityExceptions in swingui.TestRunner
403 Executors.privilegedCallable(new CheckCCL());
404
405 Runnable r = new CheckedRunnable() {
406 public void realRun() throws Exception {
407 if (System.getSecurityManager() == null)
408 return;
409 Callable task = Executors.privilegedCallable(new CheckCCL());
410 try {
411 task.call();
412 shouldThrow();
413 } catch (AccessControlException success) {}
414 }};
415
416 runWithoutPermissions(r);
417
418 // It seems rather difficult to test that the
419 // AccessControlContext of the privilegedCallable is used
420 // instead of its caller. Below is a failed attempt to do
421 // that, which does not work because the AccessController
422 // cannot capture the internal state of the current Policy.
423 // It would be much more work to differentiate based on,
424 // e.g. CodeSource.
425
426 // final AccessControlContext[] noprivAcc = new AccessControlContext[1];
427 // final Callable[] task = new Callable[1];
428
429 // runWithPermissions
430 // (new CheckedRunnable() {
431 // public void realRun() {
432 // if (System.getSecurityManager() == null)
433 // return;
434 // noprivAcc[0] = AccessController.getContext();
435 // task[0] = Executors.privilegedCallable(new CheckCCL());
436 // try {
437 // AccessController.doPrivileged(new PrivilegedAction<Void>() {
438 // public Void run() {
439 // checkCCL();
440 // return null;
441 // }}, noprivAcc[0]);
442 // shouldThrow();
443 // } catch (AccessControlException success) {}
444 // }});
445
446 // runWithPermissions
447 // (new CheckedRunnable() {
448 // public void realRun() throws Exception {
449 // if (System.getSecurityManager() == null)
450 // return;
451 // // Verify that we have an underprivileged ACC
452 // try {
453 // AccessController.doPrivileged(new PrivilegedAction<Void>() {
454 // public Void run() {
455 // checkCCL();
456 // return null;
457 // }}, noprivAcc[0]);
458 // shouldThrow();
459 // } catch (AccessControlException success) {}
460
461 // try {
462 // task[0].call();
463 // shouldThrow();
464 // } catch (AccessControlException success) {}
465 // }},
466 // new RuntimePermission("getClassLoader"),
467 // new RuntimePermission("setContextClassLoader"));
468 }
469
470 /**
471 * With permissions, calling privilegedCallable succeeds
472 */
473 public void testprivilegedCallableWithPrivs() throws Exception {
474 Runnable r = new CheckedRunnable() {
475 public void realRun() throws Exception {
476 Executors.privilegedCallable(new CheckCCL()).call();
477 }};
478
479 runWithPermissions(r,
480 new RuntimePermission("getClassLoader"),
481 new RuntimePermission("setContextClassLoader"));
482 }
483
484 /**
485 * callable(Runnable) returns null when called
486 */
487 public void testCallable1() throws Exception {
488 Callable c = Executors.callable(new NoOpRunnable());
489 assertNull(c.call());
490 }
491
492 /**
493 * callable(Runnable, result) returns result when called
494 */
495 public void testCallable2() throws Exception {
496 Callable c = Executors.callable(new NoOpRunnable(), one);
497 assertSame(one, c.call());
498 }
499
500 /**
501 * callable(PrivilegedAction) returns its result when called
502 */
503 public void testCallable3() throws Exception {
504 Callable c = Executors.callable(new PrivilegedAction() {
505 public Object run() { return one; }});
506 assertSame(one, c.call());
507 }
508
509 /**
510 * callable(PrivilegedExceptionAction) returns its result when called
511 */
512 public void testCallable4() throws Exception {
513 Callable c = Executors.callable(new PrivilegedExceptionAction() {
514 public Object run() { return one; }});
515 assertSame(one, c.call());
516 }
517
518
519 /**
520 * callable(null Runnable) throws NPE
521 */
522 public void testCallableNPE1() {
523 try {
524 Callable c = Executors.callable((Runnable) null);
525 shouldThrow();
526 } catch (NullPointerException success) {}
527 }
528
529 /**
530 * callable(null, result) throws NPE
531 */
532 public void testCallableNPE2() {
533 try {
534 Callable c = Executors.callable((Runnable) null, one);
535 shouldThrow();
536 } catch (NullPointerException success) {}
537 }
538
539 /**
540 * callable(null PrivilegedAction) throws NPE
541 */
542 public void testCallableNPE3() {
543 try {
544 Callable c = Executors.callable((PrivilegedAction) null);
545 shouldThrow();
546 } catch (NullPointerException success) {}
547 }
548
549 /**
550 * callable(null PrivilegedExceptionAction) throws NPE
551 */
552 public void testCallableNPE4() {
553 try {
554 Callable c = Executors.callable((PrivilegedExceptionAction) null);
555 shouldThrow();
556 } catch (NullPointerException success) {}
557 }
558
559
560 }