ExecutionTimeQuartzWithDayOfYearExtensionIntegrationTest.java
/*
* Copyright 2015 jmrozanec 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 com.cronutils.model.time;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.definition.TestCronDefinitionsFactory;
import com.cronutils.parser.CronParser;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Optional;
import static java.time.ZoneOffset.UTC;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
public class ExecutionTimeQuartzWithDayOfYearExtensionIntegrationTest {
private static final String BI_WEEKLY_STARTING_WITH_FIRST_DAY_OF_YEAR = "0 0 0 ? * ? * 1/14";
private static final String FIRST_QUARTER_BI_WEEKLY_STARTING_WITH_FIRST_DAY_OF_YEAR = "0 0 0 ? 1-3 ? * 1/14";
private static final String WITHOUT_DAY_OF_YEAR = "0 0 0 1 * ? *"; // i.e. DoY field omitted
private static final String WITHOUT_SPECIFIC_DAY_OF_YEAR = "0 0 0 1 * ? * ?"; // i.e. DoY field set to question mark
private static final String NEXT_EXECUTION_NOT_PRESENT_ERROR = "next execution was not present";
private static final String LAST_EXECUTION_NOT_PRESENT_ERROR = "last execution was not present";
private static final String EXPECTED_EXECUTION_NOT_PRESENT_ERROR = "expected execution was not present";
private CronParser parser;
private CronParser quartzParser;
@BeforeEach
public void setUp() {
parser = new CronParser(TestCronDefinitionsFactory.withDayOfYearDefinitionWhereYearAndDoYOptionals());
quartzParser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ));
}
@Test
public void testForCron() {
assertEquals(SingleExecutionTime.class, ExecutionTime.forCron(parser.parse(BI_WEEKLY_STARTING_WITH_FIRST_DAY_OF_YEAR)).getClass());
assertEquals(SingleExecutionTime.class, ExecutionTime.forCron(parser.parse(FIRST_QUARTER_BI_WEEKLY_STARTING_WITH_FIRST_DAY_OF_YEAR)).getClass());
assertEquals(SingleExecutionTime.class, ExecutionTime.forCron(parser.parse(WITHOUT_DAY_OF_YEAR)).getClass());
assertEquals(SingleExecutionTime.class, ExecutionTime.forCron(parser.parse(WITHOUT_SPECIFIC_DAY_OF_YEAR)).getClass());
}
@Test //issue #249
public void testNextExecutionEveryTwoWeeksStartingWithFirstDayOfYear() {
final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(BI_WEEKLY_STARTING_WITH_FIRST_DAY_OF_YEAR));
for (int i = 1; i < 30; i++) {
final ZonedDateTime now = ZonedDateTime.of(2017, 10, i, 0, 0, 0, 0, UTC);
final int dayOfMostRecentPeriod = (now.getDayOfYear() - 1) % 14;
final ZonedDateTime expected = now.plusDays(14L - dayOfMostRecentPeriod);
final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(now);
if (nextExecution.isPresent()) {
assertEquals(expected, nextExecution.get(), "Wrong next time from " + now);
} else {
fail(NEXT_EXECUTION_NOT_PRESENT_ERROR);
}
}
}
@Test
public void testLastExecutionEveryTwoWeeksStartingWithFirstDayOfYear() {
final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(BI_WEEKLY_STARTING_WITH_FIRST_DAY_OF_YEAR));
for (int i = 1; i < 30; i++) {
final ZonedDateTime now = ZonedDateTime.of(2017, 10, i, 0, 0, 0, 0, UTC);
final int dayOfMostRecentPeriod = (now.getDayOfYear() - 1) % 14;
final ZonedDateTime expected = now.minusDays(dayOfMostRecentPeriod == 0 ? 14 : dayOfMostRecentPeriod);
final Optional<ZonedDateTime> lastExecution = executionTime.lastExecution(now);
if (lastExecution.isPresent()) {
assertEquals(expected, lastExecution.get(), "Wrong next time from " + now);
} else {
fail(LAST_EXECUTION_NOT_PRESENT_ERROR);
}
}
}
@Test
public void testLastExecutionEveryTwoWeeksStartingWithFirstDayOfYearIssue249TzUTC() {
//s m H DoM M DoW Y DoY
final ZonedDateTime now = ZonedDateTime.of(2017, 10, 7, 0, 0, 0, 0, UTC);
final ZonedDateTime expected = ZonedDateTime.of(2017, 9, 24, 0, 0, 0, 0, UTC);
final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(BI_WEEKLY_STARTING_WITH_FIRST_DAY_OF_YEAR));
final Optional<ZonedDateTime> lastExecution = executionTime.lastExecution(now);
if (lastExecution.isPresent()) {
assertEquals(expected, lastExecution.get());
} else {
fail(LAST_EXECUTION_NOT_PRESENT_ERROR);
}
}
@Test
public void testLastExecutionEveryTwoWeeksStartingWithFirstDayOfYearIssue249TzBuenosAires() {
//s m H DoM M DoW Y DoY
final ZonedDateTime now = ZonedDateTime.of(2017, 10, 7, 0, 0, 0, 0, ZoneId.of("America/Argentina/Buenos_Aires"));
final ZonedDateTime expected = ZonedDateTime.of(2017, 9, 24, 0, 0, 0, 0, ZoneId.of("America/Argentina/Buenos_Aires"));
final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(BI_WEEKLY_STARTING_WITH_FIRST_DAY_OF_YEAR));
final Optional<ZonedDateTime> lastExecution = executionTime.lastExecution(now);
if (lastExecution.isPresent()) {
assertEquals(expected, lastExecution.get());
} else {
fail(LAST_EXECUTION_NOT_PRESENT_ERROR);
}
}
@Test
public void testExecutionTimesEveryTwoWeeksStartingWithFirstDayOfYear() {
final ZonedDateTime[] expectedExecutionTimes = new ZonedDateTime[] {
ZonedDateTime.of(2017, 1, 1, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 1, 15, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 1, 29, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 2, 12, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 2, 26, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 3, 12, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 3, 26, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 4, 9, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 4, 23, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 5, 7, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 5, 21, 0, 0, 0, 0, UTC),
ZonedDateTime.of(2017, 6, 4, 0, 0, 0, 0, UTC)
};
final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(BI_WEEKLY_STARTING_WITH_FIRST_DAY_OF_YEAR));
for (final ZonedDateTime expectedExecutionTime : expectedExecutionTimes) {
final Optional<ZonedDateTime> expectedExecution = executionTime.nextExecution(expectedExecutionTime.minusDays(1));
if (expectedExecution.isPresent()) {
assertEquals(expectedExecutionTime, expectedExecution.get());
} else {
fail(EXPECTED_EXECUTION_NOT_PRESENT_ERROR);
}
}
for (int i = 1; i < expectedExecutionTimes.length; i++) {
final Optional<ZonedDateTime> expectedExecution = executionTime.nextExecution(expectedExecutionTimes[i - 1]);
if (expectedExecution.isPresent()) {
assertEquals(expectedExecutionTimes[i], expectedExecution.get());
} else {
fail(EXPECTED_EXECUTION_NOT_PRESENT_ERROR);
}
}
for (int i = 1; i < expectedExecutionTimes.length; i++) {
final Optional<ZonedDateTime> expectedExecution = executionTime.lastExecution(expectedExecutionTimes[i]);
if (expectedExecution.isPresent()) {
assertEquals(expectedExecutionTimes[i - 1], expectedExecution.get());
} else {
fail(EXPECTED_EXECUTION_NOT_PRESENT_ERROR);
}
}
}
@Test //issue #188
public void testQuartzCompatibilityIfDoYisOmitted() {
final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(WITHOUT_DAY_OF_YEAR));
final ExecutionTime quartzExecutionTime = ExecutionTime.forCron(quartzParser.parse(WITHOUT_DAY_OF_YEAR));
ZonedDateTime start = ZonedDateTime.of(2017, 1, 1, 0, 0, 0, 0, UTC).minusSeconds(1);
for (int i = 0; i < 12; i++) {
final Optional<ZonedDateTime> nextQuartzExecution = quartzExecutionTime.nextExecution(start);
final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(start);
if (nextQuartzExecution.isPresent() && nextExecution.isPresent()) {
final ZonedDateTime expectedDateTime = nextQuartzExecution.get();
assertEquals(expectedDateTime, nextExecution.get());
start = expectedDateTime.plusSeconds(1);
} else {
fail("on of the asserted executions was not present");
}
}
}
@Test //issue #188
public void testQuartzCompatibilityIfDoYisQuestionMark() {
final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(WITHOUT_SPECIFIC_DAY_OF_YEAR));
final ExecutionTime quartzExecutionTime = ExecutionTime.forCron(quartzParser.parse(WITHOUT_DAY_OF_YEAR));
ZonedDateTime start = ZonedDateTime.of(2017, 1, 1, 0, 0, 0, 0, UTC).minusSeconds(1);
for (int i = 0; i < 12; i++) {
final Optional<ZonedDateTime> nextQuartzExecution = quartzExecutionTime.nextExecution(start);
final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(start);
if (nextQuartzExecution.isPresent() && nextExecution.isPresent()) {
final ZonedDateTime expectedDateTime = nextQuartzExecution.get();
assertEquals(expectedDateTime, nextExecution.get());
start = expectedDateTime.plusSeconds(1);
} else {
fail("one of the asserted executions was not present");
}
}
}
@Test //issue #190
public void testExecutionTimesWithIncrementsGreaterThanDaysOfMonth() {
final int increment = 56;
final String incrementGreaterDaysOfMonthStartingWithFirstDayOfYear = "0 0 0 ? * ? * 1/" + increment;
final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(incrementGreaterDaysOfMonthStartingWithFirstDayOfYear));
ZonedDateTime start = ZonedDateTime.of(2017, 1, 1, 0, 0, 0, 0, UTC);
for (int i = 0; i < 6; i++) {
final ZonedDateTime expected = start;
final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(start.minusSeconds(1));
if (nextExecution.isPresent()) {
final ZonedDateTime actual = nextExecution.get();
assertEquals(expected, actual);
start = expected.plusDays(increment);
} else {
fail(NEXT_EXECUTION_NOT_PRESENT_ERROR);
}
}
}
@Test
public void testCustomQuarterlySchedule() {
final ZonedDateTime firstDayOf2016 = ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, UTC);
final ZonedDateTime startWithLastDayOf2015 = ZonedDateTime.of(2015, 12, 31, 0, 0, 0, 0, UTC);
final String customQuarterlyStartingWithDay47OfYear = "0 0 0 ? * ? * 47/91";
final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(customQuarterlyStartingWithDay47OfYear));
final ZonedDateTime[] expectedExecutionTimes = new ZonedDateTime[4];
for (int j = 0; j < 4; j++) {
expectedExecutionTimes[j] = firstDayOf2016.withDayOfYear(47 + j * 91);
}
ZonedDateTime start = startWithLastDayOf2015;
for (final ZonedDateTime expectedExecutionTime : expectedExecutionTimes) {
final Optional<ZonedDateTime> nextExecution = executionTime.nextExecution(start);
if (nextExecution.isPresent()) {
final ZonedDateTime actual = nextExecution.get();
assertEquals(expectedExecutionTime, actual);
start = expectedExecutionTime.plusSeconds(1);
} else {
fail(NEXT_EXECUTION_NOT_PRESENT_ERROR);
}
}
}
}