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 a7d92b58cfe HDDS-13482. Intermittent failure in 
TestContainerStateMachineFailures (#10397)
a7d92b58cfe is described below

commit a7d92b58cfecff015937fb268e3f8ec0e80c0fab
Author: Chung En Lee <[email protected]>
AuthorDate: Wed Jun 3 23:02:47 2026 +0800

    HDDS-13482. Intermittent failure in TestContainerStateMachineFailures 
(#10397)
---
 .../rpc/TestContainerStateMachineFailures.java     | 66 ++++++++++++----------
 1 file changed, 37 insertions(+), 29 deletions(-)

diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestContainerStateMachineFailures.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestContainerStateMachineFailures.java
index cbf5b24129e..72cf9e3fc62 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestContainerStateMachineFailures.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestContainerStateMachineFailures.java
@@ -21,13 +21,14 @@
 import static 
org.apache.hadoop.hdds.HddsConfigKeys.HDDS_COMMAND_STATUS_REPORT_INTERVAL;
 import static 
org.apache.hadoop.hdds.HddsConfigKeys.HDDS_CONTAINER_REPORT_INTERVAL;
 import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_HEARTBEAT_INTERVAL;
+import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_NODE_REPORT_INTERVAL;
 import static 
org.apache.hadoop.hdds.HddsConfigKeys.HDDS_PIPELINE_REPORT_INTERVAL;
 import static 
org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerDataProto.State.QUASI_CLOSED;
 import static 
org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerDataProto.State.UNHEALTHY;
+import static 
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_DEADNODE_INTERVAL;
 import static 
org.apache.hadoop.hdds.scm.ScmConfigKeys.OZONE_SCM_STALENODE_INTERVAL;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -64,6 +65,7 @@
 import org.apache.hadoop.hdds.protocol.DatanodeID;
 import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
+import org.apache.hadoop.hdds.ratis.RatisHelper;
 import org.apache.hadoop.hdds.ratis.conf.RatisClientConfig;
 import org.apache.hadoop.hdds.scm.OzoneClientConfig;
 import org.apache.hadoop.hdds.scm.ScmConfigKeys;
@@ -100,7 +102,6 @@
 import org.apache.hadoop.ozone.protocol.commands.SCMCommand;
 import org.apache.ozone.test.GenericTestUtils;
 import org.apache.ozone.test.LambdaTestUtils;
-import org.apache.ozone.test.tag.Flaky;
 import org.apache.ratis.protocol.RaftGroupId;
 import org.apache.ratis.protocol.exceptions.StateMachineException;
 import org.apache.ratis.server.storage.FileInfo;
@@ -109,11 +110,15 @@
 import org.apache.ratis.thirdparty.com.google.protobuf.ByteString;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
 
 /**
  * Tests the containerStateMachine failure handling.
  */
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 public class TestContainerStateMachineFailures {
 
   private static MiniOzoneCluster cluster;
@@ -138,7 +143,9 @@ public static void init() throws Exception {
     conf.setTimeDuration(HDDS_PIPELINE_REPORT_INTERVAL, 200,
         TimeUnit.MILLISECONDS);
     conf.setTimeDuration(HDDS_HEARTBEAT_INTERVAL, 200, TimeUnit.MILLISECONDS);
-    conf.setTimeDuration(OZONE_SCM_STALENODE_INTERVAL, 30, TimeUnit.SECONDS);
+    conf.setTimeDuration(HDDS_NODE_REPORT_INTERVAL, 1, TimeUnit.SECONDS);
+    conf.setTimeDuration(OZONE_SCM_STALENODE_INTERVAL, 3, TimeUnit.SECONDS);
+    conf.setTimeDuration(OZONE_SCM_DEADNODE_INTERVAL, 6, TimeUnit.SECONDS);
     conf.set(OzoneConfigKeys.OZONE_SCM_CLOSE_CONTAINER_WAIT_DURATION, "2s");
     conf.set(ScmConfigKeys.OZONE_SCM_PIPELINE_SCRUB_INTERVAL, "2s");
     conf.set(ScmConfigKeys.OZONE_SCM_PIPELINE_DESTROY_TIMEOUT, "5s");
@@ -254,7 +261,6 @@ public void 
testContainerStateMachineCloseOnMissingPipeline()
   }
 
   @Test
-  @Flaky("HDDS-12215")
   public void testContainerStateMachineRestartWithDNChangePipeline()
       throws Exception {
     try (OzoneOutputStream key = 
objectStore.getVolume(volumeName).getBucket(bucketName)
@@ -304,7 +310,12 @@ public void 
testContainerStateMachineRestartWithDNChangePipeline()
     }
   }
 
+  // This test case is placed at the end because it resets the Ratis storage 
location.
+  // This causes pipelines to break. Those pipelines are closed passively
+  // via client-side retries rather than by the ScrubbingService.
+  // Running this test earlier would leave a dirty pipeline pool for 
subsequent tests.
   @Test
+  @Order(Integer.MAX_VALUE)
   public void testContainerStateMachineFailures() throws Exception {
     OzoneOutputStream key =
         objectStore.getVolume(volumeName).getBucket(bucketName)
@@ -476,16 +487,11 @@ public void testApplyTransactionFailure() throws 
Exception {
             getHddsDatanodes().get(index), omKeyLocationInfo.getPipeline());
     SimpleStateMachineStorage storage =
         (SimpleStateMachineStorage) stateMachine.getStateMachineStorage();
-    stateMachine.takeSnapshot();
-    final FileInfo snapshot = getSnapshotFileInfo(storage);
-    final Path parentPath = snapshot.getPath();
-    // Since the snapshot threshold is set to 1, since there are
-    // applyTransactions, we should see snapshots
-    
assertThat(parentPath.getParent().toFile().listFiles().length).isGreaterThan(0);
-    assertNotNull(snapshot);
     long containerID = omKeyLocationInfo.getContainerID();
     // delete the container db file
     FileUtil.fullyDelete(new File(keyValueContainerData.getContainerPath()));
+    long bcsid = containerData.getBlockCommitSequenceId();
+
     Pipeline pipeline = cluster.getStorageContainerLocationClient()
         .getContainerWithPipeline(containerID).getPipeline();
     XceiverClientSpi xceiverClient =
@@ -506,33 +512,36 @@ public void testApplyTransactionFailure() throws 
Exception {
       xceiverClientManager.releaseClient(xceiverClient, false);
     }
     // Make sure the container is marked unhealthy
-    assertSame(dn.getDatanodeStateMachine()
-        .getContainer().getContainerSet().getContainer(containerID)
-        .getContainerState(), UNHEALTHY);
+    GenericTestUtils.waitFor(() -> {
+      try {
+        return 
!((ContainerStateMachine)((XceiverServerRatis)dn.getDatanodeStateMachine()
+            .getContainer().getWriteChannel()).getServer().getDivision(
+            
RatisHelper.newRaftGroup(pipeline).getGroupId()).getStateMachine()).isStateMachineHealthy();
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }, 100, 5000);
     try {
       // try to take a new snapshot, ideally it should just fail
       stateMachine.takeSnapshot();
+      fail("Should have thrown StateMachineException because it is UNHEALTHY");
     } catch (IOException ioe) {
       assertInstanceOf(StateMachineException.class, ioe);
     }
 
-    if (snapshot.getPath().toFile().exists()) {
-      // Make sure the latest snapshot is same as the previous one
-      try {
-        final FileInfo latestSnapshot = getSnapshotFileInfo(storage);
-        assertEquals(snapshot.getPath(), latestSnapshot.getPath());
-      } catch (Throwable e) {
-        assertFalse(snapshot.getPath().toFile().exists());
-      }
-    }
+    assertEquals(bcsid, dn.getDatanodeStateMachine()
+        .getContainer().getContainerSet()
+        .getContainer(omKeyLocationInfo.getContainerID())
+        .getContainerData().getBlockCommitSequenceId());
 
+
+    final FileInfo snapshot = getSnapshotFileInfo(storage);
     // when remove pipeline, group dir including snapshot will be deleted
     LambdaTestUtils.await(10000, 500,
         () -> (!snapshot.getPath().toFile().exists()));
   }
 
   @Test
-  @Flaky("HDDS-6115")
   void testApplyTransactionIdempotencyWithClosedContainer()
       throws Exception {
     OzoneOutputStream key =
@@ -590,6 +599,8 @@ void testApplyTransactionIdempotencyWithClosedContainer()
             .getContainerState(),
         ContainerProtos.ContainerDataProto.State.CLOSED);
     assertTrue(stateMachine.isStateMachineHealthy());
+    GenericTestUtils.waitFor(() -> 
stateMachine.getLastAppliedTermIndex().getIndex() != markIndex1,
+        1000, 30000);
     try {
       stateMachine.takeSnapshot();
     } finally {
@@ -618,7 +629,6 @@ void testApplyTransactionIdempotencyWithClosedContainer()
   // not be marked unhealthy and pipeline should not fail if container gets
   // closed here.
   @Test
-  @Flaky("HDDS-13482")
   void testWriteStateMachineDataIdempotencyWithClosedContainer()
       throws Exception {
     OzoneOutputStream key =
@@ -683,7 +693,7 @@ void 
testWriteStateMachineDataIdempotencyWithClosedContainer()
     };
     Runnable r2 = () -> {
       try {
-        ByteString data = ByteString.copyFromUtf8("hello");
+        ByteString data = ByteString.copyFromUtf8("ratis");
         ContainerProtos.ContainerCommandRequestProto.Builder writeChunkRequest 
=
             ContainerTestHelper.newWriteChunkRequestBuilder(pipeline,
                 omKeyLocationInfo.getBlockID(), data.size());
@@ -698,7 +708,7 @@ void 
testWriteStateMachineDataIdempotencyWithClosedContainer()
           failCount.incrementAndGet();
         }
         String message = e.getMessage();
-        assertThat(message).doesNotContain("hello");
+        assertThat(message).doesNotContain("ratis");
         assertThat(message).contains(HddsUtils.REDACTED.toStringUtf8());
       }
     };
@@ -745,7 +755,6 @@ void 
testWriteStateMachineDataIdempotencyWithClosedContainer()
   }
 
   @Test
-  @Flaky("HDDS-14101")
   void testContainerStateMachineSingleFailureRetry()
       throws Exception {
     try (OzoneOutputStream key = 
objectStore.getVolume(volumeName).getBucket(bucketName)
@@ -776,7 +785,6 @@ void testContainerStateMachineSingleFailureRetry()
   }
 
   @Test
-  @Flaky("HDDS-14101")
   void testContainerStateMachineDualFailureRetry()
       throws Exception {
     OzoneOutputStream key =


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

Reply via email to