ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.23
Committed: Thu Nov 19 03:55:29 2009 UTC (14 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.22: +45 -104 lines
Log Message:
better 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 try {
224 TrackedCallable callable = new TrackedCallable();
225 ScheduledExecutorService p1 = Executors.newSingleThreadScheduledExecutor();
226 Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
227 assertFalse(callable.done);
228 Thread.sleep(MEDIUM_DELAY_MS);
229 assertTrue(callable.done);
230 assertEquals(Boolean.TRUE, f.get());
231 joinPool(p1);
232 } catch (RejectedExecutionException e) {}
233 }
234
235 /**
236 * a newScheduledThreadPool successfully runs delayed task
237 */
238 public void testnewScheduledThreadPool() throws Exception {
239 try {
240 TrackedCallable callable = new TrackedCallable();
241 ScheduledExecutorService p1 = Executors.newScheduledThreadPool(2);
242 Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
243 assertFalse(callable.done);
244 Thread.sleep(MEDIUM_DELAY_MS);
245 assertTrue(callable.done);
246 assertEquals(Boolean.TRUE, f.get());
247 joinPool(p1);
248 } catch (RejectedExecutionException e) {}
249 }
250
251 /**
252 * an unconfigurable newScheduledThreadPool successfully runs delayed task
253 */
254 public void testunconfigurableScheduledExecutorService() throws Exception {
255 try {
256 TrackedCallable callable = new TrackedCallable();
257 ScheduledExecutorService p1 = Executors.unconfigurableScheduledExecutorService(Executors.newScheduledThreadPool(2));
258 Future f = p1.schedule(callable, SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
259 assertFalse(callable.done);
260 Thread.sleep(MEDIUM_DELAY_MS);
261 assertTrue(callable.done);
262 assertEquals(Boolean.TRUE, f.get());
263 joinPool(p1);
264 } catch (RejectedExecutionException e) {}
265 }
266
267 /**
268 * timeouts from execute will time out if they compute too long.
269 */
270 public void testTimedCallable() throws Exception {
271 int N = 10000;
272 ExecutorService executor = Executors.newSingleThreadExecutor();
273 List<Callable<BigInteger>> tasks = new ArrayList<Callable<BigInteger>>(N);
274 try {
275 long startTime = System.currentTimeMillis();
276
277 long i = 0;
278 while (tasks.size() < N) {
279 tasks.add(new TimedCallable<BigInteger>(executor, new Fib(i), 1));
280 i += 10;
281 }
282
283 int iters = 0;
284 BigInteger sum = BigInteger.ZERO;
285 for (Iterator<Callable<BigInteger>> it = tasks.iterator(); it.hasNext();) {
286 try {
287 ++iters;
288 sum = sum.add(it.next().call());
289 }
290 catch (TimeoutException success) {
291 assertTrue(iters > 0);
292 return;
293 }
294 }
295 // if by chance we didn't ever time out, total time must be small
296 long elapsed = System.currentTimeMillis() - startTime;
297 assertTrue(elapsed < N);
298 }
299 finally {
300 joinPool(executor);
301 }
302 }
303
304
305 /**
306 * ThreadPoolExecutor using defaultThreadFactory has
307 * specified group, priority, daemon status, and name
308 */
309 public void testDefaultThreadFactory() throws Exception {
310 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
311 Runnable r = new Runnable() {
312 public void run() {
313 try {
314 Thread current = Thread.currentThread();
315 threadAssertTrue(!current.isDaemon());
316 threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
317 ThreadGroup g = current.getThreadGroup();
318 SecurityManager s = System.getSecurityManager();
319 if (s != null)
320 threadAssertTrue(g == s.getThreadGroup());
321 else
322 threadAssertTrue(g == egroup);
323 String name = current.getName();
324 threadAssertTrue(name.endsWith("thread-1"));
325 } catch (SecurityException ok) {
326 // Also pass if not allowed to change setting
327 }
328 }
329 };
330 ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
331
332 e.execute(r);
333 try {
334 e.shutdown();
335 } catch (SecurityException ok) {
336 }
337
338 try {
339 Thread.sleep(SHORT_DELAY_MS);
340 } finally {
341 joinPool(e);
342 }
343 }
344
345 /**
346 * ThreadPoolExecutor using privilegedThreadFactory has
347 * specified group, priority, daemon status, name,
348 * access control context and context class loader
349 */
350 public void testPrivilegedThreadFactory() throws Exception {
351 Policy savedPolicy = null;
352 try {
353 savedPolicy = Policy.getPolicy();
354 AdjustablePolicy policy = new AdjustablePolicy();
355 policy.addPermission(new RuntimePermission("getContextClassLoader"));
356 policy.addPermission(new RuntimePermission("setContextClassLoader"));
357 Policy.setPolicy(policy);
358 } catch (AccessControlException ok) {
359 return;
360 }
361 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
362 final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
363 final AccessControlContext thisacc = AccessController.getContext();
364 Runnable r = new Runnable() {
365 public void run() {
366 try {
367 Thread current = Thread.currentThread();
368 threadAssertTrue(!current.isDaemon());
369 threadAssertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
370 ThreadGroup g = current.getThreadGroup();
371 SecurityManager s = System.getSecurityManager();
372 if (s != null)
373 threadAssertTrue(g == s.getThreadGroup());
374 else
375 threadAssertTrue(g == egroup);
376 String name = current.getName();
377 threadAssertTrue(name.endsWith("thread-1"));
378 threadAssertTrue(thisccl == current.getContextClassLoader());
379 threadAssertTrue(thisacc.equals(AccessController.getContext()));
380 } catch (SecurityException ok) {
381 // Also pass if not allowed to change settings
382 }
383 }
384 };
385 ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
386
387 Policy.setPolicy(savedPolicy);
388 e.execute(r);
389 try {
390 e.shutdown();
391 } catch (SecurityException ok) {
392 }
393 try {
394 Thread.sleep(SHORT_DELAY_MS);
395 } finally {
396 joinPool(e);
397 }
398
399 }
400
401 void checkCCL() {
402 SecurityManager sm = System.getSecurityManager();
403 if (sm != null) {
404 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
405 sm.checkPermission(new RuntimePermission("getClassLoader"));
406 }
407 }
408
409 class CheckCCL implements Callable<Object> {
410 public Object call() {
411 checkCCL();
412 return null;
413 }
414 }
415
416
417 /**
418 * Without class loader permissions, creating
419 * privilegedCallableUsingCurrentClassLoader throws ACE
420 */
421 public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
422 Policy savedPolicy = null;
423 try {
424 savedPolicy = Policy.getPolicy();
425 AdjustablePolicy policy = new AdjustablePolicy();
426 Policy.setPolicy(policy);
427 } catch (AccessControlException ok) {
428 return;
429 }
430
431 // Check if program still has too many permissions to run test
432 try {
433 checkCCL();
434 // too many privileges to test; so return
435 Policy.setPolicy(savedPolicy);
436 return;
437 } catch (AccessControlException ok) {
438 }
439
440 try {
441 Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
442 shouldThrow();
443 } catch (AccessControlException success) {
444 } finally {
445 Policy.setPolicy(savedPolicy);
446 }
447 }
448
449 /**
450 * With class loader permissions, calling
451 * privilegedCallableUsingCurrentClassLoader does not throw ACE
452 */
453 public void testprivilegedCallableUsingCCLWithPrivs() throws Exception {
454 Policy savedPolicy = null;
455 try {
456 savedPolicy = Policy.getPolicy();
457 AdjustablePolicy policy = new AdjustablePolicy();
458 policy.addPermission(new RuntimePermission("getContextClassLoader"));
459 policy.addPermission(new RuntimePermission("setContextClassLoader"));
460 Policy.setPolicy(policy);
461 } catch (AccessControlException ok) {
462 return;
463 }
464
465 try {
466 Callable task = Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
467 task.call();
468 }
469 finally {
470 Policy.setPolicy(savedPolicy);
471 }
472 }
473
474 /**
475 * Without permissions, calling privilegedCallable throws ACE
476 */
477 public void testprivilegedCallableWithNoPrivs() throws Exception {
478 Callable task;
479 Policy savedPolicy = null;
480 AdjustablePolicy policy = null;
481 AccessControlContext noprivAcc = null;
482 try {
483 savedPolicy = Policy.getPolicy();
484 policy = new AdjustablePolicy();
485 Policy.setPolicy(policy);
486 noprivAcc = AccessController.getContext();
487 task = Executors.privilegedCallable(new CheckCCL());
488 Policy.setPolicy(savedPolicy);
489 } catch (AccessControlException ok) {
490 return; // program has too few permissions to set up test
491 }
492
493 // Make sure that program doesn't have too many permissions
494 try {
495 AccessController.doPrivileged(new PrivilegedAction() {
496 public Object run() {
497 checkCCL();
498 return null;
499 }}, noprivAcc);
500 // too many permssions; skip test
501 return;
502 } catch (AccessControlException ok) {
503 }
504
505 try {
506 task.call();
507 shouldThrow();
508 } catch (AccessControlException success) {}
509 }
510
511 /**
512 * With permissions, calling privilegedCallable succeeds
513 */
514 public void testprivilegedCallableWithPrivs() throws Exception {
515 Policy savedPolicy = null;
516 try {
517 savedPolicy = Policy.getPolicy();
518 AdjustablePolicy policy = new AdjustablePolicy();
519 policy.addPermission(new RuntimePermission("getContextClassLoader"));
520 policy.addPermission(new RuntimePermission("setContextClassLoader"));
521 Policy.setPolicy(policy);
522 } catch (AccessControlException ok) {
523 return;
524 }
525
526 Callable task = Executors.privilegedCallable(new CheckCCL());
527 try {
528 task.call();
529 } finally {
530 Policy.setPolicy(savedPolicy);
531 }
532 }
533
534 /**
535 * callable(Runnable) returns null when called
536 */
537 public void testCallable1() throws Exception {
538 Callable c = Executors.callable(new NoOpRunnable());
539 assertNull(c.call());
540 }
541
542 /**
543 * callable(Runnable, result) returns result when called
544 */
545 public void testCallable2() throws Exception {
546 Callable c = Executors.callable(new NoOpRunnable(), one);
547 assertEquals(one, c.call());
548 }
549
550 /**
551 * callable(PrivilegedAction) returns its result when called
552 */
553 public void testCallable3() throws Exception {
554 Callable c = Executors.callable(new PrivilegedAction() {
555 public Object run() { return one; }});
556 assertEquals(one, c.call());
557 }
558
559 /**
560 * callable(PrivilegedExceptionAction) returns its result when called
561 */
562 public void testCallable4() throws Exception {
563 Callable c = Executors.callable(new PrivilegedExceptionAction() {
564 public Object run() { return one; }});
565 assertEquals(one, c.call());
566 }
567
568
569 /**
570 * callable(null Runnable) throws NPE
571 */
572 public void testCallableNPE1() {
573 try {
574 Callable c = Executors.callable((Runnable) null);
575 shouldThrow();
576 } catch (NullPointerException success) {}
577 }
578
579 /**
580 * callable(null, result) throws NPE
581 */
582 public void testCallableNPE2() {
583 try {
584 Callable c = Executors.callable((Runnable) null, one);
585 shouldThrow();
586 } catch (NullPointerException success) {}
587 }
588
589 /**
590 * callable(null PrivilegedAction) throws NPE
591 */
592 public void testCallableNPE3() {
593 try {
594 Callable c = Executors.callable((PrivilegedAction) null);
595 shouldThrow();
596 } catch (NullPointerException success) {}
597 }
598
599 /**
600 * callable(null PrivilegedExceptionAction) throws NPE
601 */
602 public void testCallableNPE4() {
603 try {
604 Callable c = Executors.callable((PrivilegedExceptionAction) null);
605 shouldThrow();
606 } catch (NullPointerException success) {}
607 }
608
609
610 }