From 1cdfab9c35af253b61289cdb9a61e1c15aa542f1 Mon Sep 17 00:00:00 2001 From: f64116045 Date: Fri, 7 Aug 2026 08:55:19 +0800 Subject: [PATCH 1/2] HDDS-11620. Log SCM finalization completion --- .../scm/server/upgrade/SCMUpgradeFinalizer.java | 1 + .../hdds/scm/upgrade/TestScmFinalization.java | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/upgrade/SCMUpgradeFinalizer.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/upgrade/SCMUpgradeFinalizer.java index 6fb479592ad1..cab9321937b2 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/upgrade/SCMUpgradeFinalizer.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/upgrade/SCMUpgradeFinalizer.java @@ -118,6 +118,7 @@ public void postFinalizeUpgrade(SCMUpgradeFinalizationContext context) createPipelinesAfterFinalization(context); stateManager.removeFinalizingMark(); } + logCheckpointCrossed(FinalizationCheckpoint.FINALIZATION_COMPLETE); } private void closePipelinesBeforeFinalization(PipelineManager pipelineManager) diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/upgrade/TestScmFinalization.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/upgrade/TestScmFinalization.java index 67e661bc9d07..73c5c22589b5 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/upgrade/TestScmFinalization.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/upgrade/TestScmFinalization.java @@ -53,6 +53,8 @@ import org.apache.hadoop.ozone.OzoneConsts; import org.apache.hadoop.ozone.upgrade.UpgradeFinalization; import org.apache.hadoop.ozone.upgrade.UpgradeFinalization.StatusAndMessages; +import org.apache.hadoop.ozone.upgrade.UpgradeFinalizer; +import org.apache.ozone.test.GenericTestUtils.LogCapturer; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -231,8 +233,19 @@ public void testResumeFinalizationFromCheckpoint( // Execute upgrade finalization, then check that events happened in the // correct order. - StatusAndMessages status = - manager.finalizeUpgrade(UUID.randomUUID().toString()); + LogCapturer logCapturer = + LogCapturer.captureLogs(UpgradeFinalizer.class); + StatusAndMessages status; + try { + status = manager.finalizeUpgrade(UUID.randomUUID().toString()); + String finalizationCompleteLog = + "SCM Finalization has crossed checkpoint FINALIZATION_COMPLETE"; + assertEquals( + initialCheckpoint != FinalizationCheckpoint.FINALIZATION_COMPLETE, + logCapturer.getOutput().contains(finalizationCompleteLog)); + } finally { + logCapturer.stopCapturing(); + } assertEquals(getStatusFromCheckpoint(initialCheckpoint).status(), status.status()); From 24ad4966b41f9fd272068085db69e72a5ab23865 Mon Sep 17 00:00:00 2001 From: f64116045 Date: Sun, 9 Aug 2026 00:02:17 +0800 Subject: [PATCH 2/2] HDDS-11620. Test completion log failure path --- .../hdds/scm/upgrade/TestScmFinalization.java | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/upgrade/TestScmFinalization.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/upgrade/TestScmFinalization.java index 73c5c22589b5..12fddb06b1a3 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/upgrade/TestScmFinalization.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/upgrade/TestScmFinalization.java @@ -19,9 +19,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.matches; @@ -31,6 +33,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.io.IOException; import java.util.Arrays; import java.util.UUID; import org.apache.hadoop.hdds.conf.OzoneConfiguration; @@ -67,6 +70,8 @@ * Tests SCM finalization operations on mocked upgrade state. */ public class TestScmFinalization { + private static final String FINALIZATION_COMPLETE_LOG = + "SCM Finalization has crossed checkpoint FINALIZATION_COMPLETE"; private static final Logger LOG = LoggerFactory.getLogger(TestScmFinalization.class); @@ -238,11 +243,9 @@ public void testResumeFinalizationFromCheckpoint( StatusAndMessages status; try { status = manager.finalizeUpgrade(UUID.randomUUID().toString()); - String finalizationCompleteLog = - "SCM Finalization has crossed checkpoint FINALIZATION_COMPLETE"; assertEquals( initialCheckpoint != FinalizationCheckpoint.FINALIZATION_COMPLETE, - logCapturer.getOutput().contains(finalizationCompleteLog)); + logCapturer.getOutput().contains(FINALIZATION_COMPLETE_LOG)); } finally { logCapturer.stopCapturing(); } @@ -309,6 +312,36 @@ public void testResumeFinalizationFromCheckpoint( // have been invoked. } + @Test + public void testFinalizationCompleteNotLoggedWhenRemovingMarkFails() + throws Exception { + FinalizationStateManager stateManager = mock(FinalizationStateManager.class); + when(stateManager.crossedCheckpoint( + FinalizationCheckpoint.FINALIZATION_COMPLETE)).thenReturn(false); + doThrow(new IOException("Failed to remove finalizing mark")) + .when(stateManager).removeFinalizingMark(); + + SCMUpgradeFinalizationContext context = + mock(SCMUpgradeFinalizationContext.class); + PipelineManager pipelineManager = getMockPipelineManager( + FinalizationCheckpoint.MLV_EQUALS_SLV); + when(context.getFinalizationStateManager()).thenReturn(stateManager); + when(context.getPipelineManager()).thenReturn(pipelineManager); + when(context.getSCMContext()).thenReturn(SCMContext.emptyContext()); + + SCMUpgradeFinalizer finalizer = + new SCMUpgradeFinalizer(mock(HDDSLayoutVersionManager.class)); + LogCapturer logCapturer = LogCapturer.captureLogs(UpgradeFinalizer.class); + try { + IOException exception = assertThrows(IOException.class, + () -> finalizer.postFinalizeUpgrade(context)); + assertEquals("Failed to remove finalizing mark", exception.getMessage()); + assertFalse(logCapturer.getOutput().contains(FINALIZATION_COMPLETE_LOG)); + } finally { + logCapturer.stopCapturing(); + } + } + /** * On startup, the finalization table will be read to determine the * checkpoint we are resuming from. After this, the results will be stored