hemantk-12 commented on code in PR #5223:
URL: https://github.com/apache/ozone/pull/5223#discussion_r1308058060


##########
hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestSnapshotChain.java:
##########
@@ -273,4 +290,68 @@ public void testChainFromLoadFromTable() throws Exception {
         () -> chainManager.previousPathSnapshot(String
             .join("/", "vol1", "bucket1"), snapshotID1));
   }
+
+  private static Stream<? extends Arguments> invalidSnapshotChain() {
+    List<UUID> nodes = IntStream.range(0, 5)
+        .mapToObj(i -> UUID.randomUUID())
+        .collect(Collectors.toList());
+    return Stream.of(
+        Arguments.of(nodes, Named.of("Disconnected Snapshot Chain",
+            ImmutableMap.of(
+                nodes.get(1), nodes.get(0),
+                nodes.get(2), nodes.get(1),
+                nodes.get(4), nodes.get(3)))),
+        Arguments.of(nodes, Named.of("Complete Cyclic Snapshot Chain",
+            ImmutableMap.of(
+                nodes.get(0), nodes.get(4),
+                nodes.get(1), nodes.get(0),
+                nodes.get(2), nodes.get(1),
+                nodes.get(3), nodes.get(2),
+                nodes.get(4), nodes.get(3)))),
+        Arguments.of(nodes, Named.of("Partial Cyclic Snapshot Chain",
+            ImmutableMap.of(
+                nodes.get(0), nodes.get(3),
+                nodes.get(1), nodes.get(0),
+                nodes.get(2), nodes.get(1),
+                nodes.get(3), nodes.get(2),
+                nodes.get(4), nodes.get(3)))),
+        Arguments.of(nodes, Named.of("Diverged Snapshot Chain",
+            ImmutableMap.of(nodes.get(1), nodes.get(0),
+                nodes.get(2), nodes.get(1),
+                nodes.get(3), nodes.get(2),
+                nodes.get(4), nodes.get(2))))
+    );
+  }
+
+  @ParameterizedTest
+  @MethodSource("invalidSnapshotChain")
+  public void testInvalidGlobalChainFromLoadFromTable(
+      List<UUID> snapshotIDs, Map<UUID, UUID> snapshotChain) throws Exception {
+    Table<String, SnapshotInfo> snapshotInfo =
+        omMetadataManager.getSnapshotInfoTable();
+    for (UUID snapshotID : snapshotIDs) {
+      snapshotInfo.put(snapshotID.toString(),
+          createSnapshotInfo(snapshotID, snapshotChain.get(snapshotID),
+              snapshotChain.get(snapshotID), System.currentTimeMillis()));
+    }
+    Assertions.assertThrows(IllegalStateException.class,
+        () -> new SnapshotChainManager(omMetadataManager));
+  }
+
+  @ParameterizedTest
+  @MethodSource("invalidSnapshotChain")
+  public void testInvalidChainFromLoadFromTable(List<UUID> snapshotIDs,
+      Map<UUID, UUID> snapshotChain) throws Exception {
+    Table<String, SnapshotInfo> snapshotInfo =
+        omMetadataManager.getSnapshotInfoTable();
+    UUID prevSnapshotId = null;
+    for (UUID snapshotID : snapshotIDs) {
+      snapshotInfo.put(snapshotID.toString(),
+          createSnapshotInfo(snapshotID, snapshotChain.get(snapshotID),
+              prevSnapshotId, System.currentTimeMillis()));
+      prevSnapshotId = snapshotID;
+    }
+    Assertions.assertThrows(RuntimeException.class,

Review Comment:
   Why this is not `IllegalStateException`? I think you can change it to 
`IllegalStateException` after changing all the exception from `IOException` to 
`IllegalStateException`.



##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotChainManager.java:
##########
@@ -71,7 +71,27 @@ public SnapshotChainManager(OMMetadataManager 
metadataManager) {
   private void addSnapshotGlobal(UUID snapshotID,
                                  UUID prevGlobalID) throws IOException {
     // On add snapshot, set previous snapshot entry nextSnapshotID = snapshotID
+    if (globalSnapshotChain.containsKey(snapshotID)) {
+      throw new IllegalStateException(String.format(
+          "Snapshot chain corruption. Snapshot with snapshotId: %s is " +
+              "already present in the the chain.", snapshotID));
+    }
+    if (globalSnapshotChain.size() > 0 && prevGlobalID == null) {
+      throw new IllegalStateException(String.format("Snapshot chain " +
+          "corruption. Adding snapshot %s as head node while there are %d in " 
+
+          "the global snapshot chain.", snapshotID,
+          globalSnapshotChain.size()));
+    }
     if (prevGlobalID != null && globalSnapshotChain.containsKey(prevGlobalID)) 
{

Review Comment:
   nit: Can we move this `if` block after line 104? Basically move `if` block 
at line 98-104 before this `if `block



##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotChainManager.java:
##########
@@ -71,7 +71,27 @@ public SnapshotChainManager(OMMetadataManager 
metadataManager) {
   private void addSnapshotGlobal(UUID snapshotID,
                                  UUID prevGlobalID) throws IOException {
     // On add snapshot, set previous snapshot entry nextSnapshotID = snapshotID
+    if (globalSnapshotChain.containsKey(snapshotID)) {
+      throw new IllegalStateException(String.format(
+          "Snapshot chain corruption. Snapshot with snapshotId: %s is " +
+              "already present in the the chain.", snapshotID));

Review Comment:
   ```suggestion
                 "already present in the chain.", snapshotID));
   ```



##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotChainManager.java:
##########
@@ -105,7 +125,26 @@ private void addSnapshotPath(String snapshotPath,
           snapshotID));
     }
 
+    if (prevPathID == null && snapshotChainByPath.containsKey(snapshotPath) &&
+        !snapshotChainByPath.get(snapshotPath).isEmpty()) {
+      throw new IllegalStateException(String.format(
+          "Snapshot chain corruption. Error while adding snapshot with " +
+              "snapshotId %s with as the first snapshot in snapshot path:" +
+              " %s which already %d snapshots.", snapshotID, snapshotPath,
+          snapshotChainByPath.get(snapshotPath).size()));
+    }
+
     if (prevPathID != null && snapshotChainByPath.containsKey(snapshotPath)) {
+      if (snapshotChainByPath.get(snapshotPath).get(prevPathID)
+          .getNextSnapshotId() != null) {
+        throw new IOException(String.format("Snapshot chain corruption. " +

Review Comment:
   Please use `IllegalStateException`. Also change it for line number 100 and 
122 and remove `IOException` from the method signature as well.



##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotChainManager.java:
##########
@@ -71,7 +71,27 @@ public SnapshotChainManager(OMMetadataManager 
metadataManager) {
   private void addSnapshotGlobal(UUID snapshotID,
                                  UUID prevGlobalID) throws IOException {
     // On add snapshot, set previous snapshot entry nextSnapshotID = snapshotID
+    if (globalSnapshotChain.containsKey(snapshotID)) {
+      throw new IllegalStateException(String.format(
+          "Snapshot chain corruption. Snapshot with snapshotId: %s is " +
+              "already present in the the chain.", snapshotID));
+    }
+    if (globalSnapshotChain.size() > 0 && prevGlobalID == null) {
+      throw new IllegalStateException(String.format("Snapshot chain " +
+          "corruption. Adding snapshot %s as head node while there are %d in " 
+
+          "the global snapshot chain.", snapshotID,
+          globalSnapshotChain.size()));
+    }
     if (prevGlobalID != null && globalSnapshotChain.containsKey(prevGlobalID)) 
{
+      if (globalSnapshotChain.get(prevGlobalID).getNextSnapshotId() != null) {

Review Comment:
   nit: Should we add `hasNextSnapshotId` and `hasPreviousSnapshotId` in 
`SnapshotChainInfo`?



##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotChainManager.java:
##########
@@ -234,7 +273,10 @@ private void loadFromSnapshotInfoTable(OMMetadataManager 
metadataManager) {
     // snapshot chains - both global and local path
     try (TableIterator<String, ? extends Table.KeyValue<String, SnapshotInfo>>
              keyIter = metadataManager.getSnapshotInfoTable().iterator()) {
-      Map<Long, SnapshotInfo> snaps = new TreeMap<>();
+      Map<UUID, SnapshotInfo> snaps = new HashMap<>();
+      // Forward Linked list for snapshot chain.
+      Map<UUID, UUID> nextSnapshotIdMap = new HashMap<>();

Review Comment:
   nit: may be `snapshotToNextSnapshotMap`



##########
hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestSnapshotChain.java:
##########
@@ -239,8 +253,10 @@ public void testDeleteSnapshot() throws Exception {
     assertEquals(snapshotID3, 
chainManager.previousGlobalSnapshot(snapshotID2));
   }
 
-  @Test
-  public void testChainFromLoadFromTable() throws Exception {
+  @ParameterizedTest
+  @ValueSource(booleans = {true, false})
+  public void testChainFromLoadFromTable(boolean increasingTIme)

Review Comment:
   I think it is unnecessary to make it parameterized test. Just use random 
number generation 
[here](https://github.com/apache/ozone/blob/master/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestSnapshotChain.java#L75)
 because snapshot chain is independent of snapshot creation. It could be 
increasing, decreasing or  mix of both.



##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotChainManager.java:
##########
@@ -71,7 +71,27 @@ public SnapshotChainManager(OMMetadataManager 
metadataManager) {
   private void addSnapshotGlobal(UUID snapshotID,
                                  UUID prevGlobalID) throws IOException {
     // On add snapshot, set previous snapshot entry nextSnapshotID = snapshotID
+    if (globalSnapshotChain.containsKey(snapshotID)) {
+      throw new IllegalStateException(String.format(
+          "Snapshot chain corruption. Snapshot with snapshotId: %s is " +

Review Comment:
   nit: Can you please change exception message to `Global snapshot chain 
corruption` for all the exception messages in `addSnapshotGlobal` and `Path 
level snapshot chain corruption` for the exception messages in 
`addSnapshotPath`? And assert that exception message starts with correct 
message in the test.



##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/SnapshotChainManager.java:
##########
@@ -105,7 +125,26 @@ private void addSnapshotPath(String snapshotPath,
           snapshotID));
     }
 
+    if (prevPathID == null && snapshotChainByPath.containsKey(snapshotPath) &&
+        !snapshotChainByPath.get(snapshotPath).isEmpty()) {
+      throw new IllegalStateException(String.format(
+          "Snapshot chain corruption. Error while adding snapshot with " +

Review Comment:
   ```suggestion
             "Snapshot chain corruption. Error while adding snapshot with " +
                 "snapshotId: %s as the first snapshot in snapshot path: %s " +
                 "which already has %d snapshots.", snapshotID, snapshotPath,
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to