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