ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.53
Committed: Sat Feb 1 17:44:35 2020 UTC (4 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.52: +1 -1 lines
Log Message:
whitespace

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 unused = 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 unused = 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
144 * NullPointerException
145 */
146 public void testNewFixedThreadPool3() {
147 try {
148 ExecutorService unused = Executors.newFixedThreadPool(2, null);
149 shouldThrow();
150 } catch (NullPointerException success) {}
151 }
152
153 /**
154 * A new newFixedThreadPool with 0 threads throws IllegalArgumentException
155 */
156 public void testNewFixedThreadPool4() {
157 try {
158 ExecutorService unused = Executors.newFixedThreadPool(0);
159 shouldThrow();
160 } catch (IllegalArgumentException success) {}
161 }
162
163 /**
164 * An unconfigurable newFixedThreadPool can execute runnables
165 */
166 public void testUnconfigurableExecutorService() {
167 final ExecutorService e = Executors.unconfigurableExecutorService(Executors.newFixedThreadPool(2));
168 try (PoolCleaner cleaner = cleaner(e)) {
169 e.execute(new NoOpRunnable());
170 e.execute(new NoOpRunnable());
171 e.execute(new NoOpRunnable());
172 }
173 }
174
175 /**
176 * unconfigurableExecutorService(null) throws NPE
177 */
178 public void testUnconfigurableExecutorServiceNPE() {
179 try {
180 ExecutorService unused =
181 Executors.unconfigurableExecutorService(null);
182 shouldThrow();
183 } catch (NullPointerException success) {}
184 }
185
186 /**
187 * unconfigurableScheduledExecutorService(null) throws NPE
188 */
189 public void testUnconfigurableScheduledExecutorServiceNPE() {
190 try {
191 ExecutorService unused =
192 Executors.unconfigurableScheduledExecutorService(null);
193 shouldThrow();
194 } catch (NullPointerException success) {}
195 }
196
197 /**
198 * a newSingleThreadScheduledExecutor successfully runs delayed task
199 */
200 public void testNewSingleThreadScheduledExecutor() throws Exception {
201 final ScheduledExecutorService p = Executors.newSingleThreadScheduledExecutor();
202 try (PoolCleaner cleaner = cleaner(p)) {
203 final CountDownLatch proceed = new CountDownLatch(1);
204 final Runnable task = new CheckedRunnable() {
205 public void realRun() {
206 await(proceed);
207 }};
208 long startTime = System.nanoTime();
209 Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
210 timeoutMillis(), MILLISECONDS);
211 assertFalse(f.isDone());
212 proceed.countDown();
213 assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
214 assertSame(Boolean.TRUE, f.get());
215 assertTrue(f.isDone());
216 assertFalse(f.isCancelled());
217 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
218 }
219 }
220
221 /**
222 * a newScheduledThreadPool successfully runs delayed task
223 */
224 public void testNewScheduledThreadPool() throws Exception {
225 final ScheduledExecutorService p = Executors.newScheduledThreadPool(2);
226 try (PoolCleaner cleaner = cleaner(p)) {
227 final CountDownLatch proceed = new CountDownLatch(1);
228 final Runnable task = new CheckedRunnable() {
229 public void realRun() {
230 await(proceed);
231 }};
232 long startTime = System.nanoTime();
233 Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
234 timeoutMillis(), MILLISECONDS);
235 assertFalse(f.isDone());
236 proceed.countDown();
237 assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
238 assertSame(Boolean.TRUE, f.get());
239 assertTrue(f.isDone());
240 assertFalse(f.isCancelled());
241 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
242 }
243 }
244
245 /**
246 * an unconfigurable newScheduledThreadPool successfully runs delayed task
247 */
248 public void testUnconfigurableScheduledExecutorService() throws Exception {
249 final ScheduledExecutorService p =
250 Executors.unconfigurableScheduledExecutorService
251 (Executors.newScheduledThreadPool(2));
252 try (PoolCleaner cleaner = cleaner(p)) {
253 final CountDownLatch proceed = new CountDownLatch(1);
254 final Runnable task = new CheckedRunnable() {
255 public void realRun() {
256 await(proceed);
257 }};
258 long startTime = System.nanoTime();
259 Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
260 timeoutMillis(), MILLISECONDS);
261 assertFalse(f.isDone());
262 proceed.countDown();
263 assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
264 assertSame(Boolean.TRUE, f.get());
265 assertTrue(f.isDone());
266 assertFalse(f.isCancelled());
267 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
268 }
269 }
270
271 /**
272 * Future.get on submitted tasks will time out if they compute too long.
273 */
274 public void testTimedCallable() throws Exception {
275 final ExecutorService[] executors = {
276 Executors.newSingleThreadExecutor(),
277 Executors.newCachedThreadPool(),
278 Executors.newFixedThreadPool(2),
279 Executors.newScheduledThreadPool(2),
280 };
281
282 final Runnable sleeper = new CheckedRunnable() {
283 public void realRun() throws InterruptedException {
284 try {
285 delay(LONG_DELAY_MS);
286 } catch (InterruptedException OK) {
287 }
288 }};
289
290 List<Thread> threads = new ArrayList<>();
291 for (final ExecutorService executor : executors) {
292 threads.add(newStartedThread(new CheckedRunnable() {
293 public void realRun() {
294 Future future = executor.submit(sleeper);
295 assertFutureTimesOut(future);
296 }}));
297 }
298 for (Thread thread : threads)
299 awaitTermination(thread);
300 for (ExecutorService executor : executors)
301 executor.shutdownNow(); // assumes shutdownNow interrupts threads
302 for (ExecutorService executor : executors)
303 joinPool(executor);
304 }
305
306 /**
307 * ThreadPoolExecutor using defaultThreadFactory has
308 * specified group, priority, daemon status, and name
309 */
310 public void testDefaultThreadFactory() throws Exception {
311 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
312 final CountDownLatch done = new CountDownLatch(1);
313 Runnable r = new CheckedRunnable() {
314 public void realRun() {
315 try {
316 Thread current = Thread.currentThread();
317 assertFalse(current.isDaemon());
318 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
319 SecurityManager s = System.getSecurityManager();
320 assertSame(current.getThreadGroup(),
321 (s == null) ? egroup : s.getThreadGroup());
322 assertTrue(current.getName().endsWith("thread-1"));
323 } catch (SecurityException ok) {
324 // Also pass if not allowed to change setting
325 }
326 done.countDown();
327 }};
328 ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
329 try (PoolCleaner cleaner = cleaner(e)) {
330 e.execute(r);
331 await(done);
332 }
333 }
334
335 /**
336 * ThreadPoolExecutor using privilegedThreadFactory has
337 * specified group, priority, daemon status, name,
338 * access control context and context class loader
339 */
340 public void testPrivilegedThreadFactory() throws Exception {
341 final CountDownLatch done = new CountDownLatch(1);
342 Runnable r = new CheckedRunnable() {
343 public void realRun() throws Exception {
344 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
345 final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
346 final AccessControlContext thisacc = AccessController.getContext();
347 Runnable r = new CheckedRunnable() {
348 public void realRun() {
349 Thread current = Thread.currentThread();
350 assertFalse(current.isDaemon());
351 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
352 SecurityManager s = System.getSecurityManager();
353 assertSame(current.getThreadGroup(),
354 (s == null) ? egroup : s.getThreadGroup());
355 assertTrue(current.getName().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 unused = 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 unused = 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 unused = 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 unused = Executors.callable((PrivilegedExceptionAction) null);
592 shouldThrow();
593 } catch (NullPointerException success) {}
594 }
595
596 /**
597 * callable(runnable, x).toString() contains toString of wrapped task
598 */
599 public void testCallable_withResult_toString() {
600 if (testImplementationDetails) {
601 Runnable r = () -> {};
602 Callable<String> c = Executors.callable(r, "");
603 assertEquals(
604 identityString(c) + "[Wrapped task = " + r.toString() + "]",
605 c.toString());
606 }
607 }
608
609 /**
610 * callable(runnable).toString() contains toString of wrapped task
611 */
612 public void testCallable_toString() {
613 if (testImplementationDetails) {
614 Runnable r = () -> {};
615 Callable<Object> c = Executors.callable(r);
616 assertEquals(
617 identityString(c) + "[Wrapped task = " + r.toString() + "]",
618 c.toString());
619 }
620 }
621
622 /**
623 * privilegedCallable(callable).toString() contains toString of wrapped task
624 */
625 public void testPrivilegedCallable_toString() {
626 if (testImplementationDetails) {
627 Callable<String> c = () -> "";
628 Callable<String> priv = Executors.privilegedCallable(c);
629 assertEquals(
630 identityString(priv) + "[Wrapped task = " + c.toString() + "]",
631 priv.toString());
632 }
633 }
634
635 /**
636 * privilegedCallableUsingCurrentClassLoader(callable).toString()
637 * contains toString of wrapped task
638 */
639 public void testPrivilegedCallableUsingCurrentClassLoader_toString() {
640 if (testImplementationDetails) {
641 Callable<String> c = () -> "";
642 Callable<String> priv = Executors.privilegedCallableUsingCurrentClassLoader(c);
643 assertEquals(
644 identityString(priv) + "[Wrapped task = " + c.toString() + "]",
645 priv.toString());
646 }
647 }
648 }