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

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


The following commit(s) were added to refs/heads/master by this push:
     new af3e34377b0 HDDS-16076. Separate test class for 
testInstallSnapshotDuringBootstrapping. (#10931)
af3e34377b0 is described below

commit af3e34377b03156666014c760d51c7a36a503b89
Author: Sadanand Shenoy <[email protected]>
AuthorDate: Mon Aug 10 14:24:05 2026 +0530

    HDDS-16076. Separate test class for testInstallSnapshotDuringBootstrapping. 
(#10931)
---
 .../TestOMInstallSnapshotDuringBootstrapping.java  | 207 +++++++++++++++++++++
 .../hadoop/ozone/om/TestOMRatisSnapshots.java      | 141 +-------------
 2 files changed, 209 insertions(+), 139 deletions(-)

diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMInstallSnapshotDuringBootstrapping.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMInstallSnapshotDuringBootstrapping.java
new file mode 100644
index 00000000000..5d0d1724fef
--- /dev/null
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMInstallSnapshotDuringBootstrapping.java
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.om;
+
+import static 
org.apache.hadoop.ozone.om.TestOzoneManagerHAWithStoppedNodes.createKey;
+import static org.apache.ozone.test.OzoneTestBase.uniqueObjectName;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.apache.commons.io.IOUtils;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.conf.StorageUnit;
+import org.apache.hadoop.hdds.utils.RDBSnapshotProvider;
+import org.apache.hadoop.ozone.MiniOzoneCluster;
+import org.apache.hadoop.ozone.MiniOzoneHAClusterImpl;
+import org.apache.hadoop.ozone.OzoneConfigKeys;
+import org.apache.hadoop.ozone.client.BucketArgs;
+import org.apache.hadoop.ozone.client.ObjectStore;
+import org.apache.hadoop.ozone.client.OzoneBucket;
+import org.apache.hadoop.ozone.client.OzoneClient;
+import org.apache.hadoop.ozone.client.OzoneClientFactory;
+import org.apache.hadoop.ozone.client.OzoneVolume;
+import org.apache.hadoop.ozone.om.helpers.BucketLayout;
+import org.apache.hadoop.ozone.om.ratis.OzoneManagerRatisServer;
+import org.apache.hadoop.ozone.om.ratis.OzoneManagerRatisServerConfig;
+import org.apache.hadoop.ozone.om.ratis.OzoneManagerStateMachine;
+import org.apache.ozone.test.GenericTestUtils;
+import org.apache.ozone.test.GenericTestUtils.LogCapturer;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Regression tests for OM bootstrap install snapshot while {@code 
BOOTSTRAPPING}.
+ */
+public class TestOMInstallSnapshotDuringBootstrapping {
+
+  private static final String OM_SERVICE_ID = "om-service-bootstrap";
+  private static final int LOG_PURGE_GAP = 5;
+  private static final long SNAPSHOT_THRESHOLD = 50;
+  private static final long TARGET_LOG_INDEX = 200;
+  private static final int INSTALL_START_DEADLINE_MS = 30_000;
+  private static final int COMPLETION_DEADLINE_MS = 60_000;
+  private static final BucketLayout TEST_BUCKET_LAYOUT = 
BucketLayout.OBJECT_STORE;
+
+  private MiniOzoneHAClusterImpl cluster;
+  private OzoneClient client;
+  private OzoneBucket ozoneBucket;
+
+  @BeforeEach
+  public void init() throws Exception {
+    OzoneConfiguration conf = new OzoneConfiguration();
+    conf.setInt(OzoneConfigKeys.OZONE_CLIENT_FAILOVER_MAX_ATTEMPTS_KEY, 5);
+    conf.setInt(OMConfigKeys.OZONE_OM_RATIS_LOG_PURGE_GAP, LOG_PURGE_GAP);
+    
conf.setLong(OMConfigKeys.OZONE_OM_RATIS_SNAPSHOT_AUTO_TRIGGER_THRESHOLD_KEY,
+        SNAPSHOT_THRESHOLD);
+    conf.setStorageSize(OMConfigKeys.OZONE_OM_RATIS_SEGMENT_SIZE_KEY, 16, 
StorageUnit.KB);
+    
conf.setStorageSize(OMConfigKeys.OZONE_OM_RATIS_SEGMENT_PREALLOCATED_SIZE_KEY,
+        16, StorageUnit.KB);
+
+    OzoneManagerRatisServerConfig omRatisConf =
+        conf.getObject(OzoneManagerRatisServerConfig.class);
+    omRatisConf.setLogAppenderWaitTimeMin(10);
+    conf.setFromObject(omRatisConf);
+
+    cluster = (MiniOzoneHAClusterImpl) MiniOzoneCluster.newHABuilder(conf)
+        .setOMServiceId(OM_SERVICE_ID)
+        .setNumOfOzoneManagers(2)
+        .setNumDatanodes(1)
+        .build();
+    cluster.waitForClusterToBeReady();
+
+    client = OzoneClientFactory.getRpcClient(OM_SERVICE_ID, conf);
+    ObjectStore objectStore = client.getObjectStore();
+    String volumeName = uniqueObjectName("volume");
+    String bucketName = uniqueObjectName("bucket");
+    objectStore.createVolume(volumeName);
+    OzoneVolume volume = objectStore.getVolume(volumeName);
+    volume.createBucket(bucketName,
+        BucketArgs.newBuilder().setBucketLayout(TEST_BUCKET_LAYOUT).build());
+    ozoneBucket = volume.getBucket(bucketName);
+  }
+
+  @AfterEach
+  public void shutdown() {
+    IOUtils.closeQuietly(client);
+    if (cluster != null) {
+      cluster.shutdown();
+    }
+  }
+
+  /**
+   * Checkpoint install must proceed during {@code BOOTSTRAPPING} with the 
default
+   * v2 checkpoint API and complete successfully.
+   */
+  @Test
+  public void testInstallSnapshotDuringBootstrapping() throws Exception {
+    OzoneManager leader = cluster.getOMLeader();
+    writeKeysToIncreaseLogIndex(leader.getOmRatisServer(), TARGET_LOG_INDEX);
+    assertThat(leader.getRatisSnapshotIndex())
+        .as("leader should have purged early logs")
+        .isGreaterThan((long) LOG_PURGE_GAP);
+
+    LogCapturer omLog = LogCapturer.captureLogs(OzoneManager.class);
+    LogCapturer stateMachineLog =
+        LogCapturer.captureLogs(OzoneManagerStateMachine.class);
+    LogCapturer snapshotProviderLog =
+        LogCapturer.captureLogs(RDBSnapshotProvider.class);
+    String newNodeId = "omNode-bootstrap-ratis-snapshots";
+    ExecutorService executor = Executors.newSingleThreadExecutor();
+    Future<?> bootstrapFuture = executor.submit(() -> {
+      try {
+        cluster.bootstrapOzoneManager(newNodeId);
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    });
+
+    try {
+      waitForCheckpointInstallToStart(omLog, snapshotProviderLog);
+      bootstrapFuture.get(COMPLETION_DEADLINE_MS, TimeUnit.MILLISECONDS);
+      assertBootstrapOmJoinedRatisGroup(newNodeId);
+    } finally {
+      bootstrapFuture.cancel(true);
+      omLog.stopCapturing();
+      stateMachineLog.stopCapturing();
+      snapshotProviderLog.stopCapturing();
+      executor.shutdownNow();
+    }
+
+    assertThat(stateMachineLog.getOutput())
+        .as("Ratis should notify the bootstrapping OM to install a checkpoint")
+        .contains("Received install snapshot notification from OM leader");
+    assertThat(omLog.getOutput())
+        .as("checkpoint install must not be aborted during BOOTSTRAPPING")
+        .doesNotContain("Abort install snapshot from Leader");
+    assertThat(omLog.getOutput())
+        .as("checkpoint installation should finish")
+        .contains("Install Checkpoint is finished");
+    assertThat(snapshotProviderLog.getOutput())
+        .as("checkpoint download should start after install is accepted")
+        .contains("Prepare to download the snapshot from leader OM");
+    assertThat(snapshotProviderLog.getOutput())
+        .as("checkpoint tarball should be assembled on the bootstrapping OM")
+        .contains("DB snapshot transfer is complete.");
+  }
+
+  private void writeKeysToIncreaseLogIndex(OzoneManagerRatisServer 
omRatisServer,
+      long targetLogIndex) throws Exception {
+    long logIndex = omRatisServer.getLastAppliedTermIndex().getIndex();
+    while (logIndex < targetLogIndex) {
+      createKey(ozoneBucket);
+      logIndex = omRatisServer.getLastAppliedTermIndex().getIndex();
+    }
+  }
+
+  private void assertBootstrapOmJoinedRatisGroup(String newNodeId) {
+    OzoneManager newOm = cluster.getOzoneManager(newNodeId);
+    assertNotNull(newOm, "Bootstrapped OM should be registered on the 
cluster");
+    for (OzoneManager om : cluster.getOzoneManagersList()) {
+      assertTrue(om.doesPeerExist(newNodeId),
+          "New OM node " + newNodeId + " not present in peer list of OM " + 
om.getOMNodeId());
+      assertTrue(om.getOmRatisServer().doesPeerExist(newNodeId),
+          "New OM node " + newNodeId + " not present in Ratis peer list of OM "
+              + om.getOMNodeId());
+    }
+  }
+
+  private void waitForCheckpointInstallToStart(LogCapturer omLog,
+      LogCapturer snapshotProviderLog) throws InterruptedException, 
TimeoutException {
+    try {
+      GenericTestUtils.waitFor(() -> {
+        if (omLog.getOutput().contains("Abort install snapshot from Leader")) {
+          fail("Checkpoint install was aborted during BOOTSTRAPPING.");
+        }
+        return snapshotProviderLog.getOutput()
+            .contains("Prepare to download the snapshot from leader OM");
+      }, 200, INSTALL_START_DEADLINE_MS);
+    } catch (TimeoutException e) {
+      fail("Checkpoint download did not start within " + 
INSTALL_START_DEADLINE_MS
+          + "ms. OzoneManager log: " + omLog.getOutput()
+          + ", RDBSnapshotProvider log: " + snapshotProviderLog.getOutput());
+    }
+  }
+}
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMRatisSnapshots.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMRatisSnapshots.java
index 7be575e7162..27cfa6d10e9 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMRatisSnapshots.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMRatisSnapshots.java
@@ -30,7 +30,6 @@
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.File;
 import java.io.IOException;
@@ -54,14 +53,12 @@
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.conf.StorageUnit;
 import org.apache.hadoop.hdds.utils.FaultInjector;
-import org.apache.hadoop.hdds.utils.RDBSnapshotProvider;
 import org.apache.hadoop.hdds.utils.TransactionInfo;
 import org.apache.hadoop.hdds.utils.db.DBCheckpoint;
 import org.apache.hadoop.hdds.utils.db.RDBCheckpointUtils;
 import org.apache.hadoop.hdds.utils.db.RDBStore;
 import org.apache.hadoop.ozone.MiniOzoneCluster;
 import org.apache.hadoop.ozone.MiniOzoneHAClusterImpl;
-import org.apache.hadoop.ozone.OzoneConfigKeys;
 import org.apache.hadoop.ozone.OzoneConsts;
 import org.apache.hadoop.ozone.client.BucketArgs;
 import org.apache.hadoop.ozone.client.ObjectStore;
@@ -78,7 +75,6 @@
 import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
 import org.apache.hadoop.ozone.om.ratis.OzoneManagerRatisServer;
 import org.apache.hadoop.ozone.om.ratis.OzoneManagerRatisServerConfig;
-import org.apache.hadoop.ozone.om.ratis.OzoneManagerStateMachine;
 import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerRatisUtils;
 import org.apache.ozone.test.GenericTestUtils;
 import org.apache.ozone.test.GenericTestUtils.LogCapturer;
@@ -96,18 +92,13 @@
  * Tests the Ratis snapshots feature in OM. These tests do not depend on the
  * checkpoint transfer format and run once with the default (inode-based)
  * transfer; tests exercising the transfer path under both formats live in
- * {@link TestOMRatisSnapshotTransfer}.
+ * {@link TestOMRatisSnapshotTransfer}. Bootstrap install snapshot coverage 
lives in
+ * {@link TestOMInstallSnapshotDuringBootstrapping}.
  */
 public class TestOMRatisSnapshots {
   private static final String OM_SERVICE_ID = "om-service-test1";
-  private static final String BOOTSTRAP_OM_SERVICE_ID = "om-service-bootstrap";
   private static final int NUM_OF_OMS = 3;
 
-  private static final int BOOTSTRAP_LOG_PURGE_GAP = 5;
-  private static final long BOOTSTRAP_TARGET_LOG_INDEX = 200;
-  private static final int BOOTSTRAP_INSTALL_START_DEADLINE_MS = 30_000;
-  private static final int BOOTSTRAP_COMPLETION_DEADLINE_MS = 60_000;
-
   private MiniOzoneHAClusterImpl cluster = null;
   private ObjectStore objectStore;
   private OzoneConfiguration conf;
@@ -742,134 +733,6 @@ public void 
testInstallSnapshotFromLeaderFailedDownloadCleanupSucceeds()
     followerOM.getOmSnapshotProvider().setInjector(null);
   }
 
-  /**
-   * Regression test for bootstrap when leader logs are purged: checkpoint 
install
-   * must proceed during {@code BOOTSTRAPPING} with the default v2 checkpoint 
API
-   * and complete successfully.
-   */
-  @Test
-  public void testBootstrapInstallSnapshotDuringBootstrapping() throws 
Exception {
-    IOUtils.closeQuietly(client);
-    if (cluster != null) {
-      cluster.shutdown();
-    }
-
-    OzoneConfiguration bootstrapConf = new OzoneConfiguration();
-    
bootstrapConf.setInt(OzoneConfigKeys.OZONE_CLIENT_FAILOVER_MAX_ATTEMPTS_KEY, 5);
-    bootstrapConf.setInt(OMConfigKeys.OZONE_OM_RATIS_LOG_PURGE_GAP, 
BOOTSTRAP_LOG_PURGE_GAP);
-    
bootstrapConf.setLong(OMConfigKeys.OZONE_OM_RATIS_SNAPSHOT_AUTO_TRIGGER_THRESHOLD_KEY,
-        SNAPSHOT_THRESHOLD);
-    bootstrapConf.setStorageSize(OMConfigKeys.OZONE_OM_RATIS_SEGMENT_SIZE_KEY, 
16,
-        StorageUnit.KB);
-    
bootstrapConf.setStorageSize(OMConfigKeys.OZONE_OM_RATIS_SEGMENT_PREALLOCATED_SIZE_KEY,
-        16, StorageUnit.KB);
-
-    OzoneManagerRatisServerConfig omRatisConf =
-        bootstrapConf.getObject(OzoneManagerRatisServerConfig.class);
-    omRatisConf.setLogAppenderWaitTimeMin(10);
-    bootstrapConf.setFromObject(omRatisConf);
-
-    cluster = (MiniOzoneHAClusterImpl) 
MiniOzoneCluster.newHABuilder(bootstrapConf)
-        .setOMServiceId(BOOTSTRAP_OM_SERVICE_ID)
-        .setNumOfOzoneManagers(2)
-        .setNumDatanodes(1)
-        .build();
-    cluster.waitForClusterToBeReady();
-
-    client = OzoneClientFactory.getRpcClient(BOOTSTRAP_OM_SERVICE_ID, 
bootstrapConf);
-    objectStore = client.getObjectStore();
-    String bootstrapVolume = uniqueObjectName("volume");
-    String bootstrapBucket = uniqueObjectName("bucket");
-    objectStore.createVolume(bootstrapVolume);
-    OzoneVolume volume = objectStore.getVolume(bootstrapVolume);
-    volume.createBucket(bootstrapBucket,
-        BucketArgs.newBuilder().setBucketLayout(TEST_BUCKET_LAYOUT).build());
-    ozoneBucket = volume.getBucket(bootstrapBucket);
-
-    OzoneManager leader = cluster.getOMLeader();
-    writeKeysToIncreaseLogIndex(leader.getOmRatisServer(), 
BOOTSTRAP_TARGET_LOG_INDEX);
-    assertThat(leader.getRatisSnapshotIndex())
-        .as("leader should have purged early logs")
-        .isGreaterThan((long) BOOTSTRAP_LOG_PURGE_GAP);
-
-    LogCapturer omLog = LogCapturer.captureLogs(OzoneManager.class);
-    LogCapturer stateMachineLog =
-        LogCapturer.captureLogs(OzoneManagerStateMachine.class);
-    LogCapturer snapshotProviderLog =
-        LogCapturer.captureLogs(RDBSnapshotProvider.class);
-    String newNodeId = "omNode-bootstrap-ratis-snapshots";
-    ExecutorService executor = Executors.newSingleThreadExecutor();
-    Future<?> bootstrapFuture = executor.submit(() -> {
-      try {
-        cluster.bootstrapOzoneManager(newNodeId);
-      } catch (Exception e) {
-        throw new RuntimeException(e);
-      }
-    });
-
-    try {
-      waitForBootstrapCheckpointInstallToStart(omLog, snapshotProviderLog);
-      bootstrapFuture.get(BOOTSTRAP_COMPLETION_DEADLINE_MS, 
TimeUnit.MILLISECONDS);
-      assertBootstrapOmJoinedRatisGroup(newNodeId);
-    } finally {
-      bootstrapFuture.cancel(true);
-      omLog.stopCapturing();
-      stateMachineLog.stopCapturing();
-      snapshotProviderLog.stopCapturing();
-      executor.shutdownNow();
-      if (cluster != null) {
-        cluster.shutdown();
-      }
-    }
-
-    assertThat(stateMachineLog.getOutput())
-        .as("Ratis should notify the bootstrapping OM to install a checkpoint")
-        .contains("Received install snapshot notification from OM leader");
-    assertThat(omLog.getOutput())
-        .as("checkpoint install must not be aborted during BOOTSTRAPPING")
-        .doesNotContain("Abort install snapshot from Leader");
-    assertThat(omLog.getOutput())
-        .as("checkpoint installation should finish")
-        .contains("Install Checkpoint is finished");
-    assertThat(snapshotProviderLog.getOutput())
-        .as("checkpoint download should start after install is accepted")
-        .contains("Prepare to download the snapshot from leader OM");
-    assertThat(snapshotProviderLog.getOutput())
-        .as("checkpoint tarball should be assembled on the bootstrapping OM")
-        .contains("DB snapshot transfer is complete.");
-  }
-
-  private void assertBootstrapOmJoinedRatisGroup(String newNodeId) {
-    OzoneManager newOm = cluster.getOzoneManager(newNodeId);
-    assertNotNull(newOm, "Bootstrapped OM should be registered on the 
cluster");
-    for (OzoneManager om : cluster.getOzoneManagersList()) {
-      assertTrue(om.doesPeerExist(newNodeId),
-          "New OM node " + newNodeId + " not present in peer list of OM " + 
om.getOMNodeId());
-      assertTrue(om.getOmRatisServer().doesPeerExist(newNodeId),
-          "New OM node " + newNodeId + " not present in Ratis peer list of OM "
-              + om.getOMNodeId());
-    }
-  }
-
-  private void waitForBootstrapCheckpointInstallToStart(
-      LogCapturer omLog,
-      LogCapturer snapshotProviderLog)
-      throws InterruptedException, TimeoutException {
-    try {
-      GenericTestUtils.waitFor(() -> {
-        if (omLog.getOutput().contains("Abort install snapshot from Leader")) {
-          fail("Checkpoint install was aborted during BOOTSTRAPPING.");
-        }
-        return snapshotProviderLog.getOutput()
-            .contains("Prepare to download the snapshot from leader OM");
-      }, 200, BOOTSTRAP_INSTALL_START_DEADLINE_MS);
-    } catch (TimeoutException e) {
-      fail("Checkpoint download did not start within " + 
BOOTSTRAP_INSTALL_START_DEADLINE_MS
-          + "ms. OzoneManager log: " + omLog.getOutput()
-          + ", RDBSnapshotProvider log: " + snapshotProviderLog.getOutput());
-    }
-  }
-
   /**
    * Moves all contents from the checkpoint location into the omDbDir.
    * This reorganizes the checkpoint structure so that all checkpoint files


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to