@Test
public void testGetHivePartitionEmptyPartitions()
{

    List<SchemaColumn> autoDiscoverableSubPartitionColumns;
    List<String> storageFilePaths;
    List<HivePartitionDto> expectedHivePartitions;
    List<HivePartitionDto> resultHivePartitions;
    // Create a business object data key without any sub-partitions.
    BusinessObjectDataKey businessObjectDataKey =
        new BusinessObjectDataKey(NAMESPACE, BDEF_NAME, FORMAT_USAGE_CODE, FORMAT_FILE_TYPE_CODE, FORMAT_VERSION, PARTITION_VALUE, NO_SUBPARTITION_VALUES,
            DATA_VERSION);
    // No auto-discoverable sub-partition columns with empty partition represented by "/".
    autoDiscoverableSubPartitionColumns = new ArrayList<>();
    storageFilePaths = getStorageFilePaths(Collections.singletonList("/"));
    expectedHivePartitions =
        Collections.singletonList(HivePartitionDto.builder().withPath("").withPartitionValues(Collections.singletonList(PARTITION_VALUE)).build());
    resultHivePartitions = hive13DdlGenerator
        .getHivePartitions(businessObjectDataKey, autoDiscoverableSubPartitionColumns, TEST_S3_KEY_PREFIX, storageFilePaths, STORAGE_NAME);
    assertEquals(expectedHivePartitions, resultHivePartitions);
    // No auto-discoverable sub-partition columns with empty partition represented by "_$folder$".
    autoDiscoverableSubPartitionColumns = new ArrayList<>();
    storageFilePaths = getStorageFilePaths(Collections.singletonList("_$folder$"));
    expectedHivePartitions =
        Collections.singletonList(HivePartitionDto.builder().withPath("").withPartitionValues(Collections.singletonList(PARTITION_VALUE)).build());
    resultHivePartitions = hive13DdlGenerator
        .getHivePartitions(businessObjectDataKey, autoDiscoverableSubPartitionColumns, TEST_S3_KEY_PREFIX, storageFilePaths, STORAGE_NAME);
    assertEquals(expectedHivePartitions, resultHivePartitions);
    // Single sub-partition column with empty partition represented by "/".
    autoDiscoverableSubPartitionColumns = getPartitionColumns(Collections.singletonList("column1"));
    storageFilePaths = getStorageFilePaths(Collections.singletonList("/column1=aa/"));
    expectedHivePartitions =
        Collections.singletonList(HivePartitionDto.builder().withPath("/column1=aa").withPartitionValues(Arrays.asList(PARTITION_VALUE, "aa")).build());
    resultHivePartitions = hive13DdlGenerator
        .getHivePartitions(businessObjectDataKey, autoDiscoverableSubPartitionColumns, TEST_S3_KEY_PREFIX, storageFilePaths, STORAGE_NAME);
    assertEquals(expectedHivePartitions, resultHivePartitions);
    // Single sub-partition column with empty partition represented by "_$folder$".
    autoDiscoverableSubPartitionColumns = getPartitionColumns(Collections.singletonList("column1"));
    storageFilePaths = getStorageFilePaths(Collections.singletonList("/column1=aa_$folder$"));
    expectedHivePartitions =
        Collections.singletonList(HivePartitionDto.builder().withPath("/column1=aa").withPartitionValues(Arrays.asList(PARTITION_VALUE, "aa")).build());
    resultHivePartitions = hive13DdlGenerator
        .getHivePartitions(businessObjectDataKey, autoDiscoverableSubPartitionColumns, TEST_S3_KEY_PREFIX, storageFilePaths, STORAGE_NAME);
    assertEquals(expectedHivePartitions, resultHivePartitions);
    // Two sub-partition columns with empty partition represented by "/".
    autoDiscoverableSubPartitionColumns = getPartitionColumns(Arrays.asList("Column1", "column2"));
    storageFilePaths = getStorageFilePaths(Collections.singletonList("/column1=aa/column2=bb/"));
    expectedHivePartitions = Collections.singletonList(
        HivePartitionDto.builder().withPath("/column1=aa/column2=bb").withPartitionValues(Arrays.asList(PARTITION_VALUE, "aa", "bb")).build());
    resultHivePartitions = hive13DdlGenerator
        .getHivePartitions(businessObjectDataKey, autoDiscoverableSubPartitionColumns, TEST_S3_KEY_PREFIX, storageFilePaths, STORAGE_NAME);
    assertEquals(expectedHivePartitions, resultHivePartitions);
    // Two sub-partition columns with empty partition represented by "_$folder$".
    autoDiscoverableSubPartitionColumns = getPartitionColumns(Arrays.asList("Column1", "column2"));
    storageFilePaths = getStorageFilePaths(Collections.singletonList("/column1=aa/column2=bb_$folder$"));
    expectedHivePartitions = Collections.singletonList(
        HivePartitionDto.builder().withPath("/column1=aa/column2=bb").withPartitionValues(Arrays.asList(PARTITION_VALUE, "aa", "bb")).build());
    resultHivePartitions = hive13DdlGenerator
        .getHivePartitions(businessObjectDataKey, autoDiscoverableSubPartitionColumns, TEST_S3_KEY_PREFIX, storageFilePaths, STORAGE_NAME);
    assertEquals(expectedHivePartitions, resultHivePartitions);
    // Two sub-partition columns with empty partition represented by "/" and with data files present.
    autoDiscoverableSubPartitionColumns = getPartitionColumns(Arrays.asList("Column1", "column2"));
    storageFilePaths = getStorageFilePaths(Arrays.asList("/column1=aa/column2=bb/", "/column1=aa/column2=bb/file.dat"));
    expectedHivePartitions = Collections.singletonList(
        HivePartitionDto.builder().withPath("/column1=aa/column2=bb").withPartitionValues(Arrays.asList(PARTITION_VALUE, "aa", "bb")).build());
    resultHivePartitions = hive13DdlGenerator
        .getHivePartitions(businessObjectDataKey, autoDiscoverableSubPartitionColumns, TEST_S3_KEY_PREFIX, storageFilePaths, STORAGE_NAME);
    assertEquals(expectedHivePartitions, resultHivePartitions);
    // Two sub-partition columns with empty partition represented by "_$folder$" and with data files present.
    autoDiscoverableSubPartitionColumns = getPartitionColumns(Arrays.asList("Column1", "column2"));
    storageFilePaths = getStorageFilePaths(Arrays.asList("/column1=aa/column2=bb_$folder$", "/column1=aa/column2=bb/file.dat"));
    expectedHivePartitions = Collections.singletonList(
        HivePartitionDto.builder().withPath("/column1=aa/column2=bb").withPartitionValues(Arrays.asList(PARTITION_VALUE, "aa", "bb")).build());
    resultHivePartitions = hive13DdlGenerator
        .getHivePartitions(businessObjectDataKey, autoDiscoverableSubPartitionColumns, TEST_S3_KEY_PREFIX, storageFilePaths, STORAGE_NAME);
    assertEquals(expectedHivePartitions, resultHivePartitions);
    // Maximum supported number of sub-partition columns with empty folders present on every level and with data files present at the last sub-partition.
    // Different partition values are used to validate discovery logic for the fully qualified partitions.
    // There are also the following two special cases added:
    // - sub-partitions added that contain empty folder marker as a sub-partition value, which is allowed
    // - sub-partitions with data files that start, contain, and/or end with an empty folder marker
    autoDiscoverableSubPartitionColumns = getPartitionColumns(Arrays.asList("Column_1", "Column_2", "Column_3", "Column_4"));
    storageFilePaths = getStorageFilePaths(Arrays.asList("/",                       // an empty folder for the primary partition
        "_$folder$",                                                                // an empty folder for the primary partition
        "/column_1=a01/",                                                           // an empty folder for the first sub-partition
        "/column_1=a02_$folder$",                                                   // an empty folder for the first sub-partition
        "/column_1=a03/column-2=b01/",                                              // an empty folder for the second sub-partition
        "/column_1=a04/column-2=b02_$folder$",                                      // an empty folder for the second sub-partition
        "/column_1=a05/column-2=b03/COLUMN_3=c01/",                                 // an empty folder for the third sub-partition
        "/column_1=a06/column-2=b04/COLUMN_3=c02_$folder$",                         // an empty folder for the third sub-partition
        "/column_1=a07/column-2=b05/COLUMN_3=c03/COLUMN-4=d01/",                    // an empty folder for the forth sub-partition
        "/column_1=a08/column-2=b06/COLUMN_3=c04/COLUMN-4=d02_$folder$",            // an empty folder for the forth sub-partition
        "/column_1=a09/column-2=b07/COLUMN_3=c05/COLUMN-4=d03/file.dat",            // a data file present in the forth sub-partition
        "/column_1=a10/column-2=b08/COLUMN_3=c06/COLUMN-4=d04_$folder$/",           // a sub-partition value is an empty folder marker
        "/column_1=a11/column-2=b09/COLUMN_3=c07/COLUMN-4=d05_$folder$/file.dat",   // a sub-partition value is an empty folder marker
        "/column_1=a12/column-2=b10/COLUMN_3=c08/COLUMN-4=d06/_$folder$file.dat",   // data file name starts an empty folder marker
        "/column_1=a13/column-2=b11/COLUMN_3=c09/COLUMN-4=d07/file_$folder$.dat",   // data file name contains an empty folder marker
        "/column_1=a14/column-2=b12/COLUMN_3=c10/COLUMN-4=d08/file.dat_$folder$",   // data file name ends with an empty folder marker
        "/column_1=a15/column-2=b13/COLUMN_3=c11/COLUMN-4=d09/_$folder$"            // data file name is an empty folder marker
    ));
    expectedHivePartitions = Arrays.asList(HivePartitionDto.builder().withPath("/column_1=a07/column-2=b05/COLUMN_3=c03/COLUMN-4=d01")
            .withPartitionValues(Arrays.asList(PARTITION_VALUE, "a07", "b05", "c03", "d01")).build(),
        HivePartitionDto.builder().withPath("/column_1=a08/column-2=b06/COLUMN_3=c04/COLUMN-4=d02")
            .withPartitionValues(Arrays.asList(PARTITION_VALUE, "a08", "b06", "c04", "d02")).build(),
        HivePartitionDto.builder().withPath("/column_1=a09/column-2=b07/COLUMN_3=c05/COLUMN-4=d03")
            .withPartitionValues(Arrays.asList(PARTITION_VALUE, "a09", "b07", "c05", "d03")).build(),
        HivePartitionDto.builder().withPath("/column_1=a10/column-2=b08/COLUMN_3=c06/COLUMN-4=d04_$folder$")
            .withPartitionValues(Arrays.asList(PARTITION_VALUE, "a10", "b08", "c06", "d04_$folder$")).build(),
        HivePartitionDto.builder().withPath("/column_1=a11/column-2=b09/COLUMN_3=c07/COLUMN-4=d05_$folder$")
            .withPartitionValues(Arrays.asList(PARTITION_VALUE, "a11", "b09", "c07", "d05_$folder$")).build(),
        HivePartitionDto.builder().withPath("/column_1=a12/column-2=b10/COLUMN_3=c08/COLUMN-4=d06")
            .withPartitionValues(Arrays.asList(PARTITION_VALUE, "a12", "b10", "c08", "d06")).build(),
        HivePartitionDto.builder().withPath("/column_1=a13/column-2=b11/COLUMN_3=c09/COLUMN-4=d07")
            .withPartitionValues(Arrays.asList(PARTITION_VALUE, "a13", "b11", "c09", "d07")).build(),
        HivePartitionDto.builder().withPath("/column_1=a14/column-2=b12/COLUMN_3=c10/COLUMN-4=d08")
            .withPartitionValues(Arrays.asList(PARTITION_VALUE, "a14", "b12", "c10", "d08")).build(),
        HivePartitionDto.builder().withPath("/column_1=a15/column-2=b13/COLUMN_3=c11/COLUMN-4=d09")
            .withPartitionValues(Arrays.asList(PARTITION_VALUE, "a15", "b13", "c11", "d09")).build());
    resultHivePartitions = hive13DdlGenerator
        .getHivePartitions(businessObjectDataKey, autoDiscoverableSubPartitionColumns, TEST_S3_KEY_PREFIX, storageFilePaths, STORAGE_NAME);
    assertEquals(expectedHivePartitions, resultHivePartitions);
}