protected static void awaitUntilSuccess(
      SyncConfigNodeIServiceClient client,
      Predicate<TShowRegionResp> predicate,
      Optional<Integer> dataNodeExpectInRegionGroup,
      Optional<Integer> dataNodeExpectNotInRegionGroup) {
    AtomicReference<Set<Integer>> lastTimeDataNodes = new AtomicReference<>();
    AtomicReference<Exception> lastException = new AtomicReference<>();
    AtomicReference<SyncConfigNodeIServiceClient> clientRef = new AtomicReference<>(client);
    try {
      Awaitility.await()
          .atMost(2, TimeUnit.MINUTES)
          .pollDelay(2, TimeUnit.SECONDS)
          .until(
              () -> {
                try {
                  TShowRegionResp resp = clientRef.get().showRegion(new TShowRegionReq());
                  return predicate.test(resp);
                } catch (TException e) {
                  clientRef.set(
                      (SyncConfigNodeIServiceClient)
                          EnvFactory.getEnv().getLeaderConfigNodeConnection());
                  lastException.set(e);
                  return false;
                } catch (Exception e) {
                  // Any exception can be ignored
                  lastException.set(e);
                  return false;
                }
              });
    } catch (ConditionTimeoutException e) {
      if (lastTimeDataNodes.get() == null) {
        LOGGER.error(
            "maybe show regions fail, lastTimeDataNodes is null, last Exception:",
            lastException.get());
        throw e;
      }
      String actualSetStr = lastTimeDataNodes.get().toString();
      dataNodeExpectNotInRegionGroup.ifPresent(x -> lastTimeDataNodes.get().remove(x));
      dataNodeExpectInRegionGroup.ifPresent(x -> lastTimeDataNodes.get().add(x));
      String expectSetStr = lastTimeDataNodes.toString();
      LOGGER.error("DataNode Set {} is unexpected, expect {}", actualSetStr, expectSetStr);
      if (lastException.get() == null) {
        LOGGER.info("No exception during awaiting");
      } else {
        LOGGER.error("Last exception during awaiting:", lastException.get());
      }
      throw e;
    }
    LOGGER.info("DataNode set has been successfully changed to {}", lastTimeDataNodes.get());
  }
Monitor the node's log and kill it when detect specific log.

@param nodeWrapper Easy to understand
@param keywords When detect these keywords in node's log, stop the node forcibly
integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java