/*
* 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
}
}
}