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

voonhous pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hudi.git


The following commit(s) were added to refs/heads/master by this push:
     new f9c19c0c5b38 test(metadata): fix testReattemptOfFailedClusteringCommit 
to simulate the crash before any metadata read (#19434)
f9c19c0c5b38 is described below

commit f9c19c0c5b38b361bb1d307791cf70eff92b61ee
Author: Y Ethan Guo <[email protected]>
AuthorDate: Fri Jul 31 03:23:04 2026 -0700

    test(metadata): fix testReattemptOfFailedClusteringCommit to simulate the 
crash before any metadata read (#19434)
---
 .../hudi/client/TestJavaHoodieBackedMetadata.java  | 29 +++++++++++++++++++---
 .../hudi/functional/TestHoodieBackedMetadata.java  | 29 +++++++++++++++++++---
 2 files changed, 50 insertions(+), 8 deletions(-)

diff --git 
a/hudi-client/hudi-java-client/src/test/java/org/apache/hudi/client/TestJavaHoodieBackedMetadata.java
 
b/hudi-client/hudi-java-client/src/test/java/org/apache/hudi/client/TestJavaHoodieBackedMetadata.java
index 776816420352..2588364e0451 100644
--- 
a/hudi-client/hudi-java-client/src/test/java/org/apache/hudi/client/TestJavaHoodieBackedMetadata.java
+++ 
b/hudi-client/hudi-java-client/src/test/java/org/apache/hudi/client/TestJavaHoodieBackedMetadata.java
@@ -2008,7 +2008,7 @@ public class TestJavaHoodieBackedMetadata extends 
TestHoodieMetadataBase {
         
.withClusteringExecutionStrategyClass(JavaSortAndSizeExecutionStrategy.class.getName())
         .build();
 
-    HoodieWriteConfig newWriteConfig = getConfigBuilder(TRIP_EXAMPLE_SCHEMA, 
HoodieIndex.IndexType.BLOOM, HoodieFailedWritesCleaningPolicy.EAGER)
+    HoodieWriteConfig newWriteConfig = getConfigBuilder(TRIP_EXAMPLE_SCHEMA, 
HoodieIndex.IndexType.BLOOM, HoodieFailedWritesCleaningPolicy.LAZY)
         .withClusteringConfig(clusteringConfig)
         .withRollbackUsingMarkers(false)
         .build();
@@ -2024,6 +2024,22 @@ public class TestJavaHoodieBackedMetadata extends 
TestHoodieMetadataBase {
         partitionFiles.getValue().stream().forEach(file ->
             replacedFileIds.add(new HoodieFileGroupId(partitionFiles.getKey(), 
file))));
 
+    // manually remove clustering completed instant from .hoodie folder to 
mimic clustering
+    // succeeded in metadata table, but failed before committing to data 
table. This must happen
+    // before any subsequent metadata-table read so that no reader ever sees 
the first attempt's
+    // instant as committed, matching the crash scenario this test simulates.
+    FileCreateUtilsLegacy.deleteReplaceCommit(basePath, clusteringCommitTime);
+
+    // preconditions: clustering is pending on the data table while its 
deltacommit is completed
+    // in the metadata table.
+    metaClient.reloadActiveTimeline();
+    
assertFalse(metaClient.getActiveTimeline().filterCompletedInstants().containsInstant(clusteringCommitTime));
+    
assertTrue(metaClient.getActiveTimeline().filterPendingClusteringTimeline().containsInstant(clusteringCommitTime));
+    HoodieTableMetaClient metadataMetaClient = 
HoodieTestUtils.createMetaClient(
+        metaClient.getStorageConf(), getMetadataTableBasePath(basePath));
+    assertTrue(metadataMetaClient.getActiveTimeline().getDeltaCommitTimeline()
+        .filterCompletedInstants().containsInstant(clusteringCommitTime));
+
     // trigger new write to mimic other writes succeeding before re-attempt.
     newCommitTime = WriteClientTestUtils.createNewInstantTime();
     WriteClientTestUtils.startCommitWithTime(client, newCommitTime);
@@ -2031,10 +2047,15 @@ public class TestJavaHoodieBackedMetadata extends 
TestHoodieMetadataBase {
     writeStatuses = client.insert(records, newCommitTime);
     client.commit(newCommitTime, writeStatuses);
     assertNoWriteErrors(writeStatuses);
-    validateMetadata(client);
+    // ignore the first clustering attempt's uncommitted files when comparing 
listings.
+    validateMetadata(client, Option.of(clusteringCommitTime));
+
+    // the new write must leave the pending clustering and its metadata-table 
deltacommit intact.
+    metaClient.reloadActiveTimeline();
+    
assertTrue(metaClient.getActiveTimeline().filterPendingClusteringTimeline().containsInstant(clusteringCommitTime));
+    
assertTrue(metadataMetaClient.reloadActiveTimeline().getDeltaCommitTimeline()
+        .filterCompletedInstants().containsInstant(clusteringCommitTime));
 
-    // manually remove clustering completed instant from .hoodie folder and to 
mimic succeeded clustering in metadata table, but failed in data table.
-    FileCreateUtilsLegacy.deleteReplaceCommit(basePath, clusteringCommitTime);
     HoodieWriteMetadata<List<WriteStatus>> updatedClusterMetadata = 
newClient.cluster(clusteringCommitTime, true);
 
     metaClient.reloadActiveTimeline();
diff --git 
a/hudi-spark-datasource/hudi-spark/src/test/java/org/apache/hudi/functional/TestHoodieBackedMetadata.java
 
b/hudi-spark-datasource/hudi-spark/src/test/java/org/apache/hudi/functional/TestHoodieBackedMetadata.java
index ec0d405fad91..9aa0b43fb949 100644
--- 
a/hudi-spark-datasource/hudi-spark/src/test/java/org/apache/hudi/functional/TestHoodieBackedMetadata.java
+++ 
b/hudi-spark-datasource/hudi-spark/src/test/java/org/apache/hudi/functional/TestHoodieBackedMetadata.java
@@ -2881,7 +2881,7 @@ public class TestHoodieBackedMetadata extends 
TestHoodieMetadataBase {
         .withClusteringSortColumns("_row_key").withInlineClustering(true)
         
.withClusteringTargetPartitions(0).withInlineClusteringNumCommits(1).build();
 
-    HoodieWriteConfig newWriteConfig = getConfigBuilder(TRIP_EXAMPLE_SCHEMA, 
HoodieIndex.IndexType.BLOOM, HoodieFailedWritesCleaningPolicy.EAGER)
+    HoodieWriteConfig newWriteConfig = getConfigBuilder(TRIP_EXAMPLE_SCHEMA, 
HoodieIndex.IndexType.BLOOM, HoodieFailedWritesCleaningPolicy.LAZY)
         .withClusteringConfig(clusteringConfig)
         .withRollbackUsingMarkers(false)
         .build();
@@ -2897,6 +2897,22 @@ public class TestHoodieBackedMetadata extends 
TestHoodieMetadataBase {
         partitionFiles.getValue().stream().forEach(file ->
             replacedFileIds.add(new HoodieFileGroupId(partitionFiles.getKey(), 
file))));
 
+    // manually remove clustering completed instant from .hoodie folder to 
mimic clustering
+    // succeeded in metadata table, but failed before committing to data 
table. This must happen
+    // before any subsequent metadata-table read so that no reader ever sees 
the first attempt's
+    // instant as committed, matching the crash scenario this test simulates.
+    FileCreateUtilsLegacy.deleteReplaceCommit(basePath, clusteringCommitTime);
+
+    // preconditions: clustering is pending on the data table while its 
deltacommit is completed
+    // in the metadata table.
+    metaClient.reloadActiveTimeline();
+    
assertFalse(metaClient.getActiveTimeline().filterCompletedInstants().containsInstant(clusteringCommitTime));
+    
assertTrue(metaClient.getActiveTimeline().filterPendingClusteringTimeline().containsInstant(clusteringCommitTime));
+    HoodieTableMetaClient metadataMetaClient = 
HoodieTestUtils.createMetaClient(
+        metaClient.getStorageConf(), getMetadataTableBasePath(basePath));
+    assertTrue(metadataMetaClient.getActiveTimeline().getDeltaCommitTimeline()
+        .filterCompletedInstants().containsInstant(clusteringCommitTime));
+
     // trigger new write to mimic other writes succeeding before re-attempt.
     newCommitTime = "0000003";
     WriteClientTestUtils.startCommitWithTime(client, newCommitTime);
@@ -2904,10 +2920,15 @@ public class TestHoodieBackedMetadata extends 
TestHoodieMetadataBase {
     writeStatuses = client.insert(jsc.parallelize(records, 1), 
newCommitTime).collect();
     assertTrue(client.commit(newCommitTime, jsc.parallelize(writeStatuses), 
Option.empty(), COMMIT_ACTION, Collections.emptyMap(), Option.empty()));
     assertNoWriteErrors(writeStatuses);
-    validateMetadata(client);
+    // ignore the first clustering attempt's uncommitted files when comparing 
listings.
+    validateMetadata(client, Option.of(clusteringCommitTime));
+
+    // the new write must leave the pending clustering and its metadata-table 
deltacommit intact.
+    metaClient.reloadActiveTimeline();
+    
assertTrue(metaClient.getActiveTimeline().filterPendingClusteringTimeline().containsInstant(clusteringCommitTime));
+    
assertTrue(metadataMetaClient.reloadActiveTimeline().getDeltaCommitTimeline()
+        .filterCompletedInstants().containsInstant(clusteringCommitTime));
 
-    // manually remove clustering completed instant from .hoodie folder and to 
mimic succeeded clustering in metadata table, but failed in data table.
-    FileCreateUtilsLegacy.deleteReplaceCommit(basePath, clusteringCommitTime);
     HoodieWriteMetadata<JavaRDD<WriteStatus>> updatedClusterMetadata = 
newClient.cluster(clusteringCommitTime, true);
 
     metaClient.reloadActiveTimeline();

Reply via email to