This is an automated email from the ASF dual-hosted git repository.
Jackie-Jiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 4f7023a564a Wait for external view convergence before the single
validation run in pauseless ingestion tests (#19354)
4f7023a564a is described below
commit 4f7023a564ab8363645497a4df7297f54f472283
Author: Xiaotian (Jackie) Jiang <[email protected]>
AuthorDate: Mon Aug 24 17:19:58 2026 -0700
Wait for external view convergence before the single validation run in
pauseless ingestion tests (#19354)
---
.../tests/BasePauselessRealtimeIngestionTest.java | 6 ++++++
.../realtime/utils/PauselessRealtimeTestUtils.java | 25 ++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/BasePauselessRealtimeIngestionTest.java
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/BasePauselessRealtimeIngestionTest.java
index be447d786f9..fa5c5c01528 100644
---
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/BasePauselessRealtimeIngestionTest.java
+++
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/BasePauselessRealtimeIngestionTest.java
@@ -202,6 +202,12 @@ public abstract class BasePauselessRealtimeIngestionTest
extends BaseClusterInte
disableFailure();
+ // The repair performed by the validation run below discovers the server
hosting each stranded segment through
+ // the external view, so wait for the external view to catch up with the
ideal state first. E.g. when commit-end
+ // fails, the stranded segments are already ONLINE in the ideal state, but
on a loaded host the server may not
+ // have processed the CONSUMING -> ONLINE transitions yet, and the
one-shot repair would permanently miss them.
+
PauselessRealtimeTestUtils.waitForExternalViewToConverge(_helixResourceManager,
tableNameWithType, 100_000L);
+
// Force-expire the segments stranded by the injected failure instead of
waiting out the max segment completion
// time: they become immediately eligible for repair, and their in-flight
commit attempts keep getting rejected,
// so the single validation run below stays the only recovery path under
test. Segments created afterwards keep
diff --git
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/realtime/utils/PauselessRealtimeTestUtils.java
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/realtime/utils/PauselessRealtimeTestUtils.java
index 16b3cf5e776..4b117234f01 100644
---
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/realtime/utils/PauselessRealtimeTestUtils.java
+++
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/realtime/utils/PauselessRealtimeTestUtils.java
@@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.helix.HelixManager;
+import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState;
import org.apache.pinot.common.metadata.segment.SegmentZKMetadata;
import org.apache.pinot.common.utils.LLCSegmentName;
@@ -30,6 +31,7 @@ import org.apache.pinot.common.utils.helix.HelixHelper;
import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
import
org.apache.pinot.controller.helix.core.realtime.PinotLLCRealtimeSegmentManager;
import org.apache.pinot.spi.utils.CommonConstants;
+import org.apache.pinot.util.TestUtils;
import static org.testng.Assert.assertEquals;
@@ -45,6 +47,29 @@ public class PauselessRealtimeTestUtils {
assertEquals(segmentAssignment.size(), numSegmentsExpected);
}
+ /// Waits until the external view of the given table converges to its ideal
state, i.e. every instance of every
+ /// segment in the ideal state reaches the prescribed state in the external
view.
+ ///
+ /// The segment repair performed by the validation task discovers segment
replicas through the external view, so a
+ /// test that relies on a single validation run must wait for convergence
before triggering it: a still-pending
+ /// `CONSUMING -> ONLINE` transition would make the one-shot repair
permanently miss the segment.
+ public static void waitForExternalViewToConverge(PinotHelixResourceManager
helixResourceManager,
+ String tableNameWithType, long timeoutMs) {
+ TestUtils.waitForCondition(aVoid -> {
+ IdealState idealState =
helixResourceManager.getTableIdealState(tableNameWithType);
+ ExternalView externalView =
helixResourceManager.getTableExternalView(tableNameWithType);
+ if (idealState == null || externalView == null) {
+ return false;
+ }
+ for (Map.Entry<String, Map<String, String>> entry :
idealState.getRecord().getMapFields().entrySet()) {
+ if
(!entry.getValue().equals(externalView.getStateMap(entry.getKey()))) {
+ return false;
+ }
+ }
+ return true;
+ }, 1000, timeoutMs, "External view failed to converge to ideal state for
table: " + tableNameWithType);
+ }
+
/// Marks all current segments of the given table as exceeding the max
segment completion time, making them
/// immediately eligible for repair by the next validation run while keeping
their in-flight commit attempts
/// rejected. Segments created after this call are not affected. No-op when
the cluster is not started with a
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]