errose28 commented on code in PR #8904:
URL: https://github.com/apache/ozone/pull/8904#discussion_r2263869239


##########
hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/dn/scanner/TestOnDemandContainerScannerIntegration.java:
##########
@@ -178,4 +184,57 @@ void 
testCorruptionDetectedForOpenContainers(TestContainerCorruptions corruption
     corruption.assertLogged(openContainerID, 1, logCapturer);
   }
 
+  /**
+   * Test that {@link OnDemandContainerScanner} is triggered when the 
HddsDispatcher
+   * detects write failures and automatically triggers on-demand scans.
+   */
+  @Test
+  void testOnDemandScanTriggeredByUnhealthyContainer() throws Exception {
+    long containerID = writeDataToOpenContainer();
+    Container<?> container = getDnContainer(containerID);
+    assertEquals(State.OPEN, container.getContainerState());
+
+    Optional<Instant> initialScanTime = 
container.getContainerData().lastDataScanTime();
+    HddsDatanodeService dn = getMiniOzoneCluster().getHddsDatanodes().get(0);
+    HddsDispatcher dispatcher = (HddsDispatcher) 
dn.getDatanodeStateMachine().getContainer().getDispatcher();
+    OnDemandScannerMetrics scannerMetrics = 
dn.getDatanodeStateMachine().getContainer()
+        .getOnDemandScanner().getMetrics();
+    int initialScannedCount = scannerMetrics.getNumContainersScanned();
+
+    // Create a PutBlock request with malformed block data to trigger internal 
error
+    ContainerProtos.ContainerCommandRequestProto writeFailureRequest =
+        ContainerProtos.ContainerCommandRequestProto.newBuilder()
+            .setCmdType(ContainerProtos.Type.PutBlock)
+            .setContainerID(containerID)
+            .setDatanodeUuid(dn.getDatanodeDetails().getUuidString())
+            .setPutBlock(ContainerProtos.PutBlockRequestProto.newBuilder()
+                .setBlockData(ContainerProtos.BlockData.newBuilder()
+                    .setBlockID(ContainerProtos.DatanodeBlockID.newBuilder()
+                        .setContainerID(containerID)
+                        .setLocalID(999L)
+                        .setBlockCommitSequenceId(1)
+                        .build())
+                    .setSize(1024) // Size mismatch with chunks
+                    .build())
+                .build())
+            .build();
+
+    ContainerProtos.ContainerCommandResponseProto response = 
dispatcher.dispatch(writeFailureRequest, null);
+    assertNotEquals(ContainerProtos.Result.SUCCESS, response.getResult());
+    assertEquals(State.UNHEALTHY, container.getContainerState());
+
+    // The dispatcher should have called containerSet.scanContainerWithoutGap 
due to the failure
+    GenericTestUtils.waitFor(() -> {
+      Optional<Instant> currentScanTime = 
container.getContainerData().lastDataScanTime();
+      return currentScanTime.isPresent() && 
currentScanTime.get().isAfter(initialScanTime.orElse(Instant.EPOCH));
+    }, 500, 5000);
+
+    // Verify scan timestamp was updated
+    Optional<Instant> finalScanTime = 
container.getContainerData().lastDataScanTime();
+    assertTrue(finalScanTime.isPresent());
+    
assertTrue(finalScanTime.get().isAfter(initialScanTime.orElse(Instant.EPOCH)));

Review Comment:
   This looks like a duplicate check of the wait condition above. Once the wait 
on the timestamp passes we should be good to just check the metrics.



##########
hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/dn/scanner/TestOnDemandContainerScannerIntegration.java:
##########
@@ -178,4 +184,57 @@ void 
testCorruptionDetectedForOpenContainers(TestContainerCorruptions corruption
     corruption.assertLogged(openContainerID, 1, logCapturer);
   }
 
+  /**
+   * Test that {@link OnDemandContainerScanner} is triggered when the 
HddsDispatcher
+   * detects write failures and automatically triggers on-demand scans.
+   */
+  @Test
+  void testOnDemandScanTriggeredByUnhealthyContainer() throws Exception {
+    long containerID = writeDataToOpenContainer();
+    Container<?> container = getDnContainer(containerID);
+    assertEquals(State.OPEN, container.getContainerState());
+
+    Optional<Instant> initialScanTime = 
container.getContainerData().lastDataScanTime();
+    HddsDatanodeService dn = getMiniOzoneCluster().getHddsDatanodes().get(0);
+    HddsDispatcher dispatcher = (HddsDispatcher) 
dn.getDatanodeStateMachine().getContainer().getDispatcher();

Review Comment:
   We can use `ContainerDispatcher` here without casting.



##########
hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/dn/scanner/TestContainerScannerIntegrationAbstract.java:
##########
@@ -220,4 +220,8 @@ private OzoneOutputStream createKey(String keyName) throws 
Exception {
     return TestHelper.createKey(
         keyName, RATIS, ONE, 0, store, volumeName, bucketName);
   }
+
+  protected MiniOzoneCluster getMiniOzoneCluster() {
+    return cluster;
+  }

Review Comment:
   We only need a getter for the one datanode in the cluster:
   ```suggestion
     protected HddsDatanodeService getDatanode() {
       assertEquals(1, cluster.getHddsDatanodes().size());
       return cluster.getHddsDatanodes().get(0);
     }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to