You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by yo...@apache.org on 2026/10/20 06:37:35 UTC
(iotdb) branch master updated: Make IoTConsensus peer-list reset retries best effort (#18929)
This is an automated email from the ASF dual-hosted git repository.
CRZbulabula pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new c462a975553 Make IoTConsensus peer-list reset retries best effort (#18929)
c462a975553 is described below
commit c462a97555394c7fa01d97442effb9b8550c402a
Author: d-wang-commit <d....@gmail.com>
AuthorDate: Tue Oct 20 14:37:29 2026 +0800
Make IoTConsensus peer-list reset retries best effort (#18929)
Finish node removal after bounded peer-list reset retries are exhausted.
Keep metadata failures fatal and simplify caller-controlled retry handling.
Cover exhaustion paths and adapt regression fixtures to targeted region lookups.
---
.../iotdb/confignode/i18n/ProcedureMessages.java | 2 -
.../iotdb/confignode/i18n/ProcedureMessages.java | 2 -
.../impl/region/RemoveRegionPeerProcedure.java | 45 +++++++-------
.../impl/node/RemoveDataNodesProcedureTest.java | 72 ++++++++++++++--------
.../region/RemovePeerRestartConsensusTest.java | 10 ++-
.../impl/region/RestartDuringRemovePeerTest.java | 52 ++++++++++++++--
6 files changed, 124 insertions(+), 59 deletions(-)
diff --git a/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ProcedureMessages.java b/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
index 3874fbaac0d..737c1c49bb4 100644
--- a/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
+++ b/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
@@ -853,8 +853,6 @@ public final class ProcedureMessages {
public static final String
LOG_FAILED_TO_RESET_PEER_LIST_FOR_ARG_ON_DATANODE_ARG_TO_ARG_ARG_C8D872B4 =
"Failed to reset peer list for {} on DataNode {} to {}: {}";
- public static final String LOG_PIDARG_REMOVEREGION_STATE_ARG_FAILED_RETRY_ARG_ARG_IN_ARG_MS_41B8ECB5 =
- "[pid{}][RemoveRegion] state {} failed, retry {}/{} in {} ms.";
public static final String
EXCEPTION_FAILED_TO_FINALIZE_REGION_PEER_REMOVAL_FOR_ARG_AT_STATE_ARG_AFTER_ARG_ATTEMPTS_382EA168 =
"Failed to finalize Region peer removal for %s at state %s after %d attempts.";
diff --git a/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ProcedureMessages.java b/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
index 394480f6543..fe569097189 100644
--- a/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
+++ b/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
@@ -812,8 +812,6 @@ public final class ProcedureMessages {
public static final String
LOG_FAILED_TO_RESET_PEER_LIST_FOR_ARG_ON_DATANODE_ARG_TO_ARG_ARG_C8D872B4 =
"将 {} 在 DataNode {} 上的 peer 列表重置为 {} 失败:{}";
- public static final String LOG_PIDARG_REMOVEREGION_STATE_ARG_FAILED_RETRY_ARG_ARG_IN_ARG_MS_41B8ECB5 =
- "[pid{}][RemoveRegion] 状态 {} 失败,第 {}/{} 次重试将在 {} 毫秒后进行。";
public static final String
EXCEPTION_FAILED_TO_FINALIZE_REGION_PEER_REMOVAL_FOR_ARG_AT_STATE_ARG_AFTER_ARG_ATTEMPTS_382EA168 =
"Region %s 的 peer 移除收尾在状态 %s 尝试 %d 次后失败。";
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java
index 01993f91440..ffea2aa044c 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java
@@ -39,6 +39,8 @@ import org.apache.iotdb.mpp.rpc.thrift.TRegionMigrateResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.annotation.Nullable;
+
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -198,7 +200,15 @@ public class RemoveRegionPeerProcedure extends RegionOperationProcedure<RemoveRe
case REMOVE_REGION_LOCATION_CACHE:
tsStatus = handler.removeRegionLocation(regionId, targetDataNode);
if (tsStatus == null || tsStatus.getCode() != SUCCESS_STATUS.getStatusCode()) {
- return retryStep(state);
+ return retryStep(
+ state,
+ new ProcedureException(
+ String.format(
+ ProcedureMessages
+ .EXCEPTION_FAILED_TO_FINALIZE_REGION_PEER_REMOVAL_FOR_ARG_AT_STATE_ARG_AFTER_ARG_ATTEMPTS_382EA168,
+ regionId,
+ state,
+ getCycles() + 1)));
}
if (!handler.isIoTConsensusV1DataRegion(regionId)) {
return finishRemoval(state);
@@ -208,7 +218,8 @@ public class RemoveRegionPeerProcedure extends RegionOperationProcedure<RemoveRe
break;
case RESET_IOT_CONSENSUS_V1_PEER_LIST:
if (!handler.resetPeerListAfterRemoveForIoTConsensusV1(regionId, targetDataNode)) {
- return retryStep(state);
+ // The replica metadata is already committed. Peer list reconciliation is best effort.
+ return retryStep(state, null);
}
return finishRemoval(state);
default:
@@ -216,8 +227,11 @@ public class RemoveRegionPeerProcedure extends RegionOperationProcedure<RemoveRe
}
} catch (Exception e) {
LOGGER.error(ProcedureMessages.REMOVEREGIONPEER_STATE_FAILED, state, e);
- if (state == REMOVE_REGION_LOCATION_CACHE || state == RESET_IOT_CONSENSUS_V1_PEER_LIST) {
- return retryStep(state);
+ if (state == REMOVE_REGION_LOCATION_CACHE) {
+ return retryStep(state, new ProcedureException(e));
+ }
+ if (state == RESET_IOT_CONSENSUS_V1_PEER_LIST) {
+ return retryStep(state, null);
}
return Flow.NO_MORE_STATE;
}
@@ -225,28 +239,15 @@ public class RemoveRegionPeerProcedure extends RegionOperationProcedure<RemoveRe
return Flow.HAS_MORE_STATE;
}
- private Flow retryStep(RemoveRegionPeerState state) {
+ private Flow retryStep(
+ RemoveRegionPeerState state, @Nullable ProcedureException failureOnExhaustion) {
if (getCycles() >= MAX_FINALIZATION_RETRY) {
- ProcedureException failure =
- new ProcedureException(
- String.format(
- ProcedureMessages
- .EXCEPTION_FAILED_TO_FINALIZE_REGION_PEER_REMOVAL_FOR_ARG_AT_STATE_ARG_AFTER_ARG_ATTEMPTS_382EA168,
- regionId,
- state,
- getCycles() + 1));
- LOGGER.error(ProcedureMessages.REMOVEREGIONPEER_STATE_FAILED, state, failure);
- setFailure(failure);
+ if (failureOnExhaustion != null) {
+ setFailure(failureOnExhaustion);
+ }
return Flow.NO_MORE_STATE;
}
setNextState(state);
- LOGGER.warn(
- ProcedureMessages.LOG_PIDARG_REMOVEREGION_STATE_ARG_FAILED_RETRY_ARG_ARG_IN_ARG_MS_41B8ECB5,
- getProcId(),
- state,
- getCycles() + 1,
- MAX_FINALIZATION_RETRY,
- FINALIZATION_RETRY_INTERVAL_MS);
try {
Thread.sleep(FINALIZATION_RETRY_INTERVAL_MS);
} catch (InterruptedException e) {
diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/node/RemoveDataNodesProcedureTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/node/RemoveDataNodesProcedureTest.java
index 2769701c0d4..916270abf22 100644
--- a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/node/RemoveDataNodesProcedureTest.java
+++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/node/RemoveDataNodesProcedureTest.java
@@ -137,17 +137,19 @@ public class RemoveDataNodesProcedureTest {
}
@Test
- public void metadataRetryExhaustionCleansUpNodeRemoval() throws Exception {
- assertFinalizationFailureCleanup(RemoveRegionPeerState.REMOVE_REGION_LOCATION_CACHE, false);
+ public void metadataRetryExhaustionRetriesFailedNodeStatusCleanup() throws Exception {
+ assertFinalizationExhaustionCleanup(RemoveRegionPeerState.REMOVE_REGION_LOCATION_CACHE, true);
}
@Test
- public void peerListRetryExhaustionRetriesFailedNodeStatusCleanup() throws Exception {
- assertFinalizationFailureCleanup(RemoveRegionPeerState.RESET_IOT_CONSENSUS_V1_PEER_LIST, true);
+ public void peerListRetryExhaustionCompletesNodeRemoval() throws Exception {
+ assertFinalizationExhaustionCleanup(
+ RemoveRegionPeerState.RESET_IOT_CONSENSUS_V1_PEER_LIST, false);
}
- private void assertFinalizationFailureCleanup(
+ private void assertFinalizationExhaustionCleanup(
RemoveRegionPeerState failingState, boolean failFirstStatusRestoration) throws Exception {
+ boolean metadataFailure = failingState == RemoveRegionPeerState.REMOVE_REGION_LOCATION_CACHE;
TDataNodeLocation runningNode = fromDataNodeLocation;
TDataNodeLocation readOnlyNode = location(12);
TDataNodeLocation drainedNode = location(13);
@@ -178,10 +180,12 @@ public class RemoveDataNodesProcedureTest {
"root.remove",
new TRegionReplicaSet(
consensusGroupId, new ArrayList<>(Arrays.asList(runningNode, retainedNode))));
- groups.addRegionGroup(
- "root.remove",
- new TRegionReplicaSet(
- pendingRunningRegion, new ArrayList<>(Arrays.asList(runningNode, retainedNode))));
+ if (metadataFailure) {
+ groups.addRegionGroup(
+ "root.remove",
+ new TRegionReplicaSet(
+ pendingRunningRegion, new ArrayList<>(Arrays.asList(runningNode, retainedNode))));
+ }
groups.addRegionGroup(
"root.remove",
new TRegionReplicaSet(
@@ -229,7 +233,7 @@ public class RemoveDataNodesProcedureTest {
when(regionHandler.removeRegionLocation(consensusGroupId, runningNode))
.thenAnswer(
ignored ->
- failingState == RemoveRegionPeerState.REMOVE_REGION_LOCATION_CACHE
+ metadataFailure
? new TSStatus(TSStatusCode.MIGRATE_REGION_ERROR.getStatusCode())
: partitionInfo.removeRegionLocation(
new RemoveRegionLocationPlan(consensusGroupId, runningNode)));
@@ -302,36 +306,49 @@ public class RemoveDataNodesProcedureTest {
new RemoveDataNodesProcedure(removalTargets, originalStatuses);
long rootId = executor.submitProcedure(root);
ProcedureTestUtil.waitForProcedure(executor, rootId);
- Assert.assertTrue("Node removal must finish failure cleanup", executor.isFinished(rootId));
- Assert.assertEquals(ProcedureState.ROLLEDBACK, root.getState());
- Assert.assertFalse(root.isSuccess());
- RemoveRegionPeerProcedure failedChild =
+ Assert.assertTrue("Node removal must finish cleanup", executor.isFinished(rootId));
+ RemoveRegionPeerProcedure removalChild =
store.recorded.values().stream()
.filter(RemoveRegionPeerProcedure.class::isInstance)
.map(RemoveRegionPeerProcedure.class::cast)
.findFirst()
.get();
- Procedure<?> migrationParent = store.recorded.get(failedChild.getParentProcId());
+ Procedure<?> migrationParent = store.recorded.get(removalChild.getParentProcId());
Assert.assertTrue(migrationParent instanceof RegionMigrateProcedure);
Assert.assertEquals(rootId, migrationParent.getParentProcId());
- Assert.assertSame(failedChild.getException(), root.getException());
- Assert.assertTrue(root.getException().getMessage().contains(failingState.name()));
- if (failingState == RemoveRegionPeerState.REMOVE_REGION_LOCATION_CACHE) {
+ if (metadataFailure) {
+ Assert.assertEquals(ProcedureState.ROLLEDBACK, root.getState());
+ Assert.assertFalse(root.isSuccess());
+ Assert.assertSame(removalChild.getException(), root.getException());
+ Assert.assertTrue(root.getException().getMessage().contains(failingState.name()));
verify(regionHandler, times(4)).removeRegionLocation(consensusGroupId, runningNode);
verify(regionHandler, never()).resetPeerListAfterRemoveForIoTConsensusV1(any(), any());
} else {
+ Assert.assertTrue(root.isSuccess());
+ Assert.assertTrue(migrationParent.isSuccess());
+ Assert.assertTrue(removalChild.isSuccess());
+ Assert.assertNull(root.getException());
+ Assert.assertNull(migrationParent.getException());
+ Assert.assertNull(removalChild.getException());
verify(regionHandler).removeRegionLocation(consensusGroupId, runningNode);
verify(regionHandler, times(4))
.resetPeerListAfterRemoveForIoTConsensusV1(consensusGroupId, runningNode);
}
- // Failed children bypass STOP_DATA_NODE: root rollback must still finalize node statuses.
- Assert.assertEquals(NodeStatus.Running, currentStatuses.get(runningNode.getDataNodeId()));
+ // Metadata failures use rollback cleanup; exhausted peer-list resets use normal
+ // STOP_DATA_NODE.
+ if (metadataFailure) {
+ Assert.assertEquals(NodeStatus.Running, currentStatuses.get(runningNode.getDataNodeId()));
+ }
Assert.assertEquals(NodeStatus.ReadOnly, currentStatuses.get(readOnlyNode.getDataNodeId()));
- Assert.assertTrue(registeredNodes.contains(runningNode.getDataNodeId()));
+ Assert.assertEquals(metadataFailure, registeredNodes.contains(runningNode.getDataNodeId()));
Assert.assertTrue(registeredNodes.contains(readOnlyNode.getDataNodeId()));
Assert.assertFalse(registeredNodes.contains(drainedNode.getDataNodeId()));
- Assert.assertEquals(Collections.singleton(drainedNode.getDataNodeId()), stoppedNodes);
+ Assert.assertEquals(
+ metadataFailure
+ ? Collections.singleton(drainedNode.getDataNodeId())
+ : Set.of(runningNode.getDataNodeId(), drainedNode.getDataNodeId()),
+ stoppedNodes);
Assert.assertEquals(failFirstStatusRestoration ? 2 : 1, restorationAttempts.get());
if (failFirstStatusRestoration) {
// A node-lock wakeup must not bypass the five-second rollback retry timeout.
@@ -339,16 +356,21 @@ public class RemoveDataNodesProcedureTest {
"Status restoration must wait for the rollback retry timeout",
restorationRetryDelay.get() >= TimeUnit.SECONDS.toNanos(4));
}
- verify(nodeHandler).broadcastDataNodeStatusChange(Arrays.asList(runningNode, readOnlyNode));
+ verify(nodeHandler)
+ .broadcastDataNodeStatusChange(
+ metadataFailure
+ ? Arrays.asList(runningNode, readOnlyNode)
+ : Collections.singletonList(readOnlyNode));
// Cleanup must not undo the completed add peer or a committed removal.
Assert.assertTrue(
partitionManager.isDataNodeContainsRegion(
toDataNodeLocation.getDataNodeId(), consensusGroupId));
Assert.assertEquals(
- failingState == RemoveRegionPeerState.REMOVE_REGION_LOCATION_CACHE,
+ metadataFailure,
partitionManager.isDataNodeContainsRegion(runningNode.getDataNodeId(), consensusGroupId));
- Assert.assertTrue(
+ Assert.assertEquals(
+ metadataFailure,
partitionManager.isDataNodeContainsRegion(
runningNode.getDataNodeId(), pendingRunningRegion));
Assert.assertTrue(
diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/region/RemovePeerRestartConsensusTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/region/RemovePeerRestartConsensusTest.java
index b03f06c95a2..64f1eeecf63 100644
--- a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/region/RemovePeerRestartConsensusTest.java
+++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/region/RemovePeerRestartConsensusTest.java
@@ -159,8 +159,14 @@ public class RemovePeerRestartConsensusTest {
final PartitionInfo partitionInfo = newPartitionInfo(locations);
final ConfigManager configManager =
Mockito.mock(ConfigManager.class, Mockito.RETURNS_DEEP_STUBS);
- Mockito.when(configManager.getPartitionManager().getAllReplicaSets())
- .thenAnswer(ignored -> partitionInfo.getAllReplicaSets());
+ Mockito.when(configManager.getPartitionManager().getRegionDatabase(REGION))
+ .thenAnswer(call -> partitionInfo.getRegionDatabase(call.getArgument(0)));
+ Mockito.when(
+ configManager
+ .getPartitionManager()
+ .getReplicaSets("root.restart_repair", Collections.singletonList(REGION)))
+ .thenAnswer(
+ call -> partitionInfo.getReplicaSets(call.getArgument(0), call.getArgument(1)));
Mockito.when(
configManager
.getPartitionManager()
diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/region/RestartDuringRemovePeerTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/region/RestartDuringRemovePeerTest.java
index be868283edc..1ae8050bc01 100644
--- a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/region/RestartDuringRemovePeerTest.java
+++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/region/RestartDuringRemovePeerTest.java
@@ -66,6 +66,7 @@ import static org.apache.iotdb.consensus.ConsensusFactory.IOT_CONSENSUS_V2;
import static org.apache.iotdb.consensus.ConsensusFactory.RATIS_CONSENSUS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
@@ -117,8 +118,10 @@ public class RestartDuringRemovePeerTest {
loadManager = Mockito.mock(LoadManager.class, Mockito.RETURNS_DEEP_STUBS);
when(configManager.getPartitionManager()).thenReturn(partitionManager);
when(configManager.getLoadManager()).thenReturn(loadManager);
- when(partitionManager.getAllReplicaSets())
- .thenAnswer(ignored -> partitionInfo.getAllReplicaSets());
+ when(partitionManager.getRegionDatabase(regionId))
+ .thenAnswer(call -> partitionInfo.getRegionDatabase(call.getArgument(0)));
+ when(partitionManager.getReplicaSets("root.restart", Collections.singletonList(regionId)))
+ .thenAnswer(call -> partitionInfo.getReplicaSets(call.getArgument(0), call.getArgument(1)));
when(partitionManager.removeRegionLocation(any()))
.thenAnswer(call -> partitionInfo.removeRegionLocation(call.getArgument(0)));
handler = Mockito.spy(new RegionMaintainHandler(configManager));
@@ -286,7 +289,7 @@ public class RestartDuringRemovePeerTest {
}
@Test
- public void offlineReplicaFailsAfterThreeRetriesInsteadOfWaitingForever() throws Exception {
+ public void offlineReplicaCompletesRemovalAfterThreeRetries() throws Exception {
AccessibleRemoveProcedure procedure = beforePeerListReset();
doReturn(Collections.singletonMap(coordinator.getDataNodeId(), success()))
.when(handler)
@@ -297,8 +300,27 @@ public class RestartDuringRemovePeerTest {
assertFalse(procedure.isFailed());
}
assertEquals(0, procedure.doExecute(env).length);
- assertTrue(procedure.isFailed());
- assertTrue(procedure.getException().getMessage().contains("4"));
+ assertFalse(procedure.isFailed());
+ assertNull(procedure.getException());
+ assertEquals(finalPeers, partitionInfo.getAllReplicaSets().get(0).getDataNodeLocations());
+ verify(handler, times(4)).resetPeerList(eq(regionId), eq(finalPeers), anyMap());
+ verify(handler).removeRegionLocation(regionId, removedNode);
+ }
+
+ @Test
+ public void repeatedCorrectionExceptionsAlsoCompleteRemovalAfterThreeRetries() throws Exception {
+ AccessibleRemoveProcedure procedure = beforePeerListReset();
+ doThrow(new IllegalStateException("injected RPC failure"))
+ .when(handler)
+ .resetPeerList(any(), anyList(), anyMap());
+ for (int retry = 0; retry < 3; retry++) {
+ assertEquals(1, procedure.doExecute(env).length);
+ assertFalse(procedure.isFailed());
+ }
+ assertEquals(0, procedure.doExecute(env).length);
+ assertFalse(procedure.isFailed());
+ assertNull(procedure.getException());
+ assertEquals(finalPeers, partitionInfo.getAllReplicaSets().get(0).getDataNodeLocations());
verify(handler, times(4)).resetPeerList(eq(regionId), eq(finalPeers), anyMap());
verify(handler).removeRegionLocation(regionId, removedNode);
}
@@ -317,6 +339,24 @@ public class RestartDuringRemovePeerTest {
verify(handler, never()).resetPeerList(any(), anyList(), anyMap());
}
+ @Test
+ public void metadataExceptionsStillFailAtRetryLimitWithoutResettingPeers() throws Exception {
+ AccessibleRemoveProcedure procedure = beforeMetadataRemoval();
+ IllegalStateException failure = new IllegalStateException("injected metadata failure");
+ doThrow(failure).when(partitionManager).removeRegionLocation(any());
+ for (int retry = 0; retry < 3; retry++) {
+ assertEquals(1, procedure.doExecute(env).length);
+ assertFalse(procedure.isFailed());
+ }
+ assertEquals(0, procedure.doExecute(env).length);
+ assertTrue(procedure.isFailed());
+ assertEquals(failure, procedure.getException().getCause());
+ assertTrue(
+ partitionInfo.getAllReplicaSets().get(0).getDataNodeLocations().contains(removedNode));
+ verify(handler, times(4)).removeRegionLocation(regionId, removedNode);
+ verify(handler, never()).resetPeerList(any(), anyList(), anyMap());
+ }
+
@Test
public void interruptedRetryRetainsItsStepForRecovery() throws Exception {
AccessibleRemoveProcedure procedure = beforePeerListReset();
@@ -342,7 +382,7 @@ public class RestartDuringRemovePeerTest {
partitionInfo.removeRegionLocation(new RemoveRegionLocationPlan(regionId, removedNode));
doReturn(null).when(handler).resetPeerList(any(), anyList(), anyMap());
assertFalse(handler.resetPeerListAfterRemoveForIoTConsensusV1(regionId, removedNode));
- when(partitionManager.getAllReplicaSets()).thenReturn(Collections.emptyList());
+ when(partitionManager.getRegionDatabase(regionId)).thenReturn(null);
assertTrue(handler.resetPeerListAfterRemoveForIoTConsensusV1(regionId, removedNode));
}