diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CurrentHourProvider.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CurrentHourProvider.java index caafd711629..b68363498e4 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CurrentHourProvider.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CurrentHourProvider.java @@ -22,6 +22,7 @@ import java.util.GregorianCalendar; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.yetus.audience.InterfaceAudience; +import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; @InterfaceAudience.Private public class CurrentHourProvider { @@ -37,7 +38,8 @@ public class CurrentHourProvider { } } - private static Tick nextTick() { + @VisibleForTesting + static Tick nextTick() { Calendar calendar = new GregorianCalendar(); calendar.setTimeInMillis(EnvironmentEdgeManager.currentTime()); int currentHour = calendar.get(Calendar.HOUR_OF_DAY); @@ -52,7 +54,8 @@ public class CurrentHourProvider { calendar.set(Calendar.MILLISECOND, 0); } - private static volatile Tick tick = nextTick(); + @VisibleForTesting + static volatile Tick tick = nextTick(); public static int getCurrentHour() { Tick tick = CurrentHourProvider.tick; diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCurrentHourProvider.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCurrentHourProvider.java index 6f7d0c92cf9..6df6b9b570d 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCurrentHourProvider.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCurrentHourProvider.java @@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.regionserver.compactions; import static org.junit.Assert.assertEquals; +import java.util.Date; import java.util.TimeZone; import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.testclassification.RegionServerTests; @@ -27,12 +28,9 @@ import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @Category({RegionServerTests.class, SmallTests.class}) public class TestCurrentHourProvider { - private static final Logger LOG = LoggerFactory.getLogger(TestCurrentHourProvider.class); @ClassRule public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestCurrentHourProvider.class); @@ -42,19 +40,43 @@ public class TestCurrentHourProvider { * and the unix time of 2020-08-20 15:04:00 is 1597907081000, * by calculating the delta time to get expected time in current timezone, * then we can get special hour no matter which timezone it runs. + * + * In addition, we should consider the Daylight Saving Time. + * 1. If in DaylightTime, we need reduce one hour. + * 2. If in DaylightTime and timezone is "Antarctica/Troll", we need reduce two hours. */ @Test public void testWithEnvironmentEdge() { - // set a time represent hour 11 - long deltaFor11 = TimeZone.getDefault().getRawOffset() - 28800000; - long timeFor11 = 1597895561000L - deltaFor11; - EnvironmentEdgeManager.injectEdge(() -> timeFor11); - assertEquals(11, CurrentHourProvider.getCurrentHour()); + // test for all available zoneID + for (String zoneID : TimeZone.getAvailableIDs()) { + TimeZone timezone = TimeZone.getTimeZone(zoneID); + TimeZone.setDefault(timezone); - // set a time represent hour 15 - long deltaFor15 = TimeZone.getDefault().getRawOffset() - 28800000; - long timeFor15 = 1597907081000L - deltaFor15; - EnvironmentEdgeManager.injectEdge(() -> timeFor15); - assertEquals(15, CurrentHourProvider.getCurrentHour()); + // set a time represent hour 11 + long deltaFor11 = TimeZone.getDefault().getRawOffset() - 28800000; + long timeFor11 = 1597895561000L - deltaFor11; + EnvironmentEdgeManager.injectEdge(() -> timeFor11); + CurrentHourProvider.tick = CurrentHourProvider.nextTick(); + int hour11 = CurrentHourProvider.getCurrentHour(); + if (TimeZone.getDefault().inDaylightTime(new Date(timeFor11))) { + hour11 = "Antarctica/Troll".equals(zoneID) ? + CurrentHourProvider.getCurrentHour() - 2 : + CurrentHourProvider.getCurrentHour() - 1; + } + assertEquals(11, hour11); + + // set a time represent hour 15 + long deltaFor15 = TimeZone.getDefault().getRawOffset() - 28800000; + long timeFor15 = 1597907081000L - deltaFor15; + EnvironmentEdgeManager.injectEdge(() -> timeFor15); + CurrentHourProvider.tick = CurrentHourProvider.nextTick(); + int hour15 = CurrentHourProvider.getCurrentHour(); + if (TimeZone.getDefault().inDaylightTime(new Date(timeFor15))) { + hour15 = "Antarctica/Troll".equals(zoneID) ? + CurrentHourProvider.getCurrentHour() - 2 : + CurrentHourProvider.getCurrentHour() - 1; + } + assertEquals(15, hour15); + } } }