Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public void postFinalizeUpgrade(SCMUpgradeFinalizationContext context)
createPipelinesAfterFinalization(context);
stateManager.removeFinalizingMark();
}
logCheckpointCrossed(FinalizationCheckpoint.FINALIZATION_COMPLETE);
}

private void closePipelinesBeforeFinalization(PipelineManager pipelineManager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -53,6 +56,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;
Expand All @@ -65,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);

Expand Down Expand Up @@ -231,8 +238,17 @@ public void testResumeFinalizationFromCheckpoint(

// Execute upgrade finalization, then check that events happened in the
// correct order.
StatusAndMessages status =
manager.finalizeUpgrade(UUID.randomUUID().toString());
LogCapturer logCapturer =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about adding a failure-path test for removeFinalizingMark()? Verifying that no completion log is emitted would make the intended behavior explicit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @chihsuan for reviewing.

What do you think about adding a failure-path test for removeFinalizingMark()?

I think this makes sense. Added a test for this. Thanks for the suggestion!

LogCapturer.captureLogs(UpgradeFinalizer.class);
StatusAndMessages status;
try {
status = manager.finalizeUpgrade(UUID.randomUUID().toString());
assertEquals(
initialCheckpoint != FinalizationCheckpoint.FINALIZATION_COMPLETE,
logCapturer.getOutput().contains(FINALIZATION_COMPLETE_LOG));
} finally {
logCapturer.stopCapturing();
}
assertEquals(getStatusFromCheckpoint(initialCheckpoint).status(),
status.status());

Expand Down Expand Up @@ -296,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
Expand Down