private void recoverTest(int configNodeNum, boolean needRestartLeader) throws Exception {
    EnvFactory.getEnv().initClusterEnvironment(configNodeNum, 1);

    // prepare expectedDatabases
    Set<String> expectedDatabases = new HashSet<>();
    for (int id = CreateManyDatabasesProcedure.INITIAL_STATE; id < MAX_STATE; id++) {
      expectedDatabases.add(CreateManyDatabasesProcedure.DATABASE_NAME_PREFIX + id);
    }
    Assert.assertEquals(MAX_STATE, expectedDatabases.size());

    SyncConfigNodeIServiceClient leaderClient =
        (SyncConfigNodeIServiceClient) EnvFactory.getEnv().getLeaderConfigNodeConnection();
    leaderClient.callSpecialProcedure(TTestOperation.TEST_PROCEDURE_RECOVER);

    // Make sure the procedure has not finished yet
    TShowDatabaseResp resp = leaderClient.showDatabase(showAllDatabasesReq);
    Assert.assertTrue(resp.getDatabaseInfoMap().size() < MAX_STATE);
    // Then shutdown the leader, wait the new leader exist and the procedure continue
    final int oldLeaderIndex = EnvFactory.getEnv().getLeaderConfigNodeIndex();
    EnvFactory.getEnv().getConfigNodeWrapper(oldLeaderIndex).stopForcibly();
    if (needRestartLeader) {
      EnvFactory.getEnv().getConfigNodeWrapper(oldLeaderIndex).start();
    }
    SyncConfigNodeIServiceClient newLeaderClient =
        (SyncConfigNodeIServiceClient) EnvFactory.getEnv().getLeaderConfigNodeConnection();
    Callable<Boolean> finalCheck =
        () -> {
          TShowDatabaseResp resp1 = newLeaderClient.showDatabase(showAllDatabasesReq);
          if (MAX_STATE != resp1.getDatabaseInfoMap().size()) {
            return false;
          }
          resp1
              .getDatabaseInfoMap()
              .keySet()
              .forEach(databaseName -> expectedDatabases.remove(databaseName));
          return expectedDatabases.isEmpty();
        };
    Awaitility.await().pollDelay(1, SECONDS).atMost(1, TimeUnit.MINUTES).until(finalCheck);
  }
During CreateManyDatabasesProcedure executing, we expect that the procedure will be interrupted
only once. So let us shutdown the leader at the middle of the procedure.
integration-test/src/test/java/org/apache/iotdb/confignode/it/procedure/IoTDBProcedureIT.java