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 package jsr166; 10 11 import junit.framework.*; 12 import java.util.*; 13 import java.util.concurrent.*; 14 import java.util.concurrent.atomic.AtomicBoolean; 15 import static java.util.concurrent.TimeUnit.MILLISECONDS; 16 import java.security.*; 17 18 public class AbstractExecutorServiceTest extends JSR166TestCase { 19 20 /** 21 * A no-frills implementation of AbstractExecutorService, designed 22 * to test the submit methods only. 23 */ 24 static class DirectExecutorService extends AbstractExecutorService { execute(Runnable r)25 public void execute(Runnable r) { r.run(); } shutdown()26 public void shutdown() { shutdown = true; } shutdownNow()27 public List<Runnable> shutdownNow() { 28 shutdown = true; 29 return Collections.EMPTY_LIST; 30 } isShutdown()31 public boolean isShutdown() { return shutdown; } isTerminated()32 public boolean isTerminated() { return isShutdown(); } awaitTermination(long timeout, TimeUnit unit)33 public boolean awaitTermination(long timeout, TimeUnit unit) { 34 return isShutdown(); 35 } 36 private volatile boolean shutdown = false; 37 } 38 39 /** 40 * execute(runnable) runs it to completion 41 */ testExecuteRunnable()42 public void testExecuteRunnable() throws Exception { 43 ExecutorService e = new DirectExecutorService(); 44 final AtomicBoolean done = new AtomicBoolean(false); 45 CheckedRunnable task = new CheckedRunnable() { 46 public void realRun() { 47 done.set(true); 48 }}; 49 Future<?> future = e.submit(task); 50 assertNull(future.get()); 51 assertNull(future.get(0, MILLISECONDS)); 52 assertTrue(done.get()); 53 assertTrue(future.isDone()); 54 assertFalse(future.isCancelled()); 55 } 56 57 /** 58 * Completed submit(callable) returns result 59 */ testSubmitCallable()60 public void testSubmitCallable() throws Exception { 61 ExecutorService e = new DirectExecutorService(); 62 Future<String> future = e.submit(new StringTask()); 63 String result = future.get(); 64 assertSame(TEST_STRING, result); 65 } 66 67 /** 68 * Completed submit(runnable) returns successfully 69 */ testSubmitRunnable()70 public void testSubmitRunnable() throws Exception { 71 ExecutorService e = new DirectExecutorService(); 72 Future<?> future = e.submit(new NoOpRunnable()); 73 future.get(); 74 assertTrue(future.isDone()); 75 } 76 77 /** 78 * Completed submit(runnable, result) returns result 79 */ testSubmitRunnable2()80 public void testSubmitRunnable2() throws Exception { 81 ExecutorService e = new DirectExecutorService(); 82 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING); 83 String result = future.get(); 84 assertSame(TEST_STRING, result); 85 } 86 87 /** 88 * A submitted privileged action runs to completion 89 */ testSubmitPrivilegedAction()90 public void testSubmitPrivilegedAction() throws Exception { 91 Runnable r = new CheckedRunnable() { 92 public void realRun() throws Exception { 93 ExecutorService e = new DirectExecutorService(); 94 Future future = e.submit(Executors.callable(new PrivilegedAction() { 95 public Object run() { 96 return TEST_STRING; 97 }})); 98 99 assertSame(TEST_STRING, future.get()); 100 }}; 101 102 runWithPermissions(r, 103 new RuntimePermission("getClassLoader"), 104 new RuntimePermission("setContextClassLoader"), 105 new RuntimePermission("modifyThread")); 106 } 107 108 /** 109 * A submitted privileged exception action runs to completion 110 */ testSubmitPrivilegedExceptionAction()111 public void testSubmitPrivilegedExceptionAction() throws Exception { 112 Runnable r = new CheckedRunnable() { 113 public void realRun() throws Exception { 114 ExecutorService e = new DirectExecutorService(); 115 Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() { 116 public Object run() { 117 return TEST_STRING; 118 }})); 119 120 assertSame(TEST_STRING, future.get()); 121 }}; 122 123 runWithPermissions(r); 124 } 125 126 /** 127 * A submitted failed privileged exception action reports exception 128 */ testSubmitFailedPrivilegedExceptionAction()129 public void testSubmitFailedPrivilegedExceptionAction() throws Exception { 130 Runnable r = new CheckedRunnable() { 131 public void realRun() throws Exception { 132 ExecutorService e = new DirectExecutorService(); 133 Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() { 134 public Object run() throws Exception { 135 throw new IndexOutOfBoundsException(); 136 }})); 137 138 try { 139 future.get(); 140 shouldThrow(); 141 } catch (ExecutionException success) { 142 assertTrue(success.getCause() instanceof IndexOutOfBoundsException); 143 }}}; 144 145 runWithPermissions(r); 146 } 147 148 /** 149 * execute(null runnable) throws NPE 150 */ testExecuteNullRunnable()151 public void testExecuteNullRunnable() { 152 try { 153 ExecutorService e = new DirectExecutorService(); 154 e.submit((Runnable) null); 155 shouldThrow(); 156 } catch (NullPointerException success) {} 157 } 158 159 /** 160 * submit(null callable) throws NPE 161 */ testSubmitNullCallable()162 public void testSubmitNullCallable() { 163 try { 164 ExecutorService e = new DirectExecutorService(); 165 e.submit((Callable) null); 166 shouldThrow(); 167 } catch (NullPointerException success) {} 168 } 169 170 /** 171 * submit(callable).get() throws InterruptedException if interrupted 172 */ testInterruptedSubmit()173 public void testInterruptedSubmit() throws InterruptedException { 174 final CountDownLatch submitted = new CountDownLatch(1); 175 final CountDownLatch quittingTime = new CountDownLatch(1); 176 final ExecutorService p 177 = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS, 178 new ArrayBlockingQueue<Runnable>(10)); 179 final Callable<Void> awaiter = new CheckedCallable<Void>() { 180 public Void realCall() throws InterruptedException { 181 quittingTime.await(); 182 return null; 183 }}; 184 try { 185 Thread t = new Thread(new CheckedInterruptedRunnable() { 186 public void realRun() throws Exception { 187 Future<Void> future = p.submit(awaiter); 188 submitted.countDown(); 189 future.get(); 190 }}); 191 t.start(); 192 submitted.await(); 193 t.interrupt(); 194 t.join(); 195 } finally { 196 quittingTime.countDown(); 197 joinPool(p); 198 } 199 } 200 201 /** 202 * get of submit(callable) throws ExecutionException if callable 203 * throws exception 204 */ testSubmitEE()205 public void testSubmitEE() throws InterruptedException { 206 ThreadPoolExecutor p = 207 new ThreadPoolExecutor(1, 1, 208 60, TimeUnit.SECONDS, 209 new ArrayBlockingQueue<Runnable>(10)); 210 211 Callable c = new Callable() { 212 public Object call() { throw new ArithmeticException(); }}; 213 214 try { 215 p.submit(c).get(); 216 shouldThrow(); 217 } catch (ExecutionException success) { 218 assertTrue(success.getCause() instanceof ArithmeticException); 219 } 220 joinPool(p); 221 } 222 223 /** 224 * invokeAny(null) throws NPE 225 */ testInvokeAny1()226 public void testInvokeAny1() throws Exception { 227 ExecutorService e = new DirectExecutorService(); 228 try { 229 e.invokeAny(null); 230 shouldThrow(); 231 } catch (NullPointerException success) { 232 } finally { 233 joinPool(e); 234 } 235 } 236 237 /** 238 * invokeAny(empty collection) throws IAE 239 */ testInvokeAny2()240 public void testInvokeAny2() throws Exception { 241 ExecutorService e = new DirectExecutorService(); 242 try { 243 e.invokeAny(new ArrayList<Callable<String>>()); 244 shouldThrow(); 245 } catch (IllegalArgumentException success) { 246 } finally { 247 joinPool(e); 248 } 249 } 250 251 /** 252 * invokeAny(c) throws NPE if c has null elements 253 */ testInvokeAny3()254 public void testInvokeAny3() throws Exception { 255 ExecutorService e = new DirectExecutorService(); 256 List<Callable<Long>> l = new ArrayList<Callable<Long>>(); 257 l.add(new Callable<Long>() { 258 public Long call() { throw new ArithmeticException(); }}); 259 l.add(null); 260 try { 261 e.invokeAny(l); 262 shouldThrow(); 263 } catch (NullPointerException success) { 264 } finally { 265 joinPool(e); 266 } 267 } 268 269 /** 270 * invokeAny(c) throws ExecutionException if no task in c completes 271 */ testInvokeAny4()272 public void testInvokeAny4() throws InterruptedException { 273 ExecutorService e = new DirectExecutorService(); 274 List<Callable<String>> l = new ArrayList<Callable<String>>(); 275 l.add(new NPETask()); 276 try { 277 e.invokeAny(l); 278 shouldThrow(); 279 } catch (ExecutionException success) { 280 assertTrue(success.getCause() instanceof NullPointerException); 281 } finally { 282 joinPool(e); 283 } 284 } 285 286 /** 287 * invokeAny(c) returns result of some task in c if at least one completes 288 */ testInvokeAny5()289 public void testInvokeAny5() throws Exception { 290 ExecutorService e = new DirectExecutorService(); 291 try { 292 List<Callable<String>> l = new ArrayList<Callable<String>>(); 293 l.add(new StringTask()); 294 l.add(new StringTask()); 295 String result = e.invokeAny(l); 296 assertSame(TEST_STRING, result); 297 } finally { 298 joinPool(e); 299 } 300 } 301 302 /** 303 * invokeAll(null) throws NPE 304 */ testInvokeAll1()305 public void testInvokeAll1() throws InterruptedException { 306 ExecutorService e = new DirectExecutorService(); 307 try { 308 e.invokeAll(null); 309 shouldThrow(); 310 } catch (NullPointerException success) { 311 } finally { 312 joinPool(e); 313 } 314 } 315 316 /** 317 * invokeAll(empty collection) returns empty collection 318 */ testInvokeAll2()319 public void testInvokeAll2() throws InterruptedException { 320 ExecutorService e = new DirectExecutorService(); 321 try { 322 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>()); 323 assertTrue(r.isEmpty()); 324 } finally { 325 joinPool(e); 326 } 327 } 328 329 /** 330 * invokeAll(c) throws NPE if c has null elements 331 */ testInvokeAll3()332 public void testInvokeAll3() throws InterruptedException { 333 ExecutorService e = new DirectExecutorService(); 334 List<Callable<String>> l = new ArrayList<Callable<String>>(); 335 l.add(new StringTask()); 336 l.add(null); 337 try { 338 e.invokeAll(l); 339 shouldThrow(); 340 } catch (NullPointerException success) { 341 } finally { 342 joinPool(e); 343 } 344 } 345 346 /** 347 * get of returned element of invokeAll(c) throws exception on failed task 348 */ testInvokeAll4()349 public void testInvokeAll4() throws Exception { 350 ExecutorService e = new DirectExecutorService(); 351 try { 352 List<Callable<String>> l = new ArrayList<Callable<String>>(); 353 l.add(new NPETask()); 354 List<Future<String>> futures = e.invokeAll(l); 355 assertEquals(1, futures.size()); 356 try { 357 futures.get(0).get(); 358 shouldThrow(); 359 } catch (ExecutionException success) { 360 assertTrue(success.getCause() instanceof NullPointerException); 361 } 362 } finally { 363 joinPool(e); 364 } 365 } 366 367 /** 368 * invokeAll(c) returns results of all completed tasks in c 369 */ testInvokeAll5()370 public void testInvokeAll5() throws Exception { 371 ExecutorService e = new DirectExecutorService(); 372 try { 373 List<Callable<String>> l = new ArrayList<Callable<String>>(); 374 l.add(new StringTask()); 375 l.add(new StringTask()); 376 List<Future<String>> futures = e.invokeAll(l); 377 assertEquals(2, futures.size()); 378 for (Future<String> future : futures) 379 assertSame(TEST_STRING, future.get()); 380 } finally { 381 joinPool(e); 382 } 383 } 384 385 /** 386 * timed invokeAny(null) throws NPE 387 */ testTimedInvokeAny1()388 public void testTimedInvokeAny1() throws Exception { 389 ExecutorService e = new DirectExecutorService(); 390 try { 391 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS); 392 shouldThrow(); 393 } catch (NullPointerException success) { 394 } finally { 395 joinPool(e); 396 } 397 } 398 399 /** 400 * timed invokeAny(null time unit) throws NPE 401 */ testTimedInvokeAnyNullTimeUnit()402 public void testTimedInvokeAnyNullTimeUnit() throws Exception { 403 ExecutorService e = new DirectExecutorService(); 404 List<Callable<String>> l = new ArrayList<Callable<String>>(); 405 l.add(new StringTask()); 406 try { 407 e.invokeAny(l, MEDIUM_DELAY_MS, null); 408 shouldThrow(); 409 } catch (NullPointerException success) { 410 } finally { 411 joinPool(e); 412 } 413 } 414 415 /** 416 * timed invokeAny(empty collection) throws IAE 417 */ testTimedInvokeAny2()418 public void testTimedInvokeAny2() throws Exception { 419 ExecutorService e = new DirectExecutorService(); 420 try { 421 e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS); 422 shouldThrow(); 423 } catch (IllegalArgumentException success) { 424 } finally { 425 joinPool(e); 426 } 427 } 428 429 /** 430 * timed invokeAny(c) throws NPE if c has null elements 431 */ testTimedInvokeAny3()432 public void testTimedInvokeAny3() throws Exception { 433 ExecutorService e = new DirectExecutorService(); 434 List<Callable<Long>> l = new ArrayList<Callable<Long>>(); 435 l.add(new Callable<Long>() { 436 public Long call() { throw new ArithmeticException(); }}); 437 l.add(null); 438 try { 439 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); 440 shouldThrow(); 441 } catch (NullPointerException success) { 442 } finally { 443 joinPool(e); 444 } 445 } 446 447 /** 448 * timed invokeAny(c) throws ExecutionException if no task completes 449 */ testTimedInvokeAny4()450 public void testTimedInvokeAny4() throws Exception { 451 ExecutorService e = new DirectExecutorService(); 452 List<Callable<String>> l = new ArrayList<Callable<String>>(); 453 l.add(new NPETask()); 454 try { 455 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); 456 shouldThrow(); 457 } catch (ExecutionException success) { 458 assertTrue(success.getCause() instanceof NullPointerException); 459 } finally { 460 joinPool(e); 461 } 462 } 463 464 /** 465 * timed invokeAny(c) returns result of some task in c 466 */ testTimedInvokeAny5()467 public void testTimedInvokeAny5() throws Exception { 468 ExecutorService e = new DirectExecutorService(); 469 try { 470 List<Callable<String>> l = new ArrayList<Callable<String>>(); 471 l.add(new StringTask()); 472 l.add(new StringTask()); 473 String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); 474 assertSame(TEST_STRING, result); 475 } finally { 476 joinPool(e); 477 } 478 } 479 480 /** 481 * timed invokeAll(null) throws NPE 482 */ testTimedInvokeAll1()483 public void testTimedInvokeAll1() throws InterruptedException { 484 ExecutorService e = new DirectExecutorService(); 485 try { 486 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS); 487 shouldThrow(); 488 } catch (NullPointerException success) { 489 } finally { 490 joinPool(e); 491 } 492 } 493 494 /** 495 * timed invokeAll(null time unit) throws NPE 496 */ testTimedInvokeAllNullTimeUnit()497 public void testTimedInvokeAllNullTimeUnit() throws InterruptedException { 498 ExecutorService e = new DirectExecutorService(); 499 List<Callable<String>> l = new ArrayList<Callable<String>>(); 500 l.add(new StringTask()); 501 try { 502 e.invokeAll(l, MEDIUM_DELAY_MS, null); 503 shouldThrow(); 504 } catch (NullPointerException success) { 505 } finally { 506 joinPool(e); 507 } 508 } 509 510 /** 511 * timed invokeAll(empty collection) returns empty collection 512 */ testTimedInvokeAll2()513 public void testTimedInvokeAll2() throws InterruptedException { 514 ExecutorService e = new DirectExecutorService(); 515 try { 516 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS); 517 assertTrue(r.isEmpty()); 518 } finally { 519 joinPool(e); 520 } 521 } 522 523 /** 524 * timed invokeAll(c) throws NPE if c has null elements 525 */ testTimedInvokeAll3()526 public void testTimedInvokeAll3() throws InterruptedException { 527 ExecutorService e = new DirectExecutorService(); 528 List<Callable<String>> l = new ArrayList<Callable<String>>(); 529 l.add(new StringTask()); 530 l.add(null); 531 try { 532 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); 533 shouldThrow(); 534 } catch (NullPointerException success) { 535 } finally { 536 joinPool(e); 537 } 538 } 539 540 /** 541 * get of returned element of invokeAll(c) throws exception on failed task 542 */ testTimedInvokeAll4()543 public void testTimedInvokeAll4() throws Exception { 544 ExecutorService e = new DirectExecutorService(); 545 try { 546 List<Callable<String>> l = new ArrayList<Callable<String>>(); 547 l.add(new NPETask()); 548 List<Future<String>> futures = 549 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); 550 assertEquals(1, futures.size()); 551 try { 552 futures.get(0).get(); 553 shouldThrow(); 554 } catch (ExecutionException success) { 555 assertTrue(success.getCause() instanceof NullPointerException); 556 } 557 } finally { 558 joinPool(e); 559 } 560 } 561 562 /** 563 * timed invokeAll(c) returns results of all completed tasks in c 564 */ testTimedInvokeAll5()565 public void testTimedInvokeAll5() throws Exception { 566 ExecutorService e = new DirectExecutorService(); 567 try { 568 List<Callable<String>> l = new ArrayList<Callable<String>>(); 569 l.add(new StringTask()); 570 l.add(new StringTask()); 571 List<Future<String>> futures = 572 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); 573 assertEquals(2, futures.size()); 574 for (Future<String> future : futures) 575 assertSame(TEST_STRING, future.get()); 576 } finally { 577 joinPool(e); 578 } 579 } 580 581 /** 582 * timed invokeAll cancels tasks not completed by timeout 583 */ testTimedInvokeAll6()584 public void testTimedInvokeAll6() throws InterruptedException { 585 ExecutorService e = new DirectExecutorService(); 586 try { 587 List<Callable<String>> l = new ArrayList<Callable<String>>(); 588 l.add(new StringTask()); 589 l.add(Executors.callable(possiblyInterruptedRunnable(2 * SHORT_DELAY_MS), TEST_STRING)); 590 l.add(new StringTask()); 591 List<Future<String>> futures = 592 e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS); 593 assertEquals(l.size(), futures.size()); 594 for (Future future : futures) 595 assertTrue(future.isDone()); 596 assertFalse(futures.get(0).isCancelled()); 597 assertFalse(futures.get(1).isCancelled()); 598 assertTrue(futures.get(2).isCancelled()); 599 } finally { 600 joinPool(e); 601 } 602 } 603 604 } 605