/*******************************************************************************
* 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.services.scheduler;
import static org.junit.Assert.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import org.eclipse.skalli.services.scheduler.Schedule.SortedIntSet;
import org.junit.Test;
@SuppressWarnings("nls")
public class ScheduleTest {
@Test
public void testBasics() {
Schedule schedule = new Schedule("*", "*", "*");
assertEquals("*", schedule.getDaysOfWeek());
schedule.setDaysOfWeek(Schedule.WEEKDAYS[0]);
assertEquals(Schedule.WEEKDAYS[0], schedule.getDaysOfWeek());
assertEquals("*", schedule.getHours());
schedule.setHours("0-23");
assertEquals("0-23", schedule.getHours());
assertEquals("*", schedule.getMinutes());
schedule.setMinutes("10-20");
assertEquals("10-20", schedule.getMinutes());
Schedule newSchedule = new Schedule(schedule);
assertEquals(Schedule.WEEKDAYS[0], newSchedule.getDaysOfWeek());
assertEquals("0-23", newSchedule.getHours());
assertEquals("10-20", newSchedule.getMinutes());
assertEquals(Schedule.WEEKDAYS[0] + " 0-23 10-20", newSchedule.toString());
assertEquals(schedule, newSchedule);
schedule = new Schedule();
assertEquals("*", schedule.getDaysOfWeek());
assertEquals("*", schedule.getHours());
assertEquals("*", schedule.getMinutes());
// simulate an uninitialized Schedule -> XStream
schedule = new Schedule();
schedule.setDaysOfWeek(null);
schedule.setHours(null);
schedule.setMinutes(null);
assertEquals("*", schedule.getDaysOfWeek());
assertEquals("*", schedule.getHours());
assertEquals("*", schedule.getMinutes());
}
@Test
public void testCreateFromCalendar() throws Exception {
Calendar date = new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.ENGLISH);
date.set(Calendar.HOUR_OF_DAY, 14);
date.set(Calendar.MINUTE, 53);
for (int i = 1; i <= 7; ++i) {
date.set(Calendar.DAY_OF_WEEK, i);
Schedule schedule = new Schedule(date);
// Calendar uses 1=Sunday,2=Monday,..,7=Saturday, while cron uses 0=Sunday,1=Monday,...6=Saturday.
// So day of week in result is always 1 less than in the Calendar setting!
assertEquals(Integer.toString(i - 1) + " 14 53", schedule.getSchedule());
}
}
@Test
public void testScheduleNow() throws Exception {
Calendar now = new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.ENGLISH);
assertTrue(Schedule.NOW.isDue(now));
}
@Test
public void testSortedIntSet() {
SortedIntSet set = new SortedIntSet();
for (int i = 99; i >= 0; --i) {
set.add(i);
}
assertEquals(100, set.size());
for (int i = 0; i <= 99; ++i) {
assertEquals(i, set.get(i));
assertTrue(set.contains(i));
}
set.addAll(0, 99, 1);
assertEquals(100, set.size());
for (int i = 0; i <= 99; ++i) {
assertEquals(i, set.get(i));
}
set = new SortedIntSet();
set.addAll(0, 99, 5);
assertEquals(20, set.size());
}
@Test
public void testGetTimeSet() {
SortedIntSet list = RunnableSchedule.getTimeSet("8", 0, 23);
assertEquals(1, list.size());
assertEquals(8, list.get(0));
list = RunnableSchedule.getTimeSet("1,2,3", 0, 23);
assertEquals(3, list.size());
assertEquals(1, list.get(0));
assertEquals(2, list.get(1));
assertEquals(3, list.get(2));
list = RunnableSchedule.getTimeSet("3,1,2", 0, 23);
assertEquals(3, list.size());
assertEquals(1, list.get(0));
assertEquals(2, list.get(1));
assertEquals(3, list.get(2));
list = RunnableSchedule.getTimeSet("1-3", 0, 23);
assertEquals(3, list.size());
assertEquals(1, list.get(0));
assertEquals(2, list.get(1));
assertEquals(3, list.get(2));
list = RunnableSchedule.getTimeSet("0-23/2", 0, 23);
assertEquals(12, list.size());
int n = 0;
for (int i = 0; i < 12; ++i) {
assertEquals(n, list.get(i));
n += 2;
}
list = RunnableSchedule.getTimeSet("4,6-10/2,1-3/1,4,5,5-10/2", 0, 23);
assertEquals(10, list.size());
for (int i = 0; i < 10; ++i) {
assertEquals(i + 1, list.get(i));
}
list = RunnableSchedule.getTimeSet("18-5", 0, 23);
assertEquals(12, list.size());
n = 0;
for (int i = 0; i < 23; ++i) {
if (i <= 5 || i >= 18) {
assertTrue(list.contains(i));
assertEquals(i, list.get(n));
++n;
} else {
assertFalse(list.contains(i));
}
}
list = RunnableSchedule.getTimeSet("*", 0, 6);
assertEquals(7, list.size());
for (int i = 0; i <= 6; ++i) {
assertEquals(i, list.get(i));
}
list = RunnableSchedule.getTimeSet("*/2", 0, 6);
assertEquals(4, list.size());
n = 0;
for (int i = 0; i < 4; ++i) {
assertEquals(n, list.get(i));
n += 2;
}
list = RunnableSchedule.getTimeSet("*/10,3,13-14", 0, 23);
assertEquals(6, list.size());
assertEquals(0, list.get(0));
assertEquals(3, list.get(1));
assertEquals(10, list.get(2));
assertEquals(13, list.get(3));
assertEquals(14, list.get(4));
assertEquals(20, list.get(5));
list = RunnableSchedule.getTimeSet("13-14,*/10,3", 0, 23);
assertEquals(6, list.size());
assertEquals(0, list.get(0));
assertEquals(3, list.get(1));
assertEquals(10, list.get(2));
assertEquals(13, list.get(3));
assertEquals(14, list.get(4));
assertEquals(20, list.get(5));
// out of range
list = RunnableSchedule.getTimeSet("24", 0, 23);
assertEquals(1, list.size());
assertEquals(23, list.get(0));
list = RunnableSchedule.getTimeSet("1", 22, 23);
assertEquals(1, list.size());
assertEquals(22, list.get(0));
// invalid
try {
list = RunnableSchedule.getTimeSet("foobar", 0, 23);
fail("foobar");
} catch (NumberFormatException e) {
}
try {
list = RunnableSchedule.getTimeSet("*/foobar", 0, 23);
fail("*/foobar");
} catch (NumberFormatException e) {
}
try {
list = RunnableSchedule.getTimeSet("1-foobar", 0, 23);
fail("1-foobar");
} catch (NumberFormatException e) {
}
try {
list = RunnableSchedule.getTimeSet("1,foobar,2", 0, 23);
fail("1,foobar,2");
} catch (NumberFormatException e) {
}
}
@Test
public void testGetDaysOfWeekSet() {
SortedIntSet list = RunnableSchedule.getDaysOfWeekSet("MONDAY-SAT/2,5,SUNDAY,7", 0, 7, Schedule.WEEKDAYS,
Schedule.WEEKDAYS_SHORT);
assertEquals(0, list.get(0));
assertEquals(1, list.get(1));
assertEquals(3, list.get(2));
assertEquals(5, list.get(3));
assertEquals(7, list.get(4));
list = RunnableSchedule.normalizeDaysOfWeek(list);
assertEquals(1, list.get(0));
assertEquals(2, list.get(1));
assertEquals(4, list.get(2));
assertEquals(6, list.get(3));
list = RunnableSchedule.getDaysOfWeekSet("FRI-TUE", 0, 7, Schedule.WEEKDAYS, Schedule.WEEKDAYS_SHORT);
assertEquals(0, list.get(0));
assertEquals(1, list.get(1));
assertEquals(2, list.get(2));
assertEquals(5, list.get(3));
assertEquals(6, list.get(4));
list = RunnableSchedule.normalizeDaysOfWeek(list);
assertEquals(1, list.get(0));
assertEquals(2, list.get(1));
assertEquals(3, list.get(2));
assertEquals(6, list.get(3));
assertEquals(7, list.get(4));
list = RunnableSchedule.getDaysOfWeekSet("0-7", 0, 7, Schedule.WEEKDAYS, Schedule.WEEKDAYS_SHORT);
for (int i = 0; i <= 7; ++i) {
assertEquals(i, list.get(i));
}
list = RunnableSchedule.normalizeDaysOfWeek(list);
for (int i = 0; i <= 6; ++i) {
assertEquals(i + 1, list.get(i));
}
list = RunnableSchedule.getDaysOfWeekSet("*", 0, 7, Schedule.WEEKDAYS, Schedule.WEEKDAYS_SHORT);
for (int i = 0; i <= 6; ++i) {
assertEquals(i, list.get(i));
}
list = RunnableSchedule.normalizeDaysOfWeek(list);
for (int i = 0; i <= 6; ++i) {
assertEquals(i + 1, list.get(i));
}
list = RunnableSchedule.getDaysOfWeekSet("*/2", 0, 7, Schedule.WEEKDAYS, Schedule.WEEKDAYS_SHORT);
assertEquals(0, list.get(0));
assertEquals(2, list.get(1));
assertEquals(4, list.get(2));
assertEquals(6, list.get(3));
list = RunnableSchedule.normalizeDaysOfWeek(list);
assertEquals(1, list.get(0));
assertEquals(3, list.get(1));
assertEquals(5, list.get(2));
assertEquals(7, list.get(3));
list = RunnableSchedule.getDaysOfWeekSet("0,7,SUNDAY,*/2,MON,SUN", 0, 7, Schedule.WEEKDAYS,
Schedule.WEEKDAYS_SHORT);
assertEquals(0, list.get(0));
assertEquals(1, list.get(1));
assertEquals(2, list.get(2));
assertEquals(4, list.get(3));
assertEquals(6, list.get(4));
assertEquals(7, list.get(5));
list = RunnableSchedule.normalizeDaysOfWeek(list);
assertEquals(1, list.get(0));
assertEquals(2, list.get(1));
assertEquals(3, list.get(2));
assertEquals(5, list.get(3));
assertEquals(7, list.get(4));
}
@Test
public void testIsDue() {
Schedule schedule = new Schedule("MONDAY", "2", "0"); // Monday 2:00am
Calendar calendar = getUTCCalendar(2, 2, 0); // 2=Monday
assertTrue(schedule.isDue(calendar)); // first time we get a runnable
calendar.add(Calendar.MINUTE, 1);
assertFalse(schedule.isDue(calendar)); // one minute later, it's gone
schedule = new Schedule("*", "2", "0"); // Every day at 2:00am
calendar = getUTCCalendar(1, 2, 0);
for (int d = 1; d <= 7; ++d) {
for (int h = 0; h <= 23; ++h) {
for (int m = 0; m <= 59; ++m) {
calendar.set(Calendar.DAY_OF_WEEK, d);
calendar.set(Calendar.HOUR_OF_DAY, h);
calendar.set(Calendar.MINUTE, m);
if (h == 2 && m == 0) {
assertTrue("d=" + d, schedule.isDue(calendar));
} else {
assertFalse("d=" + d, schedule.isDue(calendar));
}
}
}
}
schedule = new Schedule("*/2", "2", "0"); // Every second day at 2:00am
calendar = getUTCCalendar(1, 2, 0); //Mon 2:00
for (int d = 1; d <= 7; ++d) {
for (int h = 0; h <= 23; ++h) {
for (int m = 0; m <= 59; ++m) {
calendar.set(Calendar.DAY_OF_WEEK, d);
calendar.set(Calendar.HOUR_OF_DAY, h);
calendar.set(Calendar.MINUTE, m);
if ((d == 1 || d == 3 || d == 5 || d == 7) && h == 2 && m == 0) {
assertTrue("d=" + d, schedule.isDue(calendar));
} else {
assertFalse("d=" + d, schedule.isDue(calendar));
}
}
}
}
schedule = new Schedule("*", "*", "*"); // Every minute
calendar = getUTCCalendar(1, 2, 0);
for (int d = 1; d <= 7; ++d) {
for (int h = 0; h <= 23; ++h) {
for (int m = 0; m <= 59; ++m) {
calendar.set(Calendar.DAY_OF_WEEK, d);
calendar.set(Calendar.HOUR_OF_DAY, h);
calendar.set(Calendar.MINUTE, m);
assertTrue("m=" + m, schedule.isDue(calendar));
}
}
}
schedule = new Schedule("*", "*", "*/5"); // Every 5th minute
calendar = getUTCCalendar(1, 2, 0); //Mon 2:00
for (int d = 1; d <= 7; ++d) {
for (int h = 0; h <= 23; ++h) {
for (int m = 0; m <= 59; ++m) {
calendar.set(Calendar.DAY_OF_WEEK, d);
calendar.set(Calendar.HOUR_OF_DAY, h);
calendar.set(Calendar.MINUTE, m);
if (m % 5 == 0) {
assertTrue("m=" + m, schedule.isDue(calendar));
} else {
assertFalse("m=" + m, schedule.isDue(calendar));
}
}
}
}
schedule = new Schedule("*", "*/2", "*/5"); // Every 5th minute of every second hour each day
calendar = getUTCCalendar(1, 0, 0); //Mon 0:00
for (int d = 1; d <= 7; ++d) {
for (int h = 0; h <= 23; ++h) {
for (int m = 0; m <= 59; ++m) {
calendar.set(Calendar.DAY_OF_WEEK, d);
calendar.set(Calendar.HOUR_OF_DAY, h);
calendar.set(Calendar.MINUTE, m);
if ((h % 2 == 0) && (m % 5 == 0)) {
assertTrue("h=" + h + ",m=" + m, schedule.isDue(calendar));
} else {
assertFalse("h=" + h + ",m=" + m, schedule.isDue(calendar));
}
}
}
}
schedule = new Schedule("MON,FRI", "*/2", "*"); // Every minute of every second hour on Monday only
calendar = getUTCCalendar(1, 0, 0);
for (int d = 1; d <= 7; ++d) {
for (int h = 0; h <= 23; h += 2) {
for (int m = 0; m <= 59; ++m) {
calendar.set(Calendar.DAY_OF_WEEK, d);
calendar.set(Calendar.HOUR_OF_DAY, h);
calendar.set(Calendar.MINUTE, m);
if ((h % 2 == 0) && (d == 2 || d == 6)) {
assertTrue("d=" + d + ",h=" + h + ",m=" + m, schedule.isDue(calendar));
} else {
assertFalse("d=" + d + ",h=" + h + ",m=" + m, schedule.isDue(calendar));
}
}
}
}
// Every 10th minute (plus at xx:03, xx:13 and xx:14) at even hours (except 06:xx, plus 15:xx) from Monday-Friday and Sunday
schedule = new Schedule("7,MON-FRIDAY", "0,2,4,8-12/2,14,15,16-23/2,", "*/10,3,13-14");
calendar = getUTCCalendar(1, 0, 0);
for (int d = 1; d <= 7; ++d) {
for (int h = 0; h <= 23; ++h) {
for (int m = 0; m <= 59; ++m) {
calendar.set(Calendar.DAY_OF_WEEK, d);
calendar.set(Calendar.HOUR_OF_DAY, h);
calendar.set(Calendar.MINUTE, m);
if ((h % 2d == 0 && h != 6 || h == 15) && (m % 10 == 0 || m == 3 || m == 13 || m == 14) && d <= 6) {
assertTrue("d=" + d + ",h=" + h + ",m=" + m, schedule.isDue(calendar));
} else {
assertFalse("d=" + d + ",h=" + h + ",m=" + m, schedule.isDue(calendar));
}
}
}
}
}
@Test
public void testIsDueWithLastRunnerDate() {
Schedule schedule = new Schedule("MONDAY", "2", "10"); // Monday 2:10am
Calendar now = getUTCCalendar(Calendar.MONDAY, 2, 15); // Monday 2:15am
Calendar lastRun1= getUTCCalendar(Calendar.MONDAY, 2, 0); // 2:00am -> last run was before now
Calendar lastRun2 = getUTCCalendar(Calendar.MONDAY, 2, 10); // 2:10am -> last run was at schedule time
Calendar lastRun3 = getUTCCalendar(Calendar.MONDAY, 2, 15); // 2:15am -> last run had same time as now
Calendar lastRun4 = getUTCCalendar(Calendar.MONDAY, 2, 20); // 2:20am -> value after now ; should never be called
assertFalse(schedule.isDue(null, now));
assertTrue(schedule.isDue(lastRun1, now));
assertFalse(schedule.isDue(lastRun2, now));
assertFalse(schedule.isDue(lastRun3, now));
assertFalse(schedule.isDue(lastRun4, now));
}
private Calendar getUTCCalendar(int dayOfWeek, int hour, int minute) {
Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.ENGLISH);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
return calendar;
}
}