/*
* Copyright 2002-2007 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.concurrent;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.core.task.NoOpRunnable;
/**
* @author Rick Evans
* @author Juergen Hoeller
*/
public class ScheduledExecutorFactoryBeanTests extends TestCase {
public void testThrowsExceptionIfPoolSizeIsLessThanZero() throws Exception {
try {
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
factory.setPoolSize(-1);
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
new NoOpScheduledExecutorTask()
});
factory.afterPropertiesSet();
fail("Pool size less than zero");
}
catch (IllegalArgumentException expected) {
}
}
public void testShutdownNowIsPropagatedToTheExecutorOnDestroy() throws Exception {
MockControl mockScheduledExecutorService = MockControl.createNiceControl(ScheduledExecutorService.class);
final ScheduledExecutorService executor = (ScheduledExecutorService) mockScheduledExecutorService.getMock();
executor.shutdownNow();
mockScheduledExecutorService.setReturnValue(null);
mockScheduledExecutorService.replay();
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
return executor;
}
};
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
new NoOpScheduledExecutorTask()
});
factory.afterPropertiesSet();
factory.destroy();
mockScheduledExecutorService.verify();
}
public void testShutdownIsPropagatedToTheExecutorOnDestroy() throws Exception {
MockControl mockScheduledExecutorService = MockControl.createNiceControl(ScheduledExecutorService.class);
final ScheduledExecutorService executor = (ScheduledExecutorService) mockScheduledExecutorService.getMock();
executor.shutdown();
mockScheduledExecutorService.setVoidCallable();
mockScheduledExecutorService.replay();
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
return executor;
}
};
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
new NoOpScheduledExecutorTask()
});
factory.setWaitForTasksToCompleteOnShutdown(true);
factory.afterPropertiesSet();
factory.destroy();
mockScheduledExecutorService.verify();
}
public void testOneTimeExecutionIsSetUpAndFiresCorrectly() throws Exception {
MockControl mockRunnable = MockControl.createControl(Runnable.class);
Runnable runnable = (Runnable) mockRunnable.getMock();
runnable.run();
mockRunnable.setVoidCallable();
mockRunnable.replay();
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
new ScheduledExecutorTask(runnable)
});
factory.afterPropertiesSet();
pauseToLetTaskStart(1);
factory.destroy();
mockRunnable.verify();
}
public void testFixedRepeatedExecutionIsSetUpAndFiresCorrectly() throws Exception {
MockControl mockRunnable = MockControl.createControl(Runnable.class);
Runnable runnable = (Runnable) mockRunnable.getMock();
runnable.run();
mockRunnable.setVoidCallable();
runnable.run();
mockRunnable.setVoidCallable();
mockRunnable.replay();
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
task.setPeriod(500);
task.setFixedRate(true);
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{task});
factory.afterPropertiesSet();
pauseToLetTaskStart(2);
factory.destroy();
mockRunnable.verify();
}
public void testFixedRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() throws Exception {
MockControl mockRunnable = MockControl.createControl(Runnable.class);
Runnable runnable = (Runnable) mockRunnable.getMock();
runnable.run();
mockRunnable.setThrowable(new IllegalStateException());
runnable.run();
mockRunnable.setThrowable(new IllegalStateException());
mockRunnable.replay();
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
task.setPeriod(500);
task.setFixedRate(true);
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{task});
factory.setContinueScheduledExecutionAfterException(true);
factory.afterPropertiesSet();
pauseToLetTaskStart(2);
factory.destroy();
mockRunnable.verify();
}
public void testWithInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectly() throws Exception {
MockControl mockRunnable = MockControl.createControl(Runnable.class);
Runnable runnable = (Runnable) mockRunnable.getMock();
runnable.run();
mockRunnable.setVoidCallable();
runnable.run();
mockRunnable.setVoidCallable();
mockRunnable.replay();
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
task.setPeriod(500);
task.setDelay(3000); // nice long wait...
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[] {task});
factory.afterPropertiesSet();
pauseToLetTaskStart(1);
// invoke destroy before tasks have even been scheduled...
factory.destroy();
try {
mockRunnable.verify();
fail("Mock must never have been called");
}
catch (AssertionFailedError expected) {
}
}
public void testWithInitialDelayRepeatedExecutionIsSetUpAndFiresCorrectlyAfterException() throws Exception {
MockControl mockRunnable = MockControl.createControl(Runnable.class);
Runnable runnable = (Runnable) mockRunnable.getMock();
runnable.run();
mockRunnable.setThrowable(new IllegalStateException());
runnable.run();
mockRunnable.setThrowable(new IllegalStateException());
mockRunnable.replay();
ScheduledExecutorTask task = new ScheduledExecutorTask(runnable);
task.setPeriod(500);
task.setDelay(3000); // nice long wait...
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[] {task});
factory.setContinueScheduledExecutionAfterException(true);
factory.afterPropertiesSet();
pauseToLetTaskStart(1);
// invoke destroy before tasks have even been scheduled...
factory.destroy();
try {
mockRunnable.verify();
fail("Mock must never have been called");
}
catch (AssertionFailedError expected) {
}
}
public void testSettingThreadFactoryToNullForcesUseOfDefaultButIsOtherwiseCool() throws Exception {
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
assertNotNull("Bah; the setThreadFactory(..) method must use a default ThreadFactory if a null arg is passed in.");
return super.createExecutor(poolSize, threadFactory, rejectedExecutionHandler);
}
};
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
new NoOpScheduledExecutorTask()
});
factory.setThreadFactory(null); // the null must not propagate
factory.afterPropertiesSet();
factory.destroy();
}
public void testSettingRejectedExecutionHandlerToNullForcesUseOfDefaultButIsOtherwiseCool() throws Exception {
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean() {
protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
assertNotNull("Bah; the setRejectedExecutionHandler(..) method must use a default RejectedExecutionHandler if a null arg is passed in.");
return super.createExecutor(poolSize, threadFactory, rejectedExecutionHandler);
}
};
factory.setScheduledExecutorTasks(new ScheduledExecutorTask[]{
new NoOpScheduledExecutorTask()
});
factory.setRejectedExecutionHandler(null); // the null must not propagate
factory.afterPropertiesSet();
factory.destroy();
}
public void testObjectTypeReportsCorrectType() throws Exception {
ScheduledExecutorFactoryBean factory = new ScheduledExecutorFactoryBean();
assertEquals(ScheduledExecutorService.class, factory.getObjectType());
}
private static void pauseToLetTaskStart(int seconds) {
try {
Thread.sleep(seconds * 1000);
}
catch (InterruptedException ignored) {
}
}
private static class NoOpScheduledExecutorTask extends ScheduledExecutorTask {
public NoOpScheduledExecutorTask() {
super(new NoOpRunnable());
}
}
}