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 9596e8d41da HDDS-12807. Clean up TestKeyManagerImpl unit test (#10640)
9596e8d41da is described below

commit 9596e8d41da675075290ef3003dd8078a5e4e507
Author: Eric C. Ho <[email protected]>
AuthorDate: Fri Jul 3 21:30:52 2026 +0800

    HDDS-12807. Clean up TestKeyManagerImpl unit test (#10640)
---
 .../apache/hadoop/ozone/om/TestKeyManagerImpl.java | 450 +++++++++++++++------
 1 file changed, 332 insertions(+), 118 deletions(-)

diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerImpl.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerImpl.java
index 058bce1f997..4883591d401 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerImpl.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerImpl.java
@@ -41,62 +41,91 @@
 import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.ratis.util.function.CheckedFunction;
 import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
-import org.mockito.Mockito;
 
 /**
  * Test class for unit tests KeyManagerImpl.
  */
 public class TestKeyManagerImpl {
-  private static Stream<Arguments> getTableIteratorParameters() {
+  private static Stream<TestCase> getSuccessfulTableIteratorParameters() {
     return Stream.of(
-        Arguments.argumentSet("Fetch first 50 entries for volume 0, bucket 0",
-            5, 10, 100, 0, 0, 0, 0, 0, 50, null),
-        Arguments.argumentSet("Fetch first 50 entries for any volume/bucket", 
5, 10, 100, null, null, 0, 0, 0, 50,
-            null),
-        Arguments.argumentSet("Fetch first 30 entries for volume 1, bucket 1", 
5, 10, 100, 1, 1, 0, 0, 0, 30, null),
-        Arguments.argumentSet("Fetch 20 entries from offset (2,2,10) for 
volume 2, bucket 2", 5, 10, 100, 2, 2, 2, 2,
-            10, 20, null),
-        Arguments.argumentSet("Fetch 40 entries from offset (2,2,50) for 
volume 3, bucket 3", 5, 10, 100, 3, 3, 3, 3,
-            50, 40, null),
-        Arguments.argumentSet("Fetch 200 entries from the very beginning (null 
start offsets)", 5, 10, 100, null,
-            null, null, null, null, 200, null),
-        Arguments.argumentSet("Fetch 200 entries starting from bucket 3, key 
50, spanning 3 buckets", 5, 10, 100,
-            null, null, 0, 3, 50, 200, null),
-        Arguments.argumentSet("Invalid: bucket is set but volume is null", 5, 
10, 100, null, 1, 0, 0, 0, 10,
-            IOException.class),
-        Arguments.argumentSet("Invalid: volume is set but bucket is null", 5, 
10, 100, 1, null, 0, 0, 0, 10,
-            IOException.class),
-        Arguments.argumentSet("Fetch 50 entries from volume 2, bucket 5, but 
only 31 exist", 5, 10, 100, 2, 5, 2, 5,
-            70, 50, null),
-        Arguments.argumentSet("Start from last volume (4), second-last bucket 
(8), key 80 but only 131 entries exist",
-            5, 10, 100, null, null, 4, 8, 80, 200, null)
+        TestCase.newBuilder("Fetch first 50 entries for volume 0, bucket 0")
+            .volumeBucket(0, 0)
+            .start(0, 0, 0)
+            .entries(50)
+            .build(),
+        TestCase.newBuilder("Fetch first 50 entries for any volume/bucket")
+            .start(0, 0, 0)
+            .entries(50)
+            .build(),
+        TestCase.newBuilder("Fetch first 30 entries for volume 1, bucket 1")
+            .volumeBucket(1, 1)
+            .start(0, 0, 0)
+            .entries(30)
+            .build(),
+        TestCase.newBuilder("Fetch 20 entries from offset (2,2,10) for volume 
2, bucket 2")
+            .volumeBucket(2, 2)
+            .start(2, 2, 10)
+            .entries(20)
+            .build(),
+        TestCase.newBuilder("Fetch 40 entries from offset (2,2,50) for volume 
3, bucket 3")
+            .volumeBucket(3, 3)
+            .start(3, 3, 50)
+            .entries(40)
+            .build(),
+        TestCase.newBuilder("Fetch 200 entries from the very beginning (null 
start offsets)")
+            .start(null, null, null)
+            .entries(200)
+            .build(),
+        TestCase.newBuilder("Fetch 200 entries starting from bucket 3, key 50, 
spanning 3 buckets")
+            .start(0, 3, 50)
+            .entries(200)
+            .build(),
+        TestCase.newBuilder("Fetch 50 entries from volume 2, bucket 5, but 
only 31 exist")
+            .volumeBucket(2, 5)
+            .start(2, 5, 70)
+            .entries(50)
+            .build(),
+        TestCase.newBuilder("Start from last volume (4), second-last bucket 
(8), key 80 "
+            + "but only 131 entries exist")
+            .start(4, 8, 80)
+            .entries(200)
+            .build()
+    );
+  }
+
+  private static Stream<TestCase> getInvalidTableIteratorParameters() {
+    return Stream.of(
+        TestCase.newBuilder("Invalid: bucket is set but volume is null")
+            .volumeBucket(null, 1)
+            .start(0, 0, 0)
+            .entries(10)
+            .build(),
+        TestCase.newBuilder("Invalid: volume is set but bucket is null")
+            .volumeBucket(1, null)
+            .start(0, 0, 0)
+            .entries(10)
+            .build()
     );
   }
 
-  @SuppressWarnings({"checkstyle:ParameterNumber"})
   private <V> List<Table.KeyValue<String, V>> mockTableIterator(
-      Class<V> valueClass, Table<String, V> table, int numberOfVolumes, int 
numberOfBucketsPerVolume,
-      int numberOfKeysPerBucket, String volumeNamePrefix, String 
bucketNamePrefix, String keyPrefix,
-      Integer volumeNumberFilter, Integer bucketNumberFilter, Integer 
startVolumeNumber, Integer startBucketNumber,
-      Integer startKeyNumber, CheckedFunction<Table.KeyValue<String, V>, 
Boolean, IOException> filter,
-      int numberOfEntries) throws IOException {
+      Class<V> valueClass, Table<String, V> table, TestCase testCase, String 
volumeNamePrefix,
+      String bucketNamePrefix, String keyPrefix,
+      CheckedFunction<Table.KeyValue<String, V>, Boolean, IOException> filter) 
throws IOException {
     TreeMap<String, V> values = new TreeMap<>();
     List<Table.KeyValue<String, V>> keyValues = new ArrayList<>();
-    String startKey = startVolumeNumber == null || startBucketNumber == null 
|| startKeyNumber == null ? null
-        : (String.format("/%s%010d/%s%010d/%s%010d", volumeNamePrefix, 
startVolumeNumber, bucketNamePrefix,
-        startBucketNumber, keyPrefix, startKeyNumber));
-    for (int i = 0; i < numberOfVolumes; i++) {
-      for (int j = 0; j < numberOfBucketsPerVolume; j++) {
-        for (int k = 0; k < numberOfKeysPerBucket; k++) {
-          String key = String.format("/%s%010d/%s%010d/%s%010d", 
volumeNamePrefix, i, bucketNamePrefix, j,
-              keyPrefix, k);
-          V value = valueClass == String.class ? (V) key : mock(valueClass);
+    String startKey = getTableKey(volumeNamePrefix, 
testCase.getStartVolumeNumber(), bucketNamePrefix,
+        testCase.getStartBucketNumber(), keyPrefix, 
testCase.getStartKeyNumber());
+    for (int i = 0; i < testCase.getNumberOfVolumes(); i++) {
+      for (int j = 0; j < testCase.getNumberOfBucketsPerVolume(); j++) {
+        for (int k = 0; k < testCase.getNumberOfKeysPerBucket(); k++) {
+          String key = getTableKey(volumeNamePrefix, i, bucketNamePrefix, j, 
keyPrefix, k);
+          V value = valueClass == String.class ? valueClass.cast(key) : 
mock(valueClass);
           values.put(key, value);
 
-          if ((volumeNumberFilter == null || i == volumeNumberFilter) &&
-              (bucketNumberFilter == null || j == bucketNumberFilter) &&
+          if ((testCase.getVolumeNumber() == null || i == 
testCase.getVolumeNumber()) &&
+              (testCase.getBucketNumber() == null || j == 
testCase.getBucketNumber()) &&
               (startKey == null || startKey.compareTo(key) <= 0)) {
             keyValues.add(Table.newKeyValue(key, value));
           }
@@ -111,124 +140,309 @@ private <V> List<Table.KeyValue<String, V>> 
mockTableIterator(
       } catch (IOException e) {
         throw new RuntimeException(e);
       }
-    }).limit(numberOfEntries).collect(Collectors.toList());
+    }).limit(testCase.getNumberOfEntries()).collect(Collectors.toList());
   }
 
-  @ParameterizedTest
-  @MethodSource("getTableIteratorParameters")
-  @SuppressWarnings({"checkstyle:ParameterNumber"})
-  public void testGetDeletedKeyEntries(int numberOfVolumes, int 
numberOfBucketsPerVolume, int numberOfKeysPerBucket,
-                                       Integer volumeNumber, Integer 
bucketNumber,
-                                       Integer startVolumeNumber, Integer 
startBucketNumber, Integer startKeyNumber,
-                                       int numberOfEntries, Class<? extends 
Exception> expectedException)
-      throws IOException {
+  @ParameterizedTest(name = "{0}")
+  @MethodSource("getSuccessfulTableIteratorParameters")
+  void testGetDeletedKeyEntries(TestCase testCase) throws IOException {
     String volumeNamePrefix = "volume";
     String bucketNamePrefix = "bucket";
     String keyPrefix = "key";
     OzoneConfiguration configuration = new OzoneConfiguration();
-    OMMetadataManager metadataManager = Mockito.mock(OMMetadataManager.class);
+    OMMetadataManager metadataManager = mock(OMMetadataManager.class);
     KeyManagerImpl km = new KeyManagerImpl(null, null, metadataManager, 
configuration, null, null, null);
-    Table<String, RepeatedOmKeyInfo> mockedDeletedTable = 
Mockito.mock(Table.class);
+    Table<String, RepeatedOmKeyInfo> mockedDeletedTable = mock(Table.class);
     when(mockedDeletedTable.getName()).thenReturn(DELETED_TABLE);
     when(metadataManager.getDeletedTable()).thenReturn(mockedDeletedTable);
     when(metadataManager.getTableBucketPrefix(eq(DELETED_TABLE), anyString(), 
anyString()))
-        .thenAnswer(i -> "/" + i.getArguments()[1] + "/" + i.getArguments()[2] 
+ "/");
+        .thenAnswer(i -> getBucketPrefix(i.getArguments()));
     CheckedFunction<Table.KeyValue<String, RepeatedOmKeyInfo>, Boolean, 
IOException> filter =
-        (kv) -> Long.parseLong(kv.getKey().split(keyPrefix)[1]) % 2 == 0;
+        (kv) -> getKeyIndex(kv.getKey(), keyPrefix) % 2 == 0;
     List<Table.KeyValue<String, List<OmKeyInfo>>> expectedEntries = 
mockTableIterator(
-        RepeatedOmKeyInfo.class, mockedDeletedTable, numberOfVolumes, 
numberOfBucketsPerVolume, numberOfKeysPerBucket,
-        volumeNamePrefix, bucketNamePrefix, keyPrefix, volumeNumber, 
bucketNumber, startVolumeNumber, startBucketNumber,
-        startKeyNumber, filter, numberOfEntries).stream()
+        RepeatedOmKeyInfo.class, mockedDeletedTable, testCase, 
volumeNamePrefix, bucketNamePrefix, keyPrefix,
+        filter).stream()
         .map(kv -> {
           String key = kv.getKey();
           RepeatedOmKeyInfo value = kv.getValue();
-          List<OmKeyInfo> omKeyInfos = 
Collections.singletonList(Mockito.mock(OmKeyInfo.class));
+          List<OmKeyInfo> omKeyInfos = 
Collections.singletonList(mock(OmKeyInfo.class));
           when(value.cloneOmKeyInfoList()).thenReturn(omKeyInfos);
           return Table.newKeyValue(key, omKeyInfos);
         }).collect(Collectors.toList());
-    String volumeName = volumeNumber == null ? null : 
(String.format("%s%010d", volumeNamePrefix, volumeNumber));
-    String bucketName = bucketNumber == null ? null : 
(String.format("%s%010d", bucketNamePrefix, bucketNumber));
-    String startKey = startVolumeNumber == null || startBucketNumber == null 
|| startKeyNumber == null ? null
-        : (String.format("/%s%010d/%s%010d/%s%010d", volumeNamePrefix, 
startVolumeNumber, bucketNamePrefix,
-        startBucketNumber, keyPrefix, startKeyNumber));
-    if (expectedException != null) {
-      assertThrows(expectedException, () -> 
km.getDeletedKeyEntries(volumeName, bucketName, startKey, filter,
-          numberOfEntries));
-    } else {
-      assertEquals(expectedEntries,
-          km.getDeletedKeyEntries(volumeName, bucketName, startKey, filter, 
numberOfEntries));
-    }
+    String volumeName = getObjectName(volumeNamePrefix, 
testCase.getVolumeNumber());
+    String bucketName = getObjectName(bucketNamePrefix, 
testCase.getBucketNumber());
+    String startKey = getTableKey(volumeNamePrefix, 
testCase.getStartVolumeNumber(), bucketNamePrefix,
+        testCase.getStartBucketNumber(), keyPrefix, 
testCase.getStartKeyNumber());
+    assertEquals(expectedEntries,
+        km.getDeletedKeyEntries(volumeName, bucketName, startKey, filter, 
testCase.getNumberOfEntries()));
   }
 
-  @ParameterizedTest
-  @MethodSource("getTableIteratorParameters")
-  @SuppressWarnings({"checkstyle:ParameterNumber"})
-  public void testGetRenameKeyEntries(int numberOfVolumes, int 
numberOfBucketsPerVolume, int numberOfKeysPerBucket,
-                                      Integer volumeNumber, Integer 
bucketNumber,
-                                      Integer startVolumeNumber, Integer 
startBucketNumber, Integer startKeyNumber,
-                                      int numberOfEntries, Class<? extends 
Exception> expectedException)
-      throws IOException {
+  @ParameterizedTest(name = "{0}")
+  @MethodSource("getInvalidTableIteratorParameters")
+  void testGetDeletedKeyEntriesFails(TestCase testCase) throws IOException {
+    String volumeNamePrefix = "volume";
+    String bucketNamePrefix = "bucket";
+    String keyPrefix = "key";
+    OzoneConfiguration configuration = new OzoneConfiguration();
+    OMMetadataManager metadataManager = mock(OMMetadataManager.class);
+    KeyManagerImpl km = new KeyManagerImpl(null, null, metadataManager, 
configuration, null, null, null);
+    Table<String, RepeatedOmKeyInfo> mockedDeletedTable = mock(Table.class);
+    when(mockedDeletedTable.getName()).thenReturn(DELETED_TABLE);
+    when(metadataManager.getDeletedTable()).thenReturn(mockedDeletedTable);
+    when(metadataManager.getTableBucketPrefix(eq(DELETED_TABLE), anyString(), 
anyString()))
+        .thenAnswer(i -> getBucketPrefix(i.getArguments()));
+    CheckedFunction<Table.KeyValue<String, RepeatedOmKeyInfo>, Boolean, 
IOException> filter =
+        (kv) -> getKeyIndex(kv.getKey(), keyPrefix) % 2 == 0;
+    String volumeName = getObjectName(volumeNamePrefix, 
testCase.getVolumeNumber());
+    String bucketName = getObjectName(bucketNamePrefix, 
testCase.getBucketNumber());
+    String startKey = getTableKey(volumeNamePrefix, 
testCase.getStartVolumeNumber(), bucketNamePrefix,
+        testCase.getStartBucketNumber(), keyPrefix, 
testCase.getStartKeyNumber());
+
+    assertThrows(IOException.class,
+        () -> km.getDeletedKeyEntries(volumeName, bucketName, startKey, 
filter, testCase.getNumberOfEntries()));
+  }
+
+  @ParameterizedTest(name = "{0}")
+  @MethodSource("getSuccessfulTableIteratorParameters")
+  void testGetRenameKeyEntries(TestCase testCase) throws IOException {
     String volumeNamePrefix = "volume";
     String bucketNamePrefix = "bucket";
     String keyPrefix = "";
     OzoneConfiguration configuration = new OzoneConfiguration();
-    OMMetadataManager metadataManager = Mockito.mock(OMMetadataManager.class);
+    OMMetadataManager metadataManager = mock(OMMetadataManager.class);
     KeyManagerImpl km = new KeyManagerImpl(null, null, metadataManager, 
configuration, null, null, null);
-    Table<String, String> mockedRenameTable = Mockito.mock(Table.class);
+    Table<String, String> mockedRenameTable = mock(Table.class);
     when(mockedRenameTable.getName()).thenReturn(SNAPSHOT_RENAMED_TABLE);
     
when(metadataManager.getSnapshotRenamedTable()).thenReturn(mockedRenameTable);
     when(metadataManager.getTableBucketPrefix(eq(SNAPSHOT_RENAMED_TABLE), 
anyString(), anyString()))
-        .thenAnswer(i -> "/" + i.getArguments()[1] + "/" + i.getArguments()[2] 
+ "/");
+        .thenAnswer(i -> getBucketPrefix(i.getArguments()));
     CheckedFunction<Table.KeyValue<String, String>, Boolean, IOException> 
filter =
-        (kv) -> Long.parseLong(kv.getKey().split("/")[3]) % 2 == 0;
+        (kv) -> getRenameKeyIndex(kv.getKey()) % 2 == 0;
     List<Table.KeyValue<String, String>> expectedEntries = mockTableIterator(
-        String.class, mockedRenameTable, numberOfVolumes, 
numberOfBucketsPerVolume, numberOfKeysPerBucket,
-        volumeNamePrefix, bucketNamePrefix, keyPrefix, volumeNumber, 
bucketNumber, startVolumeNumber, startBucketNumber,
-        startKeyNumber, filter, numberOfEntries);
-    String volumeName = volumeNumber == null ? null : 
(String.format("%s%010d", volumeNamePrefix, volumeNumber));
-    String bucketName = bucketNumber == null ? null : 
(String.format("%s%010d", bucketNamePrefix, bucketNumber));
-    String startKey = startVolumeNumber == null || startBucketNumber == null 
|| startKeyNumber == null ? null
-        : (String.format("/%s%010d/%s%010d/%s%010d", volumeNamePrefix, 
startVolumeNumber, bucketNamePrefix,
-        startBucketNumber, keyPrefix, startKeyNumber));
-    if (expectedException != null) {
-      assertThrows(expectedException, () -> 
km.getRenamesKeyEntries(volumeName, bucketName, startKey,
-          filter, numberOfEntries));
-    } else {
-      assertEquals(expectedEntries,
-          km.getRenamesKeyEntries(volumeName, bucketName, startKey, filter, 
numberOfEntries));
-    }
+        String.class, mockedRenameTable, testCase, volumeNamePrefix, 
bucketNamePrefix, keyPrefix, filter);
+    String volumeName = getObjectName(volumeNamePrefix, 
testCase.getVolumeNumber());
+    String bucketName = getObjectName(bucketNamePrefix, 
testCase.getBucketNumber());
+    String startKey = getTableKey(volumeNamePrefix, 
testCase.getStartVolumeNumber(), bucketNamePrefix,
+        testCase.getStartBucketNumber(), keyPrefix, 
testCase.getStartKeyNumber());
+    assertEquals(expectedEntries,
+        km.getRenamesKeyEntries(volumeName, bucketName, startKey, filter, 
testCase.getNumberOfEntries()));
+  }
+
+  @ParameterizedTest(name = "{0}")
+  @MethodSource("getInvalidTableIteratorParameters")
+  void testGetRenameKeyEntriesFails(TestCase testCase) throws IOException {
+    String volumeNamePrefix = "volume";
+    String bucketNamePrefix = "bucket";
+    String keyPrefix = "";
+    OzoneConfiguration configuration = new OzoneConfiguration();
+    OMMetadataManager metadataManager = mock(OMMetadataManager.class);
+    KeyManagerImpl km = new KeyManagerImpl(null, null, metadataManager, 
configuration, null, null, null);
+    Table<String, String> mockedRenameTable = mock(Table.class);
+    when(mockedRenameTable.getName()).thenReturn(SNAPSHOT_RENAMED_TABLE);
+    
when(metadataManager.getSnapshotRenamedTable()).thenReturn(mockedRenameTable);
+    when(metadataManager.getTableBucketPrefix(eq(SNAPSHOT_RENAMED_TABLE), 
anyString(), anyString()))
+        .thenAnswer(i -> getBucketPrefix(i.getArguments()));
+    CheckedFunction<Table.KeyValue<String, String>, Boolean, IOException> 
filter =
+        (kv) -> getRenameKeyIndex(kv.getKey()) % 2 == 0;
+    String volumeName = getObjectName(volumeNamePrefix, 
testCase.getVolumeNumber());
+    String bucketName = getObjectName(bucketNamePrefix, 
testCase.getBucketNumber());
+    String startKey = getTableKey(volumeNamePrefix, 
testCase.getStartVolumeNumber(), bucketNamePrefix,
+        testCase.getStartBucketNumber(), keyPrefix, 
testCase.getStartKeyNumber());
+
+    assertThrows(IOException.class,
+        () -> km.getRenamesKeyEntries(volumeName, bucketName, startKey, 
filter, testCase.getNumberOfEntries()));
   }
 
-  @ParameterizedTest
-  @MethodSource("getTableIteratorParameters")
-  @SuppressWarnings({"checkstyle:ParameterNumber"})
-  public void testGetDeletedDirEntries(int numberOfVolumes, int 
numberOfBucketsPerVolume, int numberOfKeysPerBucket,
-                                       Integer volumeNumber, Integer 
bucketNumber,
-                                       Integer startVolumeNumber, Integer 
startBucketNumber, Integer startKeyNumber,
-                                       int numberOfEntries, Class<? extends 
Exception> expectedException)
-      throws IOException {
+  @ParameterizedTest(name = "{0}")
+  @MethodSource("getSuccessfulTableIteratorParameters")
+  void testGetDeletedDirEntries(TestCase testCase) throws IOException {
     String volumeNamePrefix = "";
     String bucketNamePrefix = "";
     String keyPrefix = "key";
-    startVolumeNumber = null;
     OzoneConfiguration configuration = new OzoneConfiguration();
-    OMMetadataManager metadataManager = Mockito.mock(OMMetadataManager.class);
+    OMMetadataManager metadataManager = mock(OMMetadataManager.class);
     KeyManagerImpl km = new KeyManagerImpl(null, null, metadataManager, 
configuration, null, null, null);
-    Table<String, OmKeyInfo> mockedDeletedDirTable = Mockito.mock(Table.class);
+    Table<String, OmKeyInfo> mockedDeletedDirTable = mock(Table.class);
     when(mockedDeletedDirTable.getName()).thenReturn(DELETED_DIR_TABLE);
     
when(metadataManager.getDeletedDirTable()).thenReturn(mockedDeletedDirTable);
     when(metadataManager.getTableBucketPrefix(eq(DELETED_DIR_TABLE), 
anyString(), anyString()))
-        .thenAnswer(i -> "/" + i.getArguments()[1] + "/" + i.getArguments()[2] 
+ "/");
+        .thenAnswer(i -> getBucketPrefix(i.getArguments()));
     List<Table.KeyValue<String, OmKeyInfo>> expectedEntries = 
mockTableIterator(
-        OmKeyInfo.class, mockedDeletedDirTable, numberOfVolumes, 
numberOfBucketsPerVolume, numberOfKeysPerBucket,
-        volumeNamePrefix, bucketNamePrefix, keyPrefix, volumeNumber, 
bucketNumber, startVolumeNumber, startBucketNumber,
-        startKeyNumber, (kv) -> true, numberOfEntries);
-    String volumeName = volumeNumber == null ? null : 
(String.format("%s%010d", volumeNamePrefix, volumeNumber));
-    String bucketName = bucketNumber == null ? null : 
(String.format("%s%010d", bucketNamePrefix, bucketNumber));
-    if (expectedException != null) {
-      assertThrows(expectedException, () -> 
km.getDeletedDirEntries(volumeName, bucketName, numberOfEntries));
-    } else {
-      assertEquals(expectedEntries, km.getDeletedDirEntries(volumeName, 
bucketName, numberOfEntries));
+        OmKeyInfo.class, mockedDeletedDirTable, testCase.withoutStartKey(), 
volumeNamePrefix, bucketNamePrefix,
+        keyPrefix, (kv) -> true);
+    String volumeName = getObjectName(volumeNamePrefix, 
testCase.getVolumeNumber());
+    String bucketName = getObjectName(bucketNamePrefix, 
testCase.getBucketNumber());
+    assertEquals(expectedEntries, km.getDeletedDirEntries(volumeName, 
bucketName, testCase.getNumberOfEntries()));
+  }
+
+  @ParameterizedTest(name = "{0}")
+  @MethodSource("getInvalidTableIteratorParameters")
+  void testGetDeletedDirEntriesFails(TestCase testCase) throws IOException {
+    String volumeNamePrefix = "";
+    String bucketNamePrefix = "";
+    OzoneConfiguration configuration = new OzoneConfiguration();
+    OMMetadataManager metadataManager = mock(OMMetadataManager.class);
+    KeyManagerImpl km = new KeyManagerImpl(null, null, metadataManager, 
configuration, null, null, null);
+    Table<String, OmKeyInfo> mockedDeletedDirTable = mock(Table.class);
+    when(mockedDeletedDirTable.getName()).thenReturn(DELETED_DIR_TABLE);
+    
when(metadataManager.getDeletedDirTable()).thenReturn(mockedDeletedDirTable);
+    when(metadataManager.getTableBucketPrefix(eq(DELETED_DIR_TABLE), 
anyString(), anyString()))
+        .thenAnswer(i -> getBucketPrefix(i.getArguments()));
+    String volumeName = getObjectName(volumeNamePrefix, 
testCase.getVolumeNumber());
+    String bucketName = getObjectName(bucketNamePrefix, 
testCase.getBucketNumber());
+
+    assertThrows(IOException.class,
+        () -> km.getDeletedDirEntries(volumeName, bucketName, 
testCase.getNumberOfEntries()));
+  }
+
+  private static String getObjectName(String prefix, Integer number) {
+    return number == null ? null : String.format("%s%010d", prefix, number);
+  }
+
+  private static String getTableKey(String volumeNamePrefix, Integer 
volumeNumber, String bucketNamePrefix,
+      Integer bucketNumber, String keyPrefix, Integer keyNumber) {
+    if (volumeNumber == null || bucketNumber == null || keyNumber == null) {
+      return null;
+    }
+    return String.format("/%s%010d/%s%010d/%s%010d", volumeNamePrefix, 
volumeNumber, bucketNamePrefix, bucketNumber,
+        keyPrefix, keyNumber);
+  }
+
+  private static String getBucketPrefix(Object[] arguments) {
+    return "/" + arguments[1] + "/" + arguments[2] + "/";
+  }
+
+  private static long getKeyIndex(String key, String keyPrefix) {
+    return Long.parseLong(key.split(keyPrefix)[1]);
+  }
+
+  private static long getRenameKeyIndex(String key) {
+    return Long.parseLong(key.split("/")[3]);
+  }
+
+  private static final class TestCase {
+    private final String name;
+    private final int numberOfVolumes;
+    private final int numberOfBucketsPerVolume;
+    private final int numberOfKeysPerBucket;
+    private final Integer volumeNumber;
+    private final Integer bucketNumber;
+    private final Integer startVolumeNumber;
+    private final Integer startBucketNumber;
+    private final Integer startKeyNumber;
+    private final int numberOfEntries;
+
+    private TestCase(Builder builder) {
+      name = builder.name;
+      numberOfVolumes = builder.numberOfVolumes;
+      numberOfBucketsPerVolume = builder.numberOfBucketsPerVolume;
+      numberOfKeysPerBucket = builder.numberOfKeysPerBucket;
+      volumeNumber = builder.volumeNumber;
+      bucketNumber = builder.bucketNumber;
+      startVolumeNumber = builder.startVolumeNumber;
+      startBucketNumber = builder.startBucketNumber;
+      startKeyNumber = builder.startKeyNumber;
+      numberOfEntries = builder.numberOfEntries;
+    }
+
+    static Builder newBuilder(String name) {
+      return new Builder(name);
+    }
+
+    TestCase withoutStartKey() {
+      return newBuilder(name)
+          .tableSize(numberOfVolumes, numberOfBucketsPerVolume, 
numberOfKeysPerBucket)
+          .volumeBucket(volumeNumber, bucketNumber)
+          .start(null, startBucketNumber, startKeyNumber)
+          .entries(numberOfEntries)
+          .build();
+    }
+
+    int getNumberOfVolumes() {
+      return numberOfVolumes;
+    }
+
+    int getNumberOfBucketsPerVolume() {
+      return numberOfBucketsPerVolume;
+    }
+
+    int getNumberOfKeysPerBucket() {
+      return numberOfKeysPerBucket;
+    }
+
+    Integer getVolumeNumber() {
+      return volumeNumber;
+    }
+
+    Integer getBucketNumber() {
+      return bucketNumber;
+    }
+
+    Integer getStartVolumeNumber() {
+      return startVolumeNumber;
+    }
+
+    Integer getStartBucketNumber() {
+      return startBucketNumber;
+    }
+
+    Integer getStartKeyNumber() {
+      return startKeyNumber;
+    }
+
+    int getNumberOfEntries() {
+      return numberOfEntries;
+    }
+
+    @Override
+    public String toString() {
+      return name;
+    }
+
+    private static final class Builder {
+      private final String name;
+      private int numberOfVolumes = 5;
+      private int numberOfBucketsPerVolume = 10;
+      private int numberOfKeysPerBucket = 100;
+      private Integer volumeNumber;
+      private Integer bucketNumber;
+      private Integer startVolumeNumber;
+      private Integer startBucketNumber;
+      private Integer startKeyNumber;
+      private int numberOfEntries;
+
+      private Builder(String testName) {
+        this.name = testName;
+      }
+
+      Builder tableSize(int volumes, int bucketsPerVolume, int keysPerBucket) {
+        numberOfVolumes = volumes;
+        numberOfBucketsPerVolume = bucketsPerVolume;
+        numberOfKeysPerBucket = keysPerBucket;
+        return this;
+      }
+
+      Builder volumeBucket(Integer volume, Integer bucket) {
+        volumeNumber = volume;
+        bucketNumber = bucket;
+        return this;
+      }
+
+      Builder start(Integer volume, Integer bucket, Integer key) {
+        startVolumeNumber = volume;
+        startBucketNumber = bucket;
+        startKeyNumber = key;
+        return this;
+      }
+
+      Builder entries(int entries) {
+        numberOfEntries = entries;
+        return this;
+      }
+
+      TestCase build() {
+        return new TestCase(this);
+      }
     }
   }
 }


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

Reply via email to