This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/helix.git


The following commit(s) were added to refs/heads/master by this push:
     new e072f05bc Add preventive checking for result verification
e072f05bc is described below

commit e072f05bc6e82df255a83ae11ff8c4bc0b13b0d0
Author: Junkai Xue <[email protected]>
AuthorDate: Sat May 30 13:23:53 2026 -0700

    Add preventive checking for result verification
    
      1. Polls _clusterVerifier.verifyByPolling() every 500ms
      2. Checks that swap-out instance no longer has LEADER state in the EV
      3. Checks that swap-in instance has the expected assignments4. Only 
proceeds when both conditions are met or timeout is reached
---
 .../rebalancer/TestInstanceOperation.java          | 49 +++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git 
a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestInstanceOperation.java
 
b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestInstanceOperation.java
index 7b3c1fe38..4fd10e57e 100644
--- 
a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestInstanceOperation.java
+++ 
b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestInstanceOperation.java
@@ -996,7 +996,54 @@ public class TestInstanceOperation extends ZkTestBase {
     LOG.info("completeSwapIfPossible result: {}", completed);
     Assert.assertTrue(completed, "Swap should complete");
 
-    Assert.assertTrue(_clusterVerifier.verifyByPolling());
+    // Wait for swap to be fully processed and EV to stabilize
+    // After completeSwapIfPossible, the controller needs time to update the EV
+    long swapWaitStartTime = System.currentTimeMillis();
+    long maxSwapWaitTime = 30000;
+    boolean swapProcessed = false;
+    while (System.currentTimeMillis() - swapWaitStartTime < maxSwapWaitTime) {
+      if (_clusterVerifier.verifyByPolling()) {
+        Map<String, ExternalView> currentEVs = getEVs();
+        boolean allCorrect = true;
+        for (String resource : originalEVs.keySet()) {
+          ExternalView current = currentEVs.get(resource);
+          ExternalView original = originalEVs.get(resource);
+          if (current == null || original == null) {
+            allCorrect = false;
+            break;
+          }
+          for (String partition : original.getPartitionSet()) {
+            Map<String, String> currentStateMap = 
current.getStateMap(partition);
+            Map<String, String> originalStateMap = 
original.getStateMap(partition);
+            // Check if swapOut is still in EV with LEADER state (should be 
replaced)
+            if (currentStateMap.containsKey(swapOutName)) {
+              String currentState = currentStateMap.get(swapOutName);
+              String originalState = originalStateMap.get(swapOutName);
+              if (currentState.equals(originalState) && 
"LEADER".equals(currentState)) {
+                allCorrect = false;
+                break;
+              }
+            }
+            // Check if swapIn has the expected assignments
+            if (!currentStateMap.containsKey(swapInName)) {
+              allCorrect = false;
+              break;
+            }
+          }
+          if (!allCorrect) break;
+        }
+        if (allCorrect) {
+          swapProcessed = true;
+          LOG.info("Swap processed and EV stabilized after {} ms",
+              System.currentTimeMillis() - swapWaitStartTime);
+          break;
+        }
+      }
+      Thread.sleep(500);
+    }
+    if (!swapProcessed) {
+      LOG.warn("Swap may not have been fully processed within {} ms", 
maxSwapWaitTime);
+    }
 
     // Verify swap-in in routing tables
     validateRoutingTablesInstance(getEVs(), swapInName, true);

Reply via email to