ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ExecutorsTest.java
Revision: 1.51
Committed: Mon Dec 16 22:55:54 2019 UTC (4 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.50: +12 -10 lines
Log Message:
fix a few [UnusedVariable] warnings

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