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