/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.harmony.tests.java.util; import java.util.Timer; import java.util.TimerTask; public class TimerTaskTest extends junit.framework.TestCase { /** * Warning: These tests have the possibility to leave a VM hanging if the * Timer is not cancelled. */ class TimerTestTask extends TimerTask { private final Object sync = new Object(); private final Object start = new Object(); private int wasRun = 0; // Set this to true to see normal tests fail (or hang possibly) // The default is false and needs to be set by some tests private boolean sleepInRun = false; public void run() { synchronized (this) { wasRun++; } synchronized (start) { start.notify(); } if (sleepInRun) { try { Thread.sleep(200); } catch (InterruptedException e) { } } synchronized (sync) { sync.notify(); } } public synchronized int wasRun() { return wasRun; } public void sleepInRun(boolean value) { sleepInRun = value; } } /** * java.util.TimerTask#TimerTask() */ public void test_Constructor() { // Ensure the constructor does not fail new TimerTestTask(); } /** * java.util.TimerTask#cancel() */ public void test_cancel() { Timer t = null; try { // Ensure cancel returns false if never scheduled TimerTestTask testTask = new TimerTestTask(); assertTrue("Unsheduled tasks should return false for cancel()", !testTask.cancel()); // Ensure cancelled task never runs t = new Timer(); testTask = new TimerTestTask(); t.schedule(testTask, 500); assertTrue("TimerTask should not have run yet", testTask.cancel()); t.cancel(); // Ensure cancelling a task which has already run returns true t = new Timer(); testTask = new TimerTestTask(); t.schedule(testTask, 50); while (testTask.wasRun() == 0) { try { Thread.sleep(150); } catch (InterruptedException e) { } } assertFalse( "TimerTask.cancel() should return false if task has run", testTask.cancel()); assertFalse( "TimerTask.cancel() should return false if called a second time", testTask.cancel()); t.cancel(); // Ensure cancelling a repeated execution task which has never run // returns true t = new Timer(); testTask = new TimerTestTask(); t.schedule(testTask, 500, 500); // should never run assertTrue( "TimerTask.cancel() should return true if sheduled for repeated execution even if not run", testTask.cancel()); t.cancel(); // Ensure cancelling a repeated execution task which HAS run returns // true t = new Timer(); testTask = new TimerTestTask(); t.schedule(testTask, 50, 50); while (testTask.wasRun() == 0) { try { Thread.sleep(100); } catch (InterruptedException e) { } } assertTrue( "TimerTask.cancel() should return true if sheduled for repeated execution and run", testTask.cancel()); t.cancel(); // Ensure calling cancel a second returns false t = new Timer(); testTask = new TimerTestTask(); t.schedule(testTask, 5000); // Should never run assertTrue( "TimerTask.cancel() should return true if task has never run", testTask.cancel()); assertFalse( "TimerTask.cancel() should return false if called a second time", testTask.cancel()); t.cancel(); // Ensure cancelling a task won't cause deadlock t = new Timer(); testTask = new TimerTestTask(); testTask.sleepInRun(true); synchronized (testTask.start) { t.schedule(testTask, 0); try { testTask.start.wait(); Thread.sleep(50); } catch (InterruptedException e) { } } assertFalse("TimerTask should have been cancelled", testTask .cancel()); t.cancel(); } finally { if (t != null) t.cancel(); } } /** * java.util.TimerTask#scheduledExecutionTime() */ public void test_scheduledExecutionTime() { Timer t = null; try { // Ensure scheduledExecutionTime is roughly right t = new Timer(); TimerTestTask testTask = new TimerTestTask(); t.schedule(testTask, 100); long time = System.currentTimeMillis() + 100; synchronized (testTask.sync) { try { testTask.sync.wait(500); } catch (InterruptedException e) { } } long scheduledExecutionTime = testTask.scheduledExecutionTime(); assertTrue(scheduledExecutionTime <= time); t.cancel(); // Ensure scheduledExecutionTime is the last scheduled time t = new Timer(); testTask = new TimerTestTask(); t.schedule(testTask, 100, 500); long estNow = System.currentTimeMillis() + 100; // Will wake in 100, and every 500 run again // We want to try to get it after it's run at least once but not // twice synchronized (testTask.sync) { try { testTask.sync.wait(500); } catch (InterruptedException e) { } } scheduledExecutionTime = testTask.scheduledExecutionTime(); assertTrue(scheduledExecutionTime <= estNow); t.cancel(); } finally { if (t != null) t.cancel(); } } /** * java.util.TimerTask#run() */ public void test_run() { Timer t = null; try { // Ensure a new task is never run TimerTestTask testTask = new TimerTestTask(); try { Thread.sleep(200); } catch (InterruptedException e) { } assertEquals("TimerTask.run() method should not have been called", 0, testTask.wasRun()); // Ensure a task is run t = new Timer(); testTask = new TimerTestTask(); t.schedule(testTask, 200); while(testTask.wasRun() < 1) { try { Thread.sleep(400); } catch (InterruptedException e) { } } assertFalse(testTask.cancel()); t.cancel(); } finally { if (t != null) t.cancel(); } } }