ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.50
Committed: Wed Aug 16 17:18:34 2017 UTC (6 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.49: +52 -0 lines
Log Message:
8186265: Make toString() methods of "task" objects more useful

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
144 * NullPointerException
145 */
146 public void testNewFixedThreadPool3() {
147 try {
148 ExecutorService e = 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 e = 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 e = Executors.unconfigurableExecutorService(null);
181 shouldThrow();
182 } catch (NullPointerException success) {}
183 }
184
185 /**
186 * unconfigurableScheduledExecutorService(null) throws NPE
187 */
188 public void testUnconfigurableScheduledExecutorServiceNPE() {
189 try {
190 ExecutorService e = Executors.unconfigurableScheduledExecutorService(null);
191 shouldThrow();
192 } catch (NullPointerException success) {}
193 }
194
195 /**
196 * a newSingleThreadScheduledExecutor successfully runs delayed task
197 */
198 public void testNewSingleThreadScheduledExecutor() throws Exception {
199 final ScheduledExecutorService p = Executors.newSingleThreadScheduledExecutor();
200 try (PoolCleaner cleaner = cleaner(p)) {
201 final CountDownLatch proceed = new CountDownLatch(1);
202 final Runnable task = new CheckedRunnable() {
203 public void realRun() {
204 await(proceed);
205 }};
206 long startTime = System.nanoTime();
207 Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
208 timeoutMillis(), MILLISECONDS);
209 assertFalse(f.isDone());
210 proceed.countDown();
211 assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
212 assertSame(Boolean.TRUE, f.get());
213 assertTrue(f.isDone());
214 assertFalse(f.isCancelled());
215 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
216 }
217 }
218
219 /**
220 * a newScheduledThreadPool successfully runs delayed task
221 */
222 public void testNewScheduledThreadPool() throws Exception {
223 final ScheduledExecutorService p = Executors.newScheduledThreadPool(2);
224 try (PoolCleaner cleaner = cleaner(p)) {
225 final CountDownLatch proceed = new CountDownLatch(1);
226 final Runnable task = new CheckedRunnable() {
227 public void realRun() {
228 await(proceed);
229 }};
230 long startTime = System.nanoTime();
231 Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
232 timeoutMillis(), MILLISECONDS);
233 assertFalse(f.isDone());
234 proceed.countDown();
235 assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
236 assertSame(Boolean.TRUE, f.get());
237 assertTrue(f.isDone());
238 assertFalse(f.isCancelled());
239 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
240 }
241 }
242
243 /**
244 * an unconfigurable newScheduledThreadPool successfully runs delayed task
245 */
246 public void testUnconfigurableScheduledExecutorService() throws Exception {
247 final ScheduledExecutorService p =
248 Executors.unconfigurableScheduledExecutorService
249 (Executors.newScheduledThreadPool(2));
250 try (PoolCleaner cleaner = cleaner(p)) {
251 final CountDownLatch proceed = new CountDownLatch(1);
252 final Runnable task = new CheckedRunnable() {
253 public void realRun() {
254 await(proceed);
255 }};
256 long startTime = System.nanoTime();
257 Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
258 timeoutMillis(), MILLISECONDS);
259 assertFalse(f.isDone());
260 proceed.countDown();
261 assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
262 assertSame(Boolean.TRUE, f.get());
263 assertTrue(f.isDone());
264 assertFalse(f.isCancelled());
265 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
266 }
267 }
268
269 /**
270 * Future.get on submitted tasks will time out if they compute too long.
271 */
272 public void testTimedCallable() throws Exception {
273 final ExecutorService[] executors = {
274 Executors.newSingleThreadExecutor(),
275 Executors.newCachedThreadPool(),
276 Executors.newFixedThreadPool(2),
277 Executors.newScheduledThreadPool(2),
278 };
279
280 final Runnable sleeper = new CheckedInterruptedRunnable() {
281 public void realRun() throws InterruptedException {
282 delay(LONG_DELAY_MS);
283 }};
284
285 List<Thread> threads = new ArrayList<>();
286 for (final ExecutorService executor : executors) {
287 threads.add(newStartedThread(new CheckedRunnable() {
288 public void realRun() {
289 Future future = executor.submit(sleeper);
290 assertFutureTimesOut(future);
291 }}));
292 }
293 for (Thread thread : threads)
294 awaitTermination(thread);
295 for (ExecutorService executor : executors)
296 joinPool(executor);
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 final CountDownLatch done = new CountDownLatch(1);
306 Runnable r = new CheckedRunnable() {
307 public void realRun() {
308 try {
309 Thread current = Thread.currentThread();
310 assertFalse(current.isDaemon());
311 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
312 SecurityManager s = System.getSecurityManager();
313 assertSame(current.getThreadGroup(),
314 (s == null) ? egroup : s.getThreadGroup());
315 assertTrue(current.getName().endsWith("thread-1"));
316 } catch (SecurityException ok) {
317 // Also pass if not allowed to change setting
318 }
319 done.countDown();
320 }};
321 ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
322 try (PoolCleaner cleaner = cleaner(e)) {
323 e.execute(r);
324 await(done);
325 }
326 }
327
328 /**
329 * ThreadPoolExecutor using privilegedThreadFactory has
330 * specified group, priority, daemon status, name,
331 * access control context and context class loader
332 */
333 public void testPrivilegedThreadFactory() throws Exception {
334 final CountDownLatch done = new CountDownLatch(1);
335 Runnable r = new CheckedRunnable() {
336 public void realRun() throws Exception {
337 final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
338 final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
339 final AccessControlContext thisacc = AccessController.getContext();
340 Runnable r = new CheckedRunnable() {
341 public void realRun() {
342 Thread current = Thread.currentThread();
343 assertFalse(current.isDaemon());
344 assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
345 SecurityManager s = System.getSecurityManager();
346 assertSame(current.getThreadGroup(),
347 (s == null) ? egroup : s.getThreadGroup());
348 assertTrue(current.getName().endsWith("thread-1"));
349 assertSame(thisccl, current.getContextClassLoader());
350 assertEquals(thisacc, AccessController.getContext());
351 done.countDown();
352 }};
353 ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
354 try (PoolCleaner cleaner = cleaner(e)) {
355 e.execute(r);
356 await(done);
357 }
358 }};
359
360 runWithPermissions(r,
361 new RuntimePermission("getClassLoader"),
362 new RuntimePermission("setContextClassLoader"),
363 new RuntimePermission("modifyThread"));
364 }
365
366 boolean haveCCLPermissions() {
367 SecurityManager sm = System.getSecurityManager();
368 if (sm != null) {
369 try {
370 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
371 sm.checkPermission(new RuntimePermission("getClassLoader"));
372 } catch (AccessControlException e) {
373 return false;
374 }
375 }
376 return true;
377 }
378
379 void checkCCL() {
380 SecurityManager sm = System.getSecurityManager();
381 if (sm != null) {
382 sm.checkPermission(new RuntimePermission("setContextClassLoader"));
383 sm.checkPermission(new RuntimePermission("getClassLoader"));
384 }
385 }
386
387 class CheckCCL implements Callable<Object> {
388 public Object call() {
389 checkCCL();
390 return null;
391 }
392 }
393
394 /**
395 * Without class loader permissions, creating
396 * privilegedCallableUsingCurrentClassLoader throws ACE
397 */
398 public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
399 Runnable r = new CheckedRunnable() {
400 public void realRun() throws Exception {
401 if (System.getSecurityManager() == null)
402 return;
403 try {
404 Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
405 shouldThrow();
406 } catch (AccessControlException success) {}
407 }};
408
409 runWithoutPermissions(r);
410 }
411
412 /**
413 * With class loader permissions, calling
414 * privilegedCallableUsingCurrentClassLoader does not throw ACE
415 */
416 public void testPrivilegedCallableUsingCCLWithPrivs() throws Exception {
417 Runnable r = new CheckedRunnable() {
418 public void realRun() throws Exception {
419 Executors.privilegedCallableUsingCurrentClassLoader
420 (new NoOpCallable())
421 .call();
422 }};
423
424 runWithPermissions(r,
425 new RuntimePermission("getClassLoader"),
426 new RuntimePermission("setContextClassLoader"));
427 }
428
429 /**
430 * Without permissions, calling privilegedCallable throws ACE
431 */
432 public void testPrivilegedCallableWithNoPrivs() throws Exception {
433 // Avoid classloader-related SecurityExceptions in swingui.TestRunner
434 Executors.privilegedCallable(new CheckCCL());
435
436 Runnable r = new CheckedRunnable() {
437 public void realRun() throws Exception {
438 if (System.getSecurityManager() == null)
439 return;
440 Callable task = Executors.privilegedCallable(new CheckCCL());
441 try {
442 task.call();
443 shouldThrow();
444 } catch (AccessControlException success) {}
445 }};
446
447 runWithoutPermissions(r);
448
449 // It seems rather difficult to test that the
450 // AccessControlContext of the privilegedCallable is used
451 // instead of its caller. Below is a failed attempt to do
452 // that, which does not work because the AccessController
453 // cannot capture the internal state of the current Policy.
454 // It would be much more work to differentiate based on,
455 // e.g. CodeSource.
456
457 // final AccessControlContext[] noprivAcc = new AccessControlContext[1];
458 // final Callable[] task = new Callable[1];
459
460 // runWithPermissions
461 // (new CheckedRunnable() {
462 // public void realRun() {
463 // if (System.getSecurityManager() == null)
464 // return;
465 // noprivAcc[0] = AccessController.getContext();
466 // task[0] = Executors.privilegedCallable(new CheckCCL());
467 // try {
468 // AccessController.doPrivileged(new PrivilegedAction<Void>() {
469 // public Void run() {
470 // checkCCL();
471 // return null;
472 // }}, noprivAcc[0]);
473 // shouldThrow();
474 // } catch (AccessControlException success) {}
475 // }});
476
477 // runWithPermissions
478 // (new CheckedRunnable() {
479 // public void realRun() throws Exception {
480 // if (System.getSecurityManager() == null)
481 // return;
482 // // Verify that we have an underprivileged ACC
483 // try {
484 // AccessController.doPrivileged(new PrivilegedAction<Void>() {
485 // public Void run() {
486 // checkCCL();
487 // return null;
488 // }}, noprivAcc[0]);
489 // shouldThrow();
490 // } catch (AccessControlException success) {}
491
492 // try {
493 // task[0].call();
494 // shouldThrow();
495 // } catch (AccessControlException success) {}
496 // }},
497 // new RuntimePermission("getClassLoader"),
498 // new RuntimePermission("setContextClassLoader"));
499 }
500
501 /**
502 * With permissions, calling privilegedCallable succeeds
503 */
504 public void testPrivilegedCallableWithPrivs() throws Exception {
505 Runnable r = new CheckedRunnable() {
506 public void realRun() throws Exception {
507 Executors.privilegedCallable(new CheckCCL()).call();
508 }};
509
510 runWithPermissions(r,
511 new RuntimePermission("getClassLoader"),
512 new RuntimePermission("setContextClassLoader"));
513 }
514
515 /**
516 * callable(Runnable) returns null when called
517 */
518 public void testCallable1() throws Exception {
519 Callable c = Executors.callable(new NoOpRunnable());
520 assertNull(c.call());
521 }
522
523 /**
524 * callable(Runnable, result) returns result when called
525 */
526 public void testCallable2() throws Exception {
527 Callable c = Executors.callable(new NoOpRunnable(), one);
528 assertSame(one, c.call());
529 }
530
531 /**
532 * callable(PrivilegedAction) returns its result when called
533 */
534 public void testCallable3() throws Exception {
535 Callable c = Executors.callable(new PrivilegedAction() {
536 public Object run() { return one; }});
537 assertSame(one, c.call());
538 }
539
540 /**
541 * callable(PrivilegedExceptionAction) returns its result when called
542 */
543 public void testCallable4() throws Exception {
544 Callable c = Executors.callable(new PrivilegedExceptionAction() {
545 public Object run() { return one; }});
546 assertSame(one, c.call());
547 }
548
549 /**
550 * callable(null Runnable) throws NPE
551 */
552 public void testCallableNPE1() {
553 try {
554 Callable c = Executors.callable((Runnable) null);
555 shouldThrow();
556 } catch (NullPointerException success) {}
557 }
558
559 /**
560 * callable(null, result) throws NPE
561 */
562 public void testCallableNPE2() {
563 try {
564 Callable c = Executors.callable((Runnable) null, one);
565 shouldThrow();
566 } catch (NullPointerException success) {}
567 }
568
569 /**
570 * callable(null PrivilegedAction) throws NPE
571 */
572 public void testCallableNPE3() {
573 try {
574 Callable c = Executors.callable((PrivilegedAction) null);
575 shouldThrow();
576 } catch (NullPointerException success) {}
577 }
578
579 /**
580 * callable(null PrivilegedExceptionAction) throws NPE
581 */
582 public void testCallableNPE4() {
583 try {
584 Callable c = Executors.callable((PrivilegedExceptionAction) null);
585 shouldThrow();
586 } catch (NullPointerException success) {}
587 }
588
589 /**
590 * callable(runnable, x).toString() contains toString of wrapped task
591 */
592 public void testCallable_withResult_toString() {
593 if (testImplementationDetails) {
594 Runnable r = () -> {};
595 Callable<String> c = Executors.callable(r, "");
596 assertEquals(
597 identityString(c) + "[Wrapped task = " + r.toString() + "]",
598 c.toString());
599 }
600 }
601
602 /**
603 * callable(runnable).toString() contains toString of wrapped task
604 */
605 public void testCallable_toString() {
606 if (testImplementationDetails) {
607 Runnable r = () -> {};
608 Callable<Object> c = Executors.callable(r);
609 assertEquals(
610 identityString(c) + "[Wrapped task = " + r.toString() + "]",
611 c.toString());
612 }
613 }
614
615 /**
616 * privilegedCallable(callable).toString() contains toString of wrapped task
617 */
618 public void testPrivilegedCallable_toString() {
619 if (testImplementationDetails) {
620 Callable<String> c = () -> "";
621 Callable<String> priv = Executors.privilegedCallable(c);
622 assertEquals(
623 identityString(priv) + "[Wrapped task = " + c.toString() + "]",
624 priv.toString());
625 }
626 }
627
628 /**
629 * privilegedCallableUsingCurrentClassLoader(callable).toString()
630 * contains toString of wrapped task
631 */
632 public void testPrivilegedCallableUsingCurrentClassLoader_toString() {
633 if (testImplementationDetails) {
634 Callable<String> c = () -> "";
635 Callable<String> priv = Executors.privilegedCallableUsingCurrentClassLoader(c);
636 assertEquals(
637 identityString(priv) + "[Wrapped task = " + c.toString() + "]",
638 priv.toString());
639 }
640 }
641 }