ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.46
Committed: Sun Oct 4 16:14:48 2015 UTC (8 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.45: +61 -67 lines
Log Message:
PoolCleaning

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