ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.31
Committed: Thu Sep 16 00:52:49 2010 UTC (13 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.30: +19 -20 lines
Log Message:
testcase hygiene: introduce CheckedRecursiveAction and CheckedRecursiveTask; eliminate almost all threadAssertXXX; use preferred junit conventions;narrow the scope of exception checking code; make sure test failures in non-junit threads produce proper stacktraces

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 Runnable r = new CheckedRunnable() {
403 public void realRun() throws Exception {
404 if (System.getSecurityManager() == null)
405 return;
406 Callable task = Executors.privilegedCallable(new CheckCCL());
407 try {
408 task.call();
409 shouldThrow();
410 } catch (AccessControlException success) {}
411 }};
412
413 runWithoutPermissions(r);
414
415 // It seems rather difficult to test that the
416 // AccessControlContext of the privilegedCallable is used
417 // instead of its caller. Below is a failed attempt to do
418 // that, which does not work because the AccessController
419 // cannot capture the internal state of the current Policy.
420 // It would be much more work to differentiate based on,
421 // e.g. CodeSource.
422
423 // final AccessControlContext[] noprivAcc = new AccessControlContext[1];
424 // final Callable[] task = new Callable[1];
425
426 // runWithPermissions
427 // (new CheckedRunnable() {
428 // public void realRun() {
429 // if (System.getSecurityManager() == null)
430 // return;
431 // noprivAcc[0] = AccessController.getContext();
432 // task[0] = Executors.privilegedCallable(new CheckCCL());
433 // try {
434 // AccessController.doPrivileged(new PrivilegedAction<Void>() {
435 // public Void run() {
436 // checkCCL();
437 // return null;
438 // }}, noprivAcc[0]);
439 // shouldThrow();
440 // } catch (AccessControlException success) {}
441 // }});
442
443 // runWithPermissions
444 // (new CheckedRunnable() {
445 // public void realRun() throws Exception {
446 // if (System.getSecurityManager() == null)
447 // return;
448 // // Verify that we have an underprivileged ACC
449 // try {
450 // AccessController.doPrivileged(new PrivilegedAction<Void>() {
451 // public Void run() {
452 // checkCCL();
453 // return null;
454 // }}, noprivAcc[0]);
455 // shouldThrow();
456 // } catch (AccessControlException success) {}
457
458 // try {
459 // task[0].call();
460 // shouldThrow();
461 // } catch (AccessControlException success) {}
462 // }},
463 // new RuntimePermission("getClassLoader"),
464 // new RuntimePermission("setContextClassLoader"));
465 }
466
467 /**
468 * With permissions, calling privilegedCallable succeeds
469 */
470 public void testprivilegedCallableWithPrivs() throws Exception {
471 Runnable r = new CheckedRunnable() {
472 public void realRun() throws Exception {
473 Executors.privilegedCallable(new CheckCCL()).call();
474 }};
475
476 runWithPermissions(r,
477 new RuntimePermission("getClassLoader"),
478 new RuntimePermission("setContextClassLoader"));
479 }
480
481 /**
482 * callable(Runnable) returns null when called
483 */
484 public void testCallable1() throws Exception {
485 Callable c = Executors.callable(new NoOpRunnable());
486 assertNull(c.call());
487 }
488
489 /**
490 * callable(Runnable, result) returns result when called
491 */
492 public void testCallable2() throws Exception {
493 Callable c = Executors.callable(new NoOpRunnable(), one);
494 assertSame(one, c.call());
495 }
496
497 /**
498 * callable(PrivilegedAction) returns its result when called
499 */
500 public void testCallable3() throws Exception {
501 Callable c = Executors.callable(new PrivilegedAction() {
502 public Object run() { return one; }});
503 assertSame(one, c.call());
504 }
505
506 /**
507 * callable(PrivilegedExceptionAction) returns its result when called
508 */
509 public void testCallable4() throws Exception {
510 Callable c = Executors.callable(new PrivilegedExceptionAction() {
511 public Object run() { return one; }});
512 assertSame(one, c.call());
513 }
514
515
516 /**
517 * callable(null Runnable) throws NPE
518 */
519 public void testCallableNPE1() {
520 try {
521 Callable c = Executors.callable((Runnable) null);
522 shouldThrow();
523 } catch (NullPointerException success) {}
524 }
525
526 /**
527 * callable(null, result) throws NPE
528 */
529 public void testCallableNPE2() {
530 try {
531 Callable c = Executors.callable((Runnable) null, one);
532 shouldThrow();
533 } catch (NullPointerException success) {}
534 }
535
536 /**
537 * callable(null PrivilegedAction) throws NPE
538 */
539 public void testCallableNPE3() {
540 try {
541 Callable c = Executors.callable((PrivilegedAction) null);
542 shouldThrow();
543 } catch (NullPointerException success) {}
544 }
545
546 /**
547 * callable(null PrivilegedExceptionAction) throws NPE
548 */
549 public void testCallableNPE4() {
550 try {
551 Callable c = Executors.callable((PrivilegedExceptionAction) null);
552 shouldThrow();
553 } catch (NullPointerException success) {}
554 }
555
556
557 }