/*
* Copyright 2014 LinkedIn Corp.
*
* 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 azkaban.trigger;
import java.util.HashMap;
import java.util.Map;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.ReadablePeriod;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import azkaban.utils.Utils;
import azkaban.trigger.builtin.BasicTimeChecker;
public class BasicTimeCheckerTest {
private Condition getCondition(BasicTimeChecker timeChecker){
Map<String, ConditionChecker> checkers =
new HashMap<String, ConditionChecker>();
checkers.put(timeChecker.getId(), timeChecker);
String expr = timeChecker.getId() + ".eval()";
return new Condition(checkers, expr);
}
@Test
public void periodTimerTest() {
// get a new timechecker, start from now, repeat every minute. should
// evaluate to false now, and true a minute later.
DateTime now = DateTime.now();
ReadablePeriod period = Utils.parsePeriodString("10s");
BasicTimeChecker timeChecker =
new BasicTimeChecker("BasicTimeChecket_1", now.getMillis(),
now.getZone(), true, true, period, null);
Condition cond = getCondition(timeChecker);
assertFalse(cond.isMet());
// sleep for 1 min
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
assertTrue(cond.isMet());
cond.resetCheckers();
assertFalse(cond.isMet());
// sleep for 1 min
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
assertTrue(cond.isMet());
}
/**
* Test Base Cron Functionality.
*/
@Test
public void testQuartzCurrentZone() {
DateTime now = DateTime.now();
String cronExpression = "0 0 0 31 12 ? 2050";
BasicTimeChecker timeChecker =
new BasicTimeChecker("BasicTimeChecket_1", now.getMillis(),
now.getZone(), true, true, null, cronExpression);
System.out.println("getNextCheckTime = " + timeChecker.getNextCheckTime());
Condition cond = getCondition(timeChecker);
// 2556086400000L represent for "2050-12-31T00:00:00.000-08:00"
DateTime year2050 = new DateTime(2050, 12, 31, 0 ,0 ,0 ,now.getZone());
assertTrue(cond.getNextCheckTime() == year2050.getMillis());
}
/**
* Test when PST-->PDT happens in 2020. -8:00 -> -7:00
* See details why confusion happens during this change: https://en.wikipedia.org/wiki/Pacific_Time_Zone
*
* This test demonstrates that if the cron is under UTC settings,
* When daylight saving change occurs, 2:30 will be changed to 3:30 at that day.
*/
@Test
public void testPSTtoPDTunderUTC() {
DateTime now = DateTime.now();
// 10:30 UTC == 2:30 PST
String cronExpression = "0 30 10 8 3 ? 2020";
BasicTimeChecker timeChecker =
new BasicTimeChecker("BasicTimeChecket_1", now.getMillis(),
DateTimeZone.UTC, true, true, null, cronExpression);
System.out.println("getNextCheckTime = " + timeChecker.getNextCheckTime());
Condition cond = getCondition(timeChecker);
DateTime spring2020UTC = new DateTime(2020, 3, 8, 10, 30, 0, DateTimeZone.UTC);
DateTime spring2020PDT = new DateTime(2020, 3, 8, 3, 30, 0, DateTimeZone.forID("America/Los_Angeles"));
assertTrue(cond.getNextCheckTime() == spring2020UTC.getMillis());
assertTrue(cond.getNextCheckTime() == spring2020PDT.getMillis());
}
/**
* Test when PST-->PDT happens in 2020. -8:00 -> -7:00
* See details why confusion happens during this change: https://en.wikipedia.org/wiki/Pacific_Time_Zone
*
* This test demonstrates that 2:30 AM will not happen during the daylight saving day on Cron settings under PDT/PST.
* Since we let the cron triggered both at March 8th, and 9th, it will execute at March 9th.
*/
@Test
public void testPSTtoPDTdst2() {
DateTime now = DateTime.now();
String cronExpression = "0 30 2 8,9 3 ? 2020";
BasicTimeChecker timeChecker =
new BasicTimeChecker("BasicTimeChecker_1", now.getMillis(),
DateTimeZone.forID("America/Los_Angeles"), true, true, null, cronExpression);
System.out.println("getNextCheckTime = " + timeChecker.getNextCheckTime());
Condition cond = getCondition(timeChecker);
DateTime aTime = new DateTime(2020, 3, 9, 2, 30, 0, DateTimeZone.forID("America/Los_Angeles"));
assertTrue(cond.getNextCheckTime() == aTime.getMillis());
}
/**
* Test when PDT-->PST happens in 2020. -7:00 -> -8:00
* See details why confusion happens during this change: https://en.wikipedia.org/wiki/Pacific_Time_Zone
*
* This test cronDayLightPacificWinter1 is in order to compare against the cronDayLightPacificWinter2.
*
* In this Test, we let job run at 1:00 at Nov.1st, 2020. We know that we will have two 1:00 at that day.
* The test shows that the first 1:00 is skipped at that day.
* Schedule will still be executed once on that day.
*/
@Test
public void testPDTtoPSTdst1() {
DateTime now = DateTime.now();
// 9:00 UTC == 1:00 PST (difference is 8 hours)
String cronExpression = "0 0 1 1,2 11 ? 2020";
BasicTimeChecker timeChecker =
new BasicTimeChecker("BasicTimeChecket_1", now.getMillis(),
DateTimeZone.forID("America/Los_Angeles"), true, true, null, cronExpression);
System.out.println("getNextCheckTime = " + timeChecker.getNextCheckTime());
Condition cond = getCondition(timeChecker);
DateTime winter2020 = new DateTime(2020, 11, 1, 9, 0, 0, DateTimeZone.UTC);
DateTime winter2020_2 = new DateTime(2020, 11, 1, 1, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
DateTime winter2020_3 = new DateTime(2020, 11, 1, 2, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
assertTrue(cond.getNextCheckTime() == winter2020.getMillis());
// Both 1 and 2 o'clock can not pass the test. Based on milliseconds we got,
// winter2020_2.getMillis() == 11/1/2020, 1:00:00 AM GMT-7:00 DST
// winter2020_3.getMillis() == 11/1/2020, 2:00:00 AM GMT-8:00
// Both time doesn't match the second 1:00 AM
assertFalse(cond.getNextCheckTime() == winter2020_2.getMillis());
assertFalse(cond.getNextCheckTime() == winter2020_3.getMillis());
}
/**
* Test when PDT-->PST happens in 2020. -7:00 -> -8:00
* See details why confusion happens during this change: https://en.wikipedia.org/wiki/Pacific_Time_Zone
*
* This test cronDayLightPacificWinter2 is in order to be compared against the cronDayLightPacificWinter1.
*
* In this Test, we let job run at 0:59 at Nov.1st, 2020. it shows that it is 7:59 UTC
* The test shows 7:59 UTC jump to 9:00 UTC.
*/
@Test
public void testPDTtoPSTdst2() {
DateTime now = DateTime.now();
// 7:59 UTC == 0:59 PDT (difference is 7 hours)
String cronExpression = "0 59 0 1,2 11 ? 2020";
BasicTimeChecker timeChecker =
new BasicTimeChecker("BasicTimeChecket_1", now.getMillis(),
DateTimeZone.forID("America/Los_Angeles"), true, true, null, cronExpression);
System.out.println("getNextCheckTime = " + timeChecker.getNextCheckTime());
Condition cond = getCondition(timeChecker);
// 7:59 UTC == 0:59 PDT (difference is 7 hours)
DateTime winter2020 = new DateTime(2020, 11, 1, 7, 59, 0, DateTimeZone.UTC);
DateTime winter2020_2 = new DateTime(2020, 11, 1, 0, 59, 0, DateTimeZone.forID("America/Los_Angeles"));
// Local time remains the same.
assertTrue(cond.getNextCheckTime() == winter2020.getMillis());
assertTrue(cond.getNextCheckTime() == winter2020_2.getMillis());
}
/**
* Test when PDT-->PST happens in 2020. -7:00 -> -8:00
* See details why confusion happens during this change: https://en.wikipedia.org/wiki/Pacific_Time_Zone
*
* This test is a supplement to cronDayLightPacificWinter1.
*
* Still, we let job run at 1:30 at Nov.1st, 2020. We know that we will have two 1:30 at that day.
* The test shows the 1:30 at that day will be based on PST, not PDT. It means that the first 1:30 is skipped at that day.
*/
@Test
public void testPDTtoPSTdst3() {
DateTime now = DateTime.now();
// 9:30 UTC == 1:30 PST (difference is 8 hours)
String cronExpression = "0 30 1 1,2 11 ? 2020";
BasicTimeChecker timeChecker =
new BasicTimeChecker("BasicTimeChecket_1", now.getMillis(),
DateTimeZone.forID("America/Los_Angeles"), true, true, null, cronExpression);
System.out.println("getNextCheckTime = " + timeChecker.getNextCheckTime());
Condition cond = getCondition(timeChecker);
// 9:30 UTC == 1:30 PST (difference is 8 hours)
DateTime winter2020 = new DateTime(2020, 11, 1, 9, 30, 0, DateTimeZone.UTC);
DateTime winter2020_2 = new DateTime(2020, 11, 1, 1, 30, 0, DateTimeZone.forID("America/Los_Angeles"));
DateTime winter2020_3 = new DateTime(2020, 11, 1, 2, 30, 0, DateTimeZone.forID("America/Los_Angeles"));
assertTrue(cond.getNextCheckTime() == winter2020.getMillis());
// Both 1:30 and 2:30 can not pass the test.
assertFalse(cond.getNextCheckTime() == winter2020_2.getMillis());
assertFalse(cond.getNextCheckTime() == winter2020_3.getMillis());
}
}