001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: TestDatabaseScheduler.java 3714 2007-04-08 02:57:38Z gbevin $
007: */
008: package com.uwyn.rife.scheduler.schedulermanagers;
009:
010: import com.uwyn.rife.scheduler.exceptions.*;
011:
012: import com.uwyn.rife.config.RifeConfig;
013: import com.uwyn.rife.database.Datasource;
014: import com.uwyn.rife.scheduler.Executor;
015: import com.uwyn.rife.scheduler.Scheduler;
016: import com.uwyn.rife.scheduler.Task;
017: import com.uwyn.rife.scheduler.TaskManager;
018: import com.uwyn.rife.scheduler.TestTasktypes;
019: import com.uwyn.rife.scheduler.schedulermanagers.DatabaseScheduler;
020: import com.uwyn.rife.scheduler.schedulermanagers.DatabaseSchedulerFactory;
021: import com.uwyn.rife.tools.ExceptionUtils;
022: import com.uwyn.rife.tools.Localization;
023: import java.util.ArrayList;
024: import java.util.Calendar;
025: import java.util.Collection;
026: import java.util.Date;
027: import junit.framework.TestCase;
028:
029: public class TestDatabaseScheduler extends TestCase {
030: private Datasource mDatasource = null;
031:
032: public TestDatabaseScheduler(Datasource datasource,
033: String datasourceName, String name) {
034: super (name);
035: mDatasource = datasource;
036: }
037:
038: protected void setUp() throws Exception {
039: DatabaseScheduler schedulermanager = DatabaseSchedulerFactory
040: .getInstance(mDatasource);
041: try {
042: schedulermanager.install();
043: } catch (SchedulerManagerException e) {
044: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
045: }
046: }
047:
048: protected void tearDown() throws Exception {
049: DatabaseScheduler schedulermanager = DatabaseSchedulerFactory
050: .getInstance(mDatasource);
051: try {
052: schedulermanager.remove();
053: } catch (SchedulerManagerException e) {
054: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
055: }
056: }
057:
058: public void testInstantiateScheduler() {
059: Scheduler scheduler = DatabaseSchedulerFactory.getInstance(
060: mDatasource).getScheduler();
061: assertNotNull(scheduler);
062: }
063:
064: public void testStartStopScheduler() {
065: Scheduler scheduler = DatabaseSchedulerFactory.getInstance(
066: mDatasource).getScheduler();
067: try {
068: scheduler.start();
069: synchronized (scheduler) {
070: scheduler.interrupt();
071:
072: try {
073: scheduler.wait();
074: } catch (InterruptedException e) {
075: assertTrue(
076: ExceptionUtils.getExceptionStackTrace(e),
077: false);
078: }
079: }
080: } catch (NoExecutorForTasktypeException e) {
081: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
082: } catch (UnableToRetrieveTasksToProcessException e) {
083: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
084: }
085: }
086:
087: public void testAddExecutor() {
088: Scheduler scheduler = DatabaseSchedulerFactory.getInstance(
089: mDatasource).getScheduler();
090: Executor executor = new TestExecutor();
091:
092: assertNull(scheduler.getExecutor(executor.getHandledTasktype()));
093: try {
094: scheduler.addExecutor(executor);
095: } catch (SchedulerException e) {
096: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
097: }
098: assertEquals(executor, scheduler.getExecutor(executor
099: .getHandledTasktype()));
100: assertTrue(scheduler.removeExecutor(executor));
101: }
102:
103: public void testOneshotTaskExecution() {
104: int sleeptime = 60 * 1000;
105: Scheduler scheduler = DatabaseSchedulerFactory.getInstance(
106: mDatasource).getScheduler();
107: TestExecutor executor = new TestExecutor();
108: TaskManager taskmanager = scheduler.getTaskManager();
109: Task task = new Task();
110:
111: try {
112: task.setType(TestTasktypes.UPLOAD_GROUPS);
113: task.setPlanned(System.currentTimeMillis());
114: task.setFrequency(null);
115: task.setBusy(false);
116: } catch (FrequencyException e) {
117: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
118: }
119:
120: try {
121: scheduler.addExecutor(executor);
122: } catch (SchedulerException e) {
123: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
124: }
125: scheduler.setSleepTime(sleeptime);
126: try {
127: task.setId(taskmanager.addTask(task));
128: task = taskmanager.getTask(task.getId());
129: } catch (TaskManagerException e) {
130: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
131: }
132:
133: try {
134: scheduler.start();
135: try {
136: Thread.sleep(sleeptime * 2);
137: } catch (InterruptedException e) {
138: assertTrue(ExceptionUtils.getExceptionStackTrace(e),
139: false);
140: }
141: synchronized (scheduler) {
142: scheduler.interrupt();
143:
144: try {
145: scheduler.wait();
146: } catch (InterruptedException e) {
147: assertTrue(
148: ExceptionUtils.getExceptionStackTrace(e),
149: false);
150: }
151: }
152:
153: Collection<Task> executed_tasks = executor
154: .getExecutedTasks();
155: assertEquals(1, executed_tasks.size());
156: Task executed_task = executed_tasks.iterator().next();
157: assertTrue(task.equals(executed_task));
158: assertSame(executed_task.getTaskManager(), taskmanager);
159: } catch (NoExecutorForTasktypeException e) {
160: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
161: } catch (UnableToRetrieveTasksToProcessException e) {
162: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
163: }
164: }
165:
166: public void testRepeatingTaskExecution() {
167: int scheduler_sleeptime = 30 * 1000; // 30 seconds
168: int task_frequency = 60 * 1000; // 1 minute
169: int thread_sleeptime = scheduler_sleeptime * 6; // 3 minutes
170: Scheduler scheduler = DatabaseSchedulerFactory.getInstance(
171: mDatasource).getScheduler();
172: TestExecutor executor = new TestExecutor();
173: TaskManager taskmanager = scheduler.getTaskManager();
174: Task task = new Task();
175:
176: try {
177: task.setType(TestTasktypes.UPLOAD_GROUPS);
178: // set back a while in the past to test the catch up rescheduling
179: task.setPlanned(System.currentTimeMillis()
180: - (scheduler_sleeptime * 10));
181: task.setFrequency("* * * * *");
182: task.setBusy(false);
183: } catch (FrequencyException e) {
184: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
185: }
186:
187: scheduler.setSleepTime(scheduler_sleeptime);
188:
189: try {
190: scheduler.addExecutor(executor);
191: } catch (SchedulerException e) {
192: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
193: }
194:
195: try {
196: task.setId(taskmanager.addTask(task));
197: task = taskmanager.getTask(task.getId());
198: } catch (TaskManagerException e) {
199: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
200: }
201:
202: Collection<Task> executed_tasks = null;
203: int executed_tasks_size = -1;
204: try {
205: scheduler.start();
206: try {
207: Thread.sleep(thread_sleeptime);
208: executed_tasks = executor.getExecutedTasks();
209: executed_tasks_size = executed_tasks.size();
210: } catch (InterruptedException e) {
211: assertTrue(ExceptionUtils.getExceptionStackTrace(e),
212: false);
213: }
214: synchronized (scheduler) {
215: scheduler.interrupt();
216:
217: try {
218: scheduler.wait();
219: } catch (InterruptedException e) {
220: assertTrue(
221: ExceptionUtils.getExceptionStackTrace(e),
222: false);
223: }
224: }
225:
226: // task frequency fits in the thread sleep time
227: long number_of_executions = (thread_sleeptime / task_frequency) + 1;
228:
229: // 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);
230: Date now = new Date();
231: assertTrue(
232: "\nFAILED "
233: + mDatasource.getDriver()
234: + " \n"
235: + executor.getFirstExecution().getTime()
236: .getTime()
237: + " : "
238: + executor.getFirstExecution().getTime()
239: .toGMTString() + "\n"
240: + now.getTime() + " : " + now.toGMTString()
241: + "\ntask_frequency = " + task_frequency
242: + "\nnumber_of_executions = "
243: + number_of_executions
244: + "\nexecuted_tasks_size = "
245: + executed_tasks_size,
246: number_of_executions == executed_tasks_size
247: || number_of_executions == executed_tasks_size + 1);
248: for (Task executed_task : executed_tasks) {
249: assertEquals(task.getId(), executed_task.getId());
250: assertEquals(task.getType(), executed_task.getType());
251: assertEquals(task.getFrequency(), executed_task
252: .getFrequency());
253: assertTrue(task.getPlanned() <= executed_task
254: .getPlanned());
255: assertSame(executed_task.getTaskManager(), taskmanager);
256: }
257:
258: try {
259: taskmanager.removeTask(task.getId());
260: } catch (TaskManagerException e) {
261: assertTrue(ExceptionUtils.getExceptionStackTrace(e),
262: false);
263: }
264: } catch (NoExecutorForTasktypeException e) {
265: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
266: } catch (UnableToRetrieveTasksToProcessException e) {
267: assertTrue(ExceptionUtils.getExceptionStackTrace(e), false);
268: }
269: }
270:
271: class TestExecutor extends Executor {
272: private Calendar mFirstExecution = null;
273: private ArrayList<Task> mExecutedTasks = null;
274:
275: public TestExecutor() {
276: mExecutedTasks = new ArrayList<Task>();
277: }
278:
279: public boolean executeTask(Task task) {
280: synchronized (this ) {
281: if (null == mFirstExecution) {
282: mFirstExecution = Calendar.getInstance(
283: RifeConfig.Tools.getDefaultTimeZone(),
284: Localization.getLocale());
285: mFirstExecution.setTimeInMillis(System
286: .currentTimeMillis());
287: }
288: mExecutedTasks.add(task);
289: }
290:
291: return true;
292: }
293:
294: public Collection<Task> getExecutedTasks() {
295: synchronized (this ) {
296: return mExecutedTasks;
297: }
298: }
299:
300: public Calendar getFirstExecution() {
301: synchronized (this ) {
302: return mFirstExecution;
303: }
304: }
305:
306: public String getHandledTasktype() {
307: return TestTasktypes.UPLOAD_GROUPS;
308: }
309:
310: protected long getRescheduleDelay() {
311: return 100;
312: }
313: }
314: }
|