This is an automated email from the ASF dual-hosted git repository.

zhangduo pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2 by this push:
     new 3b3ff3d2265 HBASE-29771 TestThreadHandlerUsageQuota fails on flaky 
dashboard (#7541)
3b3ff3d2265 is described below

commit 3b3ff3d22659abee4ccefd2345e3f78dbba0ced0
Author: Duo Zhang <[email protected]>
AuthorDate: Mon Dec 15 18:35:20 2025 +0800

    HBASE-29771 TestThreadHandlerUsageQuota fails on flaky dashboard (#7541)
    
    Signed-off-by: Nihal Jain <[email protected]>
    (cherry picked from commit 0f6bbde6a8b8086b5140d2b5a55101121139c926)
---
 .../hadoop/hbase/quotas/DefaultOperationQuota.java |  5 ++-
 .../hbase/quotas/TestThreadHandlerUsageQuota.java  | 40 ++++++++++++----------
 .../hadoop/hbase/quotas/ThrottleQuotaTestUtil.java |  2 +-
 3 files changed, 26 insertions(+), 21 deletions(-)

diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/DefaultOperationQuota.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/DefaultOperationQuota.java
index 16082bff98f..e7bd67c4797 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/DefaultOperationQuota.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/DefaultOperationQuota.java
@@ -310,6 +310,8 @@ public class DefaultOperationQuota implements 
OperationQuota {
     return calculateReadCapacityUnit(actualSize) - 
calculateReadCapacityUnit(estimateSize);
   }
 
+  // TODO: the implementation of this method seems incorrect, although finally 
we will correct the
+  // usage when closing
   private long calculateHandlerUsageTimeEstimate(final double 
requestsPerSecond,
     final int numHandlerThreads) {
     if (requestsPerSecond <= numHandlerThreads) {
@@ -328,6 +330,7 @@ public class DefaultOperationQuota implements 
OperationQuota {
     long currentTime = EnvironmentEdgeManager.currentTime();
     long startTime = 
RpcServer.getCurrentCall().map(RpcCall::getStartTime).orElse(currentTime);
     long timeElapsed = currentTime - startTime;
-    return handlerUsageTimeConsumed - timeElapsed;
+    // actualTime - estimateTime
+    return timeElapsed - handlerUsageTimeConsumed;
   }
 }
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestThreadHandlerUsageQuota.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestThreadHandlerUsageQuota.java
index 58b15ec2429..9aeb96eaf3b 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestThreadHandlerUsageQuota.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestThreadHandlerUsageQuota.java
@@ -18,12 +18,12 @@
 package org.apache.hadoop.hbase.quotas;
 
 import static 
org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerUserCacheRefresh;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.lessThan;
 
 import java.io.IOException;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -34,25 +34,22 @@ import 
org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.RegionServerTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ RegionServerTests.class, MediumTests.class })
+@Tag(RegionServerTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestThreadHandlerUsageQuota {
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestThreadHandlerUsageQuota.class);
+
   private static final HBaseTestingUtility TEST_UTIL = new 
HBaseTestingUtility();
   private static final TableName TABLE_NAME = 
TableName.valueOf(UUID.randomUUID().toString());
-  private static final int REFRESH_TIME = 5;
   private static final byte[] FAMILY = Bytes.toBytes("cf");
   private static final byte[] QUALIFIER = Bytes.toBytes("q");
   private static final int MAX_OPS = 1000;
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     ThrottleQuotaTestUtil.clearQuotaCache(TEST_UTIL);
     EnvironmentEdgeManager.reset();
@@ -60,11 +57,10 @@ public class TestThreadHandlerUsageQuota {
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     // Enable quotas
     TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true);
-    TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, 
REFRESH_TIME);
 
     // Don't cache blocks to make IO predictable
     
TEST_UTIL.getConfiguration().setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 
0.0f);
@@ -86,8 +82,8 @@ public class TestThreadHandlerUsageQuota {
 
       configureThrottle();
       long throttledAttempts = ThrottleQuotaTestUtil.doGets(MAX_OPS, FAMILY, 
QUALIFIER, table);
-      assertTrue("Throttled attempts should be less than unthrottled attempts",
-        throttledAttempts < unthrottledAttempts);
+      assertThat("Throttled attempts should be less than unthrottled 
attempts", throttledAttempts,
+        lessThan(unthrottledAttempts));
     }
   }
 
@@ -99,8 +95,8 @@ public class TestThreadHandlerUsageQuota {
 
       configureThrottle();
       long throttledAttempts = ThrottleQuotaTestUtil.doPuts(MAX_OPS, FAMILY, 
QUALIFIER, table);
-      assertTrue("Throttled attempts should be less than unthrottled attempts",
-        throttledAttempts < unthrottledAttempts);
+      assertThat("Throttled attempts should be less than unthrottled 
attempts", throttledAttempts,
+        lessThan(unthrottledAttempts));
     }
   }
 
@@ -110,6 +106,9 @@ public class TestThreadHandlerUsageQuota {
         ThrottleType.REQUEST_HANDLER_USAGE_MS, 1, TimeUnit.SECONDS));
     }
     triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAME);
+    // increase the tick so we can calculate a positive rpc request time, and 
then consume all the
+    // available quota and make request fail next time
+    ThrottleQuotaTestUtil.envEdge.setValue(System.currentTimeMillis() + 10000);
   }
 
   private void unthrottleUser() throws Exception {
@@ -118,6 +117,9 @@ public class TestThreadHandlerUsageQuota {
         ThrottleType.REQUEST_HANDLER_USAGE_MS));
     }
     triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAME);
+    // increase the tick here too to make sure that we truly skip the quota 
check, not because we
+    // pass the quota check
+    ThrottleQuotaTestUtil.envEdge.setValue(System.currentTimeMillis() + 10000);
   }
 
   private static String getUserName() throws IOException {
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/ThrottleQuotaTestUtil.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/ThrottleQuotaTestUtil.java
index b343799b89d..13f35af19eb 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/ThrottleQuotaTestUtil.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/ThrottleQuotaTestUtil.java
@@ -47,7 +47,7 @@ import org.slf4j.LoggerFactory;
 public final class ThrottleQuotaTestUtil {
 
   private final static Logger LOG = 
LoggerFactory.getLogger(ThrottleQuotaTestUtil.class);
-  private static ManualEnvironmentEdge envEdge = new ManualEnvironmentEdge();
+  static ManualEnvironmentEdge envEdge = new ManualEnvironmentEdge();
   private final static int REFRESH_TIME = 30 * 60000;
   static {
     envEdge.setValue(EnvironmentEdgeManager.currentTime());

Reply via email to