/* * Copyright 2002-2006 the original author or authors. * * Licensed 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.springframework.scheduling.timer; import junit.framework.TestCase; import org.springframework.test.AssertThrows; import java.util.Timer; /** * Unit tests for the {@link TimerTaskExecutor} class. * * @author Rick Evans */ public final class TimerTaskExecutorTests extends TestCase { public void testExecuteChokesWithNullTimer() throws Exception { new AssertThrows(IllegalArgumentException.class) { public void test() throws Exception { TimerTaskExecutor executor = new TimerTaskExecutor(); executor.execute(new NoOpRunnable()); } }.runTest(); } public void testExecuteChokesWithNullTask() throws Exception { new AssertThrows(IllegalArgumentException.class) { public void test() throws Exception { TimerTaskExecutor executor = new TimerTaskExecutor(new Timer()); executor.execute(null); } }.runTest(); } public void testExecuteChokesWithNegativeDelay() throws Exception { new AssertThrows(IllegalArgumentException.class) { public void test() throws Exception { TimerTaskExecutor executor = new TimerTaskExecutor(new Timer()); executor.setDelay(-10); executor.execute(new NoOpRunnable()); } }.runTest(); } public void testExecuteReallyDoesScheduleTheSuppliedTask() throws Exception { final Object monitor = new Object(); RunAwareRunnable task = new RunAwareRunnable(monitor); TimerTaskExecutor executor = new TimerTaskExecutor(new Timer()); executor.execute(task); synchronized (monitor) { monitor.wait(5000); } assertTrue("Supplied task (a Runnable) is not being invoked.", task.isRunWasCalled()); } public void testCtorWithNullTimer() throws Exception { new AssertThrows(IllegalArgumentException.class) { public void test() throws Exception { new TimerTaskExecutor(null); } }.runTest(); } public void testCreateTimerMethodIsCalledIfNoTimerIsExplicitlySupplied() throws Exception { CreationAwareTimerTaskExecutor executor = new CreationAwareTimerTaskExecutor(); executor.afterPropertiesSet(); assertTrue("If no Timer is set explicitly, then the protected createTimer() " + "method must be called to create the Timer (it obviously isn't being called).", executor.isCreateTimerWasCalled()); } public void testCreateTimerMethodIsNotCalledIfTimerIsExplicitlySupplied() throws Exception { CreationAwareTimerTaskExecutor executor = new CreationAwareTimerTaskExecutor(); executor.setTimer(new Timer()); executor.afterPropertiesSet(); assertFalse("If a Timer is set explicitly, then the protected createTimer() " + "method must not be called to create the Timer (it obviously is being called, in error).", executor.isCreateTimerWasCalled()); } public void testThatTheDestroyCallbackCancelsTheTimerIfNoTimerIsExplicitlySupplied() throws Exception { final CancelAwareTimer timer = new CancelAwareTimer(); TimerTaskExecutor executor = new TimerTaskExecutor() { protected Timer createTimer() { return timer; } }; executor.afterPropertiesSet(); executor.destroy(); assertTrue("When the Timer used is created by the TimerTaskExecutor because " + "no Timer was set explicitly, then the destroy() callback must cancel() said Timer (it obviously isn't doing this).", timer.isCancelWasCalled()); } public void testThatTheDestroyCallbackDoesNotCancelTheTimerIfTheTimerWasSuppliedExplictly() throws Exception { TimerTaskExecutor executor = new TimerTaskExecutor(); CancelAwareTimer timer = new CancelAwareTimer(); executor.setTimer(timer); executor.afterPropertiesSet(); executor.destroy(); assertFalse("When the Timer used is not created by the TimerTaskExecutor because " + "it Timer was set explicitly, then the destroy() callback must NOT cancel() said Timer (it obviously is, in error).", timer.isCancelWasCalled()); } private final static class CreationAwareTimerTaskExecutor extends TimerTaskExecutor { private boolean createTimerWasCalled = false; public boolean isCreateTimerWasCalled() { return this.createTimerWasCalled; } protected Timer createTimer() { this.createTimerWasCalled = true; return super.createTimer(); } } private static class CancelAwareTimer extends Timer { private boolean cancelWasCalled; public boolean isCancelWasCalled() { return this.cancelWasCalled; } public void cancel() { this.cancelWasCalled = true; super.cancel(); } } private static class RunAwareRunnable implements Runnable { private boolean runWasCalled; private final Object monitor; public RunAwareRunnable(Object monitor) { this.monitor = monitor; } public boolean isRunWasCalled() { return this.runWasCalled; } public void run() { this.runWasCalled = true; synchronized (monitor) { monitor.notifyAll(); } } } private static final class NoOpRunnable implements Runnable { public void run() { // explicit no-op } } }