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

adoroszlai 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 991a291ee37 HDDS-13485. Reduce duplication between 
ContainerSafeModeRule tests (#9194)
991a291ee37 is described below

commit 991a291ee37167a607603df5e2816edfe399d3c1
Author: Michael Chu <[email protected]>
AuthorDate: Mon Nov 3 18:18:06 2025 +0800

    HDDS-13485. Reduce duplication between ContainerSafeModeRule tests (#9194)
---
 ...java => AbstractContainerSafeModeRuleTest.java} |  86 +++++-----
 .../scm/safemode/TestECContainerSafeModeRule.java  | 176 ++-------------------
 .../safemode/TestRatisContainerSafeModeRule.java   | 174 ++------------------
 3 files changed, 69 insertions(+), 367 deletions(-)

diff --git 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestECContainerSafeModeRule.java
 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/AbstractContainerSafeModeRuleTest.java
similarity index 76%
copy from 
hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestECContainerSafeModeRule.java
copy to 
hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/AbstractContainerSafeModeRuleTest.java
index 23dcbfd979a..7bfdecc7196 100644
--- 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestECContainerSafeModeRule.java
+++ 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/AbstractContainerSafeModeRuleTest.java
@@ -27,7 +27,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import org.apache.hadoop.hdds.client.ECReplicationConfig;
 import org.apache.hadoop.hdds.conf.ConfigurationSource;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
 import org.apache.hadoop.hdds.protocol.DatanodeID;
@@ -47,11 +46,11 @@
 import org.junit.jupiter.params.provider.EnumSource;
 
 /**
- * This class tests ECContainerSafeModeRule.
+ * Abstract base class for container safe mode rule tests.
  */
-public class TestECContainerSafeModeRule {
+public abstract class AbstractContainerSafeModeRuleTest {
   private List<ContainerInfo> containers;
-  private ECContainerSafeModeRule rule;
+  private AbstractContainerSafeModeRule rule;
 
   @BeforeEach
   public void setup() throws ContainerNotFoundException {
@@ -60,8 +59,10 @@ public void setup() throws ContainerNotFoundException {
     final EventQueue eventQueue = mock(EventQueue.class);
     final SCMSafeModeManager safeModeManager = mock(SCMSafeModeManager.class);
     final SafeModeMetrics metrics = mock(SafeModeMetrics.class);
+
+    when(safeModeManager.getSafeModeMetrics()).thenReturn(metrics);
     containers = new ArrayList<>();
-    
when(containerManager.getContainers(ReplicationType.EC)).thenReturn(containers);
+    
when(containerManager.getContainers(getReplicationType())).thenReturn(containers);
     
when(containerManager.getContainer(any(ContainerID.class))).thenAnswer(invocation
 -> {
       ContainerID id = invocation.getArgument(0);
       return containers.stream()
@@ -70,17 +71,14 @@ public void setup() throws ContainerNotFoundException {
           .orElseThrow(ContainerNotFoundException::new);
     });
 
-    when(safeModeManager.getSafeModeMetrics()).thenReturn(metrics);
-
-    rule = new ECContainerSafeModeRule(eventQueue, conf, containerManager, 
safeModeManager);
+    rule = createRule(eventQueue, conf, containerManager, safeModeManager);
     rule.setValidateBasedOnReportProcessing(false);
   }
 
   @Test
-  public void testRefreshInitializeECContainers() {
-    containers.add(mockECContainer(LifeCycleState.CLOSED, 1L));
-    containers.add(mockECContainer(LifeCycleState.OPEN, 2L));
-
+  public void testRefreshInitializeContainers() {
+    containers.add(mockContainer(LifeCycleState.OPEN, 1L));
+    containers.add(mockContainer(LifeCycleState.CLOSED, 2L));
     rule.refresh(true);
 
     assertEquals(0.0, rule.getCurrentContainerThreshold());
@@ -90,47 +88,49 @@ public void testRefreshInitializeECContainers() {
   @EnumSource(value = LifeCycleState.class,
       names = {"OPEN", "CLOSING", "QUASI_CLOSED", "CLOSED", "DELETING", 
"DELETED", "RECOVERING"})
   public void testValidateReturnsTrueAndFalse(LifeCycleState state) {
-    containers.add(mockECContainer(state, 1L));
+    containers.add(mockContainer(state, 1L));
     rule.refresh(true);
+
     boolean expected = state != LifeCycleState.QUASI_CLOSED && state != 
LifeCycleState.CLOSED;
     assertEquals(expected, rule.validate());
   }
 
   @Test
-  public void testProcessECContainer() {
+  public void testProcessContainer() {
     long containerId = 123L;
-    containers.add(mockECContainer(LifeCycleState.CLOSED, containerId));
+    containers.add(mockContainer(LifeCycleState.CLOSED, containerId));
     rule.refresh(true);
 
     assertEquals(0.0, rule.getCurrentContainerThreshold());
 
-    // We need at least 3 replicas to be reported to validate the rule
-    rule.process(getNewContainerReport(containerId));
-    rule.process(getNewContainerReport(containerId));
-    rule.process(getNewContainerReport(containerId));
+    // Send as many distinct reports as the container's minReplica requires
+    int minReplica = rule.getMinReplica(ContainerID.valueOf(containerId));
+    for (int i = 0; i < minReplica; i++) {
+      rule.process(getNewContainerReport(containerId));
+    }
 
     assertEquals(1.0, rule.getCurrentContainerThreshold());
   }
 
   private NodeRegistrationContainerReport getNewContainerReport(long 
containerID) {
-    DatanodeDetails datanode = mock(DatanodeDetails.class);
+    ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
     ContainerReportsProto containerReport = mock(ContainerReportsProto.class);
     NodeRegistrationContainerReport report = 
mock(NodeRegistrationContainerReport.class);
-    ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
+    DatanodeDetails datanodeDetails = mock(DatanodeDetails.class);
 
-    when(report.getDatanodeDetails()).thenReturn(datanode);
-    when(datanode.getID()).thenReturn(DatanodeID.randomID());
     when(replica.getContainerID()).thenReturn(containerID);
     
when(containerReport.getReportsList()).thenReturn(Collections.singletonList(replica));
     when(report.getReport()).thenReturn(containerReport);
+    when(report.getDatanodeDetails()).thenReturn(datanodeDetails);
+    when(datanodeDetails.getID()).thenReturn(DatanodeID.randomID());
+
     return report;
   }
 
   @Test
   public void testAllContainersClosed() {
-    containers.add(mockECContainer(LifeCycleState.CLOSED, 11L));
-    containers.add(mockECContainer(LifeCycleState.CLOSED, 32L));
-
+    containers.add(mockContainer(LifeCycleState.CLOSED, 11L));
+    containers.add(mockContainer(LifeCycleState.CLOSED, 32L));
     rule.refresh(true);
 
     assertEquals(0.0, rule.getCurrentContainerThreshold(), "Threshold should 
be 0.0 when all containers are closed");
@@ -139,9 +139,8 @@ public void testAllContainersClosed() {
 
   @Test
   public void testAllContainersOpen() {
-    containers.add(mockECContainer(LifeCycleState.OPEN, 11L));
-    containers.add(mockECContainer(LifeCycleState.OPEN, 32L));
-
+    containers.add(mockContainer(LifeCycleState.OPEN, 11L));
+    containers.add(mockContainer(LifeCycleState.OPEN, 32L));
     rule.refresh(true);
 
     assertEquals(1.0, rule.getCurrentContainerThreshold(), "Threshold should 
be 1.0 when all containers are open");
@@ -151,8 +150,7 @@ public void testAllContainersOpen() {
   @Test
   public void testDuplicateContainerIdsInReports() {
     long containerId = 42L;
-    containers.add(mockECContainer(LifeCycleState.OPEN, containerId));
-
+    containers.add(mockContainer(LifeCycleState.OPEN, containerId));
     rule.refresh(true);
 
     ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
@@ -173,11 +171,10 @@ public void testDuplicateContainerIdsInReports() {
   }
 
   @Test
-  public void testValidateBasedOnReportProcessingTrue() throws Exception {
+  public void testValidateBasedOnReportProcessingTrue() {
     rule.setValidateBasedOnReportProcessing(true);
     long containerId = 1L;
-    containers.add(mockECContainer(LifeCycleState.OPEN, containerId));
-
+    containers.add(mockContainer(LifeCycleState.OPEN, containerId));
     rule.refresh(true);
 
     ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
@@ -191,20 +188,19 @@ public void testValidateBasedOnReportProcessingTrue() 
throws Exception {
     when(report.getDatanodeDetails()).thenReturn(datanodeDetails);
     when(datanodeDetails.getID()).thenReturn(DatanodeID.randomID());
 
-
     rule.process(report);
 
     assertTrue(rule.validate(), "Should validate based on reported 
containers");
   }
 
-  private static ContainerInfo mockECContainer(LifeCycleState state, long 
containerID) {
-    ContainerInfo container = mock(ContainerInfo.class);
-    when(container.getReplicationType()).thenReturn(ReplicationType.EC);
-    when(container.getState()).thenReturn(state);
-    when(container.getContainerID()).thenReturn(containerID);
-    when(container.containerID()).thenReturn(ContainerID.valueOf(containerID));
-    when(container.getNumberOfKeys()).thenReturn(1L);
-    when(container.getReplicationConfig()).thenReturn(new 
ECReplicationConfig(3, 2));
-    return container;
-  }
+  protected abstract ReplicationType getReplicationType();
+
+  protected abstract AbstractContainerSafeModeRule createRule(
+      EventQueue eventQueue,
+      ConfigurationSource conf,
+      ContainerManager containerManager,
+      SCMSafeModeManager safeModeManager
+  );
+
+  protected abstract ContainerInfo mockContainer(LifeCycleState state, long 
containerID);
 }
diff --git 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestECContainerSafeModeRule.java
 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestECContainerSafeModeRule.java
index 23dcbfd979a..8390747cf5c 100644
--- 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestECContainerSafeModeRule.java
+++ 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestECContainerSafeModeRule.java
@@ -17,187 +17,39 @@
 
 package org.apache.hadoop.hdds.scm.safemode;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 import org.apache.hadoop.hdds.client.ECReplicationConfig;
 import org.apache.hadoop.hdds.conf.ConfigurationSource;
-import org.apache.hadoop.hdds.protocol.DatanodeDetails;
-import org.apache.hadoop.hdds.protocol.DatanodeID;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleState;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType;
-import 
org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReplicaProto;
-import 
org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReportsProto;
 import org.apache.hadoop.hdds.scm.container.ContainerID;
 import org.apache.hadoop.hdds.scm.container.ContainerInfo;
 import org.apache.hadoop.hdds.scm.container.ContainerManager;
-import org.apache.hadoop.hdds.scm.container.ContainerNotFoundException;
-import 
org.apache.hadoop.hdds.scm.server.SCMDatanodeProtocolServer.NodeRegistrationContainerReport;
 import org.apache.hadoop.hdds.server.events.EventQueue;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.EnumSource;
 
 /**
  * This class tests ECContainerSafeModeRule.
  */
-public class TestECContainerSafeModeRule {
-  private List<ContainerInfo> containers;
-  private ECContainerSafeModeRule rule;
-
-  @BeforeEach
-  public void setup() throws ContainerNotFoundException {
-    final ContainerManager containerManager = mock(ContainerManager.class);
-    final ConfigurationSource conf = mock(ConfigurationSource.class);
-    final EventQueue eventQueue = mock(EventQueue.class);
-    final SCMSafeModeManager safeModeManager = mock(SCMSafeModeManager.class);
-    final SafeModeMetrics metrics = mock(SafeModeMetrics.class);
-    containers = new ArrayList<>();
-    
when(containerManager.getContainers(ReplicationType.EC)).thenReturn(containers);
-    
when(containerManager.getContainer(any(ContainerID.class))).thenAnswer(invocation
 -> {
-      ContainerID id = invocation.getArgument(0);
-      return containers.stream()
-          .filter(c -> c.containerID().equals(id))
-          .findFirst()
-          .orElseThrow(ContainerNotFoundException::new);
-    });
-
-    when(safeModeManager.getSafeModeMetrics()).thenReturn(metrics);
-
-    rule = new ECContainerSafeModeRule(eventQueue, conf, containerManager, 
safeModeManager);
-    rule.setValidateBasedOnReportProcessing(false);
-  }
-
-  @Test
-  public void testRefreshInitializeECContainers() {
-    containers.add(mockECContainer(LifeCycleState.CLOSED, 1L));
-    containers.add(mockECContainer(LifeCycleState.OPEN, 2L));
-
-    rule.refresh(true);
-
-    assertEquals(0.0, rule.getCurrentContainerThreshold());
-  }
-
-  @ParameterizedTest
-  @EnumSource(value = LifeCycleState.class,
-      names = {"OPEN", "CLOSING", "QUASI_CLOSED", "CLOSED", "DELETING", 
"DELETED", "RECOVERING"})
-  public void testValidateReturnsTrueAndFalse(LifeCycleState state) {
-    containers.add(mockECContainer(state, 1L));
-    rule.refresh(true);
-    boolean expected = state != LifeCycleState.QUASI_CLOSED && state != 
LifeCycleState.CLOSED;
-    assertEquals(expected, rule.validate());
-  }
-
-  @Test
-  public void testProcessECContainer() {
-    long containerId = 123L;
-    containers.add(mockECContainer(LifeCycleState.CLOSED, containerId));
-    rule.refresh(true);
-
-    assertEquals(0.0, rule.getCurrentContainerThreshold());
-
-    // We need at least 3 replicas to be reported to validate the rule
-    rule.process(getNewContainerReport(containerId));
-    rule.process(getNewContainerReport(containerId));
-    rule.process(getNewContainerReport(containerId));
-
-    assertEquals(1.0, rule.getCurrentContainerThreshold());
-  }
-
-  private NodeRegistrationContainerReport getNewContainerReport(long 
containerID) {
-    DatanodeDetails datanode = mock(DatanodeDetails.class);
-    ContainerReportsProto containerReport = mock(ContainerReportsProto.class);
-    NodeRegistrationContainerReport report = 
mock(NodeRegistrationContainerReport.class);
-    ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
-
-    when(report.getDatanodeDetails()).thenReturn(datanode);
-    when(datanode.getID()).thenReturn(DatanodeID.randomID());
-    when(replica.getContainerID()).thenReturn(containerID);
-    
when(containerReport.getReportsList()).thenReturn(Collections.singletonList(replica));
-    when(report.getReport()).thenReturn(containerReport);
-    return report;
-  }
-
-  @Test
-  public void testAllContainersClosed() {
-    containers.add(mockECContainer(LifeCycleState.CLOSED, 11L));
-    containers.add(mockECContainer(LifeCycleState.CLOSED, 32L));
-
-    rule.refresh(true);
-
-    assertEquals(0.0, rule.getCurrentContainerThreshold(), "Threshold should 
be 0.0 when all containers are closed");
-    assertFalse(rule.validate(), "Validate should return false when all 
containers are closed");
-  }
-
-  @Test
-  public void testAllContainersOpen() {
-    containers.add(mockECContainer(LifeCycleState.OPEN, 11L));
-    containers.add(mockECContainer(LifeCycleState.OPEN, 32L));
-
-    rule.refresh(true);
-
-    assertEquals(1.0, rule.getCurrentContainerThreshold(), "Threshold should 
be 1.0 when all containers are open");
-    assertTrue(rule.validate(), "Validate should return true when all 
containers are open");
+public class TestECContainerSafeModeRule extends 
AbstractContainerSafeModeRuleTest {
+  @Override
+  protected ReplicationType getReplicationType() {
+    return ReplicationType.EC;
   }
 
-  @Test
-  public void testDuplicateContainerIdsInReports() {
-    long containerId = 42L;
-    containers.add(mockECContainer(LifeCycleState.OPEN, containerId));
-
-    rule.refresh(true);
-
-    ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
-    ContainerReportsProto containerReport = mock(ContainerReportsProto.class);
-    NodeRegistrationContainerReport report = 
mock(NodeRegistrationContainerReport.class);
-    DatanodeDetails datanodeDetails = mock(DatanodeDetails.class);
-
-    when(replica.getContainerID()).thenReturn(containerId);
-    
when(containerReport.getReportsList()).thenReturn(Collections.singletonList(replica));
-    when(report.getReport()).thenReturn(containerReport);
-    when(report.getDatanodeDetails()).thenReturn(datanodeDetails);
-    when(datanodeDetails.getID()).thenReturn(DatanodeID.randomID());
-
-    rule.process(report);
-    rule.process(report);
-
-    assertEquals(1.0, rule.getCurrentContainerThreshold(), "Duplicated 
containers should be counted only once");
-  }
-
-  @Test
-  public void testValidateBasedOnReportProcessingTrue() throws Exception {
-    rule.setValidateBasedOnReportProcessing(true);
-    long containerId = 1L;
-    containers.add(mockECContainer(LifeCycleState.OPEN, containerId));
-
-    rule.refresh(true);
-
-    ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
-    ContainerReportsProto reportsProto = mock(ContainerReportsProto.class);
-    NodeRegistrationContainerReport report = 
mock(NodeRegistrationContainerReport.class);
-    DatanodeDetails datanodeDetails = mock(DatanodeDetails.class);
-
-    when(replica.getContainerID()).thenReturn(containerId);
-    
when(reportsProto.getReportsList()).thenReturn(Collections.singletonList(replica));
-    when(report.getReport()).thenReturn(reportsProto);
-    when(report.getDatanodeDetails()).thenReturn(datanodeDetails);
-    when(datanodeDetails.getID()).thenReturn(DatanodeID.randomID());
-
-
-    rule.process(report);
-
-    assertTrue(rule.validate(), "Should validate based on reported 
containers");
+  @Override
+  protected AbstractContainerSafeModeRule createRule(
+      EventQueue eventQueue,
+      ConfigurationSource conf,
+      ContainerManager containerManager,
+      SCMSafeModeManager safeModeManager
+  ) {
+    return new ECContainerSafeModeRule(eventQueue, conf, containerManager, 
safeModeManager);
   }
 
-  private static ContainerInfo mockECContainer(LifeCycleState state, long 
containerID) {
+  @Override
+  protected ContainerInfo mockContainer(LifeCycleState state, long 
containerID) {
     ContainerInfo container = mock(ContainerInfo.class);
     when(container.getReplicationType()).thenReturn(ReplicationType.EC);
     when(container.getState()).thenReturn(state);
diff --git 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestRatisContainerSafeModeRule.java
 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestRatisContainerSafeModeRule.java
index 58929ffdd3f..d6b34ec8e75 100644
--- 
a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestRatisContainerSafeModeRule.java
+++ 
b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestRatisContainerSafeModeRule.java
@@ -17,186 +17,41 @@
 
 package org.apache.hadoop.hdds.scm.safemode;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 import org.apache.hadoop.hdds.client.RatisReplicationConfig;
 import org.apache.hadoop.hdds.conf.ConfigurationSource;
-import org.apache.hadoop.hdds.protocol.DatanodeDetails;
-import org.apache.hadoop.hdds.protocol.DatanodeID;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleState;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType;
-import 
org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReplicaProto;
-import 
org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReportsProto;
 import org.apache.hadoop.hdds.scm.container.ContainerID;
 import org.apache.hadoop.hdds.scm.container.ContainerInfo;
 import org.apache.hadoop.hdds.scm.container.ContainerManager;
-import org.apache.hadoop.hdds.scm.container.ContainerNotFoundException;
-import 
org.apache.hadoop.hdds.scm.server.SCMDatanodeProtocolServer.NodeRegistrationContainerReport;
 import org.apache.hadoop.hdds.server.events.EventQueue;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.EnumSource;
 
 /**
  * This class tests RatisContainerSafeModeRule.
  */
-public class TestRatisContainerSafeModeRule {
+public class TestRatisContainerSafeModeRule extends 
AbstractContainerSafeModeRuleTest {
 
-  private List<ContainerInfo> containers;
-  private RatisContainerSafeModeRule rule;
-
-  @BeforeEach
-  public void setup() throws ContainerNotFoundException {
-    final ContainerManager containerManager = mock(ContainerManager.class);
-    final ConfigurationSource conf = mock(ConfigurationSource.class);
-    final EventQueue eventQueue = mock(EventQueue.class);
-    final SCMSafeModeManager safeModeManager = mock(SCMSafeModeManager.class);
-    final SafeModeMetrics metrics = mock(SafeModeMetrics.class);
-
-    when(safeModeManager.getSafeModeMetrics()).thenReturn(metrics);
-    containers = new ArrayList<>();
-    
when(containerManager.getContainers(ReplicationType.RATIS)).thenReturn(containers);
-    
when(containerManager.getContainer(any(ContainerID.class))).thenAnswer(invocation
 -> {
-      ContainerID id = invocation.getArgument(0);
-      return containers.stream()
-          .filter(c -> c.containerID().equals(id))
-          .findFirst()
-          .orElseThrow(ContainerNotFoundException::new);
-    });
-
-    rule = new RatisContainerSafeModeRule(eventQueue, conf, containerManager, 
safeModeManager);
-    rule.setValidateBasedOnReportProcessing(false);
-  }
-
-  @Test
-  public void testRefreshInitializeRatisContainers() {
-    containers.add(mockRatisContainer(LifeCycleState.CLOSED, 1L));
-    containers.add(mockRatisContainer(LifeCycleState.OPEN, 2L));
-
-    rule.refresh(true);
-
-    assertEquals(0.0, rule.getCurrentContainerThreshold());
-  }
-
-  @ParameterizedTest
-  @EnumSource(value = LifeCycleState.class,
-      names = {"OPEN", "CLOSING", "QUASI_CLOSED", "CLOSED", "DELETING", 
"DELETED", "RECOVERING"})
-  public void testValidateReturnsTrueAndFalse(LifeCycleState state) {
-    containers.add(mockRatisContainer(state, 1L));
-    rule.refresh(true);
-
-    boolean expected = state != LifeCycleState.QUASI_CLOSED && state != 
LifeCycleState.CLOSED;
-    assertEquals(expected, rule.validate());
+  @Override
+  protected ReplicationType getReplicationType() {
+    return ReplicationType.RATIS;
   }
 
-  @Test
-  public void testProcessRatisContainer() {
-    long containerId = 123L;
-    containers.add(mockRatisContainer(LifeCycleState.CLOSED, containerId));
-
-    rule.refresh(true);
-
-    assertEquals(0.0, rule.getCurrentContainerThreshold());
-
-    ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
-    List<ContainerReplicaProto> replicas = new ArrayList<>();
-    replicas.add(replica);
-    ContainerReportsProto containerReport = mock(ContainerReportsProto.class);
-    NodeRegistrationContainerReport report = 
mock(NodeRegistrationContainerReport.class);
-    DatanodeDetails datanodeDetails = mock(DatanodeDetails.class);
-
-    when(replica.getContainerID()).thenReturn(containerId);
-    when(containerReport.getReportsList()).thenReturn(replicas);
-    when(report.getReport()).thenReturn(containerReport);
-    when(report.getDatanodeDetails()).thenReturn(datanodeDetails);
-    when(datanodeDetails.getID()).thenReturn(DatanodeID.randomID());
-
-    rule.process(report);
-
-    assertEquals(1.0, rule.getCurrentContainerThreshold());
-  }
-
-  @Test
-  public void testAllContainersClosed() throws ContainerNotFoundException {
-    containers.add(mockRatisContainer(LifeCycleState.CLOSED, 11L));
-    containers.add(mockRatisContainer(LifeCycleState.CLOSED, 32L));
-
-    rule.refresh(true);
-
-    assertEquals(0.0, rule.getCurrentContainerThreshold(), "Threshold should 
be 0.0 when all containers are closed");
-    assertFalse(rule.validate(), "Validate should return false when all 
containers are closed");
+  @Override
+  protected AbstractContainerSafeModeRule createRule(
+      EventQueue eventQueue,
+      ConfigurationSource conf,
+      ContainerManager containerManager,
+      SCMSafeModeManager safeModeManager
+  ) {
+    return new RatisContainerSafeModeRule(eventQueue, conf, containerManager, 
safeModeManager);
   }
 
-  @Test
-  public void testAllContainersOpen() {
-    containers.add(mockRatisContainer(LifeCycleState.OPEN, 11L));
-    containers.add(mockRatisContainer(LifeCycleState.OPEN, 32L));
-
-    rule.refresh(false);
-
-    assertEquals(1.0, rule.getCurrentContainerThreshold(), "Threshold should 
be 1.0 when all containers are open");
-    assertTrue(rule.validate(), "Validate should return true when all 
containers are open");
-  }
-
-  @Test
-  public void testDuplicateContainerIdsInReports() {
-    long containerId = 42L;
-    containers.add(mockRatisContainer(LifeCycleState.OPEN, containerId));
-
-    rule.refresh(true);
-
-    ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
-    ContainerReportsProto containerReport = mock(ContainerReportsProto.class);
-    NodeRegistrationContainerReport report = 
mock(NodeRegistrationContainerReport.class);
-    DatanodeDetails datanodeDetails = mock(DatanodeDetails.class);
-
-    when(replica.getContainerID()).thenReturn(containerId);
-    
when(containerReport.getReportsList()).thenReturn(Collections.singletonList(replica));
-    when(report.getReport()).thenReturn(containerReport);
-    when(report.getDatanodeDetails()).thenReturn(datanodeDetails);
-    when(datanodeDetails.getID()).thenReturn(DatanodeID.randomID());
-
-    rule.process(report);
-    rule.process(report);
-
-    assertEquals(1.0, rule.getCurrentContainerThreshold(), "Duplicated 
containers should be counted only once");
-  }
-
-  @Test
-  public void testValidateBasedOnReportProcessingTrue() throws Exception {
-    rule.setValidateBasedOnReportProcessing(true);
-    long containerId = 1L;
-    containers.add(mockRatisContainer(LifeCycleState.OPEN, containerId));
-
-    rule.refresh(false);
-
-    ContainerReplicaProto replica = mock(ContainerReplicaProto.class);
-    ContainerReportsProto reportsProto = mock(ContainerReportsProto.class);
-    NodeRegistrationContainerReport report = 
mock(NodeRegistrationContainerReport.class);
-    DatanodeDetails datanodeDetails = mock(DatanodeDetails.class);
-
-    when(replica.getContainerID()).thenReturn(containerId);
-    
when(reportsProto.getReportsList()).thenReturn(Collections.singletonList(replica));
-    when(report.getReport()).thenReturn(reportsProto);
-    when(report.getDatanodeDetails()).thenReturn(datanodeDetails);
-    when(datanodeDetails.getID()).thenReturn(DatanodeID.randomID());
-
-    rule.process(report);
-
-    assertTrue(rule.validate(), "Should validate based on reported 
containers");
-  }
-
-  private static ContainerInfo mockRatisContainer(LifeCycleState state, long 
containerID) {
+  @Override
+  protected ContainerInfo mockContainer(LifeCycleState state, long 
containerID) {
     ContainerInfo container = mock(ContainerInfo.class);
     when(container.getReplicationType()).thenReturn(ReplicationType.RATIS);
     when(container.getState()).thenReturn(state);
@@ -207,5 +62,4 @@ private static ContainerInfo 
mockRatisContainer(LifeCycleState state, long conta
         
.thenReturn(RatisReplicationConfig.getInstance(HddsProtos.ReplicationFactor.THREE));
     return container;
   }
-
 }


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

Reply via email to