ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.55
Committed: Tue Jan 26 13:33:06 2021 UTC (3 years, 3 months ago) by dl
Branch: MAIN
Changes since 1.54: +13 -13 lines
Log Message:
Replace Integer with Item class

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 CountDownLatch done = new CountDownLatch(1);
283
284 final Runnable sleeper = new CheckedRunnable() {
285 public void realRun() throws InterruptedException {
286 done.await(LONG_DELAY_MS, MILLISECONDS);
287 }};
288
289 List<Thread> threads = new ArrayList<>();
290 for (final ExecutorService executor : executors) {
291 threads.add(newStartedThread(new CheckedRunnable() {
292 public void realRun() {
293 Future<?> future = executor.submit(sleeper);
294 assertFutureTimesOut(future);
295 }}));
296 }
297 for (Thread thread : threads)
298 awaitTermination(thread);
299 done.countDown();
300 for (ExecutorService executor : executors)
301 joinPool(executor);
302 }
303
304 /**
305 * ThreadPoolExecutor using defaultThreadFactory has
306 * specified group, priority, daemon status, and name
307 */
308 public void testDefaultThreadFactory() throws Exception {
309 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
310 final CountDownLatch done = new CountDownLatch(1);
311 Runnable r = new CheckedRunnable() {
312 public void realRun() {
313 try {
314 Thread current = Thread.currentThread();
315 assertFalse(current.isDaemon());
316 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
317 SecurityManager s = System.getSecurityManager();
318 assertSame(current.getThreadGroup(),
319 (s == null) ? egroup : s.getThreadGroup());
320 assertTrue(current.getName().endsWith("thread-1"));
321 } catch (SecurityException ok) {
322 // Also pass if not allowed to change setting
323 }
324 done.countDown();
325 }};
326 ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
327 try (PoolCleaner cleaner = cleaner(e)) {
328 e.execute(r);
329 await(done);
330 }
331 }
332
333 /**
334 * ThreadPoolExecutor using privilegedThreadFactory has
335 * specified group, priority, daemon status, name,
336 * access control context and context class loader
337 */
338 public void testPrivilegedThreadFactory() throws Exception {
339 final CountDownLatch done = new CountDownLatch(1);
340 Runnable r = new CheckedRunnable() {
341 public void realRun() throws Exception {
342 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
343 final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
344 final AccessControlContext thisacc = AccessController.getContext();
345 Runnable r = new CheckedRunnable() {
346 public void realRun() {
347 Thread current = Thread.currentThread();
348 assertFalse(current.isDaemon());
349 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
350 SecurityManager s = System.getSecurityManager();
351 assertSame(current.getThreadGroup(),
352 (s == null) ? egroup : s.getThreadGroup());
353 assertTrue(current.getName().endsWith("thread-1"));
354 assertSame(thisccl, current.getContextClassLoader());
355 assertEquals(thisacc, AccessController.getContext());
356 done.countDown();
357 }};
358 ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
359 try (PoolCleaner cleaner = cleaner(e)) {
360 e.execute(r);
361 await(done);
362 }
363 }};
364
365 runWithPermissions(r,
366 new RuntimePermission("getClassLoader"),
367 new RuntimePermission("setContextClassLoader"),
368 new RuntimePermission("modifyThread"));
369 }
370
371 boolean haveCCLPermissions() {
372 SecurityManager sm = System.getSecurityManager();
373 if (sm != null) {
374 try {
375 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
376 sm.checkPermission(new RuntimePermission("getClassLoader"));
377 } catch (AccessControlException e) {
378 return false;
379 }
380 }
381 return true;
382 }
383
384 void checkCCL() {
385 SecurityManager sm = System.getSecurityManager();
386 if (sm != null) {
387 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
388 sm.checkPermission(new RuntimePermission("getClassLoader"));
389 }
390 }
391
392 class CheckCCL implements Callable<Object> {
393 public Object call() {
394 checkCCL();
395 return null;
396 }
397 }
398
399 /**
400 * Without class loader permissions, creating
401 * privilegedCallableUsingCurrentClassLoader throws ACE
402 */
403 public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
404 Runnable r = new CheckedRunnable() {
405 public void realRun() throws Exception {
406 if (System.getSecurityManager() == null)
407 return;
408 try {
409 Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
410 shouldThrow();
411 } catch (AccessControlException success) {}
412 }};
413
414 runWithoutPermissions(r);
415 }
416
417 /**
418 * With class loader permissions, calling
419 * privilegedCallableUsingCurrentClassLoader does not throw ACE
420 */
421 public void testPrivilegedCallableUsingCCLWithPrivs() throws Exception {
422 Runnable r = new CheckedRunnable() {
423 public void realRun() throws Exception {
424 Executors.privilegedCallableUsingCurrentClassLoader
425 (new NoOpCallable())
426 .call();
427 }};
428
429 runWithPermissions(r,
430 new RuntimePermission("getClassLoader"),
431 new RuntimePermission("setContextClassLoader"));
432 }
433
434 /**
435 * Without permissions, calling privilegedCallable throws ACE
436 */
437 public void testPrivilegedCallableWithNoPrivs() throws Exception {
438 // Avoid classloader-related SecurityExceptions in swingui.TestRunner
439 Executors.privilegedCallable(new CheckCCL());
440
441 Runnable r = new CheckedRunnable() {
442 public void realRun() throws Exception {
443 if (System.getSecurityManager() == null)
444 return;
445 Callable<?> task = Executors.privilegedCallable(new CheckCCL());
446 try {
447 task.call();
448 shouldThrow();
449 } catch (AccessControlException success) {}
450 }};
451
452 runWithoutPermissions(r);
453
454 // It seems rather difficult to test that the
455 // AccessControlContext of the privilegedCallable is used
456 // instead of its caller. Below is a failed attempt to do
457 // that, which does not work because the AccessController
458 // cannot capture the internal state of the current Policy.
459 // It would be much more work to differentiate based on,
460 // e.g. CodeSource.
461
462 // final AccessControlContext[] noprivAcc = new AccessControlContext[1];
463 // final Callable[] task = new Callable[1];
464
465 // runWithPermissions
466 // (new CheckedRunnable() {
467 // public void realRun() {
468 // if (System.getSecurityManager() == null)
469 // return;
470 // noprivAcc[0] = AccessController.getContext();
471 // task[0] = Executors.privilegedCallable(new CheckCCL());
472 // try {
473 // AccessController.doPrivileged(new PrivilegedAction<Void>() {
474 // public Void run() {
475 // checkCCL();
476 // return null;
477 // }}, noprivAcc[0]);
478 // shouldThrow();
479 // } catch (AccessControlException success) {}
480 // }});
481
482 // runWithPermissions
483 // (new CheckedRunnable() {
484 // public void realRun() throws Exception {
485 // if (System.getSecurityManager() == null)
486 // return;
487 // // Verify that we have an underprivileged ACC
488 // try {
489 // AccessController.doPrivileged(new PrivilegedAction<Void>() {
490 // public Void run() {
491 // checkCCL();
492 // return null;
493 // }}, noprivAcc[0]);
494 // shouldThrow();
495 // } catch (AccessControlException success) {}
496
497 // try {
498 // task[0].call();
499 // shouldThrow();
500 // } catch (AccessControlException success) {}
501 // }},
502 // new RuntimePermission("getClassLoader"),
503 // new RuntimePermission("setContextClassLoader"));
504 }
505
506 /**
507 * With permissions, calling privilegedCallable succeeds
508 */
509 public void testPrivilegedCallableWithPrivs() throws Exception {
510 Runnable r = new CheckedRunnable() {
511 public void realRun() throws Exception {
512 Executors.privilegedCallable(new CheckCCL()).call();
513 }};
514
515 runWithPermissions(r,
516 new RuntimePermission("getClassLoader"),
517 new RuntimePermission("setContextClassLoader"));
518 }
519
520 /**
521 * callable(Runnable) returns null when called
522 */
523 public void testCallable1() throws Exception {
524 Callable<?> c = Executors.callable(new NoOpRunnable());
525 assertNull(c.call());
526 }
527
528 /**
529 * callable(Runnable, result) returns result when called
530 */
531 public void testCallable2() throws Exception {
532 Callable<?> c = Executors.callable(new NoOpRunnable(), one);
533 assertSame(one, c.call());
534 }
535
536 /**
537 * callable(PrivilegedAction) returns its result when called
538 */
539 public void testCallable3() throws Exception {
540 Callable<?> c = Executors.callable(new PrivilegedAction() {
541 public Object run() { return one; }});
542 assertSame(one, c.call());
543 }
544
545 /**
546 * callable(PrivilegedExceptionAction) returns its result when called
547 */
548 public void testCallable4() throws Exception {
549 Callable<?> c = Executors.callable(new PrivilegedExceptionAction() {
550 public Object run() { return one; }});
551 assertSame(one, c.call());
552 }
553
554 /**
555 * callable(null Runnable) throws NPE
556 */
557 public void testCallableNPE1() {
558 try {
559 Callable<?> unused = Executors.callable((Runnable) null);
560 shouldThrow();
561 } catch (NullPointerException success) {}
562 }
563
564 /**
565 * callable(null, result) throws NPE
566 */
567 public void testCallableNPE2() {
568 try {
569 Callable<?> unused = Executors.callable((Runnable) null, one);
570 shouldThrow();
571 } catch (NullPointerException success) {}
572 }
573
574 /**
575 * callable(null PrivilegedAction) throws NPE
576 */
577 public void testCallableNPE3() {
578 try {
579 Callable<?> unused = Executors.callable((PrivilegedAction) null);
580 shouldThrow();
581 } catch (NullPointerException success) {}
582 }
583
584 /**
585 * callable(null PrivilegedExceptionAction) throws NPE
586 */
587 public void testCallableNPE4() {
588 try {
589 Callable<?> unused = Executors.callable((PrivilegedExceptionAction) null);
590 shouldThrow();
591 } catch (NullPointerException success) {}
592 }
593
594 /**
595 * callable(runnable, x).toString() contains toString of wrapped task
596 */
597 public void testCallable_withResult_toString() {
598 if (testImplementationDetails) {
599 Runnable r = () -> {};
600 Callable<String> c = Executors.callable(r, "");
601 assertEquals(
602 identityString(c) + "[Wrapped task = " + r.toString() + "]",
603 c.toString());
604 }
605 }
606
607 /**
608 * callable(runnable).toString() contains toString of wrapped task
609 */
610 public void testCallable_toString() {
611 if (testImplementationDetails) {
612 Runnable r = () -> {};
613 Callable<Object> c = Executors.callable(r);
614 assertEquals(
615 identityString(c) + "[Wrapped task = " + r.toString() + "]",
616 c.toString());
617 }
618 }
619
620 /**
621 * privilegedCallable(callable).toString() contains toString of wrapped task
622 */
623 public void testPrivilegedCallable_toString() {
624 if (testImplementationDetails) {
625 Callable<String> c = () -> "";
626 Callable<String> priv = Executors.privilegedCallable(c);
627 assertEquals(
628 identityString(priv) + "[Wrapped task = " + c.toString() + "]",
629 priv.toString());
630 }
631 }
632
633 /**
634 * privilegedCallableUsingCurrentClassLoader(callable).toString()
635 * contains toString of wrapped task
636 */
637 public void testPrivilegedCallableUsingCurrentClassLoader_toString() {
638 if (testImplementationDetails) {
639 Callable<String> c = () -> "";
640 Callable<String> priv = Executors.privilegedCallableUsingCurrentClassLoader(c);
641 assertEquals(
642 identityString(priv) + "[Wrapped task = " + c.toString() + "]",
643 priv.toString());
644 }
645 }
646 }