TimerTaskTest.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
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.TestTargetNew;
21import dalvik.annotation.TestTargets;
22import dalvik.annotation.TestLevel;
23import dalvik.annotation.TestTargetClass;
24
25import java.util.Timer;
26import java.util.TimerTask;
27
28@TestTargetClass(TimerTask.class)
29public class TimerTaskTest extends junit.framework.TestCase {
30    Object sync = new Object(), start = 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        private int wasRun = 0;
38
39        // Set this to true to see normal tests fail (or hang possibly)
40        // The default is false and needs to be set by some tests
41        private boolean sleepInRun = false;
42
43        public void run() {
44            synchronized (this) {
45                wasRun++;
46            }
47            synchronized (start) {
48                start.notify();
49            }
50            if (sleepInRun) {
51
52                try {
53                    Thread.sleep(200);
54                } catch (InterruptedException e) {
55                }
56            }
57            synchronized (sync) {
58                sync.notify();
59            }
60        }
61
62        public synchronized int wasRun() {
63            return wasRun;
64        }
65
66        public void sleepInRun(boolean value) {
67            sleepInRun = value;
68        }
69    }
70
71    /**
72     * @tests java.util.TimerTask#TimerTask()
73     */
74    @TestTargetNew(
75        level = TestLevel.COMPLETE,
76        notes = "",
77        method = "TimerTask",
78        args = {}
79    )
80    public void test_Constructor() {
81        // Ensure the constructor does not fail
82        new TimerTestTask();
83    }
84
85    /**
86     * @tests java.util.TimerTask#cancel()
87     */
88    @TestTargetNew(
89        level = TestLevel.COMPLETE,
90        notes = "",
91        method = "cancel",
92        args = {}
93    )
94    public void test_cancel() {
95        Timer t = null;
96        try {
97            // Ensure cancel returns false if never scheduled
98            TimerTestTask testTask = new TimerTestTask();
99            assertTrue("Unsheduled tasks should return false for cancel()",
100                    !testTask.cancel());
101
102            // Ensure cancelled task never runs
103            t = new Timer();
104            testTask = new TimerTestTask();
105            t.schedule(testTask, 500);
106            assertTrue("TimerTask should not have run yet", testTask.cancel());
107            t.cancel();
108
109            // Ensure cancelling a task which has already run returns true
110            t = new Timer();
111            testTask = new TimerTestTask();
112            t.schedule(testTask, 50);
113            while (testTask.wasRun() == 0) {
114                try {
115                    Thread.sleep(150);
116                } catch (InterruptedException e) {
117                }
118            }
119            assertFalse(
120                    "TimerTask.cancel() should return false if task has run",
121                    testTask.cancel());
122            assertFalse(
123                    "TimerTask.cancel() should return false if called a second time",
124                    testTask.cancel());
125            t.cancel();
126
127            // Ensure cancelling a repeated execution task which has never run
128            // returns true
129            t = new Timer();
130            testTask = new TimerTestTask();
131            t.schedule(testTask, 500, 500); // should never run
132            assertTrue(
133                    "TimerTask.cancel() should return true if sheduled for repeated execution even if not run",
134                    testTask.cancel());
135            t.cancel();
136
137            // Ensure cancelling a repeated execution task which HAS run returns
138            // true
139            t = new Timer();
140            testTask = new TimerTestTask();
141            t.schedule(testTask, 50, 50);
142            while (testTask.wasRun() == 0) {
143                try {
144                    Thread.sleep(100);
145                } catch (InterruptedException e) {
146                }
147            }
148            assertTrue(
149                    "TimerTask.cancel() should return true if sheduled for repeated execution and run",
150                    testTask.cancel());
151            t.cancel();
152
153            // Ensure calling cancel a second returns false
154            t = new Timer();
155            testTask = new TimerTestTask();
156            t.schedule(testTask, 5000); // Should never run
157            assertTrue(
158                    "TimerTask.cancel() should return true if task has never run",
159                    testTask.cancel());
160            assertFalse(
161                    "TimerTask.cancel() should return false if called a second time",
162                    testTask.cancel());
163            t.cancel();
164
165            // Ensure cancelling a task won't cause deadlock
166            t = new Timer();
167            testTask = new TimerTestTask();
168            testTask.sleepInRun(true);
169            synchronized (start) {
170                t.schedule(testTask, 0);
171                try {
172                    start.wait();
173                    Thread.sleep(50);
174                } catch (InterruptedException e) {
175                }
176            }
177            assertFalse("TimerTask should have been cancelled", testTask
178                    .cancel());
179            t.cancel();
180        } finally {
181            if (t != null)
182                t.cancel();
183        }
184    }
185
186    /**
187     * @tests java.util.TimerTask#scheduledExecutionTime()
188     */
189    @TestTargetNew(
190        level = TestLevel.COMPLETE,
191        notes = "",
192        method = "scheduledExecutionTime",
193        args = {}
194    )
195    public void test_scheduledExecutionTime() {
196        Timer t = null;
197        try {
198            // Ensure scheduledExecutionTime is roughly right
199            t = new Timer();
200            TimerTestTask testTask = new TimerTestTask();
201            t.schedule(testTask, 100);
202            long time = System.currentTimeMillis() + 100;
203            synchronized (sync) {
204                try {
205                    sync.wait(500);
206                } catch (InterruptedException e) {
207                }
208            }
209            long scheduledExecutionTime = testTask.scheduledExecutionTime();
210            assertTrue(scheduledExecutionTime <= time);
211            t.cancel();
212
213            // Ensure scheduledExecutionTime is the last scheduled time
214            t = new Timer();
215            testTask = new TimerTestTask();
216            t.schedule(testTask, 100, 500);
217            long estNow = System.currentTimeMillis() + 100;
218            // Will wake in 100, and every 500 run again
219            // We want to try to get it after it's run at least once but not
220            // twice
221            synchronized (sync) {
222                try {
223                    sync.wait(500);
224                } catch (InterruptedException e) {
225                }
226            }
227            scheduledExecutionTime = testTask.scheduledExecutionTime();
228            assertTrue(scheduledExecutionTime <= estNow);
229            t.cancel();
230        } finally {
231            if (t != null)
232                t.cancel();
233        }
234
235    }
236
237    /**
238     * @tests java.util.TimerTask#run()
239     */
240    @TestTargetNew(
241        level = TestLevel.COMPLETE,
242        notes = "",
243        method = "run",
244        args = {}
245    )
246    public void test_run() {
247        Timer t = null;
248        try {
249            // Ensure a new task is never run
250            TimerTestTask testTask = new TimerTestTask();
251            try {
252                Thread.sleep(200);
253            } catch (InterruptedException e) {
254            }
255            assertEquals("TimerTask.run() method should not have been called",
256                    0, testTask.wasRun());
257
258            // Ensure a task is run
259            t = new Timer();
260            testTask = new TimerTestTask();
261            t.schedule(testTask, 200);
262            while(testTask.wasRun() < 1) {
263                try {
264                    Thread.sleep(400);
265                } catch (InterruptedException e) {
266                }
267            }
268            assertFalse(testTask.cancel());
269            t.cancel();
270        } finally {
271            if (t != null)
272                t.cancel();
273        }
274
275    }
276}
277