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

Gargi-jais11 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 1503ace172d HDDS-15310. [DiskBalancer] Fix Threshold range in negative 
(#10308).
1503ace172d is described below

commit 1503ace172d6b63eea2a895dadf0dbfd08a45ed4
Author: Gargi Jaiswal <[email protected]>
AuthorDate: Thu May 21 09:46:37 2026 +0530

    HDDS-15310. [DiskBalancer] Fix Threshold range in negative (#10308).
---
 .../cli/datanode/DiskBalancerReportSubcommand.java |  8 +--
 .../cli/datanode/TestDiskBalancerSubCommands.java  | 63 ++++++++++++++++++++++
 2 files changed, 67 insertions(+), 4 deletions(-)

diff --git 
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/DiskBalancerReportSubcommand.java
 
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/DiskBalancerReportSubcommand.java
index e124ee0bc16..af730199ed8 100644
--- 
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/DiskBalancerReportSubcommand.java
+++ 
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/DiskBalancerReportSubcommand.java
@@ -108,8 +108,8 @@ private String 
generateReport(List<DatanodeDiskBalancerInfoProto> protos) {
           && p.getDiskBalancerConf().hasThreshold()) {
         double idealUsage = p.getIdealUsage();
         double threshold = p.getDiskBalancerConf().getThreshold();
-        double lt = idealUsage - threshold / 100.0;
-        double ut = idealUsage + threshold / 100.0;
+        double lt = Math.max(0.0, idealUsage - threshold / 100.0);
+        double ut = Math.min(1.0, idealUsage + threshold / 100.0);
         header.append("IdealUsage: ").append(String.format("%.8f", idealUsage))
             .append(" | Threshold: ").append(threshold).append('%')
             .append(" | ThresholdRange: (").append(String.format("%.8f", lt))
@@ -192,8 +192,8 @@ private Map<String, Object> 
toJson(DatanodeDiskBalancerInfoProto report) {
         && report.getDiskBalancerConf().hasThreshold()) {
       double idealUsage = report.getIdealUsage();
       double threshold = report.getDiskBalancerConf().getThreshold();
-      double lt = idealUsage - threshold / 100.0;
-      double ut = idealUsage + threshold / 100.0;
+      double lt = Math.max(0.0, idealUsage - threshold / 100.0);
+      double ut = Math.min(1.0, idealUsage + threshold / 100.0);
       result.put("idealUsage", String.format("%.8f", idealUsage));
       result.put("threshold %", report.getDiskBalancerConf().getThreshold());
       result.put("thresholdRange", String.format("(%.08f, %.08f)", lt, ut));
diff --git 
a/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestDiskBalancerSubCommands.java
 
b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestDiskBalancerSubCommands.java
index fd6450c1124..e5a418fb0ae 100644
--- 
a/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestDiskBalancerSubCommands.java
+++ 
b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestDiskBalancerSubCommands.java
@@ -18,6 +18,7 @@
 package org.apache.hadoop.hdds.scm.cli.datanode;
 
 import static 
org.apache.hadoop.hdds.HddsConfigKeys.HDDS_DATANODE_CLIENT_PORT_DEFAULT;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -42,6 +43,7 @@
 import java.util.Random;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 import org.apache.hadoop.hdds.HddsConfigKeys;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
@@ -56,6 +58,9 @@
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.mockito.MockedConstruction;
 import org.mockito.MockedStatic;
 import picocli.CommandLine;
@@ -590,6 +595,45 @@ public void testStatusDiskBalancerWithStdin() throws 
Exception {
 
   // ========== DiskBalancerReportSubcommand Tests ==========
 
+  static Stream<Arguments> thresholdRangeReportCases() {
+    return Stream.of(
+        Arguments.of(0.08426521, 10.0, false,
+            "ThresholdRange: (0.00000000, 0.18426521)", "ThresholdRange: (-"),
+        Arguments.of(0.95, 10.0, false,
+            "ThresholdRange: (0.85000000, 1.00000000)", "1.05000000"),
+        Arguments.of(0.95, 10.0, true,
+            "\"thresholdRange\" : \"(0.85000000, 1.00000000)\"", 
"1.05000000"));
+  }
+
+  @ParameterizedTest(name = "idealUsage={0}, threshold={1}%, json={2}")
+  @MethodSource("thresholdRangeReportCases")
+  public void testReportThresholdRangeClamped(double idealUsage,
+      double thresholdPercent, boolean jsonOutput, String 
expectedRangeSubstring,
+      String mustNotContain) throws Exception {
+    outContent.reset();
+    errContent.reset();
+
+    DiskBalancerReportSubcommand cmd = new DiskBalancerReportSubcommand();
+    DatanodeDiskBalancerInfoProto reportProto =
+        createReportProto("host-1", idealUsage, thresholdPercent);
+
+    when(mockProtocol.getDiskBalancerInfo()).thenReturn(reportProto);
+
+    try (DiskBalancerMocks mocks = setupAllMocks()) {
+      CommandLine c = new CommandLine(cmd);
+      if (jsonOutput) {
+        c.parseArgs("--json", "host-1");
+      } else {
+        c.parseArgs("host-1");
+      }
+      cmd.call();
+
+      String output = outContent.toString(DEFAULT_ENCODING);
+      assertThat(output).contains(expectedRangeSubstring);
+      assertThat(output).doesNotContain(mustNotContain);
+    }
+  }
+
   @Test
   public void testReportDiskBalancerWithInServiceDatanodes() throws Exception {
     DiskBalancerReportSubcommand cmd = new DiskBalancerReportSubcommand();
@@ -824,6 +868,25 @@ private DatanodeDiskBalancerInfoProto 
generateRandomReportProto(String hostname)
         .build();
   }
 
+  private DatanodeDiskBalancerInfoProto createReportProto(String hostname, 
double idealUsage,
+      double thresholdPercent) {
+    DatanodeDetailsProto nodeProto = DatanodeDetailsProto.newBuilder()
+        .setHostName(hostname)
+        .setIpAddress("127.0.0.1")
+        .addPorts(HddsProtos.Port.newBuilder()
+            .setName("CLIENT_RPC")
+            .setValue(HDDS_DATANODE_CLIENT_PORT_DEFAULT)
+            .build())
+        .build();
+
+    return DatanodeDiskBalancerInfoProto.newBuilder()
+        .setNode(nodeProto)
+        .setCurrentVolumeDensitySum(0.1408700123786014)
+        .setIdealUsage(idealUsage)
+        .setDiskBalancerConf(createConfigProto(thresholdPercent, 100L, 5, 
true))
+        .build();
+  }
+
   private DiskBalancerConfigurationProto createConfigProto(double threshold, 
long bandwidthInMB, int parallelThread,
       boolean stopAfterDiskEven) {
     return DiskBalancerConfigurationProto.newBuilder()


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to