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

adoroszlai 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 0cd6b3bf8a HDDS-10399. IndexOutOfBoundsException when shallow listing 
empty directory in non-FSO bucket (#6259)
0cd6b3bf8a is described below

commit 0cd6b3bf8a230b8fab71be7ecd802ef36cd7b55f
Author: SaketaChalamchala <[email protected]>
AuthorDate: Sun Feb 25 00:18:57 2024 -0800

    HDDS-10399. IndexOutOfBoundsException when shallow listing empty directory 
in non-FSO bucket (#6259)
---
 .../apache/hadoop/ozone/client/OzoneBucket.java    |   2 +-
 .../org/apache/hadoop/ozone/om/TestListKeys.java   | 114 +++++++++++++++++----
 2 files changed, 95 insertions(+), 21 deletions(-)

diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
index dc7d6cf0a7..3b76daeba4 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
@@ -1253,7 +1253,7 @@ public class OzoneBucket extends WithMetadata {
           proxy.listStatusLight(volumeName, name, delimiterKeyPrefix, false,
               startKey, listCacheSize, false);
 
-      if (addedKeyPrefix) {
+      if (addedKeyPrefix && statuses.size() > 0) {
         // previous round already include the startKey, so remove it
         statuses.remove(0);
       } else {
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestListKeys.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestListKeys.java
index be972557f4..204c0ee668 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestListKeys.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestListKeys.java
@@ -63,6 +63,8 @@ public class TestListKeys {
   private static OzoneConfiguration conf;
 
   private static OzoneBucket legacyOzoneBucket;
+
+  private static OzoneBucket obsOzoneBucket;
   private static OzoneClient client;
 
   /**
@@ -86,6 +88,10 @@ public class TestListKeys {
     legacyOzoneBucket = TestDataUtil
         .createVolumeAndBucket(client, BucketLayout.LEGACY);
 
+    // create a volume and a OBJECT_STORE bucket
+    obsOzoneBucket = TestDataUtil
+        .createVolumeAndBucket(client, BucketLayout.OBJECT_STORE);
+
     initFSNameSpace();
   }
 
@@ -99,6 +105,7 @@ public class TestListKeys {
 
   private static void initFSNameSpace() throws Exception {
     buildNameSpaceTree(legacyOzoneBucket);
+    buildNameSpaceTree(obsOzoneBucket);
   }
 
   /**
@@ -108,9 +115,9 @@ public class TestListKeys {
    *                    |
    *                    a1
    *                    |
-   *      -----------------------------------
-   *     |              |                       |
-   *     b1             b2                      b3
+   *      --------------------------------------------------------
+   *     |              |                       |                |
+   *     b1             b2                      b3               b4
    *    -------         ---------              -----------
    *   |      |        |    |   |             |    |     |
    *  c1     c2       d1   d2  d3             e1   e2   e3
@@ -125,25 +132,27 @@ public class TestListKeys {
   private static void buildNameSpaceTree(OzoneBucket ozoneBucket)
       throws Exception {
     LinkedList<String> keys = new LinkedList<>();
-    keys.add("/a1/b1/c1111.tx");
-    keys.add("/a1/b1/c1222.tx");
-    keys.add("/a1/b1/c1333.tx");
-    keys.add("/a1/b1/c1444.tx");
-    keys.add("/a1/b1/c1555.tx");
-    keys.add("/a1/b1/c1/c1.tx");
-    keys.add("/a1/b1/c12/c2.tx");
-    keys.add("/a1/b1/c12/c3.tx");
-
-    keys.add("/a1/b2/d1/d11.tx");
-    keys.add("/a1/b2/d2/d21.tx");
-    keys.add("/a1/b2/d2/d22.tx");
-    keys.add("/a1/b2/d3/d31.tx");
-
-    keys.add("/a1/b3/e1/e11.tx");
-    keys.add("/a1/b3/e2/e21.tx");
-    keys.add("/a1/b3/e3/e31.tx");
+    keys.add("a1/b1/c1111.tx");
+    keys.add("a1/b1/c1222.tx");
+    keys.add("a1/b1/c1333.tx");
+    keys.add("a1/b1/c1444.tx");
+    keys.add("a1/b1/c1555.tx");
+    keys.add("a1/b1/c1/c1.tx");
+    keys.add("a1/b1/c12/c2.tx");
+    keys.add("a1/b1/c12/c3.tx");
+
+    keys.add("a1/b2/d1/d11.tx");
+    keys.add("a1/b2/d2/d21.tx");
+    keys.add("a1/b2/d2/d22.tx");
+    keys.add("a1/b2/d3/d31.tx");
+
+    keys.add("a1/b3/e1/e11.tx");
+    keys.add("a1/b3/e2/e21.tx");
+    keys.add("a1/b3/e3/e31.tx");
 
     createKeys(ozoneBucket, keys);
+
+    ozoneBucket.createDirectory("a1/b4/");
   }
 
   private static Stream<Arguments> shallowListDataWithTrailingSlash() {
@@ -186,6 +195,58 @@ public class TestListKeys {
             "a1/b1/c1333.tx",
             "a1/b1/c1444.tx",
             "a1/b1/c1555.tx"
+        ))),
+
+        // Case-7: StartKey is empty, return key that is same as keyPrefix.
+        of("a1/b4/", "", newLinkedList(Arrays.asList(
+            "a1/b4/"
+        )))
+    );
+  }
+
+  private static Stream<Arguments> shallowListObsDataWithTrailingSlash() {
+    return Stream.of(
+
+        // Case-1: StartKey is less than prefixKey, return emptyList.
+        of("a1/b2/", "a1", newLinkedList(Collections.emptyList())),
+
+        // Case-2: StartKey is empty, return all immediate node.
+        of("a1/b2/", "", newLinkedList(Arrays.asList(
+            "a1/b2/d1/",
+            "a1/b2/d2/",
+            "a1/b2/d3/"
+        ))),
+
+        // Case-3: StartKey is same as prefixKey, return all immediate nodes.
+        of("a1/b2/", "a1/b2", newLinkedList(Arrays.asList(
+            "a1/b2/d1/",
+            "a1/b2/d2/",
+            "a1/b2/d3/"
+        ))),
+
+        // Case-4: StartKey is greater than prefixKey
+        of("a1/b2/", "a1/b2/d2/d21.tx", newLinkedList(Arrays.asList(
+            "a1/b2/d2/",
+            "a1/b2/d3/"
+        ))),
+
+        // Case-5: StartKey reaches last element, return emptyList
+        of("a1/b2/", "a1/b2/d3/d31.tx", newLinkedList(
+            Collections.emptyList()
+        )),
+
+        // Case-6: Mix result
+        of("a1/b1/", "a1/b1/c12", newLinkedList(Arrays.asList(
+            "a1/b1/c12/",
+            "a1/b1/c1222.tx",
+            "a1/b1/c1333.tx",
+            "a1/b1/c1444.tx",
+            "a1/b1/c1555.tx"
+        ))),
+
+        // Case-7: StartKey is empty, return key that is same as keyPrefix.
+        of("a1/b4/", "", newLinkedList(Arrays.asList(
+            "a1/b4/"
         )))
     );
   }
@@ -252,6 +313,11 @@ public class TestListKeys {
         of("a1/b1/c12", "", newLinkedList(Arrays.asList(
             "a1/b1/c12/",
             "a1/b1/c1222.tx"
+        ))),
+
+        // Case-10:
+        of("a1/b4", "", newLinkedList(Arrays.asList(
+            "a1/b4/"
         )))
 
     );
@@ -264,11 +330,19 @@ public class TestListKeys {
     checkKeyShallowList(keyPrefix, startKey, expectedKeys, legacyOzoneBucket);
   }
 
+  @ParameterizedTest
+  @MethodSource("shallowListObsDataWithTrailingSlash")
+  public void testShallowListObsKeysWithPrefixTrailingSlash(String keyPrefix,
+      String startKey, List<String> expectedKeys) throws Exception {
+    checkKeyShallowList(keyPrefix, startKey, expectedKeys, obsOzoneBucket);
+  }
+
   @ParameterizedTest
   @MethodSource("shallowListDataWithoutTrailingSlash")
   public void testShallowListKeysWithoutPrefixTrailingSlash(String keyPrefix,
       String startKey, List<String> expectedKeys) throws Exception {
     checkKeyShallowList(keyPrefix, startKey, expectedKeys, legacyOzoneBucket);
+    checkKeyShallowList(keyPrefix, startKey, expectedKeys, obsOzoneBucket);
   }
 
   private void checkKeyShallowList(String keyPrefix, String startKey,


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

Reply via email to