1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package tests.api.java.util; 19 20 import java.lang.Thread.UncaughtExceptionHandler; 21 import java.util.Date; 22 import java.util.Timer; 23 import java.util.TimerTask; 24 import java.util.concurrent.atomic.AtomicReference; 25 26 public class TimerTest extends junit.framework.TestCase { 27 28 int timerCounter = 0; 29 30 Object sync = new Object(); 31 32 /** 33 * Warning: These tests have the possibility to leave a VM hanging if the 34 * Timer is not cancelled. 35 */ 36 class TimerTestTask extends TimerTask { 37 int wasRun = 0; 38 39 // Should we sleep for 200 ms each run()? 40 boolean sleepInRun = false; 41 42 // Should we increment the timerCounter? 43 boolean incrementCount = false; 44 45 // Should we terminate the timer at a specific timerCounter? 46 int terminateCount = -1; 47 48 // The timer we belong to 49 Timer timer = null; 50 51 public TimerTestTask() { 52 } 53 54 public TimerTestTask(Timer t) { 55 timer = t; 56 } 57 58 public void run() { 59 synchronized (this) { 60 wasRun++; 61 } 62 if (incrementCount) 63 timerCounter++; 64 if (terminateCount == timerCounter && timer != null) 65 timer.cancel(); 66 if (sleepInRun) { 67 try { 68 Thread.sleep(200); 69 } catch (InterruptedException e) { 70 } 71 } 72 synchronized (sync) { 73 sync.notify(); 74 } 75 } 76 77 public synchronized int wasRun() { 78 return wasRun; 79 } 80 81 public void sleepInRun(boolean sleepInRun) { 82 this.sleepInRun = sleepInRun; 83 } 84 85 public void incrementCount(boolean incrementCount) { 86 this.incrementCount = incrementCount; 87 } 88 89 public void terminateCount(int terminateCount) { 90 this.terminateCount = terminateCount; 91 } 92 } 93 94 private void awaitRun(TimerTestTask task) { 95 while (task.wasRun() == 0) { 96 try { 97 Thread.sleep(150); 98 } catch (InterruptedException e) { 99 } 100 } 101 } 102 103 /** 104 * java.util.Timer#Timer(boolean) 105 */ 106 public void test_ConstructorZ() { 107 Timer t = null; 108 try { 109 // Ensure a task is run 110 t = new Timer(true); 111 TimerTestTask testTask = new TimerTestTask(); 112 t.schedule(testTask, 200); 113 awaitRun(testTask); 114 t.cancel(); 115 } finally { 116 if (t != null) 117 t.cancel(); 118 } 119 120 } 121 122 /** 123 * java.util.Timer#Timer() 124 */ 125 public void test_Constructor() { 126 Timer t = null; 127 try { 128 // Ensure a task is run 129 t = new Timer(); 130 TimerTestTask testTask = new TimerTestTask(); 131 t.schedule(testTask, 200); 132 awaitRun(testTask); 133 t.cancel(); 134 } finally { 135 if (t != null) 136 t.cancel(); 137 } 138 139 } 140 141 /** 142 * java.util.Timer#Timer(String, boolean) 143 */ 144 public void test_ConstructorSZ() { 145 Timer t = null; 146 try { 147 // Ensure a task is run 148 t = new Timer("test_ConstructorSZThread", true); 149 TimerTestTask testTask = new TimerTestTask(); 150 t.schedule(testTask, 200); 151 awaitRun(testTask); 152 t.cancel(); 153 } finally { 154 if (t != null) 155 t.cancel(); 156 } 157 158 try { 159 new Timer(null, true); 160 fail("NullPointerException expected"); 161 } catch (NullPointerException e) { 162 //expected 163 } 164 165 try { 166 new Timer(null, false); 167 fail("NullPointerException expected"); 168 } catch (NullPointerException e) { 169 //expected 170 } 171 } 172 173 /** 174 * java.util.Timer#Timer(String) 175 */ 176 public void test_ConstructorS() { 177 Timer t = null; 178 try { 179 // Ensure a task is run 180 t = new Timer("test_ConstructorSThread"); 181 TimerTestTask testTask = new TimerTestTask(); 182 t.schedule(testTask, 200); 183 awaitRun(testTask); 184 t.cancel(); 185 } finally { 186 if (t != null) 187 t.cancel(); 188 } 189 190 try { 191 new Timer(null); 192 fail("NullPointerException expected"); 193 } catch (NullPointerException e) { 194 //expected 195 } 196 } 197 198 /** 199 * java.util.Timer#cancel() 200 */ 201 public void test_cancel() { 202 Timer t = null; 203 try { 204 // Ensure a task throws an IllegalStateException after cancelled 205 t = new Timer(); 206 TimerTestTask testTask = new TimerTestTask(); 207 t.cancel(); 208 boolean exception = false; 209 try { 210 t.schedule(testTask, 100, 200); 211 } catch (IllegalStateException e) { 212 exception = true; 213 } 214 assertTrue( 215 "Scheduling a task after Timer.cancel() should throw exception", 216 exception); 217 218 // Ensure a task is run but not after cancel 219 t = new Timer(); 220 testTask = new TimerTestTask(); 221 t.schedule(testTask, 100, 500); 222 awaitRun(testTask); 223 t.cancel(); 224 synchronized (sync) { 225 try { 226 sync.wait(500); 227 } catch (InterruptedException e) { 228 } 229 } 230 assertEquals("TimerTask.run() method should not have been called after cancel", 231 1, testTask.wasRun()); 232 233 // Ensure you can call cancel more than once 234 t = new Timer(); 235 testTask = new TimerTestTask(); 236 t.schedule(testTask, 100, 500); 237 awaitRun(testTask); 238 t.cancel(); 239 t.cancel(); 240 t.cancel(); 241 synchronized (sync) { 242 try { 243 sync.wait(500); 244 } catch (InterruptedException e) { 245 } 246 } 247 assertEquals("TimerTask.run() method should not have been called after cancel", 248 1, testTask.wasRun()); 249 250 // Ensure that a call to cancel from within a timer ensures no more 251 // run 252 t = new Timer(); 253 testTask = new TimerTestTask(t); 254 testTask.incrementCount(true); 255 testTask.terminateCount(5); // Terminate after 5 runs 256 t.schedule(testTask, 100, 100); 257 synchronized (sync) { 258 try { 259 sync.wait(200); 260 sync.wait(200); 261 sync.wait(200); 262 sync.wait(200); 263 sync.wait(200); 264 sync.wait(200); 265 } catch (InterruptedException e) { 266 } 267 } 268 assertTrue("TimerTask.run() method should be called 5 times not " 269 + testTask.wasRun(), testTask.wasRun() == 5); 270 t.cancel(); 271 try { 272 Thread.sleep(200); 273 } catch (InterruptedException e) { 274 } 275 } finally { 276 if (t != null) 277 t.cancel(); 278 } 279 280 } 281 282 /** 283 * java.util.Timer#purge() 284 */ 285 public void test_purge() throws Exception { 286 Timer t = null; 287 try { 288 t = new Timer(); 289 assertEquals(0, t.purge()); 290 291 TimerTestTask[] tasks = new TimerTestTask[100]; 292 int[] delayTime = { 50, 80, 20, 70, 40, 10, 90, 30, 60 }; 293 294 int j = 0; 295 for (int i = 0; i < 100; i++) { 296 tasks[i] = new TimerTestTask(); 297 t.schedule(tasks[i], delayTime[j++], 200); 298 if (j == 9) { 299 j = 0; 300 } 301 } 302 303 for (int i = 0; i < 50; i++) { 304 tasks[i].cancel(); 305 } 306 307 assertTrue(t.purge() <= 50); 308 assertEquals(0, t.purge()); 309 } finally { 310 if (t != null) { 311 t.cancel(); 312 } 313 } 314 } 315 316 /** 317 * java.util.Timer#schedule(java.util.TimerTask, java.util.Date) 318 */ 319 public void test_scheduleLjava_util_TimerTaskLjava_util_Date() { 320 Timer t = null; 321 try { 322 // Ensure a Timer throws an IllegalStateException after cancelled 323 t = new Timer(); 324 TimerTestTask testTask = new TimerTestTask(); 325 Date d = new Date(System.currentTimeMillis() + 100); 326 t.cancel(); 327 boolean exception = false; 328 try { 329 t.schedule(testTask, d); 330 } catch (IllegalStateException e) { 331 exception = true; 332 } 333 assertTrue( 334 "Scheduling a task after Timer.cancel() should throw exception", 335 exception); 336 337 // Ensure a Timer throws an IllegalStateException if task already 338 // cancelled 339 t = new Timer(); 340 testTask = new TimerTestTask(); 341 d = new Date(System.currentTimeMillis() + 100); 342 testTask.cancel(); 343 exception = false; 344 try { 345 t.schedule(testTask, d); 346 } catch (IllegalStateException e) { 347 exception = true; 348 } 349 assertTrue( 350 "Scheduling a task after cancelling it should throw exception", 351 exception); 352 t.cancel(); 353 354 // Ensure a Timer throws an IllegalArgumentException if delay is 355 // negative 356 t = new Timer(); 357 testTask = new TimerTestTask(); 358 d = new Date(-100); 359 exception = false; 360 try { 361 t.schedule(testTask, d); 362 } catch (IllegalArgumentException e) { 363 exception = true; 364 } 365 assertTrue( 366 "Scheduling a task with negative date should throw IllegalArgumentException", 367 exception); 368 t.cancel(); 369 370 // Ensure a Timer throws a NullPointerException if the task is null 371 t = new Timer(); 372 exception = false; 373 d = new Date(System.currentTimeMillis() + 100); 374 try { 375 t.schedule(null, d); 376 } catch (NullPointerException e) { 377 exception = true; 378 } 379 assertTrue( 380 "Scheduling a null task should throw NullPointerException", 381 exception); 382 t.cancel(); 383 384 // Ensure a Timer throws a NullPointerException if the date is null 385 t = new Timer(); 386 testTask = new TimerTestTask(); 387 exception = false; 388 try { 389 t.schedule(testTask, null); 390 } catch (NullPointerException e) { 391 exception = true; 392 } 393 assertTrue( 394 "Scheduling a null date should throw NullPointerException", 395 exception); 396 t.cancel(); 397 398 // Ensure proper sequence of exceptions 399 t = new Timer(); 400 d = new Date(-100); 401 exception = false; 402 try { 403 t.schedule(null, d); 404 } catch (NullPointerException e) { 405 } catch (IllegalArgumentException e) { 406 exception = true; 407 } 408 assertTrue( 409 "Scheduling a null task with negative date should throw IllegalArgumentException first", 410 exception); 411 t.cancel(); 412 413 // Ensure a task is run 414 t = new Timer(); 415 testTask = new TimerTestTask(); 416 d = new Date(System.currentTimeMillis() + 200); 417 t.schedule(testTask, d); 418 awaitRun(testTask); 419 t.cancel(); 420 421 // Ensure multiple tasks are run 422 t = new Timer(); 423 testTask = new TimerTestTask(); 424 testTask.incrementCount(true); 425 d = new Date(System.currentTimeMillis() + 100); 426 t.schedule(testTask, d); 427 testTask = new TimerTestTask(); 428 testTask.incrementCount(true); 429 d = new Date(System.currentTimeMillis() + 150); 430 t.schedule(testTask, d); 431 testTask = new TimerTestTask(); 432 testTask.incrementCount(true); 433 d = new Date(System.currentTimeMillis() + 70); 434 t.schedule(testTask, d); 435 testTask = new TimerTestTask(); 436 testTask.incrementCount(true); 437 d = new Date(System.currentTimeMillis() + 10); 438 t.schedule(testTask, d); 439 try { 440 Thread.sleep(400); 441 } catch (InterruptedException e) { 442 } 443 assertTrue( 444 "Multiple tasks should have incremented counter 4 times not " 445 + timerCounter, timerCounter == 4); 446 t.cancel(); 447 } finally { 448 if (t != null) 449 t.cancel(); 450 } 451 } 452 453 /** 454 * java.util.Timer#schedule(java.util.TimerTask, long) 455 */ 456 public void test_scheduleLjava_util_TimerTaskJ() { 457 Timer t = null; 458 try { 459 // Ensure a Timer throws an IllegalStateException after cancelled 460 t = new Timer(); 461 TimerTestTask testTask = new TimerTestTask(); 462 t.cancel(); 463 boolean exception = false; 464 try { 465 t.schedule(testTask, 100); 466 } catch (IllegalStateException e) { 467 exception = true; 468 } 469 assertTrue( 470 "Scheduling a task after Timer.cancel() should throw exception", 471 exception); 472 473 // Ensure a Timer throws an IllegalStateException if task already 474 // cancelled 475 t = new Timer(); 476 testTask = new TimerTestTask(); 477 testTask.cancel(); 478 exception = false; 479 try { 480 t.schedule(testTask, 100); 481 } catch (IllegalStateException e) { 482 exception = true; 483 } 484 assertTrue( 485 "Scheduling a task after cancelling it should throw exception", 486 exception); 487 t.cancel(); 488 489 // Ensure a Timer throws an IllegalArgumentException if delay is 490 // negative 491 t = new Timer(); 492 testTask = new TimerTestTask(); 493 exception = false; 494 try { 495 t.schedule(testTask, -100); 496 } catch (IllegalArgumentException e) { 497 exception = true; 498 } 499 assertTrue( 500 "Scheduling a task with negative delay should throw IllegalArgumentException", 501 exception); 502 t.cancel(); 503 504 // Ensure a Timer throws a NullPointerException if the task is null 505 t = new Timer(); 506 exception = false; 507 try { 508 t.schedule(null, 10); 509 } catch (NullPointerException e) { 510 exception = true; 511 } 512 assertTrue( 513 "Scheduling a null task should throw NullPointerException", 514 exception); 515 t.cancel(); 516 517 // Ensure proper sequence of exceptions 518 t = new Timer(); 519 exception = false; 520 try { 521 t.schedule(null, -10); 522 } catch (NullPointerException e) { 523 } catch (IllegalArgumentException e) { 524 exception = true; 525 } 526 assertTrue( 527 "Scheduling a null task with negative delays should throw IllegalArgumentException first", 528 exception); 529 t.cancel(); 530 531 // Ensure a task is run 532 t = new Timer(); 533 testTask = new TimerTestTask(); 534 t.schedule(testTask, 200); 535 awaitRun(testTask); 536 t.cancel(); 537 538 // Ensure multiple tasks are run 539 t = new Timer(); 540 testTask = new TimerTestTask(); 541 testTask.incrementCount(true); 542 t.schedule(testTask, 100); 543 testTask = new TimerTestTask(); 544 testTask.incrementCount(true); 545 t.schedule(testTask, 150); 546 testTask = new TimerTestTask(); 547 testTask.incrementCount(true); 548 t.schedule(testTask, 70); 549 testTask = new TimerTestTask(); 550 testTask.incrementCount(true); 551 t.schedule(testTask, 10); 552 try { 553 Thread.sleep(400); 554 } catch (InterruptedException e) { 555 } 556 assertTrue( 557 "Multiple tasks should have incremented counter 4 times not " 558 + timerCounter, timerCounter == 4); 559 t.cancel(); 560 } finally { 561 if (t != null) 562 t.cancel(); 563 } 564 } 565 566 /** 567 * java.util.Timer#schedule(java.util.TimerTask, long, long) 568 */ 569 public void test_scheduleLjava_util_TimerTaskJJ() { 570 Timer t = null; 571 try { 572 // Ensure a Timer throws an IllegalStateException after cancelled 573 t = new Timer(); 574 TimerTestTask testTask = new TimerTestTask(); 575 t.cancel(); 576 boolean exception = false; 577 try { 578 t.schedule(testTask, 100, 100); 579 } catch (IllegalStateException e) { 580 exception = true; 581 } 582 assertTrue( 583 "Scheduling a task after Timer.cancel() should throw exception", 584 exception); 585 586 // Ensure a Timer throws an IllegalStateException if task already 587 // cancelled 588 t = new Timer(); 589 testTask = new TimerTestTask(); 590 testTask.cancel(); 591 exception = false; 592 try { 593 t.schedule(testTask, 100, 100); 594 } catch (IllegalStateException e) { 595 exception = true; 596 } 597 assertTrue( 598 "Scheduling a task after cancelling it should throw exception", 599 exception); 600 t.cancel(); 601 602 // Ensure a Timer throws an IllegalArgumentException if delay is 603 // negative 604 t = new Timer(); 605 testTask = new TimerTestTask(); 606 exception = false; 607 try { 608 t.schedule(testTask, -100, 100); 609 } catch (IllegalArgumentException e) { 610 exception = true; 611 } 612 assertTrue( 613 "Scheduling a task with negative delay should throw IllegalArgumentException", 614 exception); 615 t.cancel(); 616 617 // Ensure a Timer throws an IllegalArgumentException if period is 618 // negative 619 t = new Timer(); 620 testTask = new TimerTestTask(); 621 exception = false; 622 try { 623 t.schedule(testTask, 100, -100); 624 } catch (IllegalArgumentException e) { 625 exception = true; 626 } 627 assertTrue( 628 "Scheduling a task with negative period should throw IllegalArgumentException", 629 exception); 630 t.cancel(); 631 632 // Ensure a Timer throws an IllegalArgumentException if period is 633 // zero 634 t = new Timer(); 635 testTask = new TimerTestTask(); 636 exception = false; 637 try { 638 t.schedule(testTask, 100, 0); 639 } catch (IllegalArgumentException e) { 640 exception = true; 641 } 642 assertTrue( 643 "Scheduling a task with 0 period should throw IllegalArgumentException", 644 exception); 645 t.cancel(); 646 647 // Ensure a Timer throws a NullPointerException if the task is null 648 t = new Timer(); 649 exception = false; 650 try { 651 t.schedule(null, 10, 10); 652 } catch (NullPointerException e) { 653 exception = true; 654 } 655 assertTrue( 656 "Scheduling a null task should throw NullPointerException", 657 exception); 658 t.cancel(); 659 660 // Ensure proper sequence of exceptions 661 t = new Timer(); 662 exception = false; 663 try { 664 t.schedule(null, -10, -10); 665 } catch (NullPointerException e) { 666 } catch (IllegalArgumentException e) { 667 exception = true; 668 } 669 assertTrue( 670 "Scheduling a null task with negative delays should throw IllegalArgumentException first", 671 exception); 672 t.cancel(); 673 674 // Ensure a task is run at least twice 675 t = new Timer(); 676 testTask = new TimerTestTask(); 677 t.schedule(testTask, 100, 100); 678 try { 679 Thread.sleep(400); 680 } catch (InterruptedException e) { 681 } 682 assertTrue( 683 "TimerTask.run() method should have been called at least twice (" 684 + testTask.wasRun() + ")", testTask.wasRun() >= 2); 685 t.cancel(); 686 687 // Ensure multiple tasks are run 688 t = new Timer(); 689 testTask = new TimerTestTask(); 690 testTask.incrementCount(true); 691 t.schedule(testTask, 100, 100); // at least 9 times 692 testTask = new TimerTestTask(); 693 testTask.incrementCount(true); 694 t.schedule(testTask, 200, 100); // at least 7 times 695 testTask = new TimerTestTask(); 696 testTask.incrementCount(true); 697 t.schedule(testTask, 300, 200); // at least 4 times 698 testTask = new TimerTestTask(); 699 testTask.incrementCount(true); 700 t.schedule(testTask, 100, 200); // at least 4 times 701 try { 702 Thread.sleep(1200); // Allowed more room for error 703 } catch (InterruptedException e) { 704 } 705 assertTrue( 706 "Multiple tasks should have incremented counter 24 times not " 707 + timerCounter, timerCounter >= 24); 708 t.cancel(); 709 } finally { 710 if (t != null) 711 t.cancel(); 712 } 713 } 714 715 /** 716 * java.util.Timer#schedule(java.util.TimerTask, java.util.Date, 717 * long) 718 */ 719 public void test_scheduleLjava_util_TimerTaskLjava_util_DateJ() { 720 Timer t = null; 721 try { 722 // Ensure a Timer throws an IllegalStateException after cancelled 723 t = new Timer(); 724 TimerTestTask testTask = new TimerTestTask(); 725 Date d = new Date(System.currentTimeMillis() + 100); 726 t.cancel(); 727 boolean exception = false; 728 try { 729 t.schedule(testTask, d, 100); 730 } catch (IllegalStateException e) { 731 exception = true; 732 } 733 assertTrue( 734 "Scheduling a task after Timer.cancel() should throw exception", 735 exception); 736 737 // Ensure a Timer throws an IllegalStateException if task already 738 // cancelled 739 t = new Timer(); 740 d = new Date(System.currentTimeMillis() + 100); 741 testTask = new TimerTestTask(); 742 testTask.cancel(); 743 exception = false; 744 try { 745 t.schedule(testTask, d, 100); 746 } catch (IllegalStateException e) { 747 exception = true; 748 } 749 assertTrue( 750 "Scheduling a task after cancelling it should throw exception", 751 exception); 752 t.cancel(); 753 754 // Ensure a Timer throws an IllegalArgumentException if delay is 755 // negative 756 t = new Timer(); 757 d = new Date(-100); 758 testTask = new TimerTestTask(); 759 exception = false; 760 try { 761 t.schedule(testTask, d, 100); 762 } catch (IllegalArgumentException e) { 763 exception = true; 764 } 765 assertTrue( 766 "Scheduling a task with negative delay should throw IllegalArgumentException", 767 exception); 768 t.cancel(); 769 770 // Ensure a Timer throws an IllegalArgumentException if period is 771 // negative 772 t = new Timer(); 773 d = new Date(System.currentTimeMillis() + 100); 774 testTask = new TimerTestTask(); 775 exception = false; 776 try { 777 t.schedule(testTask, d, -100); 778 } catch (IllegalArgumentException e) { 779 exception = true; 780 } 781 assertTrue( 782 "Scheduling a task with negative period should throw IllegalArgumentException", 783 exception); 784 t.cancel(); 785 786 // Ensure a Timer throws a NullPointerException if the task is null 787 t = new Timer(); 788 d = new Date(System.currentTimeMillis() + 100); 789 exception = false; 790 try { 791 t.schedule(null, d, 10); 792 } catch (NullPointerException e) { 793 exception = true; 794 } 795 assertTrue( 796 "Scheduling a null task should throw NullPointerException", 797 exception); 798 t.cancel(); 799 800 // Ensure a Timer throws a NullPointerException if the date is null 801 t = new Timer(); 802 testTask = new TimerTestTask(); 803 exception = false; 804 try { 805 t.schedule(testTask, null, 10); 806 } catch (NullPointerException e) { 807 exception = true; 808 } 809 assertTrue( 810 "Scheduling a null task should throw NullPointerException", 811 exception); 812 t.cancel(); 813 814 // Ensure proper sequence of exceptions 815 t = new Timer(); 816 d = new Date(-100); 817 exception = false; 818 try { 819 t.schedule(null, d, 10); 820 } catch (NullPointerException e) { 821 } catch (IllegalArgumentException e) { 822 exception = true; 823 } 824 assertTrue( 825 "Scheduling a null task with negative dates should throw IllegalArgumentException first", 826 exception); 827 t.cancel(); 828 829 // Ensure a task is run at least twice 830 t = new Timer(); 831 d = new Date(System.currentTimeMillis() + 100); 832 testTask = new TimerTestTask(); 833 t.schedule(testTask, d, 100); 834 try { 835 Thread.sleep(800); 836 } catch (InterruptedException e) { 837 } 838 assertTrue( 839 "TimerTask.run() method should have been called at least twice (" 840 + testTask.wasRun() + ")", testTask.wasRun() >= 2); 841 t.cancel(); 842 843 // Ensure multiple tasks are run 844 t = new Timer(); 845 testTask = new TimerTestTask(); 846 testTask.incrementCount(true); 847 d = new Date(System.currentTimeMillis() + 100); 848 t.schedule(testTask, d, 100); // at least 9 times 849 testTask = new TimerTestTask(); 850 testTask.incrementCount(true); 851 d = new Date(System.currentTimeMillis() + 200); 852 t.schedule(testTask, d, 100); // at least 7 times 853 testTask = new TimerTestTask(); 854 testTask.incrementCount(true); 855 d = new Date(System.currentTimeMillis() + 300); 856 t.schedule(testTask, d, 200); // at least 4 times 857 testTask = new TimerTestTask(); 858 testTask.incrementCount(true); 859 d = new Date(System.currentTimeMillis() + 100); 860 t.schedule(testTask, d, 200); // at least 4 times 861 try { 862 Thread.sleep(3000); 863 } catch (InterruptedException e) { 864 } 865 assertTrue( 866 "Multiple tasks should have incremented counter 24 times not " 867 + timerCounter, timerCounter >= 24); 868 t.cancel(); 869 } finally { 870 if (t != null) 871 t.cancel(); 872 } 873 } 874 875 /** 876 * java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long, 877 * long) 878 */ 879 public void test_scheduleAtFixedRateLjava_util_TimerTaskJJ() { 880 Timer t = null; 881 try { 882 // Ensure a Timer throws an IllegalStateException after cancelled 883 t = new Timer(); 884 TimerTestTask testTask = new TimerTestTask(); 885 t.cancel(); 886 boolean exception = false; 887 try { 888 t.scheduleAtFixedRate(testTask, 100, 100); 889 } catch (IllegalStateException e) { 890 exception = true; 891 } 892 assertTrue( 893 "scheduleAtFixedRate after Timer.cancel() should throw exception", 894 exception); 895 896 // Ensure a Timer throws an IllegalArgumentException if delay is 897 // negative 898 t = new Timer(); 899 testTask = new TimerTestTask(); 900 exception = false; 901 try { 902 t.scheduleAtFixedRate(testTask, -100, 100); 903 } catch (IllegalArgumentException e) { 904 exception = true; 905 } 906 assertTrue( 907 "scheduleAtFixedRate with negative delay should throw IllegalArgumentException", 908 exception); 909 t.cancel(); 910 911 // Ensure a Timer throws an IllegalArgumentException if period is 912 // negative 913 t = new Timer(); 914 testTask = new TimerTestTask(); 915 exception = false; 916 try { 917 t.scheduleAtFixedRate(testTask, 100, -100); 918 } catch (IllegalArgumentException e) { 919 exception = true; 920 } 921 assertTrue( 922 "scheduleAtFixedRate with negative period should throw IllegalArgumentException", 923 exception); 924 t.cancel(); 925 926 // Ensure a task is run at least twice 927 t = new Timer(); 928 testTask = new TimerTestTask(); 929 t.scheduleAtFixedRate(testTask, 100, 100); 930 try { 931 Thread.sleep(400); 932 } catch (InterruptedException e) { 933 } 934 assertTrue( 935 "TimerTask.run() method should have been called at least twice (" 936 + testTask.wasRun() + ")", testTask.wasRun() >= 2); 937 t.cancel(); 938 939 class SlowThenFastTask extends TimerTask { 940 int wasRun = 0; 941 942 long startedAt; 943 944 long lastDelta; 945 946 public void run() { 947 if (wasRun == 0) 948 startedAt = System.currentTimeMillis(); 949 lastDelta = System.currentTimeMillis() 950 - (startedAt + (100 * wasRun)); 951 wasRun++; 952 if (wasRun == 2) { 953 try { 954 Thread.sleep(200); 955 } catch (InterruptedException e) { 956 } 957 } 958 } 959 960 public long lastDelta() { 961 return lastDelta; 962 } 963 964 public int wasRun() { 965 return wasRun; 966 } 967 } 968 969 // Ensure multiple tasks are run 970 t = new Timer(); 971 SlowThenFastTask slowThenFastTask = new SlowThenFastTask(); 972 973 // at least 9 times even when asleep 974 t.scheduleAtFixedRate(slowThenFastTask, 100, 100); 975 try { 976 Thread.sleep(1000); 977 } catch (InterruptedException e) { 978 } 979 long lastDelta = slowThenFastTask.lastDelta(); 980 assertTrue("Fixed Rate Schedule should catch up, but is off by " 981 + lastDelta + " ms", slowThenFastTask.lastDelta < 300); 982 t.cancel(); 983 } finally { 984 if (t != null) 985 t.cancel(); 986 } 987 } 988 989 /** 990 * java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, 991 * java.util.Date, long) 992 */ 993 public void test_scheduleAtFixedRateLjava_util_TimerTaskLjava_util_DateJ() { 994 Timer t = null; 995 try { 996 // Ensure a Timer throws an IllegalStateException after cancelled 997 t = new Timer(); 998 TimerTestTask testTask = new TimerTestTask(); 999 t.cancel(); 1000 boolean exception = false; 1001 Date d = new Date(System.currentTimeMillis() + 100); 1002 try { 1003 t.scheduleAtFixedRate(testTask, d, 100); 1004 } catch (IllegalStateException e) { 1005 exception = true; 1006 } 1007 assertTrue( 1008 "scheduleAtFixedRate after Timer.cancel() should throw exception", 1009 exception); 1010 1011 // Ensure a Timer throws an IllegalArgumentException if delay is 1012 // negative 1013 t = new Timer(); 1014 testTask = new TimerTestTask(); 1015 exception = false; 1016 d = new Date(-100); 1017 try { 1018 t.scheduleAtFixedRate(testTask, d, 100); 1019 } catch (IllegalArgumentException e) { 1020 exception = true; 1021 } 1022 assertTrue( 1023 "scheduleAtFixedRate with negative Date should throw IllegalArgumentException", 1024 exception); 1025 t.cancel(); 1026 1027 // Ensure a Timer throws an IllegalArgumentException if period is 1028 // negative 1029 t = new Timer(); 1030 testTask = new TimerTestTask(); 1031 exception = false; 1032 try { 1033 t.scheduleAtFixedRate(testTask, d, -100); 1034 } catch (IllegalArgumentException e) { 1035 exception = true; 1036 } 1037 assertTrue( 1038 "scheduleAtFixedRate with negative period should throw IllegalArgumentException", 1039 exception); 1040 t.cancel(); 1041 1042 // Ensure a Timer throws an NullPointerException if date is Null 1043 t = new Timer(); 1044 testTask = new TimerTestTask(); 1045 exception = false; 1046 try { 1047 t.scheduleAtFixedRate(testTask, null, 100); 1048 } catch (NullPointerException e) { 1049 exception = true; 1050 } 1051 assertTrue( 1052 "scheduleAtFixedRate with null date should throw NullPointerException", 1053 exception); 1054 t.cancel(); 1055 1056 // Ensure proper sequence of exceptions 1057 t = new Timer(); 1058 exception = false; 1059 d = new Date(-100); 1060 try { 1061 t.scheduleAtFixedRate(null, d, 10); 1062 } catch (NullPointerException e) { 1063 } catch (IllegalArgumentException e) { 1064 exception = true; 1065 } 1066 assertTrue( 1067 "Scheduling a null task with negative date should throw IllegalArgumentException first", 1068 exception); 1069 t.cancel(); 1070 1071 // Ensure proper sequence of exceptions 1072 t = new Timer(); 1073 exception = false; 1074 try { 1075 t.scheduleAtFixedRate(null, null, -10); 1076 } catch (NullPointerException e) { 1077 } catch (IllegalArgumentException e) { 1078 exception = true; 1079 } 1080 assertTrue( 1081 "Scheduling a null task & null date & negative period should throw IllegalArgumentException first", 1082 exception); 1083 t.cancel(); 1084 1085 // Ensure a task is run at least twice 1086 t = new Timer(); 1087 testTask = new TimerTestTask(); 1088 d = new Date(System.currentTimeMillis() + 100); 1089 t.scheduleAtFixedRate(testTask, d, 100); 1090 try { 1091 Thread.sleep(400); 1092 } catch (InterruptedException e) { 1093 } 1094 assertTrue( 1095 "TimerTask.run() method should have been called at least twice (" 1096 + testTask.wasRun() + ")", testTask.wasRun() >= 2); 1097 t.cancel(); 1098 1099 class SlowThenFastTask extends TimerTask { 1100 int wasRun = 0; 1101 1102 long startedAt; 1103 1104 long lastDelta; 1105 1106 public void run() { 1107 if (wasRun == 0) 1108 startedAt = System.currentTimeMillis(); 1109 lastDelta = System.currentTimeMillis() 1110 - (startedAt + (100 * wasRun)); 1111 wasRun++; 1112 if (wasRun == 2) { 1113 try { 1114 Thread.sleep(200); 1115 } catch (InterruptedException e) { 1116 } 1117 } 1118 } 1119 1120 public long lastDelta() { 1121 return lastDelta; 1122 } 1123 1124 public int wasRun() { 1125 return wasRun; 1126 } 1127 } 1128 1129 // Ensure multiple tasks are run 1130 t = new Timer(); 1131 SlowThenFastTask slowThenFastTask = new SlowThenFastTask(); 1132 d = new Date(System.currentTimeMillis() + 100); 1133 1134 // at least 9 times even when asleep 1135 t.scheduleAtFixedRate(slowThenFastTask, d, 100); 1136 try { 1137 Thread.sleep(1000); 1138 } catch (InterruptedException e) { 1139 } 1140 long lastDelta = slowThenFastTask.lastDelta(); 1141 assertTrue("Fixed Rate Schedule should catch up, but is off by " 1142 + lastDelta + " ms", lastDelta < 300); 1143 t.cancel(); 1144 } finally { 1145 if (t != null) 1146 t.cancel(); 1147 } 1148 } 1149 1150 /** 1151 * We used to swallow RuntimeExceptions thrown by tasks. Instead, we need to 1152 * let those exceptions bubble up, where they will both notify the thread's 1153 * uncaught exception handler and terminate the timer's thread. 1154 */ 1155 public void testThrowingTaskKillsTimerThread() throws InterruptedException { 1156 final AtomicReference<Thread> threadRef = new AtomicReference<Thread>(); 1157 new Timer().schedule(new TimerTask() { 1158 @Override public void run() { 1159 Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() { 1160 public void uncaughtException(Thread thread, Throwable ex) {} 1161 }); 1162 threadRef.set(Thread.currentThread()); 1163 throw new RuntimeException("task failure!"); 1164 } 1165 }, 1); 1166 1167 Thread.sleep(400); 1168 Thread timerThread = threadRef.get(); 1169 assertFalse(timerThread.isAlive()); 1170 } 1171 1172 protected void setUp() { 1173 timerCounter = 0; 1174 } 1175 1176 protected void tearDown() { 1177 } 1178 } 1179