/*
* Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: TestDatabaseScheduler.java 3918 2008-04-14 17:35:35Z gbevin $
*/
package com.uwyn.rife.scheduler.schedulermanagers;
import com.uwyn.rife.scheduler.exceptions.*;
import com.uwyn.rife.config.RifeConfig;
import com.uwyn.rife.database.Datasource;
import com.uwyn.rife.scheduler.Executor;
import com.uwyn.rife.scheduler.Scheduler;
import com.uwyn.rife.scheduler.Task;
import com.uwyn.rife.scheduler.TaskManager;
import com.uwyn.rife.scheduler.TestTasktypes;
import com.uwyn.rife.scheduler.schedulermanagers.DatabaseScheduler;
import com.uwyn.rife.scheduler.schedulermanagers.DatabaseSchedulerFactory;
import com.uwyn.rife.tools.ExceptionUtils;
import com.uwyn.rife.tools.Localization;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import junit.framework.TestCase;
public class TestDatabaseScheduler extends TestCase
{
private Datasource mDatasource = null;
public TestDatabaseScheduler(Datasource datasource, String datasourceName, String name)
{
super(name);
mDatasource = datasource;
}
protected void setUp()
throws Exception
{
DatabaseScheduler schedulermanager = DatabaseSchedulerFactory.getInstance(mDatasource);
try
{
schedulermanager.install();
}
catch (SchedulerManagerException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
}
protected void tearDown()
throws Exception
{
DatabaseScheduler schedulermanager = DatabaseSchedulerFactory.getInstance(mDatasource);
try
{
schedulermanager.remove();
}
catch (SchedulerManagerException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
}
public void testInstantiateScheduler()
{
Scheduler scheduler = DatabaseSchedulerFactory.getInstance(mDatasource).getScheduler();
assertNotNull(scheduler);
}
public void testStartStopScheduler()
{
Scheduler scheduler = DatabaseSchedulerFactory.getInstance(mDatasource).getScheduler();
try
{
scheduler.start();
synchronized (scheduler)
{
scheduler.interrupt();
try
{
scheduler.wait();
}
catch (InterruptedException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
}
}
catch (NoExecutorForTasktypeException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
catch (UnableToRetrieveTasksToProcessException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
}
public void testAddExecutor()
{
Scheduler scheduler = DatabaseSchedulerFactory.getInstance(mDatasource).getScheduler();
Executor executor = new TestExecutor();
assertNull(scheduler.getExecutor(executor.getHandledTasktype()));
try
{
scheduler.addExecutor(executor);
}
catch (SchedulerException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
assertEquals(executor, scheduler.getExecutor(executor.getHandledTasktype()));
assertTrue(scheduler.removeExecutor(executor));
}
public void testOneshotTaskExecution()
{
int sleeptime = 60*1000;
Scheduler scheduler = DatabaseSchedulerFactory.getInstance(mDatasource).getScheduler();
TestExecutor executor = new TestExecutor();
TaskManager taskmanager = scheduler.getTaskManager();
Task task = new Task();
try
{
task.setType(TestTasktypes.UPLOAD_GROUPS);
task.setPlanned(System.currentTimeMillis());
task.setFrequency(null);
task.setBusy(false);
}
catch (FrequencyException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
try
{
scheduler.addExecutor(executor);
}
catch (SchedulerException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
scheduler.setSleepTime(sleeptime);
try
{
task.setId(taskmanager.addTask(task));
task = taskmanager.getTask(task.getId());
}
catch (TaskManagerException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
try
{
scheduler.start();
try
{
Thread.sleep(sleeptime*2);
}
catch (InterruptedException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
synchronized (scheduler)
{
scheduler.interrupt();
try
{
scheduler.wait();
}
catch (InterruptedException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
}
Collection<Task> executed_tasks = executor.getExecutedTasks();
assertEquals(1, executed_tasks.size());
Task executed_task = executed_tasks.iterator().next();
assertTrue(task.equals(executed_task));
assertSame(executed_task.getTaskManager(), taskmanager);
}
catch (NoExecutorForTasktypeException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
catch (UnableToRetrieveTasksToProcessException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
}
public void testRepeatingTaskExecution()
{
int scheduler_sleeptime = 30*1000; // 30 seconds
int task_frequency = 60*1000; // 1 minute
int thread_sleeptime = scheduler_sleeptime*6; // 3 minutes
Scheduler scheduler = DatabaseSchedulerFactory.getInstance(mDatasource).getScheduler();
TestExecutor executor = new TestExecutor();
TaskManager taskmanager = scheduler.getTaskManager();
Task task = new Task();
try
{
task.setType(TestTasktypes.UPLOAD_GROUPS);
// set back a while in the past to test the catch up rescheduling
task.setPlanned(System.currentTimeMillis()-(scheduler_sleeptime*10));
task.setFrequency("* * * * *");
task.setBusy(false);
}
catch (FrequencyException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
scheduler.setSleepTime(scheduler_sleeptime);
try
{
scheduler.addExecutor(executor);
}
catch (SchedulerException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
try
{
task.setId(taskmanager.addTask(task));
task = taskmanager.getTask(task.getId());
}
catch (TaskManagerException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
Collection<Task> executed_tasks = null;
int executed_tasks_size = -1;
try
{
scheduler.start();
try
{
Thread.sleep(thread_sleeptime);
executed_tasks = executor.getExecutedTasks();
executed_tasks_size = executed_tasks.size();
}
catch (InterruptedException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
synchronized (scheduler)
{
scheduler.interrupt();
try
{
scheduler.wait();
}
catch (InterruptedException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
}
// task frequency fits in the thread sleep time
long number_of_executions = (thread_sleeptime/task_frequency)+1;
// System.out.println("\n"+mDatasource.getDriver()+"\n"+executor.getFirstExecution().getTime().getTime()+" : "+executor.getFirstExecution().getTime().toGMTString()+"\n"+now.getTime()+" : "+now.toGMTString()+"\ntask_frequency = "+task_frequency+"\nnumber_of_executions = "+number_of_executions+"\nexecuted_tasks_size = "+executed_tasks_size);
Date now = new Date();
assertTrue("\nFAILED "+mDatasource.getDriver()+" \n"+executor.getFirstExecution().getTime().getTime()+" : "+executor.getFirstExecution().getTime().toGMTString()+"\n"+now.getTime()+" : "+now.toGMTString()+"\ntask_frequency = "+task_frequency+"\nnumber_of_executions = "+number_of_executions+"\nexecuted_tasks_size = "+executed_tasks_size, number_of_executions == executed_tasks_size || number_of_executions == executed_tasks_size+1);
for (Task executed_task : executed_tasks)
{
assertEquals(task.getId(), executed_task.getId());
assertEquals(task.getType(), executed_task.getType());
assertEquals(task.getFrequency(), executed_task.getFrequency());
assertTrue(task.getPlanned() <= executed_task.getPlanned());
assertSame(executed_task.getTaskManager(), taskmanager);
}
try
{
taskmanager.removeTask(task.getId());
}
catch (TaskManagerException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
}
catch (NoExecutorForTasktypeException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
catch (UnableToRetrieveTasksToProcessException e)
{
assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
}
}
class TestExecutor extends Executor
{
private Calendar mFirstExecution = null;
private ArrayList<Task> mExecutedTasks = null;
public TestExecutor()
{
mExecutedTasks = new ArrayList<Task>();
}
public boolean executeTask(Task task)
{
synchronized (this)
{
if (null == mFirstExecution)
{
mFirstExecution = Calendar.getInstance(RifeConfig.Tools.getDefaultTimeZone(), Localization.getLocale());
mFirstExecution.setTimeInMillis(System.currentTimeMillis());
}
mExecutedTasks.add(task);
}
return true;
}
public Collection<Task> getExecutedTasks()
{
synchronized (this)
{
return mExecutedTasks;
}
}
public Calendar getFirstExecution()
{
synchronized (this)
{
return mFirstExecution;
}
}
public String getHandledTasktype()
{
return TestTasktypes.UPLOAD_GROUPS;
}
protected long getRescheduleDelay()
{
return 100;
}
}
}