ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.24
Committed: Fri Nov 20 22:58:48 2009 UTC (14 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.23: +25 -31 lines
Log Message:
improve exception handling

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 java.math.BigInteger;
14 import java.security.*;
15
16 public class ExecutorsTest extends JSR166TestCase {
17 public static void main(String[] args) {
18 junit.textui.TestRunner.run (suite());
19 }
20 public static Test suite() {
21 return new TestSuite(ExecutorsTest.class);
22 }
23
24 static class TimedCallable<T> implements Callable<T> {
25 private final ExecutorService exec;
26 private final Callable<T> func;
27 private final long msecs;
28
29 TimedCallable(ExecutorService exec, Callable<T> func, long msecs) {
30 this.exec = exec;
31 this.func = func;
32 this.msecs = msecs;
33 }
34
35 public T call() throws Exception {
36 Future<T> ftask = exec.submit(func);
37 try {
38 return ftask.get(msecs, TimeUnit.MILLISECONDS);
39 } finally {
40 ftask.cancel(true);
41 }
42 }
43 }
44
45
46 private static class Fib implements Callable<BigInteger> {
47 private final BigInteger n;
48 Fib(long n) {
49 if (n < 0) throw new IllegalArgumentException("need non-negative arg, but got " + n);
50 this.n = BigInteger.valueOf(n);
51 }
52 public BigInteger call() {
53 BigInteger f1 = BigInteger.ONE;
54 BigInteger f2 = f1;
55 for (BigInteger i = BigInteger.ZERO; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) {
56 BigInteger t = f1.add(f2);
57 f1 = f2;
58 f2 = t;
59 }
60 return f1;
61 }
62 };
63
64 /**
65 * A newCachedThreadPool can execute runnables
66 */
67 public void testNewCachedThreadPool1() {
68 ExecutorService e = Executors.newCachedThreadPool();
69 e.execute(new NoOpRunnable());
70 e.execute(new NoOpRunnable());
71 e.execute(new NoOpRunnable());
72 joinPool(e);
73 }
74
75 /**
76 * A newCachedThreadPool with given ThreadFactory can execute runnables
77 */
78 public void testNewCachedThreadPool2() {
79 ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory());
80 e.execute(new NoOpRunnable());
81 e.execute(new NoOpRunnable());
82 e.execute(new NoOpRunnable());
83 joinPool(e);
84 }
85
86 /**
87 * A newCachedThreadPool with null ThreadFactory throws NPE
88 */
89 public void testNewCachedThreadPool3() {
90 try {
91 ExecutorService e = Executors.newCachedThreadPool(null);
92 shouldThrow();
93 } catch (NullPointerException success) {}
94 }
95
96
97 /**
98 * A new SingleThreadExecutor can execute runnables
99 */
100 public void testNewSingleThreadExecutor1() {
101 ExecutorService e = Executors.newSingleThreadExecutor();
102 e.execute(new NoOpRunnable());
103 e.execute(new NoOpRunnable());
104 e.execute(new NoOpRunnable());
105 joinPool(e);
106 }
107
108 /**
109 * A new SingleThreadExecutor with given ThreadFactory can execute runnables
110 */
111 public void testNewSingleThreadExecutor2() {
112 ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory());
113 e.execute(new NoOpRunnable());
114 e.execute(new NoOpRunnable());
115 e.execute(new NoOpRunnable());
116 joinPool(e);
117 }
118
119 /**
120 * A new SingleThreadExecutor with null ThreadFactory throws NPE
121 */
122 public void testNewSingleThreadExecutor3() {
123 try {
124 ExecutorService e = Executors.newSingleThreadExecutor(null);
125 shouldThrow();
126 } catch (NullPointerException success) {}
127 }
128
129 /**
130 * A new SingleThreadExecutor cannot be casted to concrete implementation
131 */
132 public void testCastNewSingleThreadExecutor() {
133 ExecutorService e = Executors.newSingleThreadExecutor();
134 try {
135 ThreadPoolExecutor tpe = (ThreadPoolExecutor)e;
136 shouldThrow();
137 } catch (ClassCastException success) {
138 } finally {
139 joinPool(e);
140 }
141 }
142
143
144 /**
145 * A new newFixedThreadPool can execute runnables
146 */
147 public void testNewFixedThreadPool1() {
148 ExecutorService e = Executors.newFixedThreadPool(2);
149 e.execute(new NoOpRunnable());
150 e.execute(new NoOpRunnable());
151 e.execute(new NoOpRunnable());
152 joinPool(e);
153 }
154
155 /**
156 * A new newFixedThreadPool with given ThreadFactory can execute runnables
157 */
158 public void testNewFixedThreadPool2() {
159 ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory());
160 e.execute(new NoOpRunnable());
161 e.execute(new NoOpRunnable());
162 e.execute(new NoOpRunnable());
163 joinPool(e);
164 }
165
166 /**
167 * A new newFixedThreadPool with null ThreadFactory throws NPE
168 */
169 public void testNewFixedThreadPool3() {
170 try {
171 ExecutorService e = Executors.newFixedThreadPool(2, null);
172 shouldThrow();
173 } catch (NullPointerException success) {}
174 }
175
176 /**
177 * A new newFixedThreadPool with 0 threads throws IAE
178 */
179 public void testNewFixedThreadPool4() {
180 try {
181 ExecutorService e = Executors.newFixedThreadPool(0);
182 shouldThrow();
183 } catch (IllegalArgumentException success) {}
184 }
185
186
187 /**
188 * An unconfigurable newFixedThreadPool can execute runnables
189 */
190 public void testunconfigurableExecutorService() {
191 ExecutorService e = Executors.unconfigurableExecutorService(Executors.newFixedThreadPool(2));
192 e.execute(new NoOpRunnable());
193 e.execute(new NoOpRunnable());
194 e.execute(new NoOpRunnable());
195 joinPool(e);
196 }
197
198 /**
199 * unconfigurableExecutorService(null) throws NPE
200 */
201 public void testunconfigurableExecutorServiceNPE() {
202 try {
203 ExecutorService e = Executors.unconfigurableExecutorService(null);
204 shouldThrow();
205 } catch (NullPointerException success) {}
206 }
207
208 /**
209 * unconfigurableScheduledExecutorService(null) throws NPE
210 */
211 public void testunconfigurableScheduledExecutorServiceNPE() {
212 try {
213 ExecutorService e = Executors.unconfigurableScheduledExecutorService(null);
214 shouldThrow();
215 } catch (NullPointerException success) {}
216 }
217
218
219 /**
220 * a newSingleThreadScheduledExecutor successfully runs delayed task
221 */
222 public void testNewSingleThreadScheduledExecutor() throws Exception {
223 TrackedCallable callable = new TrackedCallable();
224 ScheduledExecutorService p1 = Executors.newSingleThreadScheduledExecutor();
225 Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
226 assertFalse(callable.done);
227 Thread.sleep(MEDIUM_DELAY_MS);
228 assertTrue(callable.done);
229 assertEquals(Boolean.TRUE, f.get());
230 joinPool(p1);
231 }
232
233 /**
234 * a newScheduledThreadPool successfully runs delayed task
235 */
236 public void testnewScheduledThreadPool() throws Exception {
237 TrackedCallable callable = new TrackedCallable();
238 ScheduledExecutorService p1 = Executors.newScheduledThreadPool(2);
239 Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
240 assertFalse(callable.done);
241 Thread.sleep(MEDIUM_DELAY_MS);
242 assertTrue(callable.done);
243 assertEquals(Boolean.TRUE, f.get());
244 joinPool(p1);
245 }
246
247 /**
248 * an unconfigurable newScheduledThreadPool successfully runs delayed task
249 */
250 public void testunconfigurableScheduledExecutorService() throws Exception {
251 TrackedCallable callable = new TrackedCallable();
252 ScheduledExecutorService p1 = Executors.unconfigurableScheduledExecutorService(Executors.newScheduledThreadPool(2));
253 Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
254 assertFalse(callable.done);
255 Thread.sleep(MEDIUM_DELAY_MS);
256 assertTrue(callable.done);
257 assertEquals(Boolean.TRUE, f.get());
258 joinPool(p1);
259 }
260
261 /**
262 * timeouts from execute will time out if they compute too long.
263 */
264 public void testTimedCallable() throws Exception {
265 int N = 10000;
266 ExecutorService executor = Executors.newSingleThreadExecutor();
267 List<Callable<BigInteger>> tasks = new ArrayList<Callable<BigInteger>>(N);
268 try {
269 long startTime = System.currentTimeMillis();
270
271 long i = 0;
272 while (tasks.size() < N) {
273 tasks.add(new TimedCallable<BigInteger>(executor, new Fib(i), 1));
274 i += 10;
275 }
276
277 int iters = 0;
278 BigInteger sum = BigInteger.ZERO;
279 for (Iterator<Callable<BigInteger>> it = tasks.iterator(); it.hasNext();) {
280 try {
281 ++iters;
282 sum = sum.add(it.next().call());
283 }
284 catch (TimeoutException success) {
285 assertTrue(iters > 0);
286 return;
287 }
288 }
289 // if by chance we didn't ever time out, total time must be small
290 long elapsed = System.currentTimeMillis() - startTime;
291 assertTrue(elapsed < N);
292 }
293 finally {
294 joinPool(executor);
295 }
296 }
297
298
299 /**
300 * ThreadPoolExecutor using defaultThreadFactory has
301 * specified group, priority, daemon status, and name
302 */
303 public void testDefaultThreadFactory() throws Exception {
304 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
305 Runnable r = new Runnable() {
306 public void run() {
307 try {
308 Thread current = Thread.currentThread();
309 threadAssertTrue(!current.isDaemon());
310 threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
311 ThreadGroup g = current.getThreadGroup();
312 SecurityManager s = System.getSecurityManager();
313 if (s != null)
314 threadAssertTrue(g == s.getThreadGroup());
315 else
316 threadAssertTrue(g == egroup);
317 String name = current.getName();
318 threadAssertTrue(name.endsWith("thread-1"));
319 } catch (SecurityException ok) {
320 // Also pass if not allowed to change setting
321 }
322 }
323 };
324 ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
325
326 e.execute(r);
327 try {
328 e.shutdown();
329 } catch (SecurityException ok) {
330 }
331
332 try {
333 Thread.sleep(SHORT_DELAY_MS);
334 } finally {
335 joinPool(e);
336 }
337 }
338
339 /**
340 * ThreadPoolExecutor using privilegedThreadFactory has
341 * specified group, priority, daemon status, name,
342 * access control context and context class loader
343 */
344 public void testPrivilegedThreadFactory() throws Exception {
345 Policy savedPolicy = null;
346 try {
347 savedPolicy = Policy.getPolicy();
348 AdjustablePolicy policy = new AdjustablePolicy();
349 policy.addPermission(new RuntimePermission("getContextClassLoader"));
350 policy.addPermission(new RuntimePermission("setContextClassLoader"));
351 Policy.setPolicy(policy);
352 } catch (AccessControlException ok) {
353 return;
354 }
355 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
356 final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
357 final AccessControlContext thisacc = AccessController.getContext();
358 Runnable r = new Runnable() {
359 public void run() {
360 try {
361 Thread current = Thread.currentThread();
362 threadAssertTrue(!current.isDaemon());
363 threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
364 ThreadGroup g = current.getThreadGroup();
365 SecurityManager s = System.getSecurityManager();
366 if (s != null)
367 threadAssertTrue(g == s.getThreadGroup());
368 else
369 threadAssertTrue(g == egroup);
370 String name = current.getName();
371 threadAssertTrue(name.endsWith("thread-1"));
372 threadAssertTrue(thisccl == current.getContextClassLoader());
373 threadAssertTrue(thisacc.equals(AccessController.getContext()));
374 } catch (SecurityException ok) {
375 // Also pass if not allowed to change settings
376 }
377 }
378 };
379 ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
380
381 Policy.setPolicy(savedPolicy);
382 e.execute(r);
383 try {
384 e.shutdown();
385 } catch (SecurityException ok) {
386 }
387 try {
388 Thread.sleep(SHORT_DELAY_MS);
389 } finally {
390 joinPool(e);
391 }
392
393 }
394
395 void checkCCL() {
396 SecurityManager sm = System.getSecurityManager();
397 if (sm != null) {
398 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
399 sm.checkPermission(new RuntimePermission("getClassLoader"));
400 }
401 }
402
403 class CheckCCL implements Callable<Object> {
404 public Object call() {
405 checkCCL();
406 return null;
407 }
408 }
409
410
411 /**
412 * Without class loader permissions, creating
413 * privilegedCallableUsingCurrentClassLoader throws ACE
414 */
415 public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
416 Policy savedPolicy = null;
417 try {
418 savedPolicy = Policy.getPolicy();
419 AdjustablePolicy policy = new AdjustablePolicy();
420 Policy.setPolicy(policy);
421 } catch (AccessControlException ok) {
422 return;
423 }
424
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 }
433
434 try {
435 Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
436 shouldThrow();
437 } catch (AccessControlException success) {
438 } finally {
439 Policy.setPolicy(savedPolicy);
440 }
441 }
442
443 /**
444 * With class loader permissions, calling
445 * privilegedCallableUsingCurrentClassLoader does not throw ACE
446 */
447 public void testprivilegedCallableUsingCCLWithPrivs() throws Exception {
448 Policy savedPolicy = null;
449 try {
450 savedPolicy = Policy.getPolicy();
451 AdjustablePolicy policy = new AdjustablePolicy();
452 policy.addPermission(new RuntimePermission("getContextClassLoader"));
453 policy.addPermission(new RuntimePermission("setContextClassLoader"));
454 Policy.setPolicy(policy);
455 } catch (AccessControlException ok) {
456 return;
457 }
458
459 try {
460 Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
461 task.call();
462 }
463 finally {
464 Policy.setPolicy(savedPolicy);
465 }
466 }
467
468 /**
469 * Without permissions, calling privilegedCallable throws ACE
470 */
471 public void testprivilegedCallableWithNoPrivs() throws Exception {
472 Callable task;
473 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 }
498
499 try {
500 task.call();
501 shouldThrow();
502 } catch (AccessControlException success) {}
503 }
504
505 /**
506 * With permissions, calling privilegedCallable succeeds
507 */
508 public void testprivilegedCallableWithPrivs() throws Exception {
509 Policy savedPolicy = null;
510 try {
511 savedPolicy = Policy.getPolicy();
512 AdjustablePolicy policy = new AdjustablePolicy();
513 policy.addPermission(new RuntimePermission("getContextClassLoader"));
514 policy.addPermission(new RuntimePermission("setContextClassLoader"));
515 Policy.setPolicy(policy);
516 } 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 }
526 }
527
528 /**
529 * callable(Runnable) returns null when called
530 */
531 public void testCallable1() throws Exception {
532 Callable c = Executors.callable(new NoOpRunnable());
533 assertNull(c.call());
534 }
535
536 /**
537 * callable(Runnable, result) returns result when called
538 */
539 public void testCallable2() throws Exception {
540 Callable c = Executors.callable(new NoOpRunnable(), one);
541 assertEquals(one, c.call());
542 }
543
544 /**
545 * callable(PrivilegedAction) returns its result when called
546 */
547 public void testCallable3() throws Exception {
548 Callable c = Executors.callable(new PrivilegedAction() {
549 public Object run() { return one; }});
550 assertEquals(one, c.call());
551 }
552
553 /**
554 * callable(PrivilegedExceptionAction) returns its result when called
555 */
556 public void testCallable4() throws Exception {
557 Callable c = Executors.callable(new PrivilegedExceptionAction() {
558 public Object run() { return one; }});
559 assertEquals(one, c.call());
560 }
561
562
563 /**
564 * callable(null Runnable) throws NPE
565 */
566 public void testCallableNPE1() {
567 try {
568 Callable c = Executors.callable((Runnable) null);
569 shouldThrow();
570 } catch (NullPointerException success) {}
571 }
572
573 /**
574 * callable(null, result) throws NPE
575 */
576 public void testCallableNPE2() {
577 try {
578 Callable c = Executors.callable((Runnable) null, one);
579 shouldThrow();
580 } catch (NullPointerException success) {}
581 }
582
583 /**
584 * callable(null PrivilegedAction) throws NPE
585 */
586 public void testCallableNPE3() {
587 try {
588 Callable c = Executors.callable((PrivilegedAction) null);
589 shouldThrow();
590 } catch (NullPointerException success) {}
591 }
592
593 /**
594 * callable(null PrivilegedExceptionAction) throws NPE
595 */
596 public void testCallableNPE4() {
597 try {
598 Callable c = Executors.callable((PrivilegedExceptionAction) null);
599 shouldThrow();
600 } catch (NullPointerException success) {}
601 }
602
603
604 }