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 1f5a8208f0a..ebbaa456047 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 @@ -17,15 +17,18 @@ */ package org.apache.hadoop.hbase.regionserver.compactions; +import com.google.errorprone.annotations.RestrictedApi; import java.util.Calendar; import java.util.GregorianCalendar; - import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.yetus.audience.InterfaceAudience; @InterfaceAudience.Private public class CurrentHourProvider { - private CurrentHourProvider() { throw new AssertionError(); } + + private CurrentHourProvider() { + throw new AssertionError(); + } private static final class Tick { final int currentHour; @@ -37,7 +40,7 @@ public class CurrentHourProvider { } } - static Tick nextTick() { + private static Tick nextTick() { Calendar calendar = new GregorianCalendar(); calendar.setTimeInMillis(EnvironmentEdgeManager.currentTime()); int currentHour = calendar.get(Calendar.HOUR_OF_DAY); @@ -52,15 +55,21 @@ public class CurrentHourProvider { calendar.set(Calendar.MILLISECOND, 0); } - static volatile Tick tick = nextTick(); + private static volatile Tick tick = nextTick(); public static int getCurrentHour() { Tick tick = CurrentHourProvider.tick; if (EnvironmentEdgeManager.currentTime() < tick.expirationTimeInMillis) { return tick.currentHour; } - - CurrentHourProvider.tick = tick = nextTick(); + tick = nextTick(); + CurrentHourProvider.tick = tick; return tick.currentHour; } + + @RestrictedApi(explanation = "Should only be called in tests", link = "", + allowedOnPath = ".*/src/test/.*") + static void advanceTick() { + tick = nextTick(); + } } 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 f0f122bd2fe..4a0e1d0fbcb 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 @@ -20,37 +20,39 @@ package org.apache.hadoop.hbase.regionserver.compactions; import static org.junit.Assert.assertEquals; import java.util.Date; +import java.util.List; import java.util.TimeZone; import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.testclassification.RegionServerTests; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.junit.ClassRule; -import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; -@Category({RegionServerTests.class, SmallTests.class}) -@Ignore("See HBASE-25385") +import org.apache.hbase.thirdparty.com.google.common.collect.Lists; + +@Category({ RegionServerTests.class, SmallTests.class }) public class TestCurrentHourProvider { + @ClassRule public static final HBaseClassTestRule CLASS_RULE = - HBaseClassTestRule.forClass(TestCurrentHourProvider.class); + HBaseClassTestRule.forClass(TestCurrentHourProvider.class); + + private static final List ZONE_IDS = Lists.newArrayList("UTC", "US/Pacific", "Etc/GMT+8"); /** - * In timezone GMT+08:00, the unix time of 2020-08-20 11:52:41 is 1597895561000 - * 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. + * In timezone GMT+08:00, the unix time of 2020-08-20 11:52:41 is 1597895561000 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. If in DaylightTime, we need reduce + * one hour. */ @Test public void testWithEnvironmentEdge() { // test for all available zoneID - for (String zoneID : TimeZone.getAvailableIDs()) { + for (String zoneID : ZONE_IDS) { TimeZone timezone = TimeZone.getTimeZone(zoneID); TimeZone.setDefault(timezone); @@ -58,12 +60,10 @@ public class TestCurrentHourProvider { long deltaFor11 = TimeZone.getDefault().getRawOffset() - 28800000; long timeFor11 = 1597895561000L - deltaFor11; EnvironmentEdgeManager.injectEdge(() -> timeFor11); - CurrentHourProvider.tick = CurrentHourProvider.nextTick(); + CurrentHourProvider.advanceTick(); int hour11 = CurrentHourProvider.getCurrentHour(); if (TimeZone.getDefault().inDaylightTime(new Date(timeFor11))) { - hour11 = "Antarctica/Troll".equals(zoneID) ? - CurrentHourProvider.getCurrentHour() - 2 : - CurrentHourProvider.getCurrentHour() - 1; + hour11 = CurrentHourProvider.getCurrentHour() - 1; } assertEquals(11, hour11); @@ -71,12 +71,10 @@ public class TestCurrentHourProvider { long deltaFor15 = TimeZone.getDefault().getRawOffset() - 28800000; long timeFor15 = 1597907081000L - deltaFor15; EnvironmentEdgeManager.injectEdge(() -> timeFor15); - CurrentHourProvider.tick = CurrentHourProvider.nextTick(); + CurrentHourProvider.advanceTick(); int hour15 = CurrentHourProvider.getCurrentHour(); if (TimeZone.getDefault().inDaylightTime(new Date(timeFor15))) { - hour15 = "Antarctica/Troll".equals(zoneID) ? - CurrentHourProvider.getCurrentHour() - 2 : - CurrentHourProvider.getCurrentHour() - 1; + hour15 = CurrentHourProvider.getCurrentHour() - 1; } assertEquals(15, hour15); }