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

siyao pushed a commit to branch HDDS-6517-Snapshot
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/HDDS-6517-Snapshot by this 
push:
     new dae9285af3 HDDS-7704. [snapshot] Add unit-testcases for snapshot 
restore (#4148)
dae9285af3 is described below

commit dae9285af3ead2ab2a3b11d009c3e993c596344f
Author: jyotirmoy-gh <[email protected]>
AuthorDate: Thu Jan 26 03:08:55 2023 +0530

    HDDS-7704. [snapshot] Add unit-testcases for snapshot restore (#4148)
---
 .../om/snapshot/TestOzoneSnapshotRestore.java      | 338 +++++++++++++++++++++
 1 file changed, 338 insertions(+)

diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOzoneSnapshotRestore.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOzoneSnapshotRestore.java
new file mode 100644
index 0000000000..799f56f41d
--- /dev/null
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOzoneSnapshotRestore.java
@@ -0,0 +1,338 @@
+/*
+ * 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.snapshot;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.hadoop.fs.ozone.OzoneFsShell;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.scm.HddsWhiteboxTestUtils;
+import org.apache.hadoop.ozone.MiniOzoneCluster;
+import org.apache.hadoop.ozone.MiniOzoneHAClusterImpl;
+import org.apache.hadoop.ozone.TestDataUtil;
+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.OzoneKey;
+import org.apache.hadoop.ozone.client.OzoneVolume;
+import org.apache.hadoop.ozone.client.io.OzoneOutputStream;
+import org.apache.hadoop.ozone.client.BucketArgs;
+import org.apache.hadoop.ozone.om.KeyManagerImpl;
+import org.apache.hadoop.ozone.om.OMStorage;
+import org.apache.hadoop.ozone.om.OmSnapshotManager;
+import org.apache.hadoop.ozone.om.OzoneManager;
+import org.apache.hadoop.ozone.om.helpers.BucketLayout;
+import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
+import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
+import org.apache.hadoop.util.ToolRunner;
+import org.apache.ozone.test.GenericTestUtils;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.rules.Timeout;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Stream;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.hadoop.fs.FileSystem.FS_DEFAULT_NAME_KEY;
+import static org.apache.hadoop.ozone.OzoneConsts.OM_DB_NAME;
+import static org.apache.hadoop.ozone.OzoneConsts.OM_KEY_PREFIX;
+import static org.apache.hadoop.ozone.OzoneConsts.OM_SNAPSHOT_DIR;
+import static org.apache.hadoop.ozone.OzoneConsts.OZONE_OFS_URI_SCHEME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.params.provider.Arguments.arguments;
+
+/**
+ * Tests Snapshot Restore function.
+ */
+
+public class TestOzoneSnapshotRestore {
+  private static final String OM_SERVICE_ID = "om-service-test1";
+  private static BucketLayout bucketLayout = BucketLayout.LEGACY;
+  private static MiniOzoneCluster cluster = null;
+  private static String volumeName;
+  private static String bucketName;
+  private static OzoneManagerProtocol writeClient;
+  private static ObjectStore store;
+  private static File metaDir;
+  private static OzoneManager leaderOzoneManager;
+  private static OzoneBucket ozoneBucket;
+  @Rule
+  public Timeout timeout = new Timeout(500, TimeUnit.SECONDS);
+  private OzoneConfiguration clientConf;
+
+  private static Stream<Arguments> bucketTypes() {
+    return Stream.of(
+            arguments(BucketLayout.FILE_SYSTEM_OPTIMIZED),
+            arguments(BucketLayout.LEGACY)
+    );
+  }
+
+  private static Stream<Arguments> bucketTypesCombinations() {
+    return Stream.of(
+            arguments(BucketLayout.FILE_SYSTEM_OPTIMIZED, BucketLayout.LEGACY),
+            arguments(BucketLayout.LEGACY, BucketLayout.FILE_SYSTEM_OPTIMIZED)
+    );
+  }
+
+  @BeforeEach
+  private void init() throws Exception {
+    OzoneConfiguration conf = new OzoneConfiguration();
+    String clusterId = UUID.randomUUID().toString();
+    String scmId = UUID.randomUUID().toString();
+    String serviceID = OM_SERVICE_ID + RandomStringUtils.randomNumeric(5);
+
+    cluster = MiniOzoneCluster.newOMHABuilder(conf)
+            .setClusterId(clusterId)
+            .setScmId(scmId)
+            .setOMServiceId(serviceID)
+            .setNumOfOzoneManagers(3)
+            .build();
+    cluster.waitForClusterToBeReady();
+
+    // create a volume and a bucket to be used by OzoneFileSystem
+    ozoneBucket = TestDataUtil
+            .createVolumeAndBucket(cluster, bucketLayout);
+    volumeName = ozoneBucket.getVolumeName();
+    bucketName = ozoneBucket.getName();
+
+    leaderOzoneManager = ((MiniOzoneHAClusterImpl) cluster).getOMLeader();
+    OzoneConfiguration leaderConfig = leaderOzoneManager.getConfiguration();
+    cluster.setConf(leaderConfig);
+
+    String hostPrefix = OZONE_OFS_URI_SCHEME + "://" + serviceID;
+    clientConf = new OzoneConfiguration(cluster.getConf());
+    clientConf.set(FS_DEFAULT_NAME_KEY, hostPrefix);
+
+    OzoneClient client = cluster.getClient();
+    store = client.getObjectStore();
+    writeClient = store.getClientProxy().getOzoneManagerClient();
+
+    KeyManagerImpl keyManager = (KeyManagerImpl) HddsWhiteboxTestUtils
+            .getInternalState(leaderOzoneManager, "keyManager");
+
+    // stop the deletion services so that keys can still be read
+    keyManager.stop();
+    metaDir = OMStorage.getOmDbDir(leaderConfig);
+
+  }
+
+  @AfterEach
+  public void tearDown() throws Exception {
+    if (cluster != null) {
+      cluster.shutdown();
+    }
+  }
+
+  private void createFileKey(OzoneBucket bucket, String key)
+          throws IOException {
+    byte[] value = RandomStringUtils.randomAscii(10240).getBytes(UTF_8);
+    OzoneOutputStream fileKey = bucket.createKey(key, value.length);
+    fileKey.write(value);
+    fileKey.close();
+  }
+
+  private void deleteKeys(OzoneBucket bucket) throws IOException {
+    Iterator<? extends OzoneKey> bucketIterator = bucket.listKeys(null);
+    while (bucketIterator.hasNext()) {
+      OzoneKey key = bucketIterator.next();
+      bucket.deleteKey(key.getName());
+    }
+  }
+
+  private String createSnapshot(String volName, String buckName)
+          throws IOException, InterruptedException, TimeoutException {
+    String snapshotName = UUID.randomUUID().toString();
+    store.createSnapshot(volName, buckName, snapshotName);
+    String snapshotKeyPrefix = OmSnapshotManager
+            .getSnapshotPrefix(snapshotName);
+    SnapshotInfo snapshotInfo = leaderOzoneManager
+            .getMetadataManager()
+            .getSnapshotInfoTable()
+            .get(SnapshotInfo.getTableKey(volName, buckName, snapshotName));
+    String snapshotDirName = metaDir + OM_KEY_PREFIX +
+            OM_SNAPSHOT_DIR + OM_KEY_PREFIX + OM_DB_NAME +
+            snapshotInfo.getCheckpointDirName() + OM_KEY_PREFIX + "CURRENT";
+    GenericTestUtils.waitFor(() -> new File(snapshotDirName).exists(),
+            1000, 120000);
+    return snapshotKeyPrefix;
+
+  }
+
+  private int keyCount(OzoneBucket bucket, String keyPrefix)
+          throws IOException {
+    Iterator<? extends OzoneKey> iterator = bucket.listKeys(keyPrefix);
+    int keyCount = 0;
+    while (iterator.hasNext()) {
+      iterator.next();
+      keyCount++;
+    }
+    return keyCount;
+  }
+
+  private void keyCopy(String sourcePath, String destPath)
+          throws Exception {
+    OzoneFsShell shell = new OzoneFsShell(clientConf);
+
+    try {
+      // Copy key from source to destination path
+      int res = ToolRunner.run(shell,
+              new String[]{"-cp", sourcePath, destPath});
+      assertEquals(0, res);
+    } finally {
+      shell.close();
+    }
+  }
+
+  @ParameterizedTest
+  @MethodSource("bucketTypes")
+  public void testRestoreSnapshot(BucketLayout bucketLayoutTest)
+          throws Exception {
+    String volume = "vol-" + RandomStringUtils.randomNumeric(5);
+    String bucket = "buc-" + RandomStringUtils.randomNumeric(5);
+    String keyPrefix = "key-";
+
+    store.createVolume(volume);
+    OzoneVolume vol = store.getVolume(volume);
+    BucketArgs bucketArgs = BucketArgs.newBuilder()
+            .setBucketLayout(bucketLayoutTest).build();
+    vol.createBucket(bucket, bucketArgs);
+    OzoneBucket buck = vol.getBucket(bucket);
+
+    for (int i = 0; i < 5; i++) {
+      createFileKey(buck, keyPrefix + i);
+    }
+
+    String snapshotKeyPrefix = createSnapshot(volume, bucket);
+
+    int volBucketKeyCount = keyCount(buck, snapshotKeyPrefix + keyPrefix);
+    Assert.assertEquals(5, volBucketKeyCount);
+
+    deleteKeys(buck);
+    int delKeyCount = keyCount(buck, keyPrefix);
+    Assert.assertEquals(0, delKeyCount);
+
+    String sourcePath = OM_KEY_PREFIX + volume + OM_KEY_PREFIX + bucket
+            + OM_KEY_PREFIX + snapshotKeyPrefix;
+    String destPath = OM_KEY_PREFIX + volume + OM_KEY_PREFIX + bucket;
+
+    for (int i = 0; i < 5; i++) {
+      keyCopy(sourcePath + keyPrefix + i, destPath);
+    }
+
+    int finalKeyCount = keyCount(buck, keyPrefix);
+    Assert.assertEquals(5, finalKeyCount);
+
+  }
+
+  @ParameterizedTest
+  @MethodSource("bucketTypes")
+  public void testRestoreSnapshotDifferentBucket(BucketLayout bucketLayoutTest)
+          throws Exception {
+    String volume = "vol-" + RandomStringUtils.randomNumeric(5);
+    String bucket = "buc-" + RandomStringUtils.randomNumeric(5);
+    String bucket2 = "buc-" + RandomStringUtils.randomNumeric(5);
+    String keyPrefix = "key-";
+
+    store.createVolume(volume);
+    OzoneVolume vol = store.getVolume(volume);
+    BucketArgs bucketArgs = BucketArgs.newBuilder()
+            .setBucketLayout(bucketLayoutTest).build();
+    vol.createBucket(bucket, bucketArgs);
+    OzoneBucket buck = vol.getBucket(bucket);
+    vol.createBucket(bucket2, bucketArgs);
+    OzoneBucket buck2 = vol.getBucket(bucket2);
+
+    for (int i = 0; i < 5; i++) {
+      createFileKey(buck, keyPrefix + i);
+    }
+
+    String snapshotKeyPrefix = createSnapshot(volume, bucket);
+
+    int volBucketKeyCount = keyCount(buck, snapshotKeyPrefix + keyPrefix);
+    Assert.assertEquals(5, volBucketKeyCount);
+
+    String sourcePath = OM_KEY_PREFIX + volume + OM_KEY_PREFIX + bucket
+            + OM_KEY_PREFIX + snapshotKeyPrefix;
+    String destPath = OM_KEY_PREFIX + volume + OM_KEY_PREFIX + bucket2;
+
+    for (int i = 0; i < 5; i++) {
+      keyCopy(sourcePath + keyPrefix + i, destPath);
+    }
+
+    int finalKeyCount = keyCount(buck2, keyPrefix);
+    Assert.assertEquals(5, finalKeyCount);
+
+  }
+
+  @ParameterizedTest
+  @MethodSource("bucketTypesCombinations")
+  public void testRestoreSnapshotDifferentBucketLayout(
+          BucketLayout bucketLayoutSource, BucketLayout bucketLayoutDest)
+          throws Exception {
+    String volume = "vol-" + RandomStringUtils.randomNumeric(5);
+    String bucket = "buc-" + RandomStringUtils.randomNumeric(5);
+    String bucket2 = "buc-" + RandomStringUtils.randomNumeric(5);
+    String keyPrefix = "key-";
+
+    store.createVolume(volume);
+    OzoneVolume vol = store.getVolume(volume);
+    BucketArgs bucketArgs = BucketArgs.newBuilder()
+            .setBucketLayout(bucketLayoutSource).build();
+    vol.createBucket(bucket, bucketArgs);
+    OzoneBucket buck = vol.getBucket(bucket);
+
+    bucketArgs = BucketArgs.newBuilder()
+            .setBucketLayout(bucketLayoutDest).build();
+    vol.createBucket(bucket2, bucketArgs);
+    OzoneBucket buck2 = vol.getBucket(bucket2);
+
+    for (int i = 0; i < 5; i++) {
+      createFileKey(buck, keyPrefix + i);
+    }
+
+    String snapshotKeyPrefix = createSnapshot(volume, bucket);
+
+    int volBucketKeyCount = keyCount(buck, snapshotKeyPrefix + keyPrefix);
+    Assert.assertEquals(5, volBucketKeyCount);
+
+    String sourcePath = OM_KEY_PREFIX + volume + OM_KEY_PREFIX + bucket
+            + OM_KEY_PREFIX + snapshotKeyPrefix;
+    String destPath = OM_KEY_PREFIX + volume + OM_KEY_PREFIX + bucket2;
+
+    for (int i = 0; i < 5; i++) {
+      keyCopy(sourcePath + keyPrefix + i, destPath);
+    }
+
+    int finalKeyCount = keyCount(buck2, keyPrefix);
+    Assert.assertEquals(5, finalKeyCount);
+
+  }
+
+}


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

Reply via email to