/*******************************************************************************
* Copyright (c) 2010-2014 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* SAP AG - initial API and implementation
*******************************************************************************/
package org.eclipse.skalli.core.scheduler;
import java.util.Calendar;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.eclipse.skalli.services.scheduler.RunnableSchedule;
import org.eclipse.skalli.services.scheduler.Schedule;
import org.eclipse.skalli.services.scheduler.Task;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@SuppressWarnings("nls")
public class SchedulerComponentTest {
private static final int TIMEOUT = 10 * 1000;
private SchedulerComponent instance;
@Before
public void setup() {
instance = new SchedulerComponent();
}
@After
public void tearDown() {
if (instance != null) {
instance.deactivate();
}
}
private static class TestRunnable implements Runnable {
int count;
@Override
public void run() {
++count;
}
}
private static class TestRunnableSchedule extends RunnableSchedule {
TestRunnable runnable = new TestRunnable();
public TestRunnableSchedule(Schedule schedule, long now) {
super(schedule, "Test");
setLastCompleted(now);
}
@Override
public boolean isDue(Calendar now) {
return true; // always claim to be due
}
@Override
public void run() {
try {
setLastStarted(getLastCompleted());
runnable.run();
} finally {
setLastCompleted(getLastCompleted() + 1L);
}
}
}
private void waitForExecution(int expectedCountAtLeast, TestRunnable runnable) {
long start = System.currentTimeMillis();
while (runnable.count < expectedCountAtLeast) {
try {
Thread.sleep(5L);
} catch (InterruptedException e) {
Assert.fail(e.getMessage());
}
if (System.currentTimeMillis() > (start + TIMEOUT)) {
Assert.fail("Task was not run, timeout (" + TIMEOUT + "ms) reached");
}
}
}
@Test
public void testRegisterSingleShot() {
TestRunnable testRunnable = new TestRunnable();
Task task = new Task(testRunnable, 0, -1L);
UUID taskId = instance.registerTask(task);
Assert.assertTrue(instance.isRegistered(taskId));
waitForExecution(1, testRunnable);
Assert.assertEquals(1, testRunnable.count); // ensure that the runnable has been called once
Assert.assertTrue(instance.isDone(taskId));
Assert.assertFalse(instance.cancel(taskId, true));
instance.unregisterTask(taskId);
Assert.assertFalse(instance.isRegistered(taskId));
}
@Test
public void testRegisterUnregisterPeriodic() {
TestRunnable testRunnable = new TestRunnable();
Task task = new Task(testRunnable, 0, 10L);
UUID taskId = instance.registerTask(task);
Assert.assertTrue(instance.isRegistered(taskId));
waitForExecution(2, testRunnable);
Assert.assertTrue(testRunnable.count > 1); // ensure that the runnable has been called multiple times
Assert.assertFalse(instance.isDone(taskId));
Assert.assertTrue(instance.cancel(taskId, true));
Assert.assertTrue(instance.isDone(taskId));
instance.unregisterTask(taskId);
Assert.assertFalse(instance.isRegistered(taskId));
}
@Test
public void testRegisterUnregisterSchedule() {
Schedule schedule = new Schedule();
long now = System.currentTimeMillis();
TestRunnableSchedule runnableSchedule = new TestRunnableSchedule(schedule, now);
instance.registerCron(100, TimeUnit.MILLISECONDS); // set the cron period to 10ms
UUID scheduleId = instance.registerSchedule(runnableSchedule);
waitForExecution(2, runnableSchedule.runnable);
int count = runnableSchedule.runnable.count;
Assert.assertTrue(count > 1); // ensure that the runnable has been called multiple times
Assert.assertTrue(instance.isDone(scheduleId)); // ensure that it is now done
Assert.assertEquals(now + count - 1, instance.getLastStarted(scheduleId));
Assert.assertEquals(now + count, instance.getLastCompleted(scheduleId));
instance.unregisterSchedule(scheduleId);
Assert.assertEquals(count, runnableSchedule.runnable.count); // ensure that the runnable has not been called further
}
}