/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the LICENSE file, which can be found at the root of the source code       *
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "H5_api_link_test.h"

/*
 * TODO: add link tests for short-circuit success in operator callback
 */

static void print_link_test_header(void *params);
static void test_create_hard_link(void *params);
static void test_create_hard_link_long_name(void *params);
static void test_create_hard_link_many(void *params);
static void test_create_hard_link_same_loc(void *params);
static void test_create_hard_link_invalid_params(void *params);
static void test_create_soft_link_existing_relative(void *params);
static void test_create_soft_link_existing_absolute(void *params);
static void test_create_soft_link_dangling_relative(void *params);
static void test_create_soft_link_dangling_absolute(void *params);
static void test_create_soft_link_long_name(void *params);
static void test_create_soft_link_many(void *params);
static void test_create_soft_link_invalid_params(void *params);
static void test_create_external_link(void *params);
static void test_create_external_link_dangling(void *params);
static void test_create_external_link_multi(void *params);
static void test_create_external_link_ping_pong(void *params);
static void test_create_external_link_invalid_params(void *params);
static void test_create_user_defined_link(void *params);
static void test_create_user_defined_link_invalid_params(void *params);
static void test_delete_link(void *params);
static void test_delete_link_reset_grp_max_crt_order(void *params);
static void test_delete_link_invalid_params(void *params);
static void test_copy_link(void *params);
static void test_copy_links_into_group_with_links(void *params);
static void test_copy_link_across_files(void *params);
static void test_copy_link_invalid_params(void *params);
static void test_move_link(void *params);
static void test_move_links_into_group_with_links(void *params);
static void test_move_link_across_files(void *params);
static void test_move_link_reset_grp_max_crt_order(void *params);
static void test_move_link_invalid_params(void *params);
static void test_get_link_val(void *params);
static void test_get_link_val_invalid_params(void *params);
static void test_get_link_info(void *params);
static void test_get_link_info_invalid_params(void *params);
static void test_get_link_name(void *params);
static void test_get_link_name_invalid_params(void *params);
static void test_link_iterate_hard_links(void *params);
static void test_link_iterate_soft_links(void *params);
static void test_link_iterate_external_links(void *params);
static void test_link_iterate_ud_links(void *params);
static void test_link_iterate_mixed_links(void *params);
static void test_link_iterate_invalid_params(void *params);
static void test_link_iterate_0_links(void *params);
static void test_link_visit_hard_links_no_cycles(void *params);
static void test_link_visit_soft_links_no_cycles(void *params);
static void test_link_visit_external_links_no_cycles(void *params);
static void test_link_visit_ud_links_no_cycles(void *params);
static void test_link_visit_mixed_links_no_cycles(void *params);
static void test_link_visit_hard_links_cycles(void *params);
static void test_link_visit_soft_links_cycles(void *params);
static void test_link_visit_external_links_cycles(void *params);
static void test_link_visit_ud_links_cycles(void *params);
static void test_link_visit_mixed_links_cycles(void *params);
static void test_link_visit_invalid_params(void *params);
static void test_link_visit_0_links(void *params);

static herr_t link_iter_hard_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                      void *op_data);
static herr_t link_iter_soft_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                      void *op_data);
static herr_t link_iter_external_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                          void *op_data);
static herr_t link_iter_mixed_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                       void *op_data);
static herr_t link_iter_invalid_params_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                          void *op_data);
static herr_t link_iter_0_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data);
static herr_t link_iter_idx_saving_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                      void *op_data);
static herr_t link_visit_hard_links_no_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                                 void *op_data);
static herr_t link_visit_soft_links_no_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                                 void *op_data);
static herr_t link_visit_external_links_no_cycles_cb(hid_t group_id, const char *name,
                                                     const H5L_info2_t *info, void *op_data);
static herr_t link_visit_mixed_links_no_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                                  void *op_data);
static herr_t link_visit_hard_links_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                              void *op_data);
static herr_t link_visit_soft_links_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                              void *op_data);
static herr_t link_visit_external_links_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                                  void *op_data);
static herr_t link_visit_mixed_links_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                               void *op_data);
static herr_t link_visit_invalid_params_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                           void *op_data);
static herr_t link_visit_0_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data);

static void
print_link_test_header(void H5_ATTR_UNUSED *params)
{
    printf("\n");
    printf("**********************************************\n");
    printf("*                                            *\n");
    printf("*              API Link Tests                *\n");
    printf("*                                            *\n");
    printf("**********************************************\n\n");
}

/*
 * A test to check that a hard link can be created
 * using H5Lcreate_hard.
 */
static void
test_create_hard_link(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;

    TESTING("hard link creation");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or hard link aren't supported with this "
               "connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, HARD_LINK_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n", HARD_LINK_TEST_GROUP_NAME);
        goto error;
    }

    if (H5Lcreate_hard(file_id, "/", group_id, HARD_LINK_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create hard link '%s'\n", HARD_LINK_TEST_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, HARD_LINK_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", HARD_LINK_TEST_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a hard link with a long name can be created
 * using H5Lcreate_hard.
 */
static void
test_create_hard_link_long_name(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id = H5I_INVALID_HID;
    char   vol_name[5];
    size_t name_len        = MAX_NAME_LEN;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    char  *objname = NULL; /* Name of object [Long] */
    size_t u;              /* Local index variable */

    TESTING("hard link creation with a long name");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or hard link aren't supported with this "
               "connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, HARD_LINK_TEST_GROUP_LONG_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n", HARD_LINK_TEST_GROUP_NAME);
        goto error;
    }

    if (H5VLget_connector_name(file_id, vol_name, 5) < 0) {
        H5_FAILED();
        printf("    couldn't get VOL connector name\n");
        goto error;
    }

    /* Construct very long file name */
    if ((objname = (char *)malloc((size_t)(name_len + 1))) == NULL)
        TEST_ERROR;

    for (u = 0; u < name_len; u++)
        objname[u] = 'a';
    objname[name_len] = '\0';

    if (H5Lcreate_hard(file_id, "/", group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create hard link with a long name\n");
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, objname, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if the link with a long name exists\n");
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    /* Release memory */
    if (objname)
        free(objname);

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    if (objname)
        free(objname);

    return;
}

/*
 * A test to check that many hard links can be created
 * using H5Lcreate_hard.
 */
static void
test_create_hard_link_many(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID;
    hid_t  group_id = H5I_INVALID_HID, group_id2 = H5I_INVALID_HID;
    bool   valid_name_matched = false;
    char   objname[HARD_LINK_TEST_GROUP_MANY_NAME_BUF_SIZE]; /* Object name */

    TESTING("hard link creation of many links");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS)) {
        SKIPPED();
        printf(
            "    API functions for basic file, group, or hard link aren't supported with this connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, HARD_LINK_TEST_GROUP_MANY_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n", HARD_LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id2 = H5Gcreate2(group_id, HARD_LINK_TEST_GROUP_MANY_FINAL_NAME, H5P_DEFAULT, H5P_DEFAULT,
                                H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n", HARD_LINK_TEST_GROUP_MANY_FINAL_NAME);
        goto error;
    }

    if (H5Lcreate_hard(group_id, HARD_LINK_TEST_GROUP_MANY_FINAL_NAME, group_id, "hard1", H5P_DEFAULT,
                       H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard1", group_id, "hard2", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard2", group_id, "hard3", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard3", group_id, "hard4", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard4", group_id, "hard5", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard5", group_id, "hard6", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard6", group_id, "hard7", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard7", group_id, "hard8", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard8", group_id, "hard9", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard9", group_id, "hard10", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard10", group_id, "hard11", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard11", group_id, "hard12", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard12", group_id, "hard13", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard13", group_id, "hard14", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard14", group_id, "hard15", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard15", group_id, "hard16", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard16", group_id, "hard17", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard17", group_id, "hard18", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard18", group_id, "hard19", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard19", group_id, "hard20", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_hard(group_id, "hard20", group_id, "hard21", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, "hard21", H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link 'hard21' exists\n");
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 'hard21' did not exist\n");
        goto error;
    }

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id2) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    /* Reopen the file and group and verify the hard link */
    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gopen2(container_group, HARD_LINK_TEST_GROUP_MANY_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container sub-group '%s'\n", HARD_LINK_TEST_GROUP_NAME);
        goto error;
    }

    /* Open the object through last hard link */
    if ((group_id2 = H5Gopen2(group_id, "hard21", H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open the group '%s' with the last hard link 'hard21'\n",
               HARD_LINK_TEST_GROUP_MANY_FINAL_NAME);
        goto error;
    }

    /* Check name */
    if (H5Iget_name(group_id2, objname, (size_t)HARD_LINK_TEST_GROUP_MANY_NAME_BUF_SIZE) < 0) {
        H5_FAILED();
        printf("    couldn't get the name of the object '%s'\n", HARD_LINK_TEST_GROUP_MANY_FINAL_NAME);
        goto error;
    }

    for (size_t i = 1; (i < HARD_LINK_TEST_GROUP_MANY_NUM_HARD_LINKS + 1 && !valid_name_matched); i++) {
        char name_possibility[H5_API_TEST_FILENAME_MAX_LENGTH];

        snprintf(name_possibility, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%zu",
                 "/" LINK_TEST_GROUP_NAME "/" HARD_LINK_TEST_GROUP_MANY_NAME "/hard", i);

        valid_name_matched |= !strcmp(objname, name_possibility);
    }

    valid_name_matched |= !strcmp(objname, "/" LINK_TEST_GROUP_NAME "/" HARD_LINK_TEST_GROUP_MANY_NAME
                                           "/" HARD_LINK_TEST_GROUP_MANY_FINAL_NAME);

    if (!valid_name_matched) {
        H5_FAILED();
        printf("    H5Iget_name failed to retrieve a valid name for '%s'\n",
               HARD_LINK_TEST_GROUP_MANY_FINAL_NAME);

        goto error;
    }

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id2) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(group_id2);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that behavior is correct when using
 * the H5L_SAME_LOC macro for H5Lcreate_hard().
 */
static void
test_create_hard_link_same_loc(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;

    TESTING_MULTIPART("hard link creation with H5L_SAME_LOC");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or hard link aren't supported with this "
               "connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, H5L_SAME_LOC_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", H5L_SAME_LOC_TEST_GROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5L_SAME_LOC_first_param)
        {
            TESTING_2("usage of H5L_SAME_LOC for first parameter of H5Lcreate_hard");

            /* Library functionality for this part of the test is broken */
            if (H5Lcreate_hard(H5L_SAME_LOC, ".", group_id, H5L_SAME_LOC_TEST_LINK_NAME1, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create first link '%s'\n", H5L_SAME_LOC_TEST_LINK_NAME1);
                PART_ERROR(H5L_SAME_LOC_first_param);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(group_id, H5L_SAME_LOC_TEST_LINK_NAME1, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link exists\n");
                PART_ERROR(H5L_SAME_LOC_first_param);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link did not exist\n");
                PART_ERROR(H5L_SAME_LOC_first_param);
            }

            PASSED();
        }
        PART_END(H5L_SAME_LOC_first_param);

        PART_BEGIN(H5L_SAME_LOC_third_param)
        {
            TESTING_2("usage of H5L_SAME_LOC for third parameter of H5Lcreate_hard");

            if (H5Lcreate_hard(group_id, ".", H5L_SAME_LOC, H5L_SAME_LOC_TEST_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create second link '%s'\n", H5L_SAME_LOC_TEST_LINK_NAME2);
                PART_ERROR(H5L_SAME_LOC_third_param);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(group_id, H5L_SAME_LOC_TEST_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", H5L_SAME_LOC_TEST_LINK_NAME2);
                PART_ERROR(H5L_SAME_LOC_third_param);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link did not exist\n");
                PART_ERROR(H5L_SAME_LOC_third_param);
            }

            PASSED();
        }
        PART_END(H5L_SAME_LOC_third_param);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a hard link can't be created when
 * H5Lcreate_hard is passed invalid parameters.
 */
static void
test_create_hard_link_invalid_params(void H5_ATTR_UNUSED *params)
{
    herr_t err_ret = -1;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};
    hid_t  ext_file_id                                        = H5I_INVALID_HID;

    TESTING_MULTIPART("hard link creation with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or hard link aren't supported with this "
               "connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, HARD_LINK_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n", HARD_LINK_INVALID_PARAMS_TEST_GROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lcreate_hard_invalid_cur_loc_id)
        {
            TESTING_2("H5Lcreate_hard with an invalid cur_loc_id");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(H5I_INVALID_HID, "/", group_id,
                                         HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link with an invalid cur_loc_id!\n");
                PART_ERROR(H5Lcreate_hard_invalid_cur_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lcreate_hard_invalid_cur_loc_id);

        PART_BEGIN(H5Lcreate_hard_invalid_cur_name)
        {
            TESTING_2("H5Lcreate_hard with an invalid cur_name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(file_id, NULL, group_id, HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                         H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link with a NULL cur_name!\n");
                PART_ERROR(H5Lcreate_hard_invalid_cur_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(file_id, "", group_id, HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                         H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link with an invalid cur_name of ''!\n");
                PART_ERROR(H5Lcreate_hard_invalid_cur_name);
            }

            PASSED();
        }
        PART_END(H5Lcreate_hard_invalid_cur_name);

        PART_BEGIN(H5Lcreate_hard_invalid_new_loc_id)
        {
            TESTING_2("H5Lcreate_hard with an invalid new_loc_id");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(file_id, "/", H5I_INVALID_HID,
                                         HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link with an invalid new_loc_id!\n");
                PART_ERROR(H5Lcreate_hard_invalid_new_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lcreate_hard_invalid_new_loc_id);

        PART_BEGIN(H5Lcreate_hard_invalid_new_name)
        {
            TESTING_2("H5Lcreate_hard with an invalid new_name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(file_id, "/", group_id, NULL, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link with a NULL new_name!\n");
                PART_ERROR(H5Lcreate_hard_invalid_new_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(file_id, "/", group_id, "", H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link with an invalid new_name of ''!\n");
                PART_ERROR(H5Lcreate_hard_invalid_new_name);
            }

            PASSED();
        }
        PART_END(H5Lcreate_hard_invalid_new_name);

        PART_BEGIN(H5Lcreate_hard_invalid_lcpl)
        {
            TESTING_2("H5Lcreate_hard with an invalid LCPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(file_id, "/", group_id, HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                         H5I_INVALID_HID, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link with an invalid LCPL!\n");
                PART_ERROR(H5Lcreate_hard_invalid_lcpl);
            }

            PASSED();
        }
        PART_END(H5Lcreate_hard_invalid_lcpl);

        PART_BEGIN(H5Lcreate_hard_invalid_lapl)
        {
            TESTING_2("H5Lcreate_hard with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(file_id, "/", group_id, HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                         H5P_DEFAULT, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link with an invalid LAPL!\n");
                PART_ERROR(H5Lcreate_hard_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lcreate_hard_invalid_lapl);

        PART_BEGIN(H5Lcreate_hard_invalid_same_loc)
        {
            TESTING_2("H5Lcreate_hard with the invalid same location");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(H5L_SAME_LOC, "/", H5L_SAME_LOC,
                                         HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link with the invalid same location!\n");
                PART_ERROR(H5Lcreate_hard_invalid_same_loc);
            }

            PASSED();
        }
        PART_END(H5Lcreate_hard_invalid_same_loc);

        PART_BEGIN(H5Lcreate_hard_across_files)
        {
            TESTING_2("H5Lcreate_hard across files");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lcreate_hard_across_files);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(file_id, "/", ext_file_id, HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                         H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link across files!\n");
                PART_ERROR(H5Lcreate_hard_across_files);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_hard(ext_file_id, "/", group_id, HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                         H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created hard link across files!\n");
                PART_ERROR(H5Lcreate_hard_across_files);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcreate_hard_across_files);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcreate_hard_across_files);
            }

            PASSED();
        }
        PART_END(H5Lcreate_hard_across_files);

        PART_BEGIN(H5Lcreate_hard_invalid_existence)
        {
            TESTING_2("invalid link existence after previous invalid H5Lcreate_hard calls");

            /* Verify the link hasn't been created */
            if ((link_exists = H5Lexists(group_id, HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n",
                       HARD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_hard_invalid_existence);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    link existed!\n");
                PART_ERROR(H5Lcreate_hard_invalid_existence);
            }

            PASSED();
        }
        PART_END(H5Lcreate_hard_invalid_existence);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(ext_file_id);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
} /* test_create_hard_link_invalid_params */

/*
 * A test to check that a soft link, which points to an
 * existing object with a relative path, can be created.
 */
static void
test_create_soft_link_existing_relative(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  object_id = H5I_INVALID_HID;

    TESTING("soft link creation to existing object by relative path");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or soft link aren't supported with this "
               "connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, SOFT_LINK_EXISTING_RELATIVE_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               SOFT_LINK_EXISTING_RELATIVE_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((object_id = H5Gcreate2(group_id, SOFT_LINK_EXISTING_RELATIVE_TEST_OBJECT_NAME, H5P_DEFAULT,
                                H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to create object '%s' for soft link's target\n",
               SOFT_LINK_EXISTING_RELATIVE_TEST_OBJECT_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;

    if (H5Lcreate_soft(SOFT_LINK_EXISTING_RELATIVE_TEST_OBJECT_NAME, group_id,
                       SOFT_LINK_EXISTING_RELATIVE_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", SOFT_LINK_EXISTING_RELATIVE_TEST_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, SOFT_LINK_EXISTING_RELATIVE_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", SOFT_LINK_EXISTING_RELATIVE_TEST_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    if ((object_id = H5Gopen2(group_id, SOFT_LINK_EXISTING_RELATIVE_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open object '%s' through the soft link\n",
               SOFT_LINK_EXISTING_RELATIVE_TEST_OBJECT_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(object_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a soft link, which points to an
 * existing object using an absolute path, can be created.
 */
static void
test_create_soft_link_existing_absolute(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID, root_id = H5I_INVALID_HID;

    TESTING("soft link creation to existing object by absolute path");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or soft link aren't supported with this "
               "connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, SOFT_LINK_EXISTING_ABSOLUTE_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               SOFT_LINK_EXISTING_ABSOLUTE_TEST_SUBGROUP_NAME);
        goto error;
    }

    if (H5Lcreate_soft("/", group_id, SOFT_LINK_EXISTING_ABSOLUTE_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) <
        0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", SOFT_LINK_EXISTING_ABSOLUTE_TEST_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, SOFT_LINK_EXISTING_ABSOLUTE_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", SOFT_LINK_EXISTING_ABSOLUTE_TEST_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    if ((root_id = H5Gopen2(group_id, SOFT_LINK_EXISTING_ABSOLUTE_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open object pointed to by soft link '%s'\n",
               SOFT_LINK_EXISTING_ABSOLUTE_TEST_LINK_NAME);
        goto error;
    }

    if (H5Gclose(root_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(root_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a soft link, which points to
 * an object that doesn't exist by using a relative
 * path, can be created.
 */
static void
test_create_soft_link_dangling_relative(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  object_id = H5I_INVALID_HID;

    TESTING("dangling soft link creation to object by relative path");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or soft link aren't supported with this "
               "connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, SOFT_LINK_DANGLING_RELATIVE_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               SOFT_LINK_DANGLING_RELATIVE_TEST_SUBGROUP_NAME);
        goto error;
    }

    if (H5Lcreate_soft(SOFT_LINK_DANGLING_RELATIVE_TEST_OBJECT_NAME, group_id,
                       SOFT_LINK_DANGLING_RELATIVE_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", SOFT_LINK_DANGLING_RELATIVE_TEST_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, SOFT_LINK_DANGLING_RELATIVE_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", SOFT_LINK_DANGLING_RELATIVE_TEST_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    H5E_BEGIN_TRY
    {
        object_id = H5Gopen2(group_id, SOFT_LINK_DANGLING_RELATIVE_TEST_LINK_NAME, H5P_DEFAULT);
    }
    H5E_END_TRY

    if (object_id >= 0) {
        H5_FAILED();
        printf("    opened target of dangling link '%s'!\n", SOFT_LINK_DANGLING_RELATIVE_TEST_LINK_NAME);
        H5Gclose(object_id);
        goto error;
    }

    if ((object_id = H5Gcreate2(group_id, SOFT_LINK_DANGLING_RELATIVE_TEST_OBJECT_NAME, H5P_DEFAULT,
                                H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to create object '%s' for soft link's target\n",
               SOFT_LINK_DANGLING_RELATIVE_TEST_OBJECT_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;

    if ((object_id = H5Gopen2(group_id, SOFT_LINK_DANGLING_RELATIVE_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to open object pointed to by soft link '%s'\n",
               SOFT_LINK_DANGLING_RELATIVE_TEST_LINK_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(object_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a soft link, which points to an
 * object that doesn't exist by using an absolute path,
 * can be created.
 */
static void
test_create_soft_link_dangling_absolute(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  object_id = H5I_INVALID_HID;

    TESTING("dangling soft link creation to object by absolute path");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or soft link aren't supported with this "
               "connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, SOFT_LINK_DANGLING_ABSOLUTE_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               SOFT_LINK_DANGLING_ABSOLUTE_TEST_SUBGROUP_NAME);
        goto error;
    }

    if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" SOFT_LINK_DANGLING_ABSOLUTE_TEST_SUBGROUP_NAME
                       "/" SOFT_LINK_DANGLING_ABSOLUTE_TEST_OBJECT_NAME,
                       group_id, SOFT_LINK_DANGLING_ABSOLUTE_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", SOFT_LINK_DANGLING_ABSOLUTE_TEST_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, SOFT_LINK_DANGLING_ABSOLUTE_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", SOFT_LINK_DANGLING_ABSOLUTE_TEST_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    H5E_BEGIN_TRY
    {
        object_id = H5Gopen2(group_id, SOFT_LINK_DANGLING_ABSOLUTE_TEST_LINK_NAME, H5P_DEFAULT);
    }
    H5E_END_TRY

    if (object_id >= 0) {
        H5_FAILED();
        printf("    opened target of dangling link '%s'!\n", SOFT_LINK_DANGLING_ABSOLUTE_TEST_LINK_NAME);
        H5Gclose(object_id);
        goto error;
    }

    if ((object_id = H5Gcreate2(group_id, SOFT_LINK_DANGLING_ABSOLUTE_TEST_OBJECT_NAME, H5P_DEFAULT,
                                H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to create object '%s' for soft link's target\n",
               SOFT_LINK_DANGLING_ABSOLUTE_TEST_OBJECT_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;

    if ((object_id = H5Gopen2(group_id, SOFT_LINK_DANGLING_ABSOLUTE_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to open object pointed to by soft link '%s'\n",
               SOFT_LINK_DANGLING_ABSOLUTE_TEST_LINK_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(object_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a soft link with a long name can be created
 * using H5Lcreate_soft.
 */
static void
test_create_soft_link_long_name(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id = H5I_INVALID_HID;
    char   vol_name[5];
    size_t name_len        = MAX_NAME_LEN;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    char  *objname = NULL; /* Name of object [Long] */
    size_t u;              /* Local index variable */

    TESTING("soft link creation with a long name");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or soft link aren't supported with this "
               "connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, SOFT_LINK_TEST_GROUP_LONG_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n", SOFT_LINK_TEST_GROUP_LONG_NAME);
        goto error;
    }

    if (H5VLget_connector_name(file_id, vol_name, 5) < 0) {
        H5_FAILED();
        printf("    couldn't get VOL connector name\n");
        goto error;
    }

    /* Construct very long file name */
    if ((objname = (char *)malloc((size_t)(name_len + 1))) == NULL)
        TEST_ERROR;

    for (u = 0; u < name_len; u++)
        objname[u] = 'b';
    objname[name_len] = '\0';

    if (H5Lcreate_soft(SOFT_LINK_TEST_LONG_OBJECT_NAME, group_id, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link with a long name\n");
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, objname, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if the link with a long name exists\n");
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    /* Release memory */
    if (objname)
        free(objname);

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    if (objname)
        free(objname);

    return;
}

/*
 * A test to check that many soft links can be created
 * using H5Lcreate_soft.
 */
static void
test_create_soft_link_many(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists        = FAIL;
    bool   valid_name_matched = false;
    hid_t  file_id            = H5I_INVALID_HID;
    hid_t  container_group    = H5I_INVALID_HID;
    hid_t  group_id           = H5I_INVALID_HID;
    hid_t  object_id          = H5I_INVALID_HID;
    char   objname[SOFT_LINK_TEST_GROUP_MANY_NAME_BUF_SIZE]; /* Object name */

    TESTING("soft link creation of many links");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or soft link aren't supported with this "
               "connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, SOFT_LINK_TEST_GROUP_MANY_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n", SOFT_LINK_TEST_GROUP_MANY_NAME);
        goto error;
    }

    if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" SOFT_LINK_TEST_GROUP_MANY_NAME
                       "/" SOFT_LINK_TEST_GROUP_MANY_FINAL_NAME,
                       group_id, "soft1", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft1", group_id, "soft2", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft2", group_id, "soft3", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft3", group_id, "soft4", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft4", group_id, "soft5", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft5", group_id, "soft6", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft6", group_id, "soft7", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft7", group_id, "soft8", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft8", group_id, "soft9", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft9", group_id, "soft10", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft10", group_id, "soft11", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft11", group_id, "soft12", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft12", group_id, "soft13", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft13", group_id, "soft14", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft14", group_id, "soft15", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;
    if (H5Lcreate_soft("soft15", group_id, "soft16", H5P_DEFAULT, H5P_DEFAULT) < 0)
        TEST_ERROR;

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, "soft16", H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link 'soft16' exists\n");
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 'soft16' did not exist\n");
        goto error;
    }

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    /* Reopen the file and group and verify the hard link */
    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gopen2(container_group, SOFT_LINK_TEST_GROUP_MANY_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container sub-group '%s'\n", SOFT_LINK_TEST_GROUP_MANY_NAME);
        goto error;
    }

    /*
     * XXX: Try to open the object through last soft link.  If should fail because it doesn't exist.  If
     * H5Oopen is available, use that.
     */
    H5E_BEGIN_TRY
    {
        object_id = H5Gopen2(group_id, "soft16", H5P_DEFAULT);
    }
    H5E_END_TRY

    if (object_id >= 0) {
        H5_FAILED();
        printf("    opened target of dangling soft link '%s'!\n", SOFT_LINK_TEST_GROUP_MANY_NAME);
        H5Gclose(object_id);
        goto error;
    }

    if ((object_id = H5Gcreate2(group_id, SOFT_LINK_TEST_GROUP_MANY_FINAL_NAME, H5P_DEFAULT, H5P_DEFAULT,
                                H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to create object '%s' for soft link's target\n", SOFT_LINK_TEST_GROUP_MANY_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;

    /*
     * XXX: Open the object through last soft link.  It should work this time.  If H5Oopen is available, use
     * that.
     */
    if ((object_id = H5Gopen2(group_id, "soft16", H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to open object pointed to by soft link '%s'\n", SOFT_LINK_TEST_GROUP_MANY_NAME);
        goto error;
    }
    /* Check name */
    if (H5Iget_name(object_id, objname, (size_t)SOFT_LINK_TEST_GROUP_MANY_NAME_BUF_SIZE) < 0) {
        H5_FAILED();
        printf("    couldn't get the name of the object 'soft16'\n");
        goto error;
    }

    for (size_t i = 1; (i < SOFT_LINK_TEST_GROUP_MANY_NAME_SOFT_LINK_COUNT + 1 && !valid_name_matched); i++) {
        char name_possibility[H5_API_TEST_FILENAME_MAX_LENGTH];

        snprintf(name_possibility, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%zu",
                 "/" LINK_TEST_GROUP_NAME "/" SOFT_LINK_TEST_GROUP_MANY_NAME "/soft", i);

        valid_name_matched |= !strcmp(objname, name_possibility);
    }

    valid_name_matched |= !strcmp(objname, "/" LINK_TEST_GROUP_NAME "/" SOFT_LINK_TEST_GROUP_MANY_NAME
                                           "/" SOFT_LINK_TEST_GROUP_MANY_FINAL_NAME);

    if (!valid_name_matched) {
        H5_FAILED();
        printf("    H5Iget_name failed to retrieve a valid name for '%s'\n",
               "/" LINK_TEST_GROUP_NAME "/" SOFT_LINK_TEST_GROUP_MANY_NAME
               "/" SOFT_LINK_TEST_GROUP_MANY_FINAL_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(object_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a soft link can't be created
 * when H5Lcreate_soft is passed invalid parameters.
 */
static void
test_create_soft_link_invalid_params(void H5_ATTR_UNUSED *params)
{
    herr_t err_ret = -1;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;

    TESTING_MULTIPART("soft link creation with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf(
            "    API functions for basic file, group, or soft link aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, SOFT_LINK_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n", SOFT_LINK_INVALID_PARAMS_TEST_GROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lcreate_soft_invalid_link_target)
        {
            TESTING_2("H5Lcreate_soft with an invalid link target");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_soft(NULL, group_id, SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT,
                                         H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created soft link '%s' with an invalid link target!\n",
                       SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_soft_invalid_link_target);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_soft("", group_id, SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT,
                                         H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created soft link '%s' with an invalid link target!\n",
                       SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_soft_invalid_link_target);
            }

            PASSED();
        }
        PART_END(H5Lcreate_soft_invalid_link_target);

        PART_BEGIN(H5Lcreate_soft_invalid_link_loc_id)
        {
            TESTING_2("H5Lcreate_soft with an invalid link_loc_id");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_soft("/", H5I_INVALID_HID, SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                         H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created soft link '%s' with an invalid link_loc_id!\n",
                       SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_soft_invalid_link_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lcreate_soft_invalid_link_loc_id);

        PART_BEGIN(H5Lcreate_soft_invalid_link_name)
        {
            TESTING_2("H5Lcreate_soft with an invalid link name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_soft("/", group_id, NULL, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created soft link '%s' with a NULL link name!\n",
                       SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_soft_invalid_link_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_soft("/", group_id, "", H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created soft link '%s' with an invalid link name of ''!\n",
                       SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_soft_invalid_link_name);
            }

            PASSED();
        }
        PART_END(H5Lcreate_soft_invalid_link_name);

        PART_BEGIN(H5Lcreate_soft_invalid_lcpl)
        {
            TESTING_2("H5Lcreate_soft with an invalid LCPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_soft("/", group_id, SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                         H5I_INVALID_HID, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created soft link '%s' with an invalid LCPL!\n",
                       SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_soft_invalid_lcpl);
            }

            PASSED();
        }
        PART_END(H5Lcreate_soft_invalid_lcpl);

        PART_BEGIN(H5Lcreate_soft_invalid_lapl)
        {
            TESTING_2("H5Lcreate_soft with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_soft("/", group_id, SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT,
                                         H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created soft link '%s' with an invalid LAPL!\n",
                       SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_soft_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lcreate_soft_invalid_lapl);

        PART_BEGIN(H5Lcreate_soft_invalid_existence)
        {
            TESTING_2("invalid link existence after previous invalid H5Lcreate_soft calls");

            /* Verify the link hasn't been created */
            if ((link_exists = H5Lexists(group_id, SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n",
                       SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_soft_invalid_existence);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    link '%s' existed!\n", SOFT_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_soft_invalid_existence);
            }

            PASSED();
        }
        PART_END(H5Lcreate_soft_invalid_existence);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that an external link can be created
 * using H5Lcreate_external.
 */
static void
test_create_external_link(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  root_id                                            = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING("external link creation to existing object");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or external link aren't supported "
               "with this connector\n");
        return;
    }

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, EXTERNAL_LINK_TEST_SUBGROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", EXTERNAL_LINK_TEST_SUBGROUP_NAME);
        goto error;
    }

    if (H5Lcreate_external(ext_link_filename, "/", group_id, EXTERNAL_LINK_TEST_LINK_NAME, H5P_DEFAULT,
                           H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create external link '%s'\n", EXTERNAL_LINK_TEST_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, EXTERNAL_LINK_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", EXTERNAL_LINK_TEST_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    if ((root_id = H5Gopen2(group_id, EXTERNAL_LINK_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open root group of other file using external link '%s'\n",
               EXTERNAL_LINK_TEST_LINK_NAME);
        goto error;
    }

    if (H5Gclose(root_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(root_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that an external link, which points to an
 * object that doesn't exist by using an absolute path, can
 * be created.
 */
static void
test_create_external_link_dangling(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id = H5I_INVALID_HID, ext_file_id = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  object_id                                          = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING("dangling external link creation");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or external link aren't supported "
               "with this connector\n");
        return;
    }

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, EXTERNAL_LINK_TEST_DANGLING_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", EXTERNAL_LINK_TEST_DANGLING_SUBGROUP_NAME);
        goto error;
    }

    if (H5Lcreate_external(ext_link_filename, "/" EXTERNAL_LINK_TEST_DANGLING_OBJECT_NAME, group_id,
                           EXTERNAL_LINK_TEST_DANGLING_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create dangling external link '%s'\n", EXTERNAL_LINK_TEST_DANGLING_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, EXTERNAL_LINK_TEST_DANGLING_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", EXTERNAL_LINK_TEST_DANGLING_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    H5E_BEGIN_TRY
    {
        object_id = H5Gopen2(group_id, EXTERNAL_LINK_TEST_DANGLING_LINK_NAME, H5P_DEFAULT);
    }
    H5E_END_TRY

    if (object_id >= 0) {
        H5_FAILED();
        printf("    opened non-existent object in other file using dangling external link '%s'!\n",
               EXTERNAL_LINK_TEST_DANGLING_LINK_NAME);
        H5Gclose(object_id);
        goto error;
    }

    if ((object_id = H5Gcreate2(ext_file_id, EXTERNAL_LINK_TEST_DANGLING_OBJECT_NAME, H5P_DEFAULT,
                                H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to create object '%s' for external link's target\n",
               EXTERNAL_LINK_TEST_DANGLING_OBJECT_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;

    if ((object_id = H5Gopen2(group_id, EXTERNAL_LINK_TEST_DANGLING_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to open object pointed to by external link '%s'\n",
               EXTERNAL_LINK_TEST_DANGLING_LINK_NAME);
        goto error;
    }

    if (H5Gclose(object_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (H5Fclose(ext_file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(object_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        H5Fclose(ext_file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that an external link to an object
 * that crosses several files using H5Lcreate_external.
 */
static void
test_create_external_link_multi(void H5_ATTR_UNUSED *params)
{
    hid_t file_id         = H5I_INVALID_HID;
    hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t group_id2 = H5I_INVALID_HID, group_id3 = H5I_INVALID_HID;
    hid_t root_id                                             = H5I_INVALID_HID;
    char  ext_link_filename1[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};
    char  ext_link_filename2[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};
    char  ext_link_filename3[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};
    char  objname[EXTERNAL_LINK_TEST_MULTI_NAME_BUF_SIZE];

    TESTING_MULTIPART("external link creation to an object across several files");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, or external link aren't supported with this "
               "connector\n");
        return;
    }

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lcreate_external_first_file)
        {
            TESTING_2("Create the first external file to be pointed to");

            snprintf(ext_link_filename1, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((file_id = H5Fcreate(ext_link_filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename1);
                PART_ERROR(H5Lcreate_external_first_file);
            }

            /* Create object down a path */
            if ((group_id = H5Gcreate2(file_id, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            if ((group_id = H5Gcreate2(file_id, "A/B", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            if ((group_id = H5Gcreate2(file_id, "A/B/C", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            /* Close file */
            if (H5Fclose(file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_first_file);

        PART_BEGIN(H5Lcreate_external_second_file)
        {
            TESTING_2("Create the second external file to be pointed to");

            snprintf(ext_link_filename2, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME2);

            if ((file_id = H5Fcreate(ext_link_filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename2);
                PART_ERROR(H5Lcreate_external_second_file);
            }

            /* Create object down a path */
            if ((group_id = H5Gcreate2(file_id, "D", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a group\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            if ((group_id = H5Gcreate2(file_id, "D/E", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a group\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            /* Create external link to object in first file */
            if (H5Lcreate_external(ext_link_filename1, "/A/B/C", group_id, "F", H5P_DEFAULT, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't create external link 'F'\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            /* Close file */
            if (H5Fclose(file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a file\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_second_file);

        PART_BEGIN(H5Lcreate_external_third_file)
        {
            TESTING_2("Create the third external file to be pointed to");

            snprintf(ext_link_filename3, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME3);

            if ((file_id = H5Fcreate(ext_link_filename3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename3);
                PART_ERROR(H5Lcreate_external_third_file);
            }

            /* Create object down a path */
            if ((group_id = H5Gcreate2(file_id, "G", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a group\n");
                PART_ERROR(H5Lcreate_external_third_file);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_third_file);
            }

            if ((group_id = H5Gcreate2(file_id, "G/H", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a group\n");
                PART_ERROR(H5Lcreate_external_third_file);
            }

            /* Create external link to object in second file */
            if (H5Lcreate_external(ext_link_filename2, "/D/E/F", group_id, "I", H5P_DEFAULT, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't create external link 'I'\n");
                PART_ERROR(H5Lcreate_external_third_file);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_third_file);
            }

            /* Close file */
            if (H5Fclose(file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a file\n");
                PART_ERROR(H5Lcreate_external_third_file);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_third_file);

        PART_BEGIN(H5Lcreate_external_final_file)
        {
            TESTING_2("Open the file and create the final external link");

            if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't open file '%s'\n", H5_api_test_filename);
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if ((group_id = H5Gcreate2(container_group, EXTERNAL_LINK_TEST_MULTI_NAME, H5P_DEFAULT,
                                       H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n", EXTERNAL_LINK_TEST_MULTI_NAME);
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if (H5Lcreate_external(ext_link_filename3, "/G/H/I", group_id, "ext_link", H5P_DEFAULT,
                                   H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link 'ext_link'\n");
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if ((group_id2 = H5Gopen2(group_id, "ext_link", H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't open the group that is the external link\n");
                PART_ERROR(H5Lcreate_external_final_file);
            }

            /* Check name */
            if (H5Iget_name(group_id2, objname, (size_t)EXTERNAL_LINK_TEST_MULTI_NAME_BUF_SIZE) < 0) {
                H5_FAILED();
                printf("    couldn't get the name of the object '%s'\n",
                       HARD_LINK_TEST_GROUP_MANY_FINAL_NAME);
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if (strcmp(objname, "/A/B/C") && strcmp(objname, "/D/E/F") && strcmp(objname, "/G/H/I") &&
                strcmp(objname, "/" LINK_TEST_GROUP_NAME "/" EXTERNAL_LINK_TEST_MULTI_NAME "/ext_link")) {
                H5_FAILED();
                printf("    H5Iget_name failed to retrieve a valid name for the object '%s'\n", "/A/B/C");
                PART_ERROR(H5Lcreate_external_final_file);
            }

            /* Create an object in the external file */
            if ((group_id3 = H5Gcreate2(group_id2, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a group 'new_group' in the external file\n");
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if (H5Gclose(group_id2) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if (H5Gclose(group_id3) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if (H5Gclose(container_group) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_final_file);
            }

            if (H5Fclose(file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a file\n");
                PART_ERROR(H5Lcreate_external_final_file);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_final_file);

        PART_BEGIN(H5Lcreate_external_object_created)
        {
            TESTING_2("Check the group being created through the external link");

            if ((file_id = H5Fopen(ext_link_filename1, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't open file '%s'\n", ext_link_filename1);
                PART_ERROR(H5Lcreate_external_object_created);
            }

            if ((group_id = H5Gopen2(file_id, "/A/B/C/new_group", H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't open a group 'new_group' in the external file\n");
                PART_ERROR(H5Lcreate_external_object_created);
            }

            /* Check name */
            if (H5Iget_name(group_id, objname, (size_t)EXTERNAL_LINK_TEST_MULTI_NAME_BUF_SIZE) < 0) {
                H5_FAILED();
                printf("    couldn't get the name of the object '/A/B/C/new_group'\n");
                PART_ERROR(H5Lcreate_external_object_created);
            }

            if (strcmp(objname, "/A/B/C/new_group") && strcmp(objname, "/D/E/F/new_group") &&
                strcmp(objname, "/G/H/I/new_group") &&
                strcmp(objname,
                       "/" LINK_TEST_GROUP_NAME "/" EXTERNAL_LINK_TEST_MULTI_NAME "/ext_link/new_group")) {
                H5_FAILED();
                printf("    H5Iget_name was unable to retrieve a valid name for the object '%s'\n",
                       "/A/B/C/new_group");
                PART_ERROR(H5Lcreate_external_object_created);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close the group\n");
                PART_ERROR(H5Lcreate_external_object_created);
            }

            if (H5Fclose(file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close the file\n");
                PART_ERROR(H5Lcreate_external_object_created);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_object_created);
    }
    END_MULTIPART;

    if (remove_test_file(NULL, ext_link_filename1) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename2) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename3) < 0)
        TEST_ERROR;

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(root_id);
        H5Gclose(group_id);
        H5Gclose(group_id2);
        H5Gclose(group_id3);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename1);
        remove_test_file(NULL, ext_link_filename2);
        remove_test_file(NULL, ext_link_filename3);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to build a file with external link to object that
 * goes back and forth between two files a couple of times:
 *
 *       file1:/link1    -> file2: /link2
 *       file2:/link2    -> file1: /link3
 *       file1:/link3    -> file2: /link4
 *       file2:/link4    -> file1: /link5
 *       file1:/link5    -> file2: /link6
 *       file2:/link6    -> file1: /final
 */
static void
test_create_external_link_ping_pong(void H5_ATTR_UNUSED *params)
{
    hid_t file_id                                             = H5I_INVALID_HID;
    hid_t group_id                                            = H5I_INVALID_HID;
    hid_t group_id2                                           = H5I_INVALID_HID;
    bool  valid_name_matched                                  = false;
    char  ext_link_filename1[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};
    char  ext_link_filename2[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};
    char  objname[EXTERNAL_LINK_TEST_MULTI_NAME_BUF_SIZE];

    TESTING_MULTIPART("external link creation to an object in ping pong style");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, or external link aren't supported with this "
               "connector\n");
        return;
    }

    snprintf(ext_link_filename1, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_PING_PONG_NAME1);
    snprintf(ext_link_filename2, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_PING_PONG_NAME2);

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lcreate_external_first_file)
        {
            TESTING_2("Create the first external file");

            /* Create the first file */
            if ((file_id = H5Fcreate(ext_link_filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename1);
                PART_ERROR(H5Lcreate_external_first_file);
            }

            /* Create external links for chain */
            if (H5Lcreate_external(ext_link_filename2, "/link2", file_id, "link1", H5P_DEFAULT, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't create external link\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            if (H5Lcreate_external(ext_link_filename2, "/link4", file_id, "link3", H5P_DEFAULT, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't create external link\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            if (H5Lcreate_external(ext_link_filename2, "/link6", file_id, "link5", H5P_DEFAULT, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't create external link\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            /* Create final object */
            if ((group_id = H5Gcreate2(file_id, "final", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            /* Close file */
            if (H5Fclose(file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_first_file);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_first_file);

        PART_BEGIN(H5Lcreate_external_second_file)
        {
            TESTING_2("Create the second external file");

            /* Create the second file */
            if ((file_id = H5Fcreate(ext_link_filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link\n", ext_link_filename2);
                PART_ERROR(H5Lcreate_external_second_file);
            }

            /* Create external links for chain */
            if (H5Lcreate_external(ext_link_filename1, "/link3", file_id, "link2", H5P_DEFAULT, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't create external link\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            if (H5Lcreate_external(ext_link_filename1, "/link5", file_id, "link4", H5P_DEFAULT, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't create external link\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            if (H5Lcreate_external(ext_link_filename1, "/final", file_id, "link6", H5P_DEFAULT, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't create external link\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            /* Close file */
            if (H5Fclose(file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close the file\n");
                PART_ERROR(H5Lcreate_external_second_file);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_second_file);

        PART_BEGIN(H5Lcreate_external_verify)
        {
            TESTING_2("Open the first file to verify the object being pointed to");

            if ((file_id = H5Fopen(ext_link_filename1, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't open file '%s'\n", ext_link_filename1);
                PART_ERROR(H5Lcreate_external_verify);
            }

            /* Open object through external link */
            if ((group_id = H5Gopen2(file_id, "link1", H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't open the group that is the external link 'link1'\n");
                PART_ERROR(H5Lcreate_external_verify);
            }

            /* Check the name of the object being pointed to */
            if (H5Iget_name(group_id, objname, (size_t)EXTERNAL_LINK_TEST_PING_PONG_NAME_BUF_SIZE) < 0) {
                H5_FAILED();
                printf("    couldn't get the name of the object\n");
                PART_ERROR(H5Lcreate_external_verify);
            }

            for (size_t i = 1; i < EXTERNAL_LINK_TEST_PING_PONG_NUM_LINKS + 1 && !valid_name_matched; i++) {
                char name_possibility[H5_API_TEST_FILENAME_MAX_LENGTH];

                snprintf(name_possibility, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%zu", "/link", i);

                valid_name_matched |= !strcmp(name_possibility, objname);
            }

            valid_name_matched |= !strcmp(objname, "/final");

            if (!valid_name_matched) {
                H5_FAILED();
                printf("    H5Iget_name was unable to retrieve a valid name for the object '%s'\n", "/final");
                PART_ERROR(H5Lcreate_external_verify);
            }

            /* Create an object in the external file */
            if ((group_id2 = H5Gcreate2(group_id, "new_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create a new group 'new_group'\n");
                PART_ERROR(H5Lcreate_external_verify);
            }

            if (H5Gclose(group_id2) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_verify);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_verify);
            }

            /* Close file */
            if (H5Fclose(file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close the file\n");
                PART_ERROR(H5Lcreate_external_verify);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_verify);

        PART_BEGIN(H5Lcreate_external_verify_again)
        {
            TESTING_2("Open the first file to verify the object being created");

            if ((file_id = H5Fopen(ext_link_filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't open file '%s'\n", ext_link_filename1);
                PART_ERROR(H5Lcreate_external_verify_again);
            }

            /* Open object through external link */
            if ((group_id = H5Gopen2(file_id, "/final/new_group", H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't open the group that is the external link\n");
                PART_ERROR(H5Lcreate_external_verify_again);
            }

            /* Check the name of the object being pointed to */
            if (H5Iget_name(group_id, objname, (size_t)EXTERNAL_LINK_TEST_PING_PONG_NAME_BUF_SIZE) < 0) {
                H5_FAILED();
                printf("    couldn't get the name of the object\n");
                PART_ERROR(H5Lcreate_external_verify_again);
            }

            for (size_t i = 1; i < EXTERNAL_LINK_TEST_PING_PONG_NUM_LINKS + 1 && !valid_name_matched; i++) {
                char name_possibility[H5_API_TEST_FILENAME_MAX_LENGTH];

                snprintf(name_possibility, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%zu%s", "/link", i,
                         "/new_group");

                valid_name_matched |= !strcmp(objname, name_possibility);
            }

            valid_name_matched |= !strcmp(objname, "/final/new_group");

            if (!valid_name_matched) {
                H5_FAILED();
                printf("    H5Iget_name was unable to find a valid name for '%s'\n", "/final/new_group");
                PART_ERROR(H5Lcreate_external_verify_again);
            }

            if (H5Gclose(group_id) < 0) {
                H5_FAILED();
                printf("    couldn't close a group\n");
                PART_ERROR(H5Lcreate_external_verify_again);
            }

            /* Close file */
            if (H5Fclose(file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close the file\n");
                PART_ERROR(H5Lcreate_external_verify_again);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_verify_again);
    }
    END_MULTIPART;

    if (remove_test_file(NULL, ext_link_filename1) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename2) < 0)
        TEST_ERROR;

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(group_id2);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename1);
        remove_test_file(NULL, ext_link_filename2);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that an external link can't be created
 * when H5Lcreate_external is passed invalid parameters.
 */
static void
test_create_external_link_invalid_params(void H5_ATTR_UNUSED *params)
{
    herr_t err_ret = -1;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("H5Lcreate_external with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or external link aren't supported "
               "with this connector\n");
        return;
    }

    TESTING_2("test setup");

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_INVALID_PARAMS_TEST_FILE_NAME);

    if ((file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, EXTERNAL_LINK_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", EXTERNAL_LINK_INVALID_PARAMS_TEST_GROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lcreate_external_invalid_file_name)
        {
            TESTING_2("H5Lcreate_external with an invalid file name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_external(NULL, "/", group_id, EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                             H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created external link '%s' using a NULL file name!\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_file_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_external("", "/", group_id, EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME,
                                             H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created external link '%s' using an invalid file name of ''!\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_file_name);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_invalid_file_name);

        PART_BEGIN(H5Lcreate_external_invalid_ext_obj_name)
        {
            TESTING_2("H5Lcreate_external with an invalid external object name");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcreate_external(ext_link_filename, NULL, group_id,
                                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created external link '%s' using a NULL external object name!\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_ext_obj_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcreate_external(ext_link_filename, "", group_id,
                                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created external link '%s' using an invalid external object name of ''!\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_ext_obj_name);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_invalid_ext_obj_name);

        PART_BEGIN(H5Lcreate_external_invalid_link_loc_id)
        {
            TESTING_2("H5Lcreate_external with an invalid link_loc_id");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcreate_external(ext_link_filename, "/", H5I_INVALID_HID,
                                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created external link '%s' using an invalid link_loc_id!\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_link_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_invalid_link_loc_id);

        PART_BEGIN(H5Lcreate_external_invalid_link_name)
        {
            TESTING_2("H5Lcreate_external with an invalid link name");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcreate_external(ext_link_filename, "/", group_id, NULL, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created external link '%s' using a NULL link_loc_id!\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_link_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_external(ext_link_filename, "/", group_id, "", H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created external link '%s' using an invalid link name of ''!\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_link_name);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_invalid_link_name);

        PART_BEGIN(H5Lcreate_external_invalid_lcpl)
        {
            TESTING_2("H5Lcreate_external with an invalid LCPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_external(ext_link_filename, "/", group_id,
                                             EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5I_INVALID_HID,
                                             H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created external link '%s' using an invalid LCPL!\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_lcpl);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_invalid_lcpl);

        PART_BEGIN(H5Lcreate_external_invalid_lapl)
        {
            TESTING_2("H5Lcreate_external with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_external(ext_link_filename, "/", group_id,
                                             EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT,
                                             H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created external link '%s' using an invalid LAPL!\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_invalid_lapl);

        PART_BEGIN(H5Lcreate_external_invalid_existence)
        {
            TESTING_2("invalid link existence after previous invalid H5Lcreate_external calls");

            /* Verify the link hasn't been created */
            if ((link_exists =
                     H5Lexists(group_id, EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n",
                       EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_existence);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    link '%s' existed!\n", EXTERNAL_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_external_invalid_existence);
            }

            PASSED();
        }
        PART_END(H5Lcreate_external_invalid_existence);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a user-defined link can be created.
 */
static void
test_create_user_defined_link(void H5_ATTR_UNUSED *params)
{
    ssize_t udata_size;
    htri_t  link_exists;
    hid_t   file_id         = H5I_INVALID_HID;
    hid_t   container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    char    udata[UD_LINK_TEST_UDATA_MAX_SIZE];

    TESTING("user-defined link creation");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
        SKIPPED();
        printf(
            "    API functions for basic file, group, link, or user-defined link aren't supported with this "
            "connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, UD_LINK_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", UD_LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((udata_size = snprintf(udata, UD_LINK_TEST_UDATA_MAX_SIZE, "udata")) < 0)
        TEST_ERROR;

    if (H5Lcreate_ud(group_id, UD_LINK_TEST_LINK_NAME, H5L_TYPE_EXTERNAL, udata, (size_t)udata_size,
                     H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create user-defined link '%s'\n", UD_LINK_TEST_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, UD_LINK_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", UD_LINK_TEST_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link '%s' didn't exist!\n", UD_LINK_TEST_LINK_NAME);
        goto error;
    }

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that H5Lcreate_ud fails when
 * it is given invalid parameters.
 */
static void
test_create_user_defined_link_invalid_params(void H5_ATTR_UNUSED *params)
{
    ssize_t udata_size;
    htri_t  link_exists;
    herr_t  err_ret         = -1;
    hid_t   file_id         = H5I_INVALID_HID;
    hid_t   container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    char    udata[UD_LINK_INVALID_PARAMS_TEST_UDATA_MAX_SIZE];

    TESTING_MULTIPART("H5Lcreate_ud with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, or user-defined link aren't supported with this "
               "connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, UD_LINK_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", UD_LINK_INVALID_PARAMS_TEST_GROUP_NAME);
        goto error;
    }

    if ((udata_size = snprintf(udata, UD_LINK_INVALID_PARAMS_TEST_UDATA_MAX_SIZE, "udata")) < 0)
        TEST_ERROR;

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lcreate_ud_invalid_link_loc_id)
        {
            TESTING_2("H5Lcreate_ud with an invalid link location ID");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcreate_ud(H5I_INVALID_HID, UD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5L_TYPE_EXTERNAL,
                                 udata, (size_t)udata_size, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created user-defined link '%s' with an invalid link location ID!\n",
                       UD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_ud_invalid_link_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lcreate_ud_invalid_link_loc_id);

        PART_BEGIN(H5Lcreate_ud_invalid_link_name)
        {
            TESTING_2("H5Lcreate_ud with an invalid link name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_ud(group_id, NULL, H5L_TYPE_EXTERNAL, udata, (size_t)udata_size,
                                       H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created user-defined link '%s' with a NULL link name!\n",
                       UD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_ud_invalid_link_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_ud(group_id, "", H5L_TYPE_EXTERNAL, udata, (size_t)udata_size,
                                       H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created user-defined link '%s' with an invalid link name of ''!\n",
                       UD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_ud_invalid_link_name);
            }

            PASSED();
        }
        PART_END(H5Lcreate_ud_invalid_link_name);

        PART_BEGIN(H5Lcreate_ud_invalid_link_type)
        {
            TESTING_2("H5Lcreate_ud with an invalid link type");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_ud(group_id, UD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5L_TYPE_HARD, udata,
                                       (size_t)udata_size, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created user-defined link '%s' with an invalid link type!\n",
                       UD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_ud_invalid_link_type);
            }

            PASSED();
        }
        PART_END(H5Lcreate_ud_invalid_link_type);

        PART_BEGIN(H5Lcreate_ud_invalid_udata_pointer)
        {
            TESTING_2("H5Lcreate_ud with an invalid udata pointer");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_ud(group_id, UD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5L_TYPE_EXTERNAL,
                                       NULL, (size_t)udata_size, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created user-defined link '%s' with an invalid udata pointer!\n",
                       UD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_ud_invalid_udata_pointer);
            }

            PASSED();
        }
        PART_END(H5Lcreate_ud_invalid_udata_pointer);

        PART_BEGIN(H5Lcreate_ud_invalid_lcpl)
        {
            TESTING_2("H5Lcreate_ud with an invalid LCPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_ud(group_id, UD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5L_TYPE_EXTERNAL,
                                       udata, (size_t)udata_size, H5I_INVALID_HID, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created user-defined link '%s' with an invalid LCPL!\n",
                       UD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_ud_invalid_lcpl);
            }

            PASSED();
        }
        PART_END(H5Lcreate_ud_invalid_lcpl);

        PART_BEGIN(H5Lcreate_ud_invalid_lapl)
        {
            TESTING_2("H5Lcreate_ud with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcreate_ud(group_id, UD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5L_TYPE_EXTERNAL,
                                       udata, (size_t)udata_size, H5P_DEFAULT, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    created user-defined link '%s' with an invalid LAPL!\n",
                       UD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_ud_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lcreate_ud_invalid_lapl);

        PART_BEGIN(H5Lcreate_ud_invalid_existence)
        {
            TESTING_2("invalid link existence after previous invalid H5Lcreate_ud calls");

            /* Verify the link hasn't been created */
            if ((link_exists = H5Lexists(group_id, UD_LINK_INVALID_PARAMS_TEST_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", UD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_ud_invalid_existence);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    link '%s' existed!\n", UD_LINK_INVALID_PARAMS_TEST_LINK_NAME);
                PART_ERROR(H5Lcreate_ud_invalid_existence);
            }

            PASSED();
        }
        PART_END(H5Lcreate_ud_invalid_existence);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a link can be deleted
 * using H5Ldelete and H5Ldelete_by_idx.
 */
static void
test_delete_link(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id = H5I_INVALID_HID, ext_file_id = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup_id                                        = H5I_INVALID_HID;
    hid_t  nested_grp_id                                      = H5I_INVALID_HID;
    hid_t  gcpl_id                                            = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link deletion");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, hard link, soft link, or external link "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
            H5_FAILED();
            printf("    couldn't set link creation order tracking\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_DELETE_TEST_SUBGROUP_NAME, H5P_DEFAULT, gcpl_id,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Ldelete_hard)
        {
            TESTING_2("H5Ldelete on hard link");

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP1_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP1_NAME);
                PART_ERROR(H5Ldelete_hard);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create first hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_hard);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if first hard link '%s' exists\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_hard);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    first hard link did not exist\n");
                PART_ERROR(H5Ldelete_hard);
            }

            if (H5Ldelete(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_hard);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if first hard link '%s' exists\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_hard);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    first hard link exists!\n");
                PART_ERROR(H5Ldelete_hard);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP1_NAME);
                PART_ERROR(H5Ldelete_hard);
            }

            PASSED();
        }
        PART_END(H5Ldelete_hard);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_hard_indirect)
        {
            TESTING_2("H5Ldelete on nested hard link");

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_NESTED_SUBGROUP_NAME1, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_NESTED_SUBGROUP_NAME1);
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            if ((nested_grp_id = H5Gcreate2(subgroup_id, LINK_DELETE_TEST_NESTED_GRP_NAME, H5P_DEFAULT,
                                            gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_NESTED_GRP_NAME);
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            if (H5Lcreate_hard(nested_grp_id, ".", nested_grp_id, LINK_DELETE_TEST_HARD_LINK_NAME,
                               H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create first hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            if ((link_exists = H5Lexists(nested_grp_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if first hard link '%s' exists\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    first hard link did not exist\n");
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            if (H5Ldelete(subgroup_id, LINK_DELETE_TEST_NESTED_HARD_LINK_NAME, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete\n",
                       LINK_DELETE_TEST_NESTED_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            if ((link_exists = H5Lexists(nested_grp_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if first hard link '%s' exists\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    first hard link exists!\n");
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            if (H5Gclose(nested_grp_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_NESTED_GRP_NAME);
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP1_NAME);
                PART_ERROR(H5Ldelete_hard_indirect);
            }

            PASSED();
        }
        PART_END(H5Ldelete_hard_indirect);

        H5E_BEGIN_TRY
        {
            H5Gclose(nested_grp_id);
            nested_grp_id = H5I_INVALID_HID;
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_soft)
        {
            TESTING_2("H5Ldelete on soft link");

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP2_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP2_NAME);
                PART_ERROR(H5Ldelete_soft);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP2_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create first soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_soft);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if first soft link '%s' exists\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_soft);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    first soft link did not exist\n");
                PART_ERROR(H5Ldelete_soft);
            }

            if (H5Ldelete(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_soft);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if first soft link '%s' exists\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_soft);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    first soft link exists!\n");
                PART_ERROR(H5Ldelete_soft);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP2_NAME);
                PART_ERROR(H5Ldelete_soft);
            }

            PASSED();
        }
        PART_END(H5Ldelete_soft);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_external)
        {
            TESTING_2("H5Ldelete on external link");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Ldelete_external);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_external);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP3_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP3_NAME);
                PART_ERROR(H5Ldelete_external);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create first external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_external);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if first external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_external);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    first external link did not exist\n");
                PART_ERROR(H5Ldelete_external);
            }

            if (H5Ldelete(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_external);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if first external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_external);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    first external link exists!\n");
                PART_ERROR(H5Ldelete_external);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP3_NAME);
                PART_ERROR(H5Ldelete_external);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_external);
            }

            PASSED();
        }
        PART_END(H5Ldelete_external);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_ud)
        {
            TESTING_2("H5Ldelete on user-defined link");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Ldelete_ud);
        }
        PART_END(H5Ldelete_ud);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_hard_crt_order_increasing)
        {
            TESTING_2("H5Ldelete_by_idx on hard link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP5_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP5_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by creation order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by creation order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by creation order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP5_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_hard_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_hard_crt_order_decreasing)
        {
            TESTING_2("H5Ldelete_by_idx on hard link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP6_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP6_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by creation order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by creation order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by creation order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP6_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_hard_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_hard_name_order_increasing)
        {
            TESTING_2("H5Ldelete_by_idx on hard link by alphabetical order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP7_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP7_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP7_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_hard_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_hard_name_order_decreasing)
        {
            TESTING_2("H5Ldelete_by_idx on hard link by alphabetical order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP8_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP8_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete hard link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link '%s' exists after deletion!\n", LINK_DELETE_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP8_NAME);
                PART_ERROR(H5Ldelete_by_idx_hard_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_hard_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_soft_crt_order_increasing)
        {
            TESTING_2("H5Ldelete_by_idx on soft link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP9_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP9_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP9_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP9_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP9_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by creation order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by creation order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by creation order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP9_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_soft_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_soft_crt_order_decreasing)
        {
            TESTING_2("H5Ldelete_by_idx on soft link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP10_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP10_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP10_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP10_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP10_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by creation order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by creation order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by creation order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP10_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_soft_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_soft_name_order_increasing)
        {
            TESTING_2("H5Ldelete_by_idx on soft link by alphabetical order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP11_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP11_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP11_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP11_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP11_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP11_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_soft_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_soft_name_order_decreasing)
        {
            TESTING_2("H5Ldelete_by_idx on soft link by alphabetical order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP12_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP12_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP12_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP12_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_DELETE_TEST_SUBGROUP_NAME
                               "/" LINK_DELETE_TEST_SUBGROUP12_NAME,
                               subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete soft link '%s' using H5Ldelete_by_idx by alphabetical order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link '%s' exists after deletion!\n", LINK_DELETE_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP12_NAME);
                PART_ERROR(H5Ldelete_by_idx_soft_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_soft_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_external_crt_order_increasing)
        {
            TESTING_2("H5Ldelete_by_idx on external link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            /* Create file for external link to reference */
            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP13_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP13_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by creation order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by creation order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by creation order in "
                       "increasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP13_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_external_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_external_crt_order_decreasing)
        {
            TESTING_2("H5Ldelete_by_idx on external link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            /* Create file for external link to reference */
            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP14_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP14_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by creation order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by creation order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by creation order in "
                       "decreasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP14_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_external_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_external_name_order_increasing)
        {
            TESTING_2("H5Ldelete_by_idx on external link by alphabetical order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_external_name_order_increasing);
            }

            /* Create file for external link to reference */
            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP15_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP15_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by alphabetical "
                       "order in increasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by alphabetical "
                       "order in increasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by alphabetical "
                       "order in increasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP15_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_external_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_external_name_order_decreasing)
        {
            TESTING_2("H5Ldelete_by_idx on external link by alphabetical order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX)) {
                SKIPPED();
                printf("    by index isn't supported with this VOL connector\n");
                PART_EMPTY(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            /* Create file for external link to reference */
            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_TEST_SUBGROUP16_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", LINK_DELETE_TEST_SUBGROUP16_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            /* Delete a link */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by alphabetical "
                       "order in decreasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            /* Ensure that the link is gone and others remain */
            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            /* Repeat until all links have been deleted */
            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by alphabetical "
                       "order in decreasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist after deletion of a different link!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (H5Ldelete_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't delete external link '%s' using H5Ldelete_by_idx by alphabetical "
                       "order in decreasing order\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, LINK_DELETE_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link '%s' exists after deletion!\n",
                       LINK_DELETE_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", LINK_DELETE_TEST_SUBGROUP16_NAME);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Ldelete_by_idx_external_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_external_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_ud_crt_order_increasing)
        {
            TESTING_2("H5Ldelete_by_idx on user-defined link by creation order in increasing order");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Ldelete_by_idx_ud_crt_order_increasing);
        }
        PART_END(H5Ldelete_by_idx_ud_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_ud_crt_order_decreasing)
        {
            TESTING_2("H5Ldelete_by_idx on user-defined link by creation order in decreasing order");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Ldelete_by_idx_ud_crt_order_decreasing);
        }
        PART_END(H5Ldelete_by_idx_ud_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_ud_name_order_increasing)
        {
            TESTING_2("H5Ldelete_by_idx on user-defined link by alphabetical order in increasing order");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Ldelete_by_idx_ud_name_order_increasing);
        }
        PART_END(H5Ldelete_by_idx_ud_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_by_idx_ud_name_order_decreasing)
        {
            TESTING_2("H5Ldelete_by_idx on user-defined link by alphabetical order in decreasing order");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Ldelete_by_idx_ud_name_order_decreasing);
        }
        PART_END(H5Ldelete_by_idx_ud_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(ext_file_id);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a group's always-increasing
 * maximum link creation order value gets reset once
 * all the links have been deleted from the group.
 */
static void
test_delete_link_reset_grp_max_crt_order(void H5_ATTR_UNUSED *params)
{
    H5G_info_t grp_info;
    size_t     i;
    hid_t      file_id         = H5I_INVALID_HID;
    hid_t      container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t      subgroup_id = H5I_INVALID_HID;
    hid_t      gcpl_id     = H5I_INVALID_HID;
    char       link_name[LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE];

    TESTING_MULTIPART("H5Ldelete of all links in group resets group's maximum link creation order value");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or creation order "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
        H5_FAILED();
        printf("    couldn't set link creation order tracking\n");
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_SUBGROUP_NAME,
                               H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n",
               LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_SUBGROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Ldelete_links_bottom_up)
        {
            TESTING_2("H5Ldelete from least-recently created link to most-recently created link");

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_SUBGROUP1_NAME,
                                          H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n",
                       LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_SUBGROUP1_NAME);
                PART_ERROR(H5Ldelete_links_bottom_up);
            }

            /* Create several links inside the group */
            for (i = 0; i < LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS; i++) {
                snprintf(link_name, LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE, "link%d", (int)i);

                if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                    H5_FAILED();
                    printf("    couldn't create hard link '%s'\n", link_name);
                    PART_ERROR(H5Ldelete_links_bottom_up);
                }
            }

            /* Delete the links, checking the group's maximum creation order value each time */
            for (i = 0; i < LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS; i++) {
                memset(&grp_info, 0, sizeof(grp_info));

                if (H5Gget_info(subgroup_id, &grp_info) < 0) {
                    H5_FAILED();
                    printf("    failed to retrieve group's info\n");
                    PART_ERROR(H5Ldelete_links_bottom_up);
                }

                if (grp_info.max_corder != LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS) {
                    H5_FAILED();
                    printf("    group's maximum creation order value got adjusted to %lld during link "
                           "deletion; value should have remained at %d\n",
                           (long long)grp_info.max_corder, LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS);
                    PART_ERROR(H5Ldelete_links_bottom_up);
                }

                snprintf(link_name, LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE, "link%d", (int)i);

                if (H5Ldelete(subgroup_id, link_name, H5P_DEFAULT) < 0) {
                    H5_FAILED();
                    printf("    failed to delete link '%s'\n", link_name);
                    PART_ERROR(H5Ldelete_links_bottom_up);
                }
            }

            /* Ensure the group's maximum creation order value has now reset to 0 after all the links are gone
             */
            memset(&grp_info, 0, sizeof(grp_info));

            if (H5Gget_info(subgroup_id, &grp_info) < 0) {
                H5_FAILED();
                printf("    failed to retrieve group's info\n");
                PART_ERROR(H5Ldelete_links_bottom_up);
            }

            if (grp_info.max_corder != 0) {
                H5_FAILED();
                printf("    group's maximum creation order value didn't reset to 0 after deleting all "
                       "links from group; value is still %lld\n",
                       (long long)grp_info.max_corder);
                PART_ERROR(H5Ldelete_links_bottom_up);
            }

            PASSED();
        }
        PART_END(H5Ldelete_links_bottom_up);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Ldelete_links_top_down)
        {
            TESTING_2("H5Ldelete from most-recently created link to least-recently created link");

            if ((subgroup_id = H5Gcreate2(group_id, LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_SUBGROUP2_NAME,
                                          H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n",
                       LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_SUBGROUP2_NAME);
                PART_ERROR(H5Ldelete_links_top_down);
            }

            /* Create several links inside the group */
            for (i = 0; i < LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS; i++) {
                snprintf(link_name, LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE, "link%d", (int)i);

                if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                    H5_FAILED();
                    printf("    couldn't create hard link '%s'\n", link_name);
                    PART_ERROR(H5Ldelete_links_top_down);
                }
            }

            /* Delete the links, checking the group's maximum creation order value each time */
            for (i = 0; i < LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS; i++) {
                memset(&grp_info, 0, sizeof(grp_info));

                if (H5Gget_info(subgroup_id, &grp_info) < 0) {
                    H5_FAILED();
                    printf("    failed to retrieve group's info\n");
                    PART_ERROR(H5Ldelete_links_top_down);
                }

                if (grp_info.max_corder != LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS) {
                    H5_FAILED();
                    printf("    group's maximum creation order value got adjusted to %lld during link "
                           "deletion; value should have remained at %d\n",
                           (long long)grp_info.max_corder, LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS);
                    PART_ERROR(H5Ldelete_links_top_down);
                }

                snprintf(link_name, LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE, "link%d",
                         (int)(LINK_DELETE_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS - i - 1));

                if (H5Ldelete(subgroup_id, link_name, H5P_DEFAULT) < 0) {
                    H5_FAILED();
                    printf("    failed to delete link '%s'\n", link_name);
                    PART_ERROR(H5Ldelete_links_top_down);
                }
            }

            /* Ensure the group's maximum creation order value has now reset to 0 after all the links are gone
             */
            memset(&grp_info, 0, sizeof(grp_info));

            if (H5Gget_info(subgroup_id, &grp_info) < 0) {
                H5_FAILED();
                printf("    failed to retrieve group's info\n");
                PART_ERROR(H5Ldelete_links_top_down);
            }

            if (grp_info.max_corder != 0) {
                H5_FAILED();
                printf("    group's maximum creation order value didn't reset to 0 after deleting all "
                       "links from group; value is still %lld\n",
                       (long long)grp_info.max_corder);
                PART_ERROR(H5Ldelete_links_top_down);
            }

            PASSED();
        }
        PART_END(H5Ldelete_links_top_down);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

static void
test_delete_link_invalid_params(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    herr_t err_ret         = -1;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;

    TESTING_MULTIPART("H5Ldelete with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_BY_IDX) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, flag by index, or hard link aren't "
               "supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, LINK_DELETE_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_DELETE_INVALID_PARAMS_TEST_GROUP_NAME);
        goto error;
    }

    if (H5Lcreate_hard(group_id, ".", group_id, LINK_DELETE_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                       H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create hard link '%s'\n", LINK_DELETE_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    /* Verify the links have been created */
    if ((link_exists = H5Lexists(group_id, LINK_DELETE_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if first hard link '%s' exists\n",
               LINK_DELETE_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    first hard link did not exist\n");
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Ldelete_invalid_loc_id)
        {
            TESTING_2("H5Ldelete with an invalid location ID");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Ldelete(H5I_INVALID_HID, LINK_DELETE_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete succeeded with an invalid location ID!\n");
                PART_ERROR(H5Ldelete_invalid_loc_id);
            }

            PASSED();
        }
        PART_END(H5Ldelete_invalid_loc_id);

        PART_BEGIN(H5Ldelete_invalid_link_name)
        {
            TESTING_2("H5Ldelete with an invalid link name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete(group_id, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete succeeded with a NULL link name!\n");
                PART_ERROR(H5Ldelete_invalid_link_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete(group_id, "", H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete succeeded with an invalid link name of ''!\n");
                PART_ERROR(H5Ldelete_invalid_link_name);
            }

            PASSED();
        }
        PART_END(H5Ldelete_invalid_link_name);

        PART_BEGIN(H5Ldelete_invalid_lapl)
        {
            TESTING_2("H5Ldelete with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Ldelete(group_id, LINK_DELETE_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete succeeded with an invalid LAPL!\n");
                PART_ERROR(H5Ldelete_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Ldelete_invalid_lapl);

        PART_BEGIN(H5Ldelete_by_idx_invalid_loc_id)
        {
            TESTING_2("H5Ldelete_by_idx with an invalid location ID");

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete_by_idx(H5I_INVALID_HID, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete_by_idx succeeded with an invalid location ID!\n");
                PART_ERROR(H5Ldelete_by_idx_invalid_loc_id);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_invalid_loc_id);

        PART_BEGIN(H5Ldelete_by_idx_invalid_grp_name)
        {
            TESTING_2("H5Ldelete_by_idx with an invalid group name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete_by_idx(group_id, NULL, H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete_by_idx succeeded with a NULL group name!\n");
                PART_ERROR(H5Ldelete_by_idx_invalid_grp_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete_by_idx(group_id, "", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete_by_idx succeeded with an invalid group name of ''!\n");
                PART_ERROR(H5Ldelete_by_idx_invalid_grp_name);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_invalid_grp_name);

        PART_BEGIN(H5Ldelete_by_idx_invalid_index_type)
        {
            TESTING_2("H5Ldelete_by_idx with an invalid index type");

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_UNKNOWN, H5_ITER_INC, 0, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete_by_idx succeeded with invalid index type H5_INDEX_UNKNOWN!\n");
                PART_ERROR(H5Ldelete_by_idx_invalid_index_type);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_N, H5_ITER_INC, 0, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete_by_idx succeeded with invalid index type H5_INDEX_N!\n");
                PART_ERROR(H5Ldelete_by_idx_invalid_index_type);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_invalid_index_type);

        PART_BEGIN(H5Ldelete_by_idx_invalid_index_order)
        {
            TESTING_2("H5Ldelete_by_idx with an invalid iteration ordering");

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_UNKNOWN, 0, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete_by_idx succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n");
                PART_ERROR(H5Ldelete_by_idx_invalid_index_order);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_N, 0, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete_by_idx succeeded with invalid iteration ordering H5_ITER_N!\n");
                PART_ERROR(H5Ldelete_by_idx_invalid_index_order);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_invalid_index_order);

        PART_BEGIN(H5Ldelete_by_idx_invalid_lapl)
        {
            TESTING_2("H5Ldelete_by_idx with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Ldelete_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Ldelete_by_idx succeeded with an invalid LAPL!\n");
                PART_ERROR(H5Ldelete_by_idx_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_invalid_lapl);

        PART_BEGIN(H5Ldelete_by_idx_link_existence)
        {
            TESTING_2("valid link existence after previous invalid H5Ldelete(_by_idx) calls");

            /* Verify that the link hasn't been deleted */
            if ((link_exists =
                     H5Lexists(group_id, LINK_DELETE_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       LINK_DELETE_INVALID_PARAMS_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Ldelete_by_idx_link_existence);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link didn't exist!\n");
                PART_ERROR(H5Ldelete_by_idx_link_existence);
            }

            PASSED();
        }
        PART_END(H5Ldelete_by_idx_link_existence);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a link can be copied using H5Lcopy.
 */
static void
test_copy_link(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id = H5I_INVALID_HID, ext_file_id = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  src_grp_id = H5I_INVALID_HID, dst_grp_id = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link copying");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, hard link, soft link, or external link aren't "
               "supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't opewn container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, COPY_LINK_TEST_SUBGROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", COPY_LINK_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((src_grp_id = H5Gcreate2(group_id, COPY_LINK_TEST_SRC_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                                 H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", COPY_LINK_TEST_SRC_GROUP_NAME);
        goto error;
    }

    if ((dst_grp_id = H5Gcreate2(group_id, COPY_LINK_TEST_DST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                                 H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", COPY_LINK_TEST_DST_GROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lcopy_hard_no_check)
        {
            TESTING_2("H5Lcopy on hard link (copied link's properties not checked)");

            /* Try to copy a hard link */
            if (H5Lcreate_hard(group_id, ".", src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", COPY_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", COPY_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", COPY_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            /* Copy the link */
            if (H5Lcopy(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME, dst_grp_id,
                        COPY_LINK_TEST_HARD_LINK_COPY_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy hard link '%s'\n", COPY_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            /* Verify the link has been copied and still exists in the source group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_HARD_LINK_COPY_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link copy '%s' exists\n",
                       COPY_LINK_TEST_HARD_LINK_COPY_NAME);
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link copy did not exist\n");
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original hard link '%s' exists\n",
                       COPY_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original hard link did not exist\n");
                PART_ERROR(H5Lcopy_hard_no_check);
            }

            PASSED();
        }
        PART_END(H5Lcopy_hard_no_check);

        PART_BEGIN(H5Lcopy_hard_check)
        {
            H5L_info2_t orig_info, new_info;
            int         cmp_value;

            TESTING_2("H5Lcopy on hard link (copied link's properties checked)");

            /* Try to copy a hard link */
            if (H5Lcreate_hard(group_id, ".", src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", COPY_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lcopy_hard_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", COPY_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lcopy_hard_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lcopy_hard_check);
            }

            /* Retrieve the link's info */
            if (H5Lget_info2(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME2, &orig_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", COPY_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lcopy_hard_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", COPY_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lcopy_hard_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_hard_check);
            }

            /* Copy the link */
            if (H5Lcopy(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME2, dst_grp_id,
                        COPY_LINK_TEST_HARD_LINK_COPY_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy hard link '%s'\n", COPY_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lcopy_hard_check);
            }

            /* Verify the link has been copied and still exists in the source group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_HARD_LINK_COPY_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link copy '%s' exists\n",
                       COPY_LINK_TEST_HARD_LINK_COPY_NAME2);
                PART_ERROR(H5Lcopy_hard_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link copy did not exist\n");
                PART_ERROR(H5Lcopy_hard_check);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original hard link '%s' exists\n",
                       COPY_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lcopy_hard_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original hard link did not exist\n");
                PART_ERROR(H5Lcopy_hard_check);
            }

            /* Retrieve the new link's info */
            if (H5Lget_info2(dst_grp_id, COPY_LINK_TEST_HARD_LINK_COPY_NAME2, &new_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", COPY_LINK_TEST_HARD_LINK_COPY_NAME2);
                PART_ERROR(H5Lcopy_hard_check);
            }

            if (new_info.type != orig_info.type) {
                H5_FAILED();
                printf("    copied link's link type doesn't match original link's type\n");
                PART_ERROR(H5Lcopy_hard_check);
            }

            if (H5Otoken_cmp(dst_grp_id, &new_info.u.token, &orig_info.u.token, &cmp_value) < 0) {
                H5_FAILED();
                printf("    failed to compare link target tokens\n");
                PART_ERROR(H5Lcopy_hard_check);
            }

            if (cmp_value != 0) {
                H5_FAILED();
                printf("    copied hard link's object token doesn't match original link's object token\n");
                PART_ERROR(H5Lcopy_hard_check);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (new_info.corder_valid != orig_info.corder_valid) {
                    H5_FAILED();
                    printf("    copied link's 'corder_valid' field doesn't match original link's "
                           "'corder_valid' field\n");
                    PART_ERROR(H5Lcopy_hard_check);
                }

                if (new_info.corder_valid && orig_info.corder_valid &&
                    (new_info.corder != orig_info.corder)) {
                    H5_FAILED();
                    printf("    copied link's creation order value %" PRId64
                           " doesn't match original link's creation order value %" PRId64 "\n",
                           new_info.corder, orig_info.corder);
                    PART_ERROR(H5Lcopy_hard_check);
                }
            }

            if (new_info.cset != orig_info.cset) {
                H5_FAILED();
                printf("    copied link's character set doesn't match original link's character set\n");
                PART_ERROR(H5Lcopy_hard_check);
            }

            PASSED();
        }
        PART_END(H5Lcopy_hard_check);

        PART_BEGIN(H5Lcopy_hard_same_loc)
        {
            TESTING_2("H5Lcopy on hard link using H5L_SAME_LOC");

            /* Try to copy a hard link */
            if (H5Lcreate_hard(group_id, ".", src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", COPY_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", COPY_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            /* Verify the links don't currently exist in the target group */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME2);
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            /* Copy the link using H5L_SAME_LOC as the first parameter to H5Lcopy */
            if (H5Lcopy(H5L_SAME_LOC, COPY_LINK_TEST_HARD_LINK_NAME3, src_grp_id,
                        COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy hard link '%s' using H5L_SAME_LOC as first parameter to H5Lcopy\n",
                       COPY_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            /* Copy the link using H5L_SAME_LOC as the third parameter to H5Lcopy */
            if (H5Lcopy(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME3, H5L_SAME_LOC,
                        COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy hard link '%s' using H5L_SAME_LOC as third parameter to H5Lcopy\n",
                       COPY_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            /* Verify the links have been copied and the original still exist in the source group */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if hard link copy '%s' exists\n",
                       COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link copy did not exist\n");
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if hard link copy '%s' exists\n",
                       COPY_LINK_TEST_HARD_LINK_SAME_LOC_NAME2);
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link copy did not exist\n");
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original hard link '%s' exists\n",
                       COPY_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original hard link did not exist\n");
                PART_ERROR(H5Lcopy_hard_same_loc);
            }

            PASSED();
        }
        PART_END(H5Lcopy_hard_same_loc);

        PART_BEGIN(H5Lcopy_soft_no_check)
        {
            TESTING_2("H5Lcopy on soft link (copied link's properties not checked)");

            /* Try to copy a soft link */
            if (H5Lcreate_soft(COPY_LINK_TEST_SOFT_LINK_TARGET_PATH, src_grp_id,
                               COPY_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", COPY_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", COPY_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", COPY_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            /* Copy the link */
            if (H5Lcopy(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME, dst_grp_id,
                        COPY_LINK_TEST_SOFT_LINK_COPY_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy soft link '%s'\n", COPY_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            /* Verify the link has been copied and still exists in the source group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_SOFT_LINK_COPY_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' copy exists\n",
                       COPY_LINK_TEST_SOFT_LINK_COPY_NAME);
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link copy did not exist\n");
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original soft link '%s' exists\n",
                       COPY_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original soft link did not exist\n");
                PART_ERROR(H5Lcopy_soft_no_check);
            }

            PASSED();
        }
        PART_END(H5Lcopy_soft_no_check);

        PART_BEGIN(H5Lcopy_soft_check)
        {
            H5L_info2_t orig_info, new_info;
            char        orig_link_val[COPY_LINK_TEST_LINK_VAL_BUF_SIZE];
            char        new_link_val[COPY_LINK_TEST_LINK_VAL_BUF_SIZE];

            TESTING_2("H5Lcopy on soft link (copied link's properties checked)");

            /* Try to copy a soft link */
            if (H5Lcreate_soft(COPY_LINK_TEST_SOFT_LINK_TARGET_PATH, src_grp_id,
                               COPY_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", COPY_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", COPY_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lcopy_soft_check);
            }

            /* Retrieve the link's info */
            if (H5Lget_info2(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME2, &orig_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", COPY_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            /* Retrieve the link's value */
            if (H5Lget_val(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME2, orig_link_val,
                           COPY_LINK_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve value for soft link '%s'\n", COPY_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", COPY_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_soft_check);
            }

            /* Copy the link */
            if (H5Lcopy(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME2, dst_grp_id,
                        COPY_LINK_TEST_SOFT_LINK_COPY_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy soft link '%s'\n", COPY_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            /* Verify the link has been copied and still exists in the source group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_SOFT_LINK_COPY_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' copy exists\n",
                       COPY_LINK_TEST_SOFT_LINK_COPY_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link copy did not exist\n");
                PART_ERROR(H5Lcopy_soft_check);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original soft link '%s' exists\n",
                       COPY_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original soft link did not exist\n");
                PART_ERROR(H5Lcopy_soft_check);
            }

            /* Retrieve the new link's info */
            if (H5Lget_info2(dst_grp_id, COPY_LINK_TEST_SOFT_LINK_COPY_NAME2, &new_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", COPY_LINK_TEST_SOFT_LINK_COPY_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            if (new_info.type != orig_info.type) {
                H5_FAILED();
                printf("    copied link's link type doesn't match original link's type\n");
                PART_ERROR(H5Lcopy_soft_check);
            }

            if (new_info.u.val_size != orig_info.u.val_size) {
                H5_FAILED();
                printf("    copied soft link's value size of %llu doesn't match original link's value size "
                       "of %llu\n",
                       (unsigned long long)new_info.u.val_size, (unsigned long long)orig_info.u.val_size);
                PART_ERROR(H5Lcopy_soft_check);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (new_info.corder_valid != orig_info.corder_valid) {
                    H5_FAILED();
                    printf("    copied link's 'corder_valid' field doesn't match original link's "
                           "'corder_valid' field\n");
                    PART_ERROR(H5Lcopy_soft_check);
                }

                if (new_info.corder_valid && orig_info.corder_valid &&
                    (new_info.corder != orig_info.corder)) {
                    H5_FAILED();
                    printf("    copied link's creation order value %" PRId64
                           " doesn't match original link's creation order value %" PRId64 "\n",
                           new_info.corder, orig_info.corder);
                    PART_ERROR(H5Lcopy_soft_check);
                }
            }

            if (new_info.cset != orig_info.cset) {
                H5_FAILED();
                printf("    copied link's character set doesn't match original link's character set\n");
                PART_ERROR(H5Lcopy_soft_check);
            }

            /* Check the soft link's value */
            if (H5Lget_val(dst_grp_id, COPY_LINK_TEST_SOFT_LINK_COPY_NAME2, new_link_val,
                           COPY_LINK_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve value for soft link '%s'\n",
                       COPY_LINK_TEST_SOFT_LINK_COPY_NAME2);
                PART_ERROR(H5Lcopy_soft_check);
            }

            if (strncmp(orig_link_val, new_link_val, COPY_LINK_TEST_LINK_VAL_BUF_SIZE)) {
                H5_FAILED();
                printf("    copied soft link's value '%s' doesn't match original link's value '%s'\n",
                       new_link_val, orig_link_val);
                PART_ERROR(H5Lcopy_soft_check);
            }

            PASSED();
        }
        PART_END(H5Lcopy_soft_check);

        PART_BEGIN(H5Lcopy_soft_same_loc)
        {
            TESTING_2("H5Lcopy on soft link using H5L_SAME_LOC");

            /* Try to copy a soft link */
            if (H5Lcreate_soft(COPY_LINK_TEST_SOFT_LINK_TARGET_PATH, src_grp_id,
                               COPY_LINK_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", COPY_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", COPY_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            /* Verify the links don't currently exist in the target group */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME2);
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            /* Copy the link using H5L_SAME_LOC as the first parameter to H5Lcopy */
            if (H5Lcopy(H5L_SAME_LOC, COPY_LINK_TEST_SOFT_LINK_NAME3, src_grp_id,
                        COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy soft link '%s' using H5L_SAME_LOC as first parameter to H5Lcopy\n",
                       COPY_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            /* Copy the link using H5L_SAME_LOC as the third parameter to H5Lcopy */
            if (H5Lcopy(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME3, H5L_SAME_LOC,
                        COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy soft link '%s' using H5L_SAME_LOC as third parameter to H5Lcopy\n",
                       COPY_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            /* Verify the links have been copied and the original still exists in the source group */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' copy exists\n",
                       COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link copy did not exist\n");
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' copy exists\n",
                       COPY_LINK_TEST_SOFT_LINK_SAME_LOC_NAME2);
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link copy did not exist\n");
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original soft link '%s' exists\n",
                       COPY_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original soft link did not exist\n");
                PART_ERROR(H5Lcopy_soft_same_loc);
            }

            PASSED();
        }
        PART_END(H5Lcopy_soft_same_loc);

        PART_BEGIN(H5Lcopy_external_no_check)
        {
            TESTING_2("H5Lcopy on external link (copied link's properties not checked)");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lcopy_external_no_check);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcopy_external_no_check);
            }

            /* Try to copy an external link */
            if (H5Lcreate_external(ext_link_filename, "/", src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", COPY_LINK_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lcopy_external_no_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lcopy_external_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lcopy_external_no_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lcopy_external_no_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_external_no_check);
            }

            /* Copy the link */
            if (H5Lcopy(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME, dst_grp_id,
                        COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy external link '%s'\n", COPY_LINK_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lcopy_external_no_check);
            }

            /* Verify the link has been copied and still exists in the source group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link copy '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME);
                PART_ERROR(H5Lcopy_external_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link copy did not exist\n");
                PART_ERROR(H5Lcopy_external_no_check);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lcopy_external_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original external link did not exist\n");
                PART_ERROR(H5Lcopy_external_no_check);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcopy_external_no_check);
            }

            PASSED();
        }
        PART_END(H5Lcopy_external_no_check);

        H5E_BEGIN_TRY
        {
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lcopy_external_check)
        {
            H5L_info2_t orig_info, new_info;
            const char *orig_filename, *new_filename;
            const char *orig_objname, *new_objname;
            unsigned    unpack_flags = 0;
            char        orig_link_val[COPY_LINK_TEST_LINK_VAL_BUF_SIZE];
            char        new_link_val[COPY_LINK_TEST_LINK_VAL_BUF_SIZE];

            TESTING_2("H5Lcopy on external link (copied link's properties checked)");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcopy_external_check);
            }

            /* Try to copy an external link */
            if (H5Lcreate_external(ext_link_filename, "/", src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME2,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", COPY_LINK_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lcopy_external_check);
            }

            /* Retrieve the link's info */
            if (H5Lget_info2(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME2, &orig_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", COPY_LINK_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            /* Retrieve the link's value */
            if (H5Lget_val(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME2, orig_link_val,
                           COPY_LINK_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve value for external link '%s'\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (H5Lunpack_elink_val(orig_link_val, orig_info.u.val_size, &unpack_flags, &orig_filename,
                                    &orig_objname) < 0) {
                H5_FAILED();
                printf("    couldn't unpack original external link's value buffer\n");
                PART_ERROR(H5Lcopy_external_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_external_check);
            }

            /* Copy the link */
            if (H5Lcopy(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME2, dst_grp_id,
                        COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy external link '%s'\n", COPY_LINK_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            /* Verify the link has been copied and still exists in the source group */
            if ((link_exists = H5Lexists(dst_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link copy '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link copy did not exist\n");
                PART_ERROR(H5Lcopy_external_check);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original external link did not exist\n");
                PART_ERROR(H5Lcopy_external_check);
            }

            /* Retrieve the new link's info */
            if (H5Lget_info2(dst_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME2, &new_info, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (new_info.type != orig_info.type) {
                H5_FAILED();
                printf("    copied link's link type doesn't match original link's type\n");
                PART_ERROR(H5Lcopy_external_check);
            }

            if (new_info.u.val_size != orig_info.u.val_size) {
                H5_FAILED();
                printf("    copied external link's value size of %llu doesn't match original link's value "
                       "size of %llu\n",
                       (unsigned long long)new_info.u.val_size, (unsigned long long)orig_info.u.val_size);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (new_info.corder_valid != orig_info.corder_valid) {
                    H5_FAILED();
                    printf("    copied link's 'corder_valid' field doesn't match original link's "
                           "'corder_valid' field\n");
                    PART_ERROR(H5Lcopy_external_check);
                }

                if (new_info.corder_valid && orig_info.corder_valid &&
                    (new_info.corder != orig_info.corder)) {
                    H5_FAILED();
                    printf("    copied link's creation order value %" PRId64
                           " doesn't match original link's creation "
                           "order value %" PRId64 "\n",
                           new_info.corder, orig_info.corder);
                    PART_ERROR(H5Lcopy_external_check);
                }
            }

            if (new_info.cset != orig_info.cset) {
                H5_FAILED();
                printf("    copied link's character set doesn't match original link's character set\n");
                PART_ERROR(H5Lcopy_external_check);
            }

            /* Check the external link's value */
            if (H5Lget_val(dst_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME2, new_link_val,
                           COPY_LINK_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve value for external link '%s'\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_COPY_NAME2);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (H5Lunpack_elink_val(new_link_val, new_info.u.val_size, &unpack_flags, &new_filename,
                                    &new_objname) < 0) {
                H5_FAILED();
                printf("    couldn't unpack copied external link's value buffer\n");
                PART_ERROR(H5Lcopy_external_check);
            }

            if (strncmp(new_filename, orig_filename, strlen(orig_filename)) < 0) {
                H5_FAILED();
                printf("    copied external link's filename '%s' doesn't match original external link's "
                       "filename '%s'\n",
                       new_filename, orig_filename);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (strncmp(new_objname, orig_objname, strlen(orig_objname)) < 0) {
                H5_FAILED();
                printf("    copied external link's object name '%s' doesn't match original external link's "
                       "object name '%s'\n",
                       new_objname, orig_objname);
                PART_ERROR(H5Lcopy_external_check);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcopy_external_check);
            }

            PASSED();
        }
        PART_END(H5Lcopy_external_check);

        H5E_BEGIN_TRY
        {
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lcopy_external_same_loc)
        {
            TESTING_2("H5Lcopy on external link using H5L_SAME_LOC");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            /* Try to copy an external link */
            if (H5Lcreate_external(ext_link_filename, "/", src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME3,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", COPY_LINK_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            /* Verify the links don't currently exist in the target group */
            if ((link_exists =
                     H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if ((link_exists =
                     H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME2);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link existed in target group before copy!\n");
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            /* Copy the link using H5L_SAME_LOC as the first parameter to H5Lcopy */
            if (H5Lcopy(H5L_SAME_LOC, COPY_LINK_TEST_EXTERNAL_LINK_NAME3, src_grp_id,
                        COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy external link '%s' using H5L_SAME_LOC as first parameter to "
                       "H5Lcopy\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            /* Copy the link using H5L_SAME_LOC as the third parameter to H5Lcopy */
            if (H5Lcopy(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME3, H5L_SAME_LOC,
                        COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to copy external link '%s' using H5L_SAME_LOC as third parameter to "
                       "H5Lcopy\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            /* Verify the links have been copied and the original still exists in the source group */
            if ((link_exists =
                     H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link copy '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link copy did not exist\n");
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if ((link_exists =
                     H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link copy '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_SAME_LOC_NAME2);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link copy did not exist\n");
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original external link '%s' exists\n",
                       COPY_LINK_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original external link did not exist\n");
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcopy_external_same_loc);
            }

            PASSED();
        }
        PART_END(H5Lcopy_external_same_loc);

        H5E_BEGIN_TRY
        {
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lcopy_ud_no_check)
        {
            TESTING_2("H5Lcopy on user-defined link (copied link's properties not checked)");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lcopy_ud_no_check);
        }
        PART_END(H5Lcopy_ud_no_check);

        PART_BEGIN(H5Lcopy_ud_check)
        {
            TESTING_2("H5Lcopy on user-defined link (copied link's properties checked)");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lcopy_ud_check);
        }
        PART_END(H5Lcopy_ud_check);

        PART_BEGIN(H5Lcopy_ud_same_loc)
        {
            TESTING_2("H5Lcopy on user-defined link using H5L_SAME_LOC");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lcopy_ud_same_loc);
        }
        PART_END(H5Lcopy_ud_same_loc);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(dst_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(src_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(dst_grp_id);
        H5Gclose(src_grp_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(ext_file_id);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that using H5Lcopy to copy links into a
 * group which already contains links will cause the new links
 * to have creation order values ranging from the target group's
 * maximum link creation order value and upwards. This is to
 * check that it is not possible to run into the situation where
 * H5Lcopy might cause a group to have two links with the same
 * creation order values.
 */
static void
test_copy_links_into_group_with_links(void H5_ATTR_UNUSED *params)
{
    TESTING("H5Lcopy adjusting creation order values for copied links");

    SKIPPED();

    return;
}

/*
 * A test to check the behavior of copying a link across files.
 * This should fail for hard links but succeed for soft and
 * external links (and user-defined links of those types).
 *
 * TODO: Ideally, tests should be written to verify that the
 *       copied links retain the properties of the original
 *       links.
 */
static void
test_copy_link_across_files(void H5_ATTR_UNUSED *params)
{
    TESTING("link copying across files");

    /* TODO */

    SKIPPED();

    return;
}

/*
 * A test to check that a link can't be copied
 * when H5Lcopy is passed invalid parameters.
 */
static void
test_copy_link_invalid_params(void H5_ATTR_UNUSED *params)
{
    herr_t err_ret = -1;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  src_grp_id = H5I_INVALID_HID, dst_grp_id = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};
    hid_t  ext_file_id                                        = H5I_INVALID_HID;

    TESTING_MULTIPART("H5Lcopy with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or hard links aren't supported with this "
               "connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, COPY_LINK_INVALID_PARAMS_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", COPY_LINK_INVALID_PARAMS_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((src_grp_id = H5Gcreate2(group_id, COPY_LINK_INVALID_PARAMS_TEST_SRC_GROUP_NAME, H5P_DEFAULT,
                                 H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", COPY_LINK_INVALID_PARAMS_TEST_SRC_GROUP_NAME);
        goto error;
    }

    if ((dst_grp_id = H5Gcreate2(group_id, COPY_LINK_INVALID_PARAMS_TEST_DST_GROUP_NAME, H5P_DEFAULT,
                                 H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", COPY_LINK_INVALID_PARAMS_TEST_DST_GROUP_NAME);
        goto error;
    }

    if (H5Lcreate_hard(group_id, ".", src_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                       H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create hard link '%s'\n", COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(src_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if hard link '%s' exists\n",
               COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    hard link did not exist\n");
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lcopy_invalid_src_loc_id)
        {
            TESTING_2("H5Lcopy with an invalid source location ID");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcopy(H5I_INVALID_HID, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id,
                            COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_COPY_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded with an invalid source location ID\n");
                PART_ERROR(H5Lcopy_invalid_src_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lcopy_invalid_src_loc_id);

        PART_BEGIN(H5Lcopy_invalid_src_name)
        {
            TESTING_2("H5Lcopy with an invalid source name");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcopy(src_grp_id, NULL, dst_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_COPY_NAME,
                            H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded with a NULL source name\n");
                PART_ERROR(H5Lcopy_invalid_src_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcopy(src_grp_id, "", dst_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_COPY_NAME,
                            H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded with an invalid source name of ''\n");
                PART_ERROR(H5Lcopy_invalid_src_name);
            }

            PASSED();
        }
        PART_END(H5Lcopy_invalid_src_name);

        PART_BEGIN(H5Lcopy_invalid_dst_loc_id)
        {
            TESTING_2("H5Lcopy with an invalid destination location ID");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcopy(src_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5I_INVALID_HID,
                            COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_COPY_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded with an invalid destination location ID\n");
                PART_ERROR(H5Lcopy_invalid_dst_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lcopy_invalid_dst_loc_id);

        PART_BEGIN(H5Lcopy_invalid_dst_name)
        {
            TESTING_2("H5Lcopy with an invalid destination name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcopy(src_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id, NULL,
                                  H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded with a NULL destination name\n");
                PART_ERROR(H5Lcopy_invalid_dst_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lcopy(src_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id, "",
                                  H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded with an invalid destination name of ''\n");
                PART_ERROR(H5Lcopy_invalid_dst_name);
            }

            PASSED();
        }
        PART_END(H5Lcopy_invalid_dst_name);

        PART_BEGIN(H5Lcopy_invalid_lcpl)
        {
            TESTING_2("H5Lcopy with an invalid LCPL");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcopy(src_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id,
                            COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_COPY_NAME, H5I_INVALID_HID, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded with an invalid LCPL\n");
                PART_ERROR(H5Lcopy_invalid_lcpl);
            }

            PASSED();
        }
        PART_END(H5Lcopy_invalid_lcpl);

        PART_BEGIN(H5Lcopy_invalid_lapl)
        {
            TESTING_2("H5Lcopy with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcopy(src_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id,
                            COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_COPY_NAME, H5P_DEFAULT, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded with an invalid LAPL\n");
                PART_ERROR(H5Lcopy_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lcopy_invalid_lapl);

        PART_BEGIN(H5Lcopy_invalid_same_location)
        {
            TESTING_2("H5Lcopy with an invalid same location");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcopy(H5L_SAME_LOC, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5L_SAME_LOC,
                            COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_COPY_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded with an invalid same location\n");
                PART_ERROR(H5Lcopy_invalid_same_location);
            }

            PASSED();
        }
        PART_END(H5Lcopy_invalid_same_location);

        PART_BEGIN(H5Lcopy_invalid_across_files)
        {
            TESTING_2("H5Lcopy invalid across files");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lcopy_invalid_across_files);
            }

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lcopy(src_grp_id, COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, ext_file_id,
                            COPY_LINK_INVALID_PARAMS_TEST_HARD_LINK_COPY_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lcopy succeeded in copying a hard link across files!\n");
                PART_ERROR(H5Lcopy_invalid_across_files);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcopy_invalid_across_files);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lcopy_invalid_across_files);
            }

            PASSED();
        }
        PART_END(H5Lcopy_invalid_across_files);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(dst_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(src_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(dst_grp_id);
        H5Gclose(src_grp_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(ext_file_id);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a link can be moved with H5Lmove.
 */
static void
test_move_link(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  src_grp_id = H5I_INVALID_HID, dst_grp_id = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};
    hid_t  ext_file_id                                        = H5I_INVALID_HID;

    TESTING_MULTIPART("link moving");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, hard link, soft link, or external link aren't "
               "supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, MOVE_LINK_TEST_SUBGROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((src_grp_id = H5Gcreate2(group_id, MOVE_LINK_TEST_SRC_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                                 H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_TEST_SRC_GROUP_NAME);
        goto error;
    }

    if ((dst_grp_id = H5Gcreate2(group_id, MOVE_LINK_TEST_DST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT,
                                 H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_TEST_DST_GROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lmove_hard_no_check)
        {
            TESTING_2("H5Lmove on hard link (moved link's properties not checked)");

            /* Try to move a hard link */
            if (H5Lcreate_hard(group_id, ".", src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", MOVE_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_hard_no_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_hard_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lmove_hard_no_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_hard_no_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link existed in target group before move!\n");
                PART_ERROR(H5Lmove_hard_no_check);
            }

            /* Move the link */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME, dst_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME,
                        H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s'\n", MOVE_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_hard_no_check);
            }

            /* Verify the link has been moved */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_hard_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lmove_hard_no_check);
            }

            /* Verify the old link is gone */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if old hard link '%s' exists\n",
                       MOVE_LINK_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_hard_no_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    old hard link exists\n");
                PART_ERROR(H5Lmove_hard_no_check);
            }

            PASSED();
        }
        PART_END(H5Lmove_hard_no_check);

        PART_BEGIN(H5Lmove_hard_check)
        {
            H5L_info2_t orig_info, new_info;
            int         cmp_value;

            TESTING_2("H5Lmove on hard link (moved link's properties checked)");

            /* Try to move a hard link */
            if (H5Lcreate_hard(group_id, ".", src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", MOVE_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lmove_hard_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lmove_hard_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lmove_hard_check);
            }

            /* Retrieve the link's info */
            if (H5Lget_info2(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME2, &orig_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", MOVE_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lmove_hard_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lmove_hard_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link existed in target group before move!\n");
                PART_ERROR(H5Lmove_hard_check);
            }

            /* Move the link */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME2, dst_grp_id,
                        MOVE_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s'\n", MOVE_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lmove_hard_check);
            }

            /* Verify the link has been moved */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lmove_hard_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lmove_hard_check);
            }

            /* Verify the old link is gone */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if old hard link '%s' exists\n",
                       MOVE_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lmove_hard_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    old hard link exists\n");
                PART_ERROR(H5Lmove_hard_check);
            }

            /* Retrieve the moved link's info */
            if (H5Lget_info2(dst_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME2, &new_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", MOVE_LINK_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lmove_hard_check);
            }

            if (new_info.type != orig_info.type) {
                H5_FAILED();
                printf("    moved link's link type doesn't match original link's type\n");
                PART_ERROR(H5Lmove_hard_check);
            }

            if (H5Otoken_cmp(dst_grp_id, &new_info.u.token, &orig_info.u.token, &cmp_value) < 0) {
                H5_FAILED();
                printf("    failed to compare link target tokens\n");
                PART_ERROR(H5Lmove_hard_check);
            }

            if (cmp_value != 0) {
                H5_FAILED();
                printf("    moved hard link's object token doesn't match original link's object token\n");
                PART_ERROR(H5Lmove_hard_check);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (new_info.corder_valid != orig_info.corder_valid) {
                    H5_FAILED();
                    printf(
                        "    moved link's 'corder_valid' field doesn't match original link's 'corder_valid' "
                        "field\n");
                    PART_ERROR(H5Lmove_hard_check);
                }

                if (new_info.corder_valid && orig_info.corder_valid &&
                    (new_info.corder != orig_info.corder)) {
                    H5_FAILED();
                    printf("    moved link's creation order value %" PRId64
                           " doesn't match original link's creation order value %" PRId64 "\n",
                           new_info.corder, orig_info.corder);
                    PART_ERROR(H5Lmove_hard_check);
                }
            }

            if (new_info.cset != orig_info.cset) {
                H5_FAILED();
                printf("    moved link's character set doesn't match original link's character set\n");
                PART_ERROR(H5Lmove_hard_check);
            }

            PASSED();
        }
        PART_END(H5Lmove_hard_check);

        PART_BEGIN(H5Lmove_hard_same_loc)
        {
            TESTING_2("H5Lmove on hard link using H5L_SAME_LOC");

            /* Try to move a hard link */
            if (H5Lcreate_hard(group_id, ".", src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", MOVE_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link existed in target group before move!\n");
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            /* Rename the link using H5L_SAME_LOC as the first parameter to H5Lmove */
            if (H5Lmove(H5L_SAME_LOC, MOVE_LINK_TEST_HARD_LINK_NAME3, src_grp_id,
                        MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s' using H5L_SAME_LOC as first parameter to H5Lmove\n",
                       MOVE_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            /* Ensure the link has been renamed */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    original hard link existed in target group after move!\n");
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist after move!\n");
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            /* Rename the link back using H5L_SAME_LOC as the third parameter to H5Lmove */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME, H5L_SAME_LOC,
                        MOVE_LINK_TEST_HARD_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s' using H5L_SAME_LOC as third parameter to H5Lmove\n",
                       MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            /* Verify the link has been renamed back */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original hard link did not exist after moving the link back!\n");
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if old hard link '%s' exists\n",
                       MOVE_LINK_TEST_HARD_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    renamed hard link exists after moving the link back!\n");
                PART_ERROR(H5Lmove_hard_same_loc);
            }

            PASSED();
        }
        PART_END(H5Lmove_hard_same_loc);

        PART_BEGIN(H5Lmove_hard_rename)
        {
            TESTING_2("H5Lmove to rename hard link without moving it");

            /* Try to rename a hard link */
            if (H5Lcreate_hard(group_id, ".", src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME4, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", MOVE_LINK_TEST_HARD_LINK_NAME4);
                PART_ERROR(H5Lmove_hard_rename);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME4, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n", MOVE_LINK_TEST_HARD_LINK_NAME4);
                PART_ERROR(H5Lmove_hard_rename);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lmove_hard_rename);
            }

            /* Verify the renamed link doesn't currently exist in the source group */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NEW_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if renamed hard link '%s' exists\n",
                       MOVE_LINK_TEST_HARD_LINK_NEW_NAME);
                PART_ERROR(H5Lmove_hard_rename);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    renamed hard link existed in source group before move!\n");
                PART_ERROR(H5Lmove_hard_rename);
            }

            /* Rename the link */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME4, src_grp_id,
                        MOVE_LINK_TEST_HARD_LINK_NEW_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to rename link '%s'\n", MOVE_LINK_TEST_HARD_LINK_NAME4);
                PART_ERROR(H5Lmove_hard_rename);
            }

            /* Verify the link has been renamed */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NEW_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if renamed hard link '%s' exists\n",
                       MOVE_LINK_TEST_HARD_LINK_NEW_NAME);
                PART_ERROR(H5Lmove_hard_rename);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    renamed hard link did not exist\n");
                PART_ERROR(H5Lmove_hard_rename);
            }

            /* Verify the old link is gone */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_HARD_LINK_NAME4, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if old hard link '%s' exists\n",
                       MOVE_LINK_TEST_HARD_LINK_NAME4);
                PART_ERROR(H5Lmove_hard_rename);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    old hard link exists\n");
                PART_ERROR(H5Lmove_hard_rename);
            }

            PASSED();
        }
        PART_END(H5Lmove_hard_rename);

        PART_BEGIN(H5Lmove_soft_no_check)
        {
            TESTING_2("H5Lmove on soft link (moved link's properties not checked)");

            /* Try to move a soft link */
            if (H5Lcreate_soft(MOVE_LINK_TEST_SOFT_LINK_TARGET_PATH, src_grp_id,
                               MOVE_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lmove_soft_no_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lmove_soft_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lmove_soft_no_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lmove_soft_no_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link existed in target group before move!\n");
                PART_ERROR(H5Lmove_soft_no_check);
            }

            /* Move the link */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME, dst_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME,
                        H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lmove_soft_no_check);
            }

            /* Verify the link has been moved */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lmove_soft_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lmove_soft_no_check);
            }

            /* Verify the old link is gone */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if old soft link '%s' exists\n",
                       MOVE_LINK_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lmove_soft_no_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    old soft link exists\n");
                PART_ERROR(H5Lmove_soft_no_check);
            }

            PASSED();
        }
        PART_END(H5Lmove_soft_no_check);

        PART_BEGIN(H5Lmove_soft_check)
        {
            H5L_info2_t orig_info, new_info;
            char        orig_link_val[MOVE_LINK_TEST_LINK_VAL_BUF_SIZE];
            char        new_link_val[MOVE_LINK_TEST_LINK_VAL_BUF_SIZE];

            TESTING_2("H5Lmove on soft link (moved link's properties checked)");

            /* Try to move a soft link */
            if (H5Lcreate_soft(MOVE_LINK_TEST_SOFT_LINK_TARGET_PATH, src_grp_id,
                               MOVE_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lmove_soft_check);
            }

            /* Retrieve the link's info */
            if (H5Lget_info2(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME2, &orig_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            /* Retrieve the link's value */
            if (H5Lget_val(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME2, orig_link_val,
                           MOVE_LINK_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve value for soft link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link existed in target group before move!\n");
                PART_ERROR(H5Lmove_soft_check);
            }

            /* Move the link */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME2, dst_grp_id,
                        MOVE_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            /* Verify the link has been moved */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lmove_soft_check);
            }

            /* Verify the old link is gone */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if old soft link '%s' exists\n",
                       MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    old soft link exists\n");
                PART_ERROR(H5Lmove_soft_check);
            }

            /* Retrieve the moved link's info */
            if (H5Lget_info2(dst_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME2, &new_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            if (new_info.type != orig_info.type) {
                H5_FAILED();
                printf("    moved link's link type doesn't match original link's type\n");
                PART_ERROR(H5Lmove_soft_check);
            }

            if (new_info.u.val_size != orig_info.u.val_size) {
                H5_FAILED();
                printf("    moved soft link's value size of %llu doesn't match original link's value size "
                       "of %llu\n",
                       (unsigned long long)new_info.u.val_size, (unsigned long long)orig_info.u.val_size);
                PART_ERROR(H5Lmove_soft_check);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (new_info.corder_valid != orig_info.corder_valid) {
                    H5_FAILED();
                    printf(
                        "    moved link's 'corder_valid' field doesn't match original link's 'corder_valid' "
                        "field\n");
                    PART_ERROR(H5Lmove_soft_check);
                }

                if (new_info.corder_valid && orig_info.corder_valid &&
                    (new_info.corder != orig_info.corder)) {
                    H5_FAILED();
                    printf("    moved link's creation order value %" PRId64
                           " doesn't match original link's creation order value %" PRId64 "\n",
                           new_info.corder, orig_info.corder);
                    PART_ERROR(H5Lmove_soft_check);
                }
            }

            if (new_info.cset != orig_info.cset) {
                H5_FAILED();
                printf("    moved link's character set doesn't match original link's character set\n");
                PART_ERROR(H5Lmove_soft_check);
            }

            /* Check the soft link's value */
            if (H5Lget_val(dst_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME2, new_link_val,
                           MOVE_LINK_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve value for soft link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lmove_soft_check);
            }

            if (strncmp(orig_link_val, new_link_val, MOVE_LINK_TEST_LINK_VAL_BUF_SIZE)) {
                H5_FAILED();
                printf("    moved soft link's value '%s' doesn't match original link's value '%s'\n",
                       new_link_val, orig_link_val);
                PART_ERROR(H5Lmove_soft_check);
            }

            PASSED();
        }
        PART_END(H5Lmove_soft_check);

        PART_BEGIN(H5Lmove_soft_same_loc)
        {
            TESTING_2("H5Lmove on soft link using H5L_SAME_LOC");

            /* Try to move a soft link */
            if (H5Lcreate_soft(MOVE_LINK_TEST_SOFT_LINK_TARGET_PATH, src_grp_id,
                               MOVE_LINK_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    soft link existed in target group before move!\n");
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            /* Rename the link using H5L_SAME_LOC as the first parameter to H5Lmove */
            if (H5Lmove(H5L_SAME_LOC, MOVE_LINK_TEST_SOFT_LINK_NAME3, src_grp_id,
                        MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s' using H5L_SAME_LOC as first parameter to H5Lmove\n",
                       MOVE_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            /* Ensure the link has been renamed */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    original soft link existed in target group after move!\n");
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist after move!\n");
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            /* Rename the link back using H5L_SAME_LOC as the third parameter to H5Lmove */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME, H5L_SAME_LOC,
                        MOVE_LINK_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s' using H5L_SAME_LOC as third parameter to H5Lmove\n",
                       MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            /* Verify the link has been renamed back */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original hard link did not exist after moving the link back!\n");
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if old soft link '%s' exists\n",
                       MOVE_LINK_TEST_SOFT_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    renamed soft link exists after moving the link back!\n");
                PART_ERROR(H5Lmove_soft_same_loc);
            }

            PASSED();
        }
        PART_END(H5Lmove_soft_same_loc);

        PART_BEGIN(H5Lmove_soft_rename)
        {
            TESTING_2("H5Lmove to rename soft link without moving it");

            /* Try to rename a soft link */
            if (H5Lcreate_soft(MOVE_LINK_TEST_SOFT_LINK_TARGET_PATH, src_grp_id,
                               MOVE_LINK_TEST_SOFT_LINK_NAME4, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME4);
                PART_ERROR(H5Lmove_soft_rename);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME4, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n", MOVE_LINK_TEST_SOFT_LINK_NAME4);
                PART_ERROR(H5Lmove_soft_rename);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lmove_soft_rename);
            }

            /* Verify the renamed link doesn't currently exist in the source group */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NEW_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if renamed soft link '%s' exists\n",
                       MOVE_LINK_TEST_SOFT_LINK_NEW_NAME);
                PART_ERROR(H5Lmove_soft_rename);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    renamed soft link existed in source group before move!\n");
                PART_ERROR(H5Lmove_soft_rename);
            }

            /* Rename the link */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME4, src_grp_id,
                        MOVE_LINK_TEST_SOFT_LINK_NEW_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to rename link '%s'\n", MOVE_LINK_TEST_SOFT_LINK_NAME4);
                PART_ERROR(H5Lmove_soft_rename);
            }

            /* Verify the link has been renamed */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NEW_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if renamed soft link '%s' exists\n",
                       MOVE_LINK_TEST_SOFT_LINK_NEW_NAME);
                PART_ERROR(H5Lmove_soft_rename);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    renamed soft link did not exist\n");
                PART_ERROR(H5Lmove_soft_rename);
            }

            /* Verify the old link is gone */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_SOFT_LINK_NAME4, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if old soft link '%s' exists\n",
                       MOVE_LINK_TEST_SOFT_LINK_NAME4);
                PART_ERROR(H5Lmove_soft_rename);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    old soft link exists\n");
                PART_ERROR(H5Lmove_soft_rename);
            }

            PASSED();
        }
        PART_END(H5Lmove_soft_rename);

        PART_BEGIN(H5Lmove_external_no_check)
        {
            TESTING_2("H5Lmove on external link (moved link's properties not checked)");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_no_check);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_no_check);
            }

            /* Try to move an external link */
            if (H5Lcreate_external(ext_link_filename, "/", src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME);
                PART_ERROR(H5Lmove_external_no_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME);
                PART_ERROR(H5Lmove_external_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lmove_external_no_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME);
                PART_ERROR(H5Lmove_external_no_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link existed in target group before move!\n");
                PART_ERROR(H5Lmove_external_no_check);
            }

            /* Move the link */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME, dst_grp_id,
                        MOVE_LINK_TEST_EXTERN_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME);
                PART_ERROR(H5Lmove_external_no_check);
            }

            /* Verify the link has been moved */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME);
                PART_ERROR(H5Lmove_external_no_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lmove_external_no_check);
            }

            /* Verify the old link is gone */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if old external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME);
                PART_ERROR(H5Lmove_external_no_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    old external link exists\n");
                PART_ERROR(H5Lmove_external_no_check);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_no_check);
            }

            PASSED();
        }
        PART_END(H5Lmove_external_no_check);

        H5E_BEGIN_TRY
        {
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lmove_external_check)
        {
            H5L_info2_t orig_info, new_info;
            const char *orig_filename, *new_filename;
            const char *orig_objname, *new_objname;
            unsigned    unpack_flags = 0;
            char        orig_link_val[MOVE_LINK_TEST_LINK_VAL_BUF_SIZE];
            char        new_link_val[MOVE_LINK_TEST_LINK_VAL_BUF_SIZE];

            TESTING_2("H5Lmove on external link (moved link's properties checked)");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_check);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_check);
            }

            /* Try to move an external link */
            if (H5Lcreate_external(ext_link_filename, "/", src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lmove_external_check);
            }

            /* Retrieve the link's info */
            if (H5Lget_info2(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2, &orig_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            /* Retrieve the link's value */
            if (H5Lget_val(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2, orig_link_val,
                           MOVE_LINK_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve value for external link '%s'\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            if (H5Lunpack_elink_val(orig_link_val, orig_info.u.val_size, &unpack_flags, &orig_filename,
                                    &orig_objname) < 0) {
                H5_FAILED();
                printf("    couldn't unpack original external link's value buffer\n");
                PART_ERROR(H5Lmove_external_check);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link existed in target group before move!\n");
                PART_ERROR(H5Lmove_external_check);
            }

            /* Move the link */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2, dst_grp_id,
                        MOVE_LINK_TEST_EXTERN_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            /* Verify the link has been moved */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lmove_external_check);
            }

            /* Verify the old link is gone */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if old external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    old external link exists\n");
                PART_ERROR(H5Lmove_external_check);
            }

            /* Retrieve the moved link's info */
            if (H5Lget_info2(dst_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2, &new_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve info for link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            if (new_info.type != orig_info.type) {
                H5_FAILED();
                printf("    moved link's link type doesn't match original link's type\n");
                PART_ERROR(H5Lmove_external_check);
            }

            if (new_info.u.val_size != orig_info.u.val_size) {
                H5_FAILED();
                printf("    moved external link's value size of %llu doesn't match original link's value "
                       "size of %llu\n",
                       (unsigned long long)new_info.u.val_size, (unsigned long long)orig_info.u.val_size);
                PART_ERROR(H5Lmove_external_check);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (new_info.corder_valid != orig_info.corder_valid) {
                    H5_FAILED();
                    printf(
                        "    moved link's 'corder_valid' field doesn't match original link's 'corder_valid' "
                        "field\n");
                    PART_ERROR(H5Lmove_external_check);
                }

                if (new_info.corder_valid && orig_info.corder_valid &&
                    (new_info.corder != orig_info.corder)) {
                    H5_FAILED();
                    printf("    moved link's creation order value %" PRId64
                           " doesn't match original link's creation "
                           "order value %" PRId64 "\n",
                           new_info.corder, orig_info.corder);
                    PART_ERROR(H5Lmove_external_check);
                }
            }

            if (new_info.cset != orig_info.cset) {
                H5_FAILED();
                printf("    moved link's character set doesn't match original link's character set\n");
                PART_ERROR(H5Lmove_external_check);
            }

            /* Check the external link's value */
            if (H5Lget_val(dst_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME2, new_link_val,
                           MOVE_LINK_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't retrieve value for external link '%s'\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME2);
                PART_ERROR(H5Lmove_external_check);
            }

            if (H5Lunpack_elink_val(new_link_val, new_info.u.val_size, &unpack_flags, &new_filename,
                                    &new_objname) < 0) {
                H5_FAILED();
                printf("    couldn't unpack moved external link's value buffer\n");
                PART_ERROR(H5Lmove_external_check);
            }

            if (strncmp(new_filename, orig_filename, strlen(orig_filename)) < 0) {
                H5_FAILED();
                printf("    moved external link's filename '%s' doesn't match original external link's "
                       "filename '%s'\n",
                       new_filename, orig_filename);
                PART_ERROR(H5Lmove_external_check);
            }

            if (strncmp(new_objname, orig_objname, strlen(orig_objname)) < 0) {
                H5_FAILED();
                printf("    moved external link's object name '%s' doesn't match original external link's "
                       "object name '%s'\n",
                       new_objname, orig_objname);
                PART_ERROR(H5Lmove_external_check);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_check);
            }

            PASSED();
        }
        PART_END(H5Lmove_external_check);

        H5E_BEGIN_TRY
        {
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lmove_external_same_loc)
        {
            TESTING_2("H5Lmove on external link using H5L_SAME_LOC");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            /* Try to move an external link */
            if (H5Lcreate_external(ext_link_filename, "/", src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME3,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME3);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME3);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lmove_external_same_loc);
            }

            /* Verify the link doesn't currently exist in the target group */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    external link existed in target group before move!\n");
                PART_ERROR(H5Lmove_external_same_loc);
            }

            /* Rename the link using H5L_SAME_LOC as the first parameter to H5Lmove */
            if (H5Lmove(H5L_SAME_LOC, MOVE_LINK_TEST_EXTERN_LINK_NAME3, src_grp_id,
                        MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME3);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            /* Ensure the link has been renamed */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME3);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    original external link existed in target group after move!\n");
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist after move!\n");
                PART_ERROR(H5Lmove_external_same_loc);
            }

            /* Rename the link back using H5L_SAME_LOC as the third parameter to H5Lmove */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME, H5L_SAME_LOC,
                        MOVE_LINK_TEST_EXTERN_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to move link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            /* Verify the link has been renamed back */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME3);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original external link did not exist after moving the link back!\n");
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if old external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_SAME_LOC_NAME);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    renamed external link exists after moving the link back!\n");
                PART_ERROR(H5Lmove_external_same_loc);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_same_loc);
            }

            PASSED();
        }
        PART_END(H5Lmove_external_same_loc);

        H5E_BEGIN_TRY
        {
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lmove_external_rename)
        {
            TESTING_2("H5Lmove to rename external link without moving it");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_rename);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_rename);
            }

            /* Try to move an external link */
            if (H5Lcreate_external(ext_link_filename, "/", src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME4,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME4);
                PART_ERROR(H5Lmove_external_rename);
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME4, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME4);
                PART_ERROR(H5Lmove_external_rename);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lmove_external_rename);
            }

            /* Verify the renamed link doesn't currently exist in the source group */
            if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NEW_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if renamed external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NEW_NAME);
                PART_ERROR(H5Lmove_external_rename);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    renamed external link existed in source group before move!\n");
                PART_ERROR(H5Lmove_external_rename);
            }

            /* Rename the link */
            if (H5Lmove(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME4, src_grp_id,
                        MOVE_LINK_TEST_EXTERN_LINK_NEW_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to rename link '%s'\n", MOVE_LINK_TEST_EXTERN_LINK_NAME4);
                PART_ERROR(H5Lmove_external_rename);
            }

            /* Verify the link has been renamed */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NEW_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if renamed external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NEW_NAME);
                PART_ERROR(H5Lmove_external_rename);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    renamed external link did not exist\n");
                PART_ERROR(H5Lmove_external_rename);
            }

            /* Verify the old link is gone */
            if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_TEST_EXTERN_LINK_NAME4, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if old external link '%s' exists\n",
                       MOVE_LINK_TEST_EXTERN_LINK_NAME4);
                PART_ERROR(H5Lmove_external_rename);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    old external link exists\n");
                PART_ERROR(H5Lmove_external_rename);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lmove_external_rename);
            }

            PASSED();
        }
        PART_END(H5Lmove_external_rename);

        H5E_BEGIN_TRY
        {
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lmove_ud_no_check)
        {
            TESTING_2("H5Lmove on user-defined link (moved link's properties not checked)");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lmove_ud_no_check);
        }
        PART_END(H5Lmove_ud_no_check);

        PART_BEGIN(H5Lmove_ud_check)
        {
            TESTING_2("H5Lmove on user-defined link (moved link's properties checked)");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lmove_ud_check);
        }
        PART_END(H5Lmove_ud_check);

        PART_BEGIN(H5Lmove_ud_same_loc)
        {
            TESTING_2("H5Lmove on user-defined link using H5L_SAME_LOC");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lmove_ud_same_loc);
        }
        PART_END(H5Lmove_ud_same_loc);

        PART_BEGIN(H5Lmove_ud_rename)
        {
            TESTING_2("H5Lmove to rename user-defined link without moving it");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lmove_ud_rename);
        }
        PART_END(H5Lmove_ud_rename);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(dst_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(src_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(dst_grp_id);
        H5Gclose(src_grp_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        H5Fclose(ext_file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that using H5Lmove to move links into a
 * group which already contains links will cause the new links
 * to have creation order values ranging from the target group's
 * maximum link creation order value and upwards. This is to
 * check that it is not possible to run into the situation where
 * H5Lmove might cause a group to have two links with the same
 * creation order values.
 */
static void
test_move_links_into_group_with_links(void H5_ATTR_UNUSED *params)
{
    H5L_info2_t link_info;
    size_t      i;
    hid_t       file_id         = H5I_INVALID_HID;
    hid_t       container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t       src_grp_id = H5I_INVALID_HID, dst_grp_id = H5I_INVALID_HID;
    hid_t       gcpl_id = H5I_INVALID_HID;
    char        link_name[MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_BUF_SIZE];

    TESTING("H5Lmove adjusting creation order values for moved links");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, hard link, or creation order aren't "
               "supported with this connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
        H5_FAILED();
        printf("    couldn't set link creation order tracking\n");
        goto error;
    }

    if ((src_grp_id = H5Gcreate2(group_id, MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_SRC_GRP_NAME, H5P_DEFAULT,
                                 gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_SRC_GRP_NAME);
        goto error;
    }

    if ((dst_grp_id = H5Gcreate2(group_id, MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_DST_GRP_NAME, H5P_DEFAULT,
                                 gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_DST_GRP_NAME);
        goto error;
    }

    /* Create several links in the source group */
    for (i = 0; i < MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_NUM_LINKS; i++) {
        snprintf(link_name, MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_BUF_SIZE, "link_to_move%d", (int)i);

        if (H5Lcreate_hard(src_grp_id, ".", src_grp_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("    couldn't create link '%s' in source group\n", link_name);
            goto error;
        }

        /* Check the current creation order value for each link */
        memset(&link_info, 0, sizeof(link_info));
        if (H5Lget_info2(src_grp_id, link_name, &link_info, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("    failed to retrieve info for link '%s'\n", link_name);
            goto error;
        }

        if (!link_info.corder_valid) {
            H5_FAILED();
            printf("    creation order value for newly-created link '%s' was marked as not valid!\n",
                   link_name);
            goto error;
        }

        if (link_info.corder != (int64_t)i) {
            H5_FAILED();
            printf("    creation order value %lld for link '%s' did not match expected value %lld\n",
                   (long long)link_info.corder, link_name, (long long)i);
            goto error;
        }
    }

    /* Create several links in the destination group */
    for (i = 0; i < MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_NUM_LINKS; i++) {
        snprintf(link_name, MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_BUF_SIZE, "link%d", (int)i);

        if (H5Lcreate_hard(dst_grp_id, ".", dst_grp_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("    couldn't create link '%s' in destination group\n", link_name);
            goto error;
        }
    }

    /* Move all the links from the source group into the destination group */
    for (i = 0; i < MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_NUM_LINKS; i++) {
        snprintf(link_name, MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_BUF_SIZE, "link_to_move%d", (int)i);

        if (H5Lmove(src_grp_id, link_name, dst_grp_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("    failed to move link '%s' from source group to destination group\n", link_name);
            goto error;
        }

        /* Check that the creation order value for each moved link has been adjusted */
        memset(&link_info, 0, sizeof(link_info));
        if (H5Lget_info2(dst_grp_id, link_name, &link_info, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("    failed to retrieve info for link '%s'\n", link_name);
            goto error;
        }

        if (!link_info.corder_valid) {
            H5_FAILED();
            printf("    creation order value for moved link '%s' was marked as not valid!\n", link_name);
            goto error;
        }

        if (link_info.corder != (int64_t)(i + MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_NUM_LINKS)) {
            H5_FAILED();
            printf("    creation order value for moved link '%s' was not adjusted after move! It should "
                   "have been %lld but was %lld\n",
                   link_name, (long long)(i + MOVE_LINK_INTO_GRP_WITH_LINKS_TEST_NUM_LINKS),
                   (long long)link_info.corder);
            goto error;
        }
    }

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(dst_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(src_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(dst_grp_id);
        H5Gclose(src_grp_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the behavior of moving a link across files.
 * This should fail for hard links but succeed for soft and
 * external links (and user-defined links of those types).
 *
 * TODO: Ideally, tests should be written to verify that the
 *       moved links retain their original properties.
 */
static void
test_move_link_across_files(void H5_ATTR_UNUSED *params)
{
    TESTING("link moving across files");

    /* TODO */

    SKIPPED();

    return;
}

/*
 * A test to check that a group's always-increasing
 * maximum link creation order value gets reset once
 * all the links have been moved out of the group.
 */
static void
test_move_link_reset_grp_max_crt_order(void H5_ATTR_UNUSED *params)
{
    H5G_info_t grp_info;
    size_t     i;
    hid_t      file_id         = H5I_INVALID_HID;
    hid_t      container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t      src_grp_id = H5I_INVALID_HID, dst_grp_id = H5I_INVALID_HID;
    hid_t      gcpl_id = H5I_INVALID_HID;
    char       link_name[MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE];

    TESTING("H5Lmove of all links out of group resets group's maximum link creation order value");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_MORE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, hard link, or creation order aren't "
               "supported with this connector\n");
        return;
    }

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
        H5_FAILED();
        printf("    couldn't set link creation order tracking\n");
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container sub-group '%s'\n",
               MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((src_grp_id = H5Gcreate2(group_id, MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_SRC_GRP_NAME, H5P_DEFAULT,
                                 gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_SRC_GRP_NAME);
        goto error;
    }

    if ((dst_grp_id = H5Gcreate2(group_id, MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_DST_GRP_NAME, H5P_DEFAULT,
                                 gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_DST_GRP_NAME);
        goto error;
    }

    /* Create several links inside the source group */
    for (i = 0; i < MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS; i++) {
        snprintf(link_name, MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE, "link%d", (int)i);

        if (H5Lcreate_hard(src_grp_id, ".", src_grp_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("    couldn't create hard link '%s' in source group\n", link_name);
            goto error;
        }
    }

    /*
     * Move links out of the source group and into the destination group, checking the
     * source group's maximum creation order value each time.
     */
    for (i = 0; i < MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS; i++) {
        memset(&grp_info, 0, sizeof(grp_info));

        if (H5Gget_info(src_grp_id, &grp_info) < 0) {
            H5_FAILED();
            printf("    failed to retrieve source group's info\n");
            goto error;
        }

        if (grp_info.max_corder != MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS) {
            H5_FAILED();
            printf("    source group's maximum creation order value got adjusted to %lld during link "
                   "moving; value should have remained at %d\n",
                   (long long)grp_info.max_corder, MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS);
            goto error;
        }

        snprintf(link_name, MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_BUF_SIZE, "link%d", (int)i);

        if (H5Lmove(src_grp_id, link_name, dst_grp_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("    failed to move link '%s' to destination group\n", link_name);
            goto error;
        }
    }

    /*
     * Ensure the source group's maximum creation order value has now
     * reset to 0 after all the links have been moved out of it.
     */
    memset(&grp_info, 0, sizeof(grp_info));

    if (H5Gget_info(src_grp_id, &grp_info) < 0) {
        H5_FAILED();
        printf("    failed to retrieve source group's info\n");
        goto error;
    }

    if (grp_info.max_corder != 0) {
        H5_FAILED();
        printf("    source group's maximum creation order value didn't reset to 0 after moving all links "
               "out of it; value is still %lld\n",
               (long long)grp_info.max_corder);
        goto error;
    }

    /* For good measure, check that destination group's max. creation order value is as expected */
    memset(&grp_info, 0, sizeof(grp_info));

    if (H5Gget_info(dst_grp_id, &grp_info) < 0) {
        H5_FAILED();
        printf("    failed to retrieve destination group's info\n");
        goto error;
    }

    if (grp_info.max_corder != MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS) {
        H5_FAILED();
        printf("    destination group's maximum creation order value of %lld didn't match expected value "
               "of %d after moving all links into it\n",
               (long long)grp_info.max_corder, MOVE_LINK_RESET_MAX_CRT_ORDER_TEST_NUM_LINKS);
        goto error;
    }

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(dst_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(src_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(dst_grp_id);
        H5Gclose(src_grp_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that H5Lmove fails when it is given
 * invalid parameters.
 */
static void
test_move_link_invalid_params(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    herr_t err_ret         = -1;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  src_grp_id = H5I_INVALID_HID, dst_grp_id = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};
    hid_t  ext_file_id                                        = H5I_INVALID_HID;

    TESTING_MULTIPART("H5Lmove with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or hard link aren't supported with this "
               "connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, MOVE_LINK_INVALID_PARAMS_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_INVALID_PARAMS_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((src_grp_id = H5Gcreate2(group_id, MOVE_LINK_INVALID_PARAMS_TEST_SRC_GROUP_NAME, H5P_DEFAULT,
                                 H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_INVALID_PARAMS_TEST_SRC_GROUP_NAME);
        goto error;
    }

    if ((dst_grp_id = H5Gcreate2(group_id, MOVE_LINK_INVALID_PARAMS_TEST_DST_GROUP_NAME, H5P_DEFAULT,
                                 H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create group '%s'\n", MOVE_LINK_INVALID_PARAMS_TEST_DST_GROUP_NAME);
        goto error;
    }

    if (H5Lcreate_hard(group_id, ".", src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                       H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create hard link '%s'\n", MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if hard link '%s' exists\n",
               MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    hard link did not exist\n");
        goto error;
    }

    /* Verify the link doesn't currently exist in the target group */
    if ((link_exists = H5Lexists(dst_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if hard link '%s' exists\n",
               MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    if (link_exists) {
        H5_FAILED();
        printf("    hard link existed in target group before move!\n");
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lmove_invalid_src_loc_id)
        {
            TESTING_2("H5Lmove with an invalid source location ID");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(H5I_INVALID_HID, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id,
                                  MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded with an invalid source location ID!\n");
                PART_ERROR(H5Lmove_invalid_src_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lmove_invalid_src_loc_id);

        PART_BEGIN(H5Lmove_invalid_src_name)
        {
            TESTING_2("H5Lmove with an invalid source name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(src_grp_id, NULL, dst_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME,
                                  H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded with a NULL source name!\n");
                PART_ERROR(H5Lmove_invalid_src_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(src_grp_id, "", dst_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME,
                                  H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded with an invalid source name of ''!\n");
                PART_ERROR(H5Lmove_invalid_src_name);
            }

            PASSED();
        }
        PART_END(H5Lmove_invalid_src_name);

        PART_BEGIN(H5Lmove_invalid_dst_loc_id)
        {
            TESTING_2("H5Lmove with an invalid destination location ID");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5I_INVALID_HID,
                                  MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded with an invalid destination location ID!\n");
                PART_ERROR(H5Lmove_invalid_dst_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lmove_invalid_dst_loc_id);

        PART_BEGIN(H5Lmove_invalid_dst_name)
        {
            TESTING_2("H5Lmove with an invalid destination name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id, NULL,
                                  H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded with a NULL destination name!\n");
                PART_ERROR(H5Lmove_invalid_dst_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id, "",
                                  H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded with an invalid destination name of ''!\n");
                PART_ERROR(H5Lmove_invalid_dst_name);
            }

            PASSED();
        }
        PART_END(H5Lmove_invalid_dst_name);

        PART_BEGIN(H5Lmove_invalid_lcpl)
        {
            TESTING_2("H5Lmove with an invalid LCPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id,
                                  MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5I_INVALID_HID, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded with an invalid LCPL!\n");
                PART_ERROR(H5Lmove_invalid_lcpl);
            }

            PASSED();
        }
        PART_END(H5Lmove_invalid_lcpl);

        PART_BEGIN(H5Lmove_invalid_lapl)
        {
            TESTING_2("H5Lmove with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, dst_grp_id,
                                  MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded with an invalid LAPL!\n");
                PART_ERROR(H5Lmove_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lmove_invalid_lapl);

        PART_BEGIN(H5Lmove_existence)
        {
            TESTING_2("valid link existence in original group after previous invalid H5Lmove calls");

            /* Verify the link hasn't been moved */
            if ((link_exists =
                     H5Lexists(src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_existence);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link didn't exist in source group after invalid move!\n");
                PART_ERROR(H5Lmove_existence);
            }

            if ((link_exists =
                     H5Lexists(dst_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_existence);
            }

            if (link_exists) {
                H5_FAILED();
                printf("    hard link existed in target group after invalid move!\n");
                PART_ERROR(H5Lmove_existence);
            }

            PASSED();
        }
        PART_END(H5Lmove_existence);

        PART_BEGIN(H5Lmove_same_location)
        {
            TESTING_2("H5Lmove with an invalid same location");

            /* Move a group within the file.  Both of source and destination use
             * H5L_SAME_LOC.  Should fail. */
            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(H5L_SAME_LOC, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5L_SAME_LOC,
                                  MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded with an invalid same location!\n");
                PART_ERROR(H5Lmove_same_location);
            }

            PASSED();
        }
        PART_END(H5Lmove_same_location);

        PART_BEGIN(H5Lmove_across_files)
        {
            TESTING_2("H5Lmove into another file");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lmove_across_files);
            }

            /* Move a group across files. */
            H5E_BEGIN_TRY
            {
                err_ret = H5Lmove(src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, ext_file_id,
                                  MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lmove succeeded in moving a hard link across files!\n");
                PART_ERROR(H5Lmove_across_files);
            }

            /* Ensure that original link still exists */
            if ((link_exists =
                     H5Lexists(src_grp_id, MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if original link '%s' exists after invalid link move\n",
                       MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_across_files);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    original link '%s' didn't exist after failed move!\n",
                       MOVE_LINK_INVALID_PARAMS_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lmove_across_files);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    failed to close a file!\n");
                PART_ERROR(H5Lmove_across_files);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lmove_across_files);
            }

            PASSED();
        }
        PART_END(H5Lmove_across_files);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Gclose(dst_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(src_grp_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Gclose(dst_grp_id);
        H5Gclose(src_grp_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(ext_file_id);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a soft or external link's value can
 * be retrieved by using H5Lget_val and H5Lget_val_by_idx.
 */
static void
test_get_link_val(void H5_ATTR_UNUSED *params)
{
    H5L_info2_t link_info;
    const char *ext_link_filepath;
    const char *ext_link_val;
    unsigned    ext_link_flags;
    htri_t      link_exists;
    size_t      link_val_size;
    char        link_val_buf[GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE];
    hid_t       file_id = H5I_INVALID_HID, ext_file_id = H5I_INVALID_HID;
    hid_t       container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t       subgroup_id                                        = H5I_INVALID_HID;
    hid_t       gcpl_id                                            = H5I_INVALID_HID;
    char        ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link value retrieval");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, soft link, external link, or creation "
               "order aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
            H5_FAILED();
            printf("    couldn't set link creation order tracking\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, GET_LINK_VAL_TEST_SUBGROUP_NAME, H5P_DEFAULT, gcpl_id,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lget_val_soft)
        {
            const char *link_target = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME;

            TESTING_2("H5Lget_val on soft link");

            memset(&link_info, 0, sizeof(link_info));

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP1_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP1_NAME);
                PART_ERROR(H5Lget_val_soft);
            }

            if (H5Lcreate_soft(link_target, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_soft);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_soft);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_soft);
            }

            if (H5Lget_info2(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, &link_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info\n");
                PART_ERROR(H5Lget_val_soft);
            }

            link_val_size = strlen(link_target) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu did not match expected size of %zu\n", link_info.u.val_size,
                       link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (H5Lget_val(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, link_val_buf,
                           GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value\n");
                PART_ERROR(H5Lget_val_soft);
            }

            if (strncmp(link_val_buf, link_target, link_val_size)) {
                H5_FAILED();
                printf("    soft link value did not match\n");
                PART_ERROR(H5Lget_val_soft);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP1_NAME);
                PART_ERROR(H5Lget_val_soft);
            }

            PASSED();
        }
        PART_END(H5Lget_val_soft);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_external)
        {
            const char *ext_obj_name = "/";

            TESTING_2("H5Lget_val on external link");

            memset(&link_info, 0, sizeof(link_info));

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_val_external);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_external);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP2_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP2_NAME);
                PART_ERROR(H5Lget_val_external);
            }

            if (H5Lcreate_external(ext_link_filename, ext_obj_name, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_external);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_external);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_external);
            }

            if (H5Lget_info2(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME, &link_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info\n");
                PART_ERROR(H5Lget_val_external);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu did not match expected size of %zu\n", link_info.u.val_size,
                       link_val_size);
                PART_ERROR(H5Lget_val_external);
            }

            if (H5Lget_val(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME, link_val_buf,
                           GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value\n");
                PART_ERROR(H5Lget_val_external);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_external);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_external);
            }

            if (strncmp(ext_link_val, ext_obj_name, strlen(ext_obj_name) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name);
                PART_ERROR(H5Lget_val_external);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP2_NAME);
                PART_ERROR(H5Lget_val_external);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_external);
            }

            PASSED();
        }
        PART_END(H5Lget_val_external);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_ud)
        {
            TESTING_2("H5Lget_val on user-defined link");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lget_val_ud);
        }
        PART_END(H5Lget_val_ud);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_soft_crt_order_increasing)
        {
            const char *link_target_a = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP4_NAME "A";
            const char *link_target_b = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP4_NAME "B";
            const char *link_target_c = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP4_NAME "C";

            TESTING_2("H5Lget_val_by_idx on soft link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP4_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP4_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft(link_target_a, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (H5Lcreate_soft(link_target_b, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (H5Lcreate_soft(link_target_c, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            /* Verify the links exist */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            /* Retrieve the info and value of each link in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            link_val_size = strlen(link_target_a) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 0, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (strncmp(link_val_buf, link_target_a, strlen(link_target_a) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 0, link_target_a);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            link_val_size = strlen(link_target_b) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 1, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (strncmp(link_val_buf, link_target_b, strlen(link_target_b) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 1, link_target_b);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            link_val_size = strlen(link_target_c) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 2, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (strncmp(link_val_buf, link_target_c, strlen(link_target_c) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 2, link_target_c);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP4_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_soft_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_soft_crt_order_decreasing)
        {
            const char *link_target_a = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP5_NAME "A";
            const char *link_target_b = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP5_NAME "B";
            const char *link_target_c = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP5_NAME "C";

            TESTING_2("H5Lget_val_by_idx on soft link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP5_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP5_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft(link_target_a, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lcreate_soft(link_target_b, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lcreate_soft(link_target_c, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            /* Verify the links exist */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            /* Retrieve the info and value of each link in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            link_val_size = strlen(link_target_a) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 2, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if (strncmp(link_val_buf, link_target_a, strlen(link_target_a) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 2, link_target_a);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            link_val_size = strlen(link_target_b) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 1, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if (strncmp(link_val_buf, link_target_b, strlen(link_target_b) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 1, link_target_b);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            link_val_size = strlen(link_target_c) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 0, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if (strncmp(link_val_buf, link_target_c, strlen(link_target_c) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 0, link_target_c);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP5_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_soft_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_soft_name_order_increasing)
        {
            const char *link_target_a = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP6_NAME "A";
            const char *link_target_b = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP6_NAME "B";
            const char *link_target_c = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP6_NAME "C";

            TESTING_2("H5Lget_val_by_idx on soft link by alphabetical order in increasing order");

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP6_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP6_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft(link_target_a, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if (H5Lcreate_soft(link_target_b, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if (H5Lcreate_soft(link_target_c, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            /* Verify the links exist */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            /* Retrieve the info and value of each link in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            link_val_size = strlen(link_target_a) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 0, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if (strncmp(link_val_buf, link_target_a, strlen(link_target_a) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 0, link_target_a);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            link_val_size = strlen(link_target_b) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 1, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if (strncmp(link_val_buf, link_target_b, strlen(link_target_b) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 1, link_target_b);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            link_val_size = strlen(link_target_c) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 2, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if (strncmp(link_val_buf, link_target_c, strlen(link_target_c) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 2, link_target_c);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP6_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_soft_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_soft_name_order_decreasing)
        {
            const char *link_target_a = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP7_NAME "A";
            const char *link_target_b = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP7_NAME "B";
            const char *link_target_c = "/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_TEST_SUBGROUP_NAME
                                        "/" GET_LINK_VAL_TEST_SUBGROUP7_NAME "C";

            TESTING_2("H5Lget_val_by_idx on soft link by alphabetical order in decreasing order");

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP7_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP7_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft(link_target_a, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if (H5Lcreate_soft(link_target_b, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if (H5Lcreate_soft(link_target_c, subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            /* Verify the links exist */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            /* Retrieve the info and value of each link in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            link_val_size = strlen(link_target_a) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 2, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if (strncmp(link_val_buf, link_target_a, strlen(link_target_a) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 2, link_target_a);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            link_val_size = strlen(link_target_b) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 1, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if (strncmp(link_val_buf, link_target_b, strlen(link_target_b) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 1, link_target_b);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve soft link's info at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            link_val_size = strlen(link_target_c) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 0, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link value at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if (strncmp(link_val_buf, link_target_c, strlen(link_target_c) + 1)) {
                H5_FAILED();
                printf("    link value '%s' for link at index %d did not match expected value '%s'\n",
                       link_val_buf, 0, link_target_c);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP7_NAME);
                PART_ERROR(H5Lget_val_by_idx_soft_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_soft_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_external_crt_order_increasing)
        {
            const char *ext_obj_name_a = "/A";
            const char *ext_obj_name_b = "/B";
            const char *ext_obj_name_c = "/C";

            TESTING_2("H5Lget_val_by_idx on external link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP8_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP8_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, ext_obj_name_a, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_obj_name_b, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_obj_name_c, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            /* Verify the links exist */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            /* Retrieve the info and value of each link in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_a) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 0, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_a, strlen(ext_obj_name_a) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_a);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_b) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 1, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_b, strlen(ext_obj_name_b) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_b);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_c) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 2, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_c, strlen(ext_obj_name_c) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_c);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP8_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_external_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_external_crt_order_decreasing)
        {
            const char *ext_obj_name_a = "/A";
            const char *ext_obj_name_b = "/B";
            const char *ext_obj_name_c = "/C";

            TESTING_2("H5Lget_val_by_idx on external link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP9_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP9_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, ext_obj_name_a, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_obj_name_b, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_obj_name_c, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            /* Verify the links exist */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            /* Retrieve the info and value of each link in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_a) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d not match expected size of %zu\n",
                       link_info.u.val_size, 2, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_a, strlen(ext_obj_name_a) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_a);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_b) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 1, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_b, strlen(ext_obj_name_b) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_b);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_c) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 0, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_c, strlen(ext_obj_name_c) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_c);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP9_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_external_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_external_name_order_increasing)
        {
            const char *ext_obj_name_a = "/A";
            const char *ext_obj_name_b = "/B";
            const char *ext_obj_name_c = "/C";

            TESTING_2("H5Lget_val_by_idx on external link by alphabetical order in increasing order");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP10_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP10_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, ext_obj_name_a, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_obj_name_b, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_obj_name_c, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            /* Verify the links exist */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            /* Retrieve the info and value of each link in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_a) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 0, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_a, strlen(ext_obj_name_a) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_a);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_b) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 1, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_b, strlen(ext_obj_name_b) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_b);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_c) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 2, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_c, strlen(ext_obj_name_c) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_c);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP10_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_external_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_external_name_order_decreasing)
        {
            const char *ext_obj_name_a = "/A";
            const char *ext_obj_name_b = "/B";
            const char *ext_obj_name_c = "/C";

            TESTING_2("H5Lget_val_by_idx on external link by alphabetical order in decreasing order");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_VAL_TEST_SUBGROUP11_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_VAL_TEST_SUBGROUP11_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, ext_obj_name_a, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_obj_name_b, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_obj_name_c, subgroup_id,
                                   GET_LINK_VAL_TEST_EXT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            /* Verify the links exist */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_VAL_TEST_EXT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", GET_LINK_VAL_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            /* Retrieve the info and value of each link in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_a) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 2, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 2);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_a, strlen(ext_obj_name_a) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_a);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_b) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 1, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 1);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_b, strlen(ext_obj_name_b) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_b);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve external link's info at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_obj_name_c) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link value size %zu for link at index %d did not match expected size of %zu\n",
                       link_info.u.val_size, 0, link_val_size);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            memset(link_val_buf, 0, GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE);
            if (H5Lget_val_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, link_val_buf,
                                  GET_LINK_VAL_TEST_LINK_VAL_BUF_SIZE, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link value at index %d\n", 0);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (H5Lunpack_elink_val(link_val_buf, link_info.u.val_size, &ext_link_flags, &ext_link_filepath,
                                    &ext_link_val) < 0) {
                H5_FAILED();
                printf("    couldn't unpack external link value buffer\n");
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (strncmp(ext_link_filepath, ext_link_filename, strlen(ext_link_filename) + 1)) {
                H5_FAILED();
                printf("    external link target file '%s' did not match expected '%s'\n", ext_link_filepath,
                       ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (strncmp(ext_link_val, ext_obj_name_c, strlen(ext_obj_name_c) + 1)) {
                H5_FAILED();
                printf("    external link value '%s' did not match expected '%s'\n", ext_link_val,
                       ext_obj_name_c);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_VAL_TEST_SUBGROUP11_NAME);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_val_by_idx_external_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_external_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_ud_crt_order_increasing)
        {
            TESTING_2("H5Lget_val_by_idx on user-defined link by creation order in increasing order");

            SKIPPED();
            PART_EMPTY(H5Lget_val_by_idx_ud_crt_order_increasing);
        }
        PART_END(H5Lget_val_by_idx_ud_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_ud_crt_order_decreasing)
        {
            TESTING_2("H5Lget_val_by_idx on user-defined link by creation order in decreasing order");

            SKIPPED();
            PART_EMPTY(H5Lget_val_by_idx_ud_crt_order_decreasing);
        }
        PART_END(H5Lget_val_by_idx_ud_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_ud_name_order_increasing)
        {
            TESTING_2("H5Lget_val_by_idx on user-defined link by alphabetical order in increasing order");

            SKIPPED();
            PART_EMPTY(H5Lget_val_by_idx_ud_name_order_increasing);
        }
        PART_END(H5Lget_val_by_idx_ud_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_val_by_idx_ud_name_order_decreasing)
        {
            TESTING_2("H5Lget_val_by_idx on user-defined link by alphabetical order in decreasing order");

            SKIPPED();
            PART_EMPTY(H5Lget_val_by_idx_ud_name_order_decreasing);
        }
        PART_END(H5Lget_val_by_idx_ud_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(ext_file_id);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a soft or external link's value can't be
 * retrieved when H5Lget_val(_by_idx) is passed invalid parameters.
 */
static void
test_get_link_val_invalid_params(void H5_ATTR_UNUSED *params)
{
    H5L_info2_t link_info;
    htri_t      link_exists;
    herr_t      err_ret           = -1;
    size_t      link_val_buf_size = 0;
    char       *link_val_buf      = NULL;
    hid_t       file_id           = H5I_INVALID_HID;
    hid_t       container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t       gcpl_id = H5I_INVALID_HID;

    TESTING_MULTIPART("link value retrieval with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, soft link, external link, or creation "
               "order aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, GET_LINK_VAL_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT,
                               gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", GET_LINK_VAL_INVALID_PARAMS_TEST_GROUP_NAME);
        goto error;
    }

    if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_VAL_INVALID_PARAMS_TEST_GROUP_NAME, group_id,
                       GET_LINK_VAL_INVALID_PARAMS_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", GET_LINK_VAL_INVALID_PARAMS_TEST_SOFT_LINK_NAME);
        goto error;
    }

    /* Verify the links have been created */
    if ((link_exists = H5Lexists(group_id, GET_LINK_VAL_INVALID_PARAMS_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n",
               GET_LINK_VAL_INVALID_PARAMS_TEST_SOFT_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    link_val_buf_size = 100;
    if (NULL == (link_val_buf = (char *)malloc(link_val_buf_size))) {
        H5_FAILED();
        printf("    couldn't allocate buffer for storing link value\n");
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lget_val_invalid_loc_id)
        {
            TESTING_2("H5Lget_val with an invalid location ID");

            memset(&link_info, 0, sizeof(link_info));

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val(H5I_INVALID_HID, GET_LINK_VAL_INVALID_PARAMS_TEST_SOFT_LINK_NAME,
                                     link_val_buf, link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val succeeded with an invalid location ID\n");
                PART_ERROR(H5Lget_val_invalid_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lget_val_invalid_loc_id);

        PART_BEGIN(H5Lget_val_invalid_link_name)
        {
            TESTING_2("H5Lget_val with an invalid link name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val(group_id, NULL, link_val_buf, link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val succeeded with a NULL link name\n");
                PART_ERROR(H5Lget_val_invalid_link_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val(group_id, "", link_val_buf, link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val succeeded with an invalid link name of ''\n");
                PART_ERROR(H5Lget_val_invalid_link_name);
            }

            PASSED();
        }
        PART_END(H5Lget_val_invalid_link_name);

        PART_BEGIN(H5Lget_val_invalid_lapl)
        {
            TESTING_2("H5Lget_val with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val(group_id, GET_LINK_VAL_INVALID_PARAMS_TEST_SOFT_LINK_NAME, link_val_buf,
                                     link_val_buf_size, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val succeeded with an invalid LAPL\n");
                PART_ERROR(H5Lget_val_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lget_val_invalid_lapl);

        PART_BEGIN(H5Lget_val_by_idx_invalid_loc_id)
        {
            TESTING_2("H5Lget_val_by_idx with an invalid location ID");

            memset(&link_info, 0, sizeof(link_info));

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val_by_idx(H5I_INVALID_HID, ".", H5_INDEX_NAME, H5_ITER_INC, 0, link_val_buf,
                                            link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val_by_idx succeeded with an invalid location ID!\n");
                PART_ERROR(H5Lget_val_by_idx_invalid_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_invalid_loc_id);

        PART_BEGIN(H5Lget_val_by_idx_invalid_grp_name)
        {
            TESTING_2("H5Lget_val_by_idx with an invalid group name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val_by_idx(group_id, NULL, H5_INDEX_NAME, H5_ITER_INC, 0, link_val_buf,
                                            link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val_by_idx succeeded with a NULL group name!\n");
                PART_ERROR(H5Lget_val_by_idx_invalid_grp_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val_by_idx(group_id, "", H5_INDEX_NAME, H5_ITER_INC, 0, link_val_buf,
                                            link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val_by_idx succeeded with an invalid group name of ''!\n");
                PART_ERROR(H5Lget_val_by_idx_invalid_grp_name);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_invalid_grp_name);

        PART_BEGIN(H5Lget_val_by_idx_invalid_index_type)
        {
            TESTING_2("H5Lget_val_by_idx with an invalid index type");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val_by_idx(group_id, ".", H5_INDEX_UNKNOWN, H5_ITER_INC, 0, link_val_buf,
                                            link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val_by_idx succeeded with invalid index type H5_INDEX_UNKNOWN!\n");
                PART_ERROR(H5Lget_val_by_idx_invalid_index_type);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val_by_idx(group_id, ".", H5_INDEX_N, H5_ITER_INC, 0, link_val_buf,
                                            link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val_by_idx succeeded with invalid index type H5_INDEX_N!\n");
                PART_ERROR(H5Lget_val_by_idx_invalid_index_type);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_invalid_index_type);

        PART_BEGIN(H5Lget_val_by_idx_invalid_iter_order)
        {
            TESTING_2("H5Lget_val_by_idx with an invalid iteration ordering");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_UNKNOWN, 0, link_val_buf,
                                            link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val_by_idx succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n");
                PART_ERROR(H5Lget_val_by_idx_invalid_iter_order);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_N, 0, link_val_buf,
                                            link_val_buf_size, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val_by_idx succeeded with invalid iteration ordering H5_ITER_N!\n");
                PART_ERROR(H5Lget_val_by_idx_invalid_iter_order);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_invalid_iter_order);

        PART_BEGIN(H5Lget_val_by_idx_invalid_lapl)
        {
            TESTING_2("H5Lget_val_by_idx with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_val_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, link_val_buf,
                                            link_val_buf_size, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_val_by_idx succeeded with an invalid LAPL!\n");
                PART_ERROR(H5Lget_val_by_idx_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lget_val_by_idx_invalid_lapl);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (link_val_buf) {
        free(link_val_buf);
        link_val_buf = NULL;
    }

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        if (link_val_buf)
            free(link_val_buf);
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of H5Lget_info2 and
 * H5Lget_info_by_idx2.
 */
static void
test_get_link_info(void H5_ATTR_UNUSED *params)
{
    H5L_info2_t link_info;
    const char *ext_objname = "/";
    htri_t      link_exists;
    size_t      link_val_size;
    hid_t       file_id = H5I_INVALID_HID, ext_file_id = H5I_INVALID_HID;
    hid_t       container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t       subgroup_id                                        = H5I_INVALID_HID;
    hid_t       gcpl_id                                            = H5I_INVALID_HID;
    char        ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link info retrieval");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, soft link, hard link, or external link "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
            H5_FAILED();
            printf("    couldn't set link creation order tracking\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, GET_LINK_INFO_TEST_GROUP_NAME, H5P_DEFAULT, gcpl_id,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", GET_LINK_INFO_TEST_GROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lget_info_hard)
        {
            TESTING_2("H5Lget_info2 on hard link");

            memset(&link_info, 0, sizeof(link_info));

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP1_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP1_NAME);
                PART_ERROR(H5Lget_info_hard);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_hard);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_hard);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link did not exist\n");
                PART_ERROR(H5Lget_info_hard);
            }

            if (H5Lget_info2(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, &link_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info\n");
                PART_ERROR(H5Lget_info_hard);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_hard);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 0)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)0);
                    PART_ERROR(H5Lget_info_hard);
                }
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP1_NAME);
                PART_ERROR(H5Lget_info_hard);
            }

            PASSED();
        }
        PART_END(H5Lget_info_hard);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_soft)
        {
            TESTING_2("H5Lget_info2 on soft link");

            memset(&link_info, 0, sizeof(link_info));

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP2_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP2_NAME);
                PART_ERROR(H5Lget_info_soft);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP2_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_soft);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_soft);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link did not exist\n");
                PART_ERROR(H5Lget_info_soft);
            }

            if (H5Lget_info2(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, &link_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info\n");
                PART_ERROR(H5Lget_info_soft);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_soft);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP2_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_soft);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 0)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)0);
                    PART_ERROR(H5Lget_info_soft);
                }
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP2_NAME);
                PART_ERROR(H5Lget_info_soft);
            }

            PASSED();
        }
        PART_END(H5Lget_info_soft);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_external)
        {
            TESTING_2("H5Lget_info2 on external link");

            memset(&link_info, 0, sizeof(link_info));

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_info_external);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_external);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP3_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP3_NAME);
                PART_ERROR(H5Lget_info_external);
            }

            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_external);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_external);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link did not exist\n");
                PART_ERROR(H5Lget_info_external);
            }

            if (H5Lget_info2(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME, &link_info, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info\n");
                PART_ERROR(H5Lget_info_external);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_external);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_external);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 0)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)0);
                    PART_ERROR(H5Lget_info_external);
                }
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP3_NAME);
                PART_ERROR(H5Lget_info_external);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_external);
            }

            PASSED();
        }
        PART_END(H5Lget_info_external);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_ud)
        {
            TESTING_2("H5Lget_info2 on user-defined link");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lget_info_ud);
        }
        PART_END(H5Lget_info_ud);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_hard_crt_order_increasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on hard link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP5_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP5_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (link_info.corder_valid && (link_info.corder != 0)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)0);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (link_info.corder_valid && (link_info.corder != 1)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)1);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (link_info.corder_valid && (link_info.corder != 2)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP5_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_hard_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_hard_crt_order_decreasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on hard link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP6_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP6_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (link_info.corder_valid && (link_info.corder != 0)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)0);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (link_info.corder_valid && (link_info.corder != 1)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)1);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (link_info.corder_valid && (link_info.corder != 2)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)2);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP6_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_hard_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_hard_name_order_increasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on hard link by alphabetical order in increasing order");

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP7_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP7_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 0)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)0);
                    PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 1)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)1);
                    PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 2)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)2);
                    PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
                }
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP7_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_hard_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_hard_name_order_decreasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on hard link by alphabetical order in decreasing order");

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP8_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP8_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 0)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)0);
                    PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 1)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)1);
                    PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get hard link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_HARD) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 2)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)2);
                    PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
                }
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP8_NAME);
                PART_ERROR(H5Lget_info_by_idx_hard_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_hard_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_soft_crt_order_increasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on soft link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP9_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP9_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP9_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP9_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP9_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP9_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (link_info.corder_valid && (link_info.corder != 0)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)0);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP9_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (link_info.corder_valid && (link_info.corder != 1)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)1);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP9_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (link_info.corder_valid && (link_info.corder != 2)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP9_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_soft_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_soft_crt_order_decreasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on soft link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP10_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP10_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP10_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP10_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP10_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP10_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (link_info.corder_valid && (link_info.corder != 0)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)0);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP10_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (link_info.corder_valid && (link_info.corder != 1)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)1);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP10_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (link_info.corder_valid && (link_info.corder != 2)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)2);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP10_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_soft_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_soft_name_order_increasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on soft link by alphabetical order in increasing order");

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP11_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP11_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP11_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP11_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP11_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP11_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 0)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)0);
                    PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP11_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 1)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)1);
                    PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP11_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%zu' did not match expected value '%zu'\n",
                       link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 2)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)2);
                    PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
                }
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP11_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_soft_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_soft_name_order_decreasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on soft link by alphabetical order in decreasing order");

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP12_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP12_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP12_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP12_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                               "/" GET_LINK_INFO_TEST_SUBGROUP12_NAME,
                               subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP12_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 0)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)0);
                    PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP12_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 1)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)1);
                    PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get soft link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_SOFT) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            link_val_size = strlen("/" LINK_TEST_GROUP_NAME "/" GET_LINK_INFO_TEST_GROUP_NAME
                                   "/" GET_LINK_INFO_TEST_SUBGROUP12_NAME) +
                            1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 2)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)2);
                    PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
                }
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP12_NAME);
                PART_ERROR(H5Lget_info_by_idx_soft_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_soft_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_external_crt_order_increasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on external link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP13_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP13_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (link_info.corder_valid && (link_info.corder != 0)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)0);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (link_info.corder_valid && (link_info.corder != 1)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)1);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (link_info.corder_valid && (link_info.corder != 2)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP13_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_external_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_external_crt_order_decreasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on external link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP14_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP14_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (link_info.corder_valid && (link_info.corder != 0)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)0);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (link_info.corder_valid && (link_info.corder != 1)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)1);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (link_info.corder_valid && (link_info.corder != 2)) {
                H5_FAILED();
                printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                       (long long)link_info.corder, (long long)2);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP14_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_external_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_external_name_order_increasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on external link by alphabetical order in increasing order");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP15_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP15_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 0)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)0);
                    PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 1)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)1);
                    PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 2)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)2);
                    PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
                }
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP15_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_external_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_external_name_order_decreasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on external link by alphabetical order in decreasing order");

            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_INFO_TEST_SUBGROUP16_NAME, H5P_DEFAULT, gcpl_id,
                                          H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create subgroup '%s'\n", GET_LINK_INFO_TEST_SUBGROUP16_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, ext_objname, subgroup_id,
                                   GET_LINK_INFO_TEST_EXT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME2);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_INFO_TEST_EXT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before deletion\n",
                       GET_LINK_INFO_TEST_EXT_LINK_NAME3);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            /* Retrieve info of links in turn */
            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 2);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 0)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)0);
                    PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 1);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 1)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)1);
                    PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
                }
            }

            memset(&link_info, 0, sizeof(link_info));
            if (H5Lget_info_by_idx2(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, &link_info,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't get external link info for index %d\n", 0);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (link_info.type != H5L_TYPE_EXTERNAL) {
                H5_FAILED();
                printf("    incorrect link type returned\n");
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            link_val_size = 1 + strlen(ext_link_filename) + 1 + strlen(ext_objname) + 1;
            if (link_info.u.val_size != link_val_size) {
                H5_FAILED();
                printf("    link's value size '%lld' did not match expected value '%zu'\n",
                       (long long)link_info.u.val_size, link_val_size);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
                if (link_info.corder_valid && (link_info.corder != 2)) {
                    H5_FAILED();
                    printf("    link's creation order value '%lld' did not match expected value '%lld'\n",
                           (long long)link_info.corder, (long long)2);
                    PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
                }
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group '%s'\n", GET_LINK_INFO_TEST_SUBGROUP16_NAME);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_info_by_idx_external_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_external_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_ud_crt_order_increasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on user-defined link by creation order in increasing order");

            SKIPPED();
            PART_EMPTY(H5Lget_info_by_idx_ud_crt_order_increasing);
        }
        PART_END(H5Lget_info_by_idx_ud_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_ud_crt_order_decreasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on user-defined link by creation order in decreasing order");

            SKIPPED();
            PART_EMPTY(H5Lget_info_by_idx_ud_crt_order_decreasing);
        }
        PART_END(H5Lget_info_by_idx_ud_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_ud_name_order_increasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on user-defined link by alphabetical order in increasing order");

            SKIPPED();
            PART_EMPTY(H5Lget_info_by_idx_ud_name_order_increasing);
        }
        PART_END(H5Lget_info_by_idx_ud_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_info_by_idx_ud_name_order_decreasing)
        {
            TESTING_2("H5Lget_info_by_idx2 on user-defined link by alphabetical order in decreasing order");

            SKIPPED();
            PART_EMPTY(H5Lget_info_by_idx_ud_name_order_decreasing);
        }
        PART_END(H5Lget_info_by_idx_ud_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(ext_file_id);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a link's info can't be retrieved
 * when H5Lget_info(_by_idx)2 is passed invalid parameters.
 */
static void
test_get_link_info_invalid_params(void H5_ATTR_UNUSED *params)
{
    H5L_info2_t link_info;
    herr_t      err_ret = -1;
    htri_t      link_exists;
    hid_t       file_id         = H5I_INVALID_HID;
    hid_t       container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t       gcpl_id = H5I_INVALID_HID;

    TESTING_MULTIPART("link info retrieval with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, or hard link "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, GET_LINK_INFO_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT,
                               gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", GET_LINK_INFO_INVALID_PARAMS_TEST_GROUP_NAME);
        goto error;
    }

    if (H5Lcreate_hard(group_id, ".", group_id, GET_LINK_INFO_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                       H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create hard link '%s'\n", GET_LINK_INFO_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, GET_LINK_INFO_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if hard link '%s' exists\n",
               GET_LINK_INFO_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    hard link did not exist\n");
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lget_info_invalid_loc_id)
        {
            TESTING_2("H5Lget_info2 with an invalid location ID");

            memset(&link_info, 0, sizeof(link_info));

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_info2(H5I_INVALID_HID, GET_LINK_INFO_INVALID_PARAMS_TEST_HARD_LINK_NAME,
                                       &link_info, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info2 succeeded with an invalid location ID!\n");
                PART_ERROR(H5Lget_info_invalid_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lget_info_invalid_loc_id);

        PART_BEGIN(H5Lget_info_invalid_link_name)
        {
            TESTING_2("H5Lget_info2 with an invalid link name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_info2(group_id, NULL, &link_info, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info2 succeeded with a NULL link name!\n");
                PART_ERROR(H5Lget_info_invalid_link_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_info2(group_id, "", &link_info, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info2 succeeded with an invalid link name of ''!\n");
                PART_ERROR(H5Lget_info_invalid_link_name);
            }

            PASSED();
        }
        PART_END(H5Lget_info_invalid_link_name);

        PART_BEGIN(H5Lget_info_invalid_lapl)
        {
            TESTING_2("H5Lget_info2 with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_info2(group_id, GET_LINK_INFO_INVALID_PARAMS_TEST_HARD_LINK_NAME, &link_info,
                                       H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info2 succeeded with an invalid LAPL!\n");
                PART_ERROR(H5Lget_info_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lget_info_invalid_lapl);

        memset(&link_info, 0, sizeof(link_info));

        PART_BEGIN(H5Lget_info_by_idx_invalid_loc_id)
        {
            TESTING_2("H5Lget_info_by_idx2 with an invalid location ID");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_info_by_idx2(H5I_INVALID_HID, ".", H5_INDEX_NAME, H5_ITER_INC, 0, &link_info,
                                              H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info_by_idx2 succeeded with an invalid location ID!\n");
                PART_ERROR(H5Lget_info_by_idx_invalid_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_invalid_loc_id);

        PART_BEGIN(H5Lget_info_by_idx_invalid_grp_name)
        {
            TESTING_2("H5Lget_info_by_idx2 with an invalid group name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_info_by_idx2(group_id, NULL, H5_INDEX_NAME, H5_ITER_INC, 0, &link_info,
                                              H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info_by_idx2 succeeded with a NULL group name!\n");
                PART_ERROR(H5Lget_info_by_idx_invalid_grp_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lget_info_by_idx2(group_id, "", H5_INDEX_NAME, H5_ITER_INC, 0, &link_info, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info_by_idx2 succeeded with an invalid group name of ''!\n");
                PART_ERROR(H5Lget_info_by_idx_invalid_grp_name);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_invalid_grp_name);

        PART_BEGIN(H5Lget_info_by_idx_invalid_index_type)
        {
            TESTING_2("H5Lget_info_by_idx2 with an invalid index type");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_info_by_idx2(group_id, ".", H5_INDEX_UNKNOWN, H5_ITER_INC, 0, &link_info,
                                              H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info_by_idx2 succeeded with invalid index type H5_INDEX_UNKNOWN!\n");
                PART_ERROR(H5Lget_info_by_idx_invalid_index_type);
            }

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lget_info_by_idx2(group_id, ".", H5_INDEX_N, H5_ITER_INC, 0, &link_info, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info_by_idx2 succeeded with invalid index type H5_INDEX_N!\n");
                PART_ERROR(H5Lget_info_by_idx_invalid_index_type);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_invalid_index_type);

        PART_BEGIN(H5Lget_info_by_idx_invalid_iter_order)
        {
            TESTING_2("H5Lget_info_by_idx2 with an invalid iteration ordering");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_UNKNOWN, 0, &link_info,
                                              H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf(
                    "    H5Lget_info_by_idx2 succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n");
                PART_ERROR(H5Lget_info_by_idx_invalid_iter_order);
            }

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_N, 0, &link_info, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info_by_idx2 succeeded with invalid iteration ordering H5_ITER_N!\n");
                PART_ERROR(H5Lget_info_by_idx_invalid_iter_order);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_invalid_iter_order);

        PART_BEGIN(H5Lget_info_by_idx_invalid_lapl)
        {
            TESTING_2("H5Lget_info_by_idx2 with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lget_info_by_idx2(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, &link_info,
                                              H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_info_by_idx2 succeeded with an invalid LAPL!\n");
                PART_ERROR(H5Lget_info_by_idx_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lget_info_by_idx_invalid_lapl);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a link's name can be correctly
 * retrieved by using H5Lget_name_by_idx.
 */
static void
test_get_link_name(void H5_ATTR_UNUSED *params)
{
    ssize_t link_name_buf_size = 0;
    htri_t  link_exists;
    hid_t   file_id = H5I_INVALID_HID, ext_file_id = H5I_INVALID_HID;
    hid_t   container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t   subgroup_id = H5I_INVALID_HID;
    hid_t   gcpl_id     = H5I_INVALID_HID;
    char    link_name_buf[GET_LINK_NAME_TEST_BUF_SIZE];
    char    ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link name retrieval");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, soft link, hard link, or external link "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
            H5_FAILED();
            printf("    couldn't set link creation order tracking\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, GET_LINK_NAME_TEST_GROUP_NAME, H5P_DEFAULT, gcpl_id,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", GET_LINK_NAME_TEST_GROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lget_name_by_idx_hard_crt_order_increasing)
        {
            TESTING_2("H5Lget_name_by_idx on hard link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            /* Create several hard links in reverse order to test creation order */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_hard_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_hard_crt_order_decreasing)
        {
            TESTING_2("H5Lget_name_by_idx on hard link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME2, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            /* Create several hard links in reverse order to test creation order */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_hard_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_hard_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_hard_name_order_increasing)
        {
            TESTING_2("H5Lget_name_by_idx on hard link by alphabetical order in increasing order");

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME3, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_hard_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_hard_name_order_decreasing)
        {
            TESTING_2("H5Lget_name_by_idx on hard link by alphabetical order in decreasing order");

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME4, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_HARD_SUBGROUP_NAME4);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            /* Create several hard links */
            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME2, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME3, H5P_DEFAULT,
                               H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create hard link '%s'\n", GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_HARD_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if hard link '%s' exists\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    hard link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_HARD_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_HARD_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_HARD_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_hard_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_hard_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_soft_crt_order_increasing)
        {
            TESTING_2("H5Lget_name_by_idx on soft link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            /* Create several soft links in reverse order to test creation order */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_soft_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_soft_crt_order_decreasing)
        {
            TESTING_2("H5Lget_name_by_idx on soft link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME2, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            /* Create several soft links in reverse order to test creation order */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_soft_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_soft_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_soft_name_order_increasing)
        {
            TESTING_2("H5Lget_name_by_idx on soft link by alphabetical order in increasing order");

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME3, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_soft_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_soft_name_order_decreasing)
        {
            TESTING_2("H5Lget_name_by_idx on soft link by alphabetical order in decreasing order");

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME4, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_SOFT_SUBGROUP_NAME4);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            /* Create several soft links */
            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" GET_LINK_NAME_TEST_GROUP_NAME, subgroup_id,
                               GET_LINK_NAME_TEST_SOFT_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create soft link '%s'\n", GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME2, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_SOFT_LINK_NAME3, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if soft link '%s' exists\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    soft link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_SOFT_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_SOFT_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_SOFT_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_soft_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_soft_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_external_crt_order_increasing)
        {
            TESTING_2("H5Lget_name_by_idx on external link by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            /* Create file for external link to reference */
            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            /* Create several external links in reverse order to test creation order */
            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id,
                                   GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id,
                                   GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_external_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_external_crt_order_decreasing)
        {
            TESTING_2("H5Lget_name_by_idx on external link by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            /* Create file for external link to reference */
            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME2, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            /* Create several external links in reverse order to test creation order */
            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id,
                                   GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id,
                                   GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_crt_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_external_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_external_name_order_increasing)
        {
            TESTING_2("H5Lget_name_by_idx on external link by alphabetical order in increasing order");

            /* Create file for external link to reference */
            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME3, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id,
                                   GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id,
                                   GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_increasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_external_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_external_name_order_decreasing)
        {
            TESTING_2("H5Lget_name_by_idx on external link by alphabetical order in decreasing order");

            /* Create file for external link to reference */
            snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
                     EXTERNAL_LINK_TEST_FILE_NAME);

            if ((ext_file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (H5Fclose(ext_file_id) < 0) {
                H5_FAILED();
                printf("    couldn't close file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            /* Create group to hold some links */
            if ((subgroup_id = H5Gcreate2(group_id, GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME4, H5P_DEFAULT,
                                          gcpl_id, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create container subgroup '%s'\n",
                       GET_LINK_NAME_TEST_EXTERNAL_SUBGROUP_NAME4);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            /* Create several external links */
            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME,
                                   H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id,
                                   GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id,
                                   GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to create external link '%s'\n", GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            /* Verify the links have been created */
            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if ((link_exists = H5Lexists(subgroup_id, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3, H5P_DEFAULT)) <
                0) {
                H5_FAILED();
                printf("    couldn't determine if external link '%s' exists\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    external link '%s' did not exist before name retrieval\n",
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            /* Retrieve link names */
            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 0, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME3);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 1, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME2);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if ((link_name_buf_size = H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2,
                                                         NULL, 0, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name size\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (H5Lget_name_by_idx(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, 2, link_name_buf,
                                   (size_t)link_name_buf_size + 1, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    failed to retrieve link name\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (strncmp(link_name_buf, GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME,
                        strlen(GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME) + 1)) {
                H5_FAILED();
                printf("    link name '%s' did not match expected name '%s'\n", link_name_buf,
                       GET_LINK_NAME_TEST_EXTERNAL_LINK_NAME);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (H5Gclose(subgroup_id) < 0) {
                H5_FAILED();
                printf("    failed to close group\n");
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            if (remove_test_file(NULL, ext_link_filename) < 0) {
                H5_FAILED();
                printf("    failed to delete external file '%s'\n", ext_link_filename);
                PART_ERROR(H5Lget_name_by_idx_external_name_order_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_external_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
            H5Fclose(ext_file_id);
            ext_file_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_ud_crt_order_increasing)
        {
            TESTING_2("H5Lget_name_by_idx on user-defined link by creation order in increasing order");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lget_name_by_idx_ud_crt_order_increasing);
        }
        PART_END(H5Lget_name_by_idx_ud_crt_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_ud_crt_order_decreasing)
        {
            TESTING_2("H5Lget_name_by_idx on user-defined link by creation order in decreasing order");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lget_name_by_idx_ud_crt_order_decreasing);
        }
        PART_END(H5Lget_name_by_idx_ud_crt_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_ud_name_order_increasing)
        {
            TESTING_2("H5Lget_name_by_idx on user-defined link by alphabetical order in increasing order");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lget_name_by_idx_ud_name_order_increasing);
        }
        PART_END(H5Lget_name_by_idx_ud_name_order_increasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY

        PART_BEGIN(H5Lget_name_by_idx_ud_name_order_decreasing)
        {
            TESTING_2("H5Lget_name_by_idx on user-defined link by alphabetical order in decreasing order");

            /* TODO */

            SKIPPED();
            PART_EMPTY(H5Lget_name_by_idx_ud_name_order_decreasing);
        }
        PART_END(H5Lget_name_by_idx_ud_name_order_decreasing);

        H5E_BEGIN_TRY
        {
            H5Gclose(subgroup_id);
            subgroup_id = H5I_INVALID_HID;
        }
        H5E_END_TRY
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(ext_file_id);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that a link's name can't be retrieved
 * when H5Lget_name_by_idx is passed invalid parameters.
 */
static void
test_get_link_name_invalid_params(void H5_ATTR_UNUSED *params)
{
    ssize_t ret;
    htri_t  link_exists;
    size_t  link_name_buf_size = 0;
    hid_t   file_id            = H5I_INVALID_HID;
    hid_t   container_group    = H5I_INVALID_HID;
    hid_t   group_id           = H5I_INVALID_HID;
    char   *link_name_buf      = NULL;

    TESTING_MULTIPART("link name retrieval with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, soft link, hard link, or external link "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, GET_LINK_NAME_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", GET_LINK_NAME_INVALID_PARAMS_TEST_GROUP_NAME);
        goto error;
    }

    if (H5Lcreate_hard(group_id, ".", group_id, GET_LINK_NAME_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT,
                       H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    failed to create hard link '%s'\n", GET_LINK_NAME_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    /* Verify the link has been created */
    if ((link_exists = H5Lexists(group_id, GET_LINK_NAME_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if link exists\n");
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link did not exist\n");
        goto error;
    }

    if ((ret = H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, NULL, link_name_buf_size,
                                  H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    failed to retrieve link name size\n");
        goto error;
    }

    link_name_buf_size = (size_t)ret;
    if (NULL == (link_name_buf = (char *)malloc(link_name_buf_size + 1)))
        TEST_ERROR;

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lget_name_by_idx_invalid_loc_id)
        {
            TESTING_2("H5Lget_name_by_idx with an invalid location ID");

            H5E_BEGIN_TRY
            {
                ret = H5Lget_name_by_idx(H5I_INVALID_HID, ".", H5_INDEX_NAME, H5_ITER_INC, 0, link_name_buf,
                                         link_name_buf_size + 1, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_name_by_idx succeeded with an invalid location ID!\n");
                PART_ERROR(H5Lget_name_by_idx_invalid_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_invalid_loc_id);

        PART_BEGIN(H5Lget_name_by_idx_invalid_grp_name)
        {
            TESTING_2("H5Lget_name_by_idx with an invalid group name");

            H5E_BEGIN_TRY
            {
                ret = H5Lget_name_by_idx(group_id, NULL, H5_INDEX_NAME, H5_ITER_INC, 0, link_name_buf,
                                         link_name_buf_size + 1, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_name_by_idx succeeded with a NULL group name!\n");
                PART_ERROR(H5Lget_name_by_idx_invalid_grp_name);
            }

            H5E_BEGIN_TRY
            {
                ret = H5Lget_name_by_idx(group_id, "", H5_INDEX_NAME, H5_ITER_INC, 0, link_name_buf,
                                         link_name_buf_size + 1, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_name_by_idx succeeded with an invalid group name of ''!\n");
                PART_ERROR(H5Lget_name_by_idx_invalid_grp_name);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_invalid_grp_name);

        PART_BEGIN(H5Lget_name_by_idx_invalid_index_type)
        {
            TESTING_2("H5Lget_name_by_idx with an invalid index type");

            H5E_BEGIN_TRY
            {
                ret = H5Lget_name_by_idx(group_id, ".", H5_INDEX_UNKNOWN, H5_ITER_INC, 0, link_name_buf,
                                         link_name_buf_size + 1, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_name_by_idx succeeded with invalid index type H5_INDEX_UNKNOWN!\n");
                PART_ERROR(H5Lget_name_by_idx_invalid_index_type);
            }

            H5E_BEGIN_TRY
            {
                ret = H5Lget_name_by_idx(group_id, ".", H5_INDEX_N, H5_ITER_INC, 0, link_name_buf,
                                         link_name_buf_size + 1, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_name_by_idx succeeded with invalid index type H5_INDEX_N!\n");
                PART_ERROR(H5Lget_name_by_idx_invalid_index_type);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_invalid_index_type);

        PART_BEGIN(H5Lget_name_by_idx_invalid_iter_order)
        {
            TESTING_2("H5Lget_name_by_idx with an invalid iteration ordering");

            H5E_BEGIN_TRY
            {
                ret = H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_UNKNOWN, 0, link_name_buf,
                                         link_name_buf_size + 1, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_name_by_idx succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n");
                PART_ERROR(H5Lget_name_by_idx_invalid_iter_order);
            }

            H5E_BEGIN_TRY
            {
                ret = H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_N, 0, link_name_buf,
                                         link_name_buf_size + 1, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_name_by_idx succeeded with invalid iteration ordering H5_ITER_N!\n");
                PART_ERROR(H5Lget_name_by_idx_invalid_iter_order);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_invalid_iter_order);

        PART_BEGIN(H5Lget_name_by_idx_invalid_lapl)
        {
            TESTING_2("H5Lget_name_by_idx with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                ret = H5Lget_name_by_idx(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, 0, link_name_buf,
                                         link_name_buf_size + 1, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (ret >= 0) {
                H5_FAILED();
                printf("    H5Lget_name_by_idx succeeded with an invalid LAPL!\n");
                PART_ERROR(H5Lget_name_by_idx_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lget_name_by_idx_invalid_lapl);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (link_name_buf) {
        free(link_name_buf);
        link_name_buf = NULL;
    }

    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        if (link_name_buf)
            free(link_name_buf);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of link
 * iteration using H5Literate(_by_name)2 with
 * only hard links. Iteration is done in
 * increasing and decreasing order of both link
 * name and link creation order.
 */
static void
test_link_iterate_hard_links(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  gcpl_id     = H5I_INVALID_HID;
    hid_t  dset_id     = H5I_INVALID_HID;
    hid_t  dset_dtype  = H5I_INVALID_HID;
    hid_t  dset_dspace = H5I_INVALID_HID;

    TESTING_MULTIPART("link iteration (only hard links)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, dataset, link, or iterate aren't "
               "supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
            H5_FAILED();
            printf("    couldn't set link creation order tracking\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_ITER_HARD_LINKS_TEST_SUBGROUP_NAME, H5P_DEFAULT, gcpl_id,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_ITER_HARD_LINKS_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, false)) < 0)
        TEST_ERROR;

    if ((dset_dspace =
             generate_random_dataspace(LINK_ITER_HARD_LINKS_TEST_DSET_SPACE_RANK, NULL, NULL, false)) < 0)
        TEST_ERROR;

    for (i = 0; i < LINK_ITER_HARD_LINKS_TEST_NUM_LINKS; i++) {
        char dset_name[LINK_ITER_HARD_LINKS_TEST_BUF_SIZE];

        /* Create the datasets with a reverse-ordering naming scheme to test creation order later */
        snprintf(dset_name, LINK_ITER_HARD_LINKS_TEST_BUF_SIZE, LINK_ITER_HARD_LINKS_TEST_LINK_NAME "%d",
                 (int)(LINK_ITER_HARD_LINKS_TEST_NUM_LINKS - i - 1));

        if ((dset_id = H5Dcreate2(group_id, dset_name, dset_dtype, dset_dspace, H5P_DEFAULT, H5P_DEFAULT,
                                  H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't create hard link '%s'\n", dset_name);
            goto error;
        }

        /* Verify the link has been created */
        if ((link_exists = H5Lexists(group_id, dset_name, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't determine if link '%s' exists\n", dset_name);
            goto error;
        }

        if (!link_exists) {
            H5_FAILED();
            printf("    link '%s' did not exist\n", dset_name);
            goto error;
        }

        if (H5Dclose(dset_id) < 0) {
            H5_FAILED();
            printf("    couldn't close dataset '%s'\n", dset_name);
            goto error;
        }
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Literate_link_name_increasing)
        {
            TESTING_2("H5Literate2 by link name in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    API functions for external or user-defined link aren't supported with this "
                       "connector\n");
                PART_EMPTY(H5Literate_link_name_increasing);
            }

            i = 0;

            /* Test basic link iteration capability using both index types and both index orders */
            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_hard_links_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_link_name_increasing);
            }

            if (i != LINK_ITER_HARD_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_name_increasing);

        PART_BEGIN(H5Literate_link_name_decreasing)
        {
            TESTING_2("H5Literate2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_ITER_HARD_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_DEC, NULL, link_iter_hard_links_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_link_name_decreasing);
            }

            if (i != 2 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_name_decreasing);

        PART_BEGIN(H5Literate_link_creation_increasing)
        {
            TESTING_2("H5Literate2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_hard_links_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_link_creation_increasing);
            }

            if (i != 3 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_creation_increasing);

        PART_BEGIN(H5Literate_link_creation_decreasing)
        {
            TESTING_2("H5Literate2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_hard_links_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_link_creation_decreasing);
            }

            if (i != 4 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_creation_decreasing);

        PART_BEGIN(H5Literate_by_name_link_name_increasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in increasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = 0;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_HARD_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_hard_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_link_name_increasing);
            }

            if (i != LINK_ITER_HARD_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_link_name_increasing);

        PART_BEGIN(H5Literate_by_name_link_name_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_ITER_HARD_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_HARD_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, NULL, link_iter_hard_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_link_name_decreasing);
            }

            if (i != 2 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_link_name_decreasing);

        PART_BEGIN(H5Literate_by_name_creation_increasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_HARD_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_hard_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_creation_increasing);
            }

            if (i != 3 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_creation_increasing);

        PART_BEGIN(H5Literate_by_name_creation_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_HARD_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_hard_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_creation_decreasing);
            }

            if (i != 4 * LINK_ITER_HARD_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Sclose(dset_dspace) < 0)
        TEST_ERROR;
    if (H5Tclose(dset_dtype) < 0)
        TEST_ERROR;
    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Sclose(dset_dspace);
        H5Tclose(dset_dtype);
        H5Dclose(dset_id);
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of link
 * iteration using H5Literate(_by_name)2 with
 * only soft links. Iteration is done in
 * increasing and decreasing order of both link
 * name and link creation order.
 */
static void
test_link_iterate_soft_links(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  gcpl_id = H5I_INVALID_HID;

    TESTING_MULTIPART("link iteration (only soft links)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, soft link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
            H5_FAILED();
            printf("    couldn't set link creation order tracking\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_ITER_SOFT_LINKS_TEST_SUBGROUP_NAME, H5P_DEFAULT, gcpl_id,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_ITER_SOFT_LINKS_TEST_SUBGROUP_NAME);
        goto error;
    }

    for (i = 0; i < LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS; i++) {
        char link_name[LINK_ITER_SOFT_LINKS_TEST_BUF_SIZE];
        char link_target[LINK_ITER_SOFT_LINKS_TEST_BUF_SIZE];

        /* Create the links with a reverse-ordering naming scheme to test creation order later */
        snprintf(link_name, LINK_ITER_SOFT_LINKS_TEST_BUF_SIZE, LINK_ITER_SOFT_LINKS_TEST_LINK_NAME "%d",
                 (int)(LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS - i - 1));

        snprintf(link_target, LINK_ITER_SOFT_LINKS_TEST_BUF_SIZE, "target%d",
                 (int)(LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS - i - 1));

        if (H5Lcreate_soft(link_target, group_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("    couldn't create soft link '%s'\n", link_name);
            goto error;
        }

        /* Verify the link has been created */
        if ((link_exists = H5Lexists(group_id, link_name, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't determine if link '%s' exists\n", link_name);
            goto error;
        }

        if (!link_exists) {
            H5_FAILED();
            printf("    link '%s' did not exist\n", link_name);
            goto error;
        }
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Literate_link_name_increasing)
        {
            TESTING_2("H5Literate2 by link name in increasing order");

            i = 0;

            /* Test basic link iteration capability using both index types and both index orders */
            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_soft_links_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_link_name_increasing);
            }

            if (i != LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_name_increasing);

        PART_BEGIN(H5Literate_link_name_decreasing)
        {
            TESTING_2("H5Literate2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_DEC, NULL, link_iter_soft_links_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_link_name_decreasing);
            }

            if (i != 2 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_name_decreasing);

        PART_BEGIN(H5Literate_link_creation_increasing)
        {
            TESTING_2("H5Literate2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_soft_links_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_link_creation_increasing);
            }

            if (i != 3 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_creation_increasing);

        PART_BEGIN(H5Literate_link_creation_decreasing)
        {
            TESTING_2("H5Literate2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_soft_links_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_link_creation_decreasing);
            }

            if (i != 4 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_creation_decreasing);

        PART_BEGIN(H5Literate_by_name_link_name_increasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in increasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = 0;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_SOFT_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_soft_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_link_name_increasing);
            }

            if (i != LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_link_name_increasing);

        PART_BEGIN(H5Literate_by_name_link_name_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_SOFT_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, NULL, link_iter_soft_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_link_name_decreasing);
            }

            if (i != 2 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_link_name_decreasing);

        PART_BEGIN(H5Literate_by_name_creation_increasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_SOFT_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_soft_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_creation_increasing);
            }

            if (i != 3 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_creation_increasing);

        PART_BEGIN(H5Literate_by_name_creation_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_SOFT_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_soft_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_creation_decreasing);
            }

            if (i != 4 * LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of link
 * iteration using H5Literate(_by_name)2 with
 * only external links. Iteration is done in
 * increasing and decreasing order of both link
 * name and link creation order.
 */
static void
test_link_iterate_external_links(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  gcpl_id                                            = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link iteration (only external links)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, external link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
            H5_FAILED();
            printf("    couldn't set link creation order tracking\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_ITER_EXT_LINKS_TEST_SUBGROUP_NAME, H5P_DEFAULT, gcpl_id,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_ITER_EXT_LINKS_TEST_SUBGROUP_NAME);
        goto error;
    }

    for (i = 0; i < LINK_ITER_EXT_LINKS_TEST_NUM_LINKS; i++) {
        char link_name[LINK_ITER_EXT_LINKS_TEST_BUF_SIZE];

        /* Create the links with a reverse-ordering naming scheme to test creation order later */
        snprintf(link_name, LINK_ITER_EXT_LINKS_TEST_BUF_SIZE, LINK_ITER_EXT_LINKS_TEST_LINK_NAME "%d",
                 (int)(LINK_ITER_EXT_LINKS_TEST_NUM_LINKS - i - 1));

        if (H5Lcreate_external(ext_link_filename, "/", group_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
            H5_FAILED();
            printf("    couldn't create external link '%s'\n", link_name);
            goto error;
        }

        /* Verify the link has been created */
        if ((link_exists = H5Lexists(group_id, link_name, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't determine if link '%s' exists\n", link_name);
            goto error;
        }

        if (!link_exists) {
            H5_FAILED();
            printf("    link '%s' did not exist\n", link_name);
            goto error;
        }
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Literate_link_name_increasing)
        {
            TESTING_2("H5Literate2 by link name in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
                SKIPPED();
                printf("    external link API is not supported with this VOL connector\n");
                PART_EMPTY(H5Literate_link_name_increasing);
            }

            i = 0;

            /* Test basic link iteration capability using both index types and both index orders */
            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_external_links_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_link_name_increasing);
            }

            if (i != LINK_ITER_EXT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_name_increasing);

        PART_BEGIN(H5Literate_link_name_decreasing)
        {
            TESTING_2("H5Literate2 by link name in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
                SKIPPED();
                printf("    external link API is not supported with this VOL connector\n");
                PART_EMPTY(H5Literate_link_name_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_ITER_EXT_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_DEC, NULL, link_iter_external_links_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_link_name_decreasing);
            }

            if (i != 2 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_name_decreasing);

        PART_BEGIN(H5Literate_link_creation_increasing)
        {
            TESTING_2("H5Literate2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
                SKIPPED();
                printf("    creation order tracking or the external link API aren't supported with this VOL "
                       "connector\n");
                PART_EMPTY(H5Literate_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_external_links_cb,
                            &i) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_link_creation_increasing);
            }

            if (i != 3 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_creation_increasing);

        PART_BEGIN(H5Literate_link_creation_decreasing)
        {
            TESTING_2("H5Literate2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
                SKIPPED();
                printf("    creation order tracking or the external link API aren't supported with this VOL "
                       "connector\n");
                PART_EMPTY(H5Literate_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_external_links_cb,
                            &i) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_link_creation_decreasing);
            }

            if (i != 4 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_creation_decreasing);

        PART_BEGIN(H5Literate_by_name_link_name_increasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
                SKIPPED();
                printf("    the external link API is not supported with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_link_name_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 0;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_EXT_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_external_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_link_name_increasing);
            }

            if (i != LINK_ITER_EXT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_link_name_increasing);

        PART_BEGIN(H5Literate_by_name_link_name_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
                SKIPPED();
                printf("    creation order tracking or the external link API aren't supported with this VOL "
                       "connector\n");
                PART_EMPTY(H5Literate_by_name_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_ITER_EXT_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_EXT_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, NULL, link_iter_external_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_link_name_decreasing);
            }

            if (i != 2 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_link_name_decreasing);

        PART_BEGIN(H5Literate_by_name_creation_increasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
                SKIPPED();
                printf("    creation order tracking or the external link API aren't supported with this VOL "
                       "connector\n");
                PART_EMPTY(H5Literate_by_name_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(file_id,
                                    "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_EXT_LINKS_TEST_SUBGROUP_NAME,
                                    H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_external_links_cb, &i,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_creation_increasing);
            }

            if (i != 3 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_creation_increasing);

        PART_BEGIN(H5Literate_by_name_creation_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
                SKIPPED();
                printf("    creation order tracking or the external link API are not supported with this VOL "
                       "connector\n");
                PART_EMPTY(H5Literate_by_name_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(file_id,
                                    "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_EXT_LINKS_TEST_SUBGROUP_NAME,
                                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_external_links_cb, &i,
                                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_creation_decreasing);
            }

            if (i != 4 * LINK_ITER_EXT_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of link
 * iteration using H5Literate(_by_name)2 with
 * only user-defined links. Iteration is done
 * in increasing and decreasing order of both
 * link name and link creation order.
 *
 * TODO refactor test so that creation order tests
 * actually test the order that objects were created in.
 */
static void
test_link_iterate_ud_links(void H5_ATTR_UNUSED *params)
{
    TESTING("link iteration (only user-defined links)");

    SKIPPED();

    return;
}

/*
 * A test to check the functionality of link
 * iteration using H5Literate(_by_name)2 with
 * mixed link types. Iteration is done in
 * increasing and decreasing order of both link
 * name and link creation order.
 *
 * TODO refactor test so that creation order tests
 * actually test the order that objects were created in.
 *
 * TODO add UD links
 *
 * TODO refactor link saving portion into its own test
 */
static void
test_link_iterate_mixed_links(void H5_ATTR_UNUSED *params)
{
    hsize_t saved_idx;
    size_t  i;
    htri_t  link_exists;
    hid_t   file_id         = H5I_INVALID_HID;
    hid_t   container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t   gcpl_id     = H5I_INVALID_HID;
    hid_t   dset_id     = H5I_INVALID_HID;
    hid_t   dset_dtype  = H5I_INVALID_HID;
    hid_t   dset_dspace = H5I_INVALID_HID;
    int     halted;
    char    ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link iteration (mixed link types)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, soft link, external link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
            H5_FAILED();
            printf("    couldn't set link creation order tracking\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_ITER_MIXED_LINKS_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_ITER_MIXED_LINKS_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, false)) < 0)
        TEST_ERROR;

    if ((dset_dspace =
             generate_random_dataspace(LINK_ITER_MIXED_LINKS_TEST_DSET_SPACE_RANK, NULL, NULL, false)) < 0)
        TEST_ERROR;

    if ((dset_id = H5Dcreate2(group_id, LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME, dset_dtype, dset_dspace,
                              H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create hard link '%s'\n", LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME);
        goto error;
    }

    if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_ITER_MIXED_LINKS_TEST_SUBGROUP_NAME
                       "/" LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME,
                       group_id, LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME);
        goto error;
    }

    if (H5Lcreate_external(ext_link_filename, "/", group_id, LINK_ITER_MIXED_LINKS_TEST_EXT_LINK_NAME,
                           H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create external link '%s'\n", LINK_ITER_MIXED_LINKS_TEST_EXT_LINK_NAME);
        goto error;
    }

    /* Verify the links have been created */
    if ((link_exists = H5Lexists(group_id, LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    first link did not exist\n");
        goto error;
    }

    if ((link_exists = H5Lexists(group_id, LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    second link did not exist\n");
        goto error;
    }

    if ((link_exists = H5Lexists(group_id, LINK_ITER_MIXED_LINKS_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", LINK_ITER_MIXED_LINKS_TEST_EXT_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    third link did not exist\n");
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Literate_link_name_increasing)
        {
            TESTING_2("H5Literate2 by link name in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    creation order tracking, external links, or user-defined links aren't supported "
                       "with this VOL connector\n");
                PART_EMPTY(H5Literate_link_name_increasing);
            }

            i = 0;

            /* Test basic link iteration capability using both index types and both index orders */
            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_mixed_links_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_link_name_increasing);
            }

            if (i != LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_name_increasing);

        PART_BEGIN(H5Literate_link_name_decreasing)
        {
            TESTING_2("H5Literate2 by link name in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    creation order tracking, external links, or user-defined links aren't supported "
                       "with this VOL connector\n");
                PART_EMPTY(H5Literate_link_name_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_DEC, NULL, link_iter_mixed_links_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_link_name_decreasing);
            }

            if (i != 2 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_name_decreasing);

        PART_BEGIN(H5Literate_link_creation_increasing)
        {
            TESTING_2("H5Literate2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    creation order tracking, external links, or user-defined links aren't supported "
                       "with this VOL connector\n");
                PART_EMPTY(H5Literate_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_mixed_links_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_link_creation_increasing);
            }

            if (i != 3 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_creation_increasing);

        PART_BEGIN(H5Literate_link_creation_decreasing)
        {
            TESTING_2("H5Literate2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    creation order tracking, external links, or user-defined links aren't supported "
                       "with this VOL connector\n");
                PART_EMPTY(H5Literate_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_mixed_links_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_link_creation_decreasing);
            }

            if (i != 4 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_link_creation_decreasing);

        PART_BEGIN(H5Literate_by_name_link_name_increasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    external links or user-defined links aren't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_link_name_increasing);
            }

            i = 0;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_MIXED_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_mixed_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_link_name_increasing);
            }

            if (i != LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_link_name_increasing);

        PART_BEGIN(H5Literate_by_name_link_name_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    external links or user-defined links aren't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_link_name_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_MIXED_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, NULL, link_iter_mixed_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_link_name_decreasing);
            }

            if (i != 2 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_link_name_decreasing);

        PART_BEGIN(H5Literate_by_name_creation_increasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    creation order tracking, external links, or user-defined links aren't supported "
                       "with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_MIXED_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_mixed_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_creation_increasing);
            }

            if (i != 3 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_creation_increasing);

        PART_BEGIN(H5Literate_by_name_creation_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    creation order tracking, external links, or user-defined links aren't supported "
                       "with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS;

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_MIXED_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_mixed_links_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_creation_decreasing);
            }

            if (i != 4 * LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not iterated over!\n");
                PART_ERROR(H5Literate_by_name_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_creation_decreasing);

        PART_BEGIN(H5Literate_index_saving_increasing)
        {
            TESTING_2("H5Literate2 index-saving capabilities in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    creation order tracking, external links, or user-defined links aren't supported "
                       "with this VOL connector\n");
                PART_EMPTY(H5Literate_index_saving_increasing);
            }

            /* Test the H5Literate2 index-saving capabilities */
            saved_idx = 0;
            halted    = 0;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, &saved_idx, link_iter_idx_saving_cb,
                            &halted) < 0) {
                H5_FAILED();
                printf("    H5Literate2 index-saving capability test failed\n");
                PART_ERROR(H5Literate_index_saving_increasing);
            }

            if (saved_idx != 2) {
                H5_FAILED();
                printf("    saved index after iteration was wrong\n");
                PART_ERROR(H5Literate_index_saving_increasing);
            }

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, &saved_idx, link_iter_idx_saving_cb,
                            &halted) < 0) {
                H5_FAILED();
                printf("    couldn't finish iterating when beginning from saved index\n");
                PART_ERROR(H5Literate_index_saving_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_index_saving_increasing);
#ifdef BROKEN
        PART_BEGIN(H5Literate_index_saving_decreasing)
        {
            TESTING_2("H5Literate2 index-saving capabilities in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
                !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
                SKIPPED();
                printf("    creation order tracking, external links, or user-defined links aren't supported "
                       "with this VOL connector\n");
                PART_EMPTY(H5Literate_index_saving_decreasing);
            }

            saved_idx = LINK_ITER_MIXED_LINKS_TEST_NUM_LINKS - 1;
            halted    = 0;

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, &saved_idx, link_iter_idx_saving_cb,
                            &halted) < 0) {
                H5_FAILED();
                printf("    H5Literate2 index-saving capability test failed\n");
                PART_ERROR(H5Literate_index_saving_decreasing);
            }

            if (saved_idx != 2) {
                H5_FAILED();
                printf("    saved index after iteration was wrong\n");
                PART_ERROR(H5Literate_index_saving_decreasing);
            }

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, &saved_idx, link_iter_idx_saving_cb,
                            &halted) < 0) {
                H5_FAILED();
                printf("    couldn't finish iterating when beginning from saved index\n");
                PART_ERROR(H5Literate_index_saving_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_index_saving_decreasing);
#endif
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Sclose(dset_dspace) < 0)
        TEST_ERROR;
    if (H5Tclose(dset_dtype) < 0)
        TEST_ERROR;
    if (H5Dclose(dset_id) < 0)
        TEST_ERROR;
    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Sclose(dset_dspace);
        H5Tclose(dset_dtype);
        H5Dclose(dset_id);
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that H5Literate(_by_name)2 fails
 * when given invalid parameters.
 */
static void
test_link_iterate_invalid_params(void H5_ATTR_UNUSED *params)
{
    herr_t err_ret = -1;
    size_t i;
    htri_t link_exists;
    hid_t  file_id                                            = H5I_INVALID_HID;
    hid_t  container_group                                    = H5I_INVALID_HID;
    hid_t  group_id                                           = H5I_INVALID_HID;
    hid_t  dset_id                                            = H5I_INVALID_HID;
    hid_t  dset_dtype                                         = H5I_INVALID_HID;
    hid_t  dset_dspace                                        = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link iteration with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC)) {
        SKIPPED();
        printf("    API functions for basic file, group, dataset, link, soft link, external link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, false)) < 0)
        TEST_ERROR;

    if ((dset_dspace =
             generate_random_dataspace(LINK_ITER_INVALID_PARAMS_TEST_DSET_SPACE_RANK, NULL, NULL, false)) < 0)
        TEST_ERROR;

    if ((dset_id = H5Dcreate2(group_id, LINK_ITER_INVALID_PARAMS_TEST_HARD_LINK_NAME, dset_dtype, dset_dspace,
                              H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create hard link '%s'\n", LINK_ITER_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME
                       "/" LINK_ITER_INVALID_PARAMS_TEST_HARD_LINK_NAME,
                       group_id, LINK_ITER_INVALID_PARAMS_TEST_SOFT_LINK_NAME, H5P_DEFAULT,
                       H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", LINK_ITER_INVALID_PARAMS_TEST_SOFT_LINK_NAME);
        goto error;
    }
    if (H5Lcreate_external(ext_link_filename, "/", group_id, LINK_ITER_INVALID_PARAMS_TEST_EXT_LINK_NAME,
                           H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create external link '%s'\n", LINK_ITER_INVALID_PARAMS_TEST_EXT_LINK_NAME);
        goto error;
    }
    /* Verify the links have been created */
    if ((link_exists = H5Lexists(group_id, LINK_ITER_INVALID_PARAMS_TEST_HARD_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", LINK_ITER_INVALID_PARAMS_TEST_HARD_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    first link did not exist\n");
        goto error;
    }

    if ((link_exists = H5Lexists(group_id, LINK_ITER_INVALID_PARAMS_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", LINK_ITER_INVALID_PARAMS_TEST_SOFT_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    second link did not exist\n");
        goto error;
    }
    if ((link_exists = H5Lexists(group_id, LINK_ITER_INVALID_PARAMS_TEST_EXT_LINK_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if link '%s' exists\n", LINK_ITER_INVALID_PARAMS_TEST_EXT_LINK_NAME);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    third link did not exist\n");
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        i = 0;

        PART_BEGIN(H5Literate_invalid_grp_id)
        {
            TESTING_2("H5Literate2 with an invalid group ID");

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate2(H5I_INVALID_HID, H5_INDEX_NAME, H5_ITER_INC, NULL,
                                      link_iter_invalid_params_cb, NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate2 succeeded with an invalid group ID!\n");
                PART_ERROR(H5Literate_invalid_grp_id);
            }

            PASSED();
        }
        PART_END(H5Literate_invalid_grp_id);

        PART_BEGIN(H5Literate_invalid_index_type)
        {
            TESTING_2("H5Literate2 with an invalid index type");

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate2(group_id, H5_INDEX_UNKNOWN, H5_ITER_INC, NULL,
                                      link_iter_invalid_params_cb, NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate2 succeeded with invalid index type H5_INDEX_UNKNOWN!\n");
                PART_ERROR(H5Literate_invalid_index_type);
            }

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Literate2(group_id, H5_INDEX_N, H5_ITER_INC, NULL, link_iter_invalid_params_cb, NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate2 succeeded with invalid index type H5_INDEX_N!\n");
                PART_ERROR(H5Literate_invalid_index_type);
            }

            PASSED();
        }
        PART_END(H5Literate_invalid_index_type);

        PART_BEGIN(H5Literate_invalid_iter_order)
        {
            TESTING_2("H5Literate2 with an invalid iteration ordering");

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_UNKNOWN, NULL,
                                      link_iter_invalid_params_cb, NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate2 succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n");
                PART_ERROR(H5Literate_invalid_iter_order);
            }

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_N, NULL, link_iter_invalid_params_cb, NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate2 succeeded with invalid iteration ordering H5_ITER_N!\n");
                PART_ERROR(H5Literate_invalid_iter_order);
            }

            PASSED();
        }
        PART_END(H5Literate_invalid_iter_order);

        PART_BEGIN(H5Literate_by_name_invalid_loc_id)
        {
            TESTING_2("H5Literate_by_name2 with an invalid location ID");

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate_by_name2(
                    H5I_INVALID_HID, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 succeeded with an invalid location ID!\n");
                PART_ERROR(H5Literate_by_name_invalid_loc_id);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_invalid_loc_id);

        PART_BEGIN(H5Literate_by_name_invalid_grp_name)
        {
            TESTING_2("H5Literate_by_name2 with an invalid group name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate_by_name2(file_id, NULL, H5_INDEX_NAME, H5_ITER_INC, NULL,
                                              link_iter_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 succeeded with a NULL group name!\n");
                PART_ERROR(H5Literate_by_name_invalid_grp_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate_by_name2(file_id, "", H5_INDEX_NAME, H5_ITER_INC, NULL,
                                              link_iter_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 succeeded with an invalid group name of ''!\n");
                PART_ERROR(H5Literate_by_name_invalid_grp_name);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_invalid_grp_name);

        PART_BEGIN(H5Literate_by_name_invalid_index_type)
        {
            TESTING_2("H5Literate_by_name2 with an invalid index type");

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_UNKNOWN, H5_ITER_INC, NULL, link_iter_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 succeeded with invalid index type H5_INDEX_UNKNOWN!\n");
                PART_ERROR(H5Literate_by_name_invalid_index_type);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_N, H5_ITER_INC, NULL, link_iter_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 succeeded with invalid index type H5_INDEX_N!\n");
                PART_ERROR(H5Literate_by_name_invalid_index_type);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_invalid_index_type);

        PART_BEGIN(H5Literate_by_name_invalid_iter_order)
        {
            TESTING_2("H5Literate_by_name2 with an invalid iteration ordering");

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_UNKNOWN, NULL, link_iter_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf(
                    "    H5Literate_by_name2 succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n");
                PART_ERROR(H5Literate_by_name_invalid_iter_order);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_N, NULL, link_iter_invalid_params_cb, &i, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 succeeded with invalid iteration ordering H5_ITER_N!\n");
                PART_ERROR(H5Literate_by_name_invalid_iter_order);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_invalid_iter_order);

        PART_BEGIN(H5Literate_by_name_invalid_lapl)
        {
            TESTING_2("H5Literate_by_name2 with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_invalid_params_cb, NULL, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 succeeded with an invalid LAPL!\n");
                PART_ERROR(H5Literate_by_name_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_invalid_lapl);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Sclose(dset_dspace) < 0)
        TEST_ERROR;
    if (H5Tclose(dset_dtype) < 0)
        TEST_ERROR;
    if (H5Dclose(dset_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Sclose(dset_dspace);
        H5Tclose(dset_dtype);
        H5Dclose(dset_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that link iteration performed on a
 * group with no links in it is not problematic.
 */
static void
test_link_iterate_0_links(void H5_ATTR_UNUSED *params)
{
    hid_t file_id         = H5I_INVALID_HID;
    hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t gcpl_id = H5I_INVALID_HID;

    TESTING_MULTIPART("link iteration on group with 0 links");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, or iterate aren't supported "
               "with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create GCPL for link creation order tracking\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED) < 0) {
            H5_FAILED();
            printf("    couldn't set link creation order tracking\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_ITER_0_LINKS_TEST_SUBGROUP_NAME, H5P_DEFAULT, gcpl_id,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_ITER_0_LINKS_TEST_SUBGROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Literate_0_links_name_increasing)
        {
            TESTING_2("H5Literate2 by link name in increasing order");

            /* Test basic link iteration capability using both index types and both index orders */
            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, link_iter_0_links_cb, NULL) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_0_links_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_0_links_name_increasing);

        PART_BEGIN(H5Literate_0_links_name_decreasing)
        {
            TESTING_2("H5Literate2 by link name in decreasing order");

            if (H5Literate2(group_id, H5_INDEX_NAME, H5_ITER_DEC, NULL, link_iter_0_links_cb, NULL) < 0) {
                H5_FAILED();
                printf("    H5Literate2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_0_links_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_0_links_name_decreasing);

        PART_BEGIN(H5Literate_0_links_creation_increasing)
        {
            TESTING_2("H5Literate2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_0_links_creation_increasing);
            }

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_0_links_cb, NULL) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_0_links_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_0_links_creation_increasing);

        PART_BEGIN(H5Literate_0_links_creation_decreasing)
        {
            TESTING_2("H5Literate2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_0_links_creation_decreasing);
            }

            if (H5Literate2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_0_links_cb, NULL) <
                0) {
                H5_FAILED();
                printf("    H5Literate2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_0_links_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_0_links_creation_decreasing);

        PART_BEGIN(H5Literate_by_name_0_links_name_increasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in increasing order");

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_0_LINKS_TEST_SUBGROUP_NAME, H5_INDEX_NAME,
                    H5_ITER_INC, NULL, link_iter_0_links_cb, NULL, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_0_links_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_0_links_name_increasing);

        PART_BEGIN(H5Literate_by_name_0_links_name_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by link name in decreasing order");

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_0_LINKS_TEST_SUBGROUP_NAME, H5_INDEX_NAME,
                    H5_ITER_DEC, NULL, link_iter_0_links_cb, NULL, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_0_links_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_0_links_name_decreasing);

        PART_BEGIN(H5Literate_by_name_0_links_creation_increasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_0_links_creation_increasing);
            }

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_0_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, link_iter_0_links_cb, NULL, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Literate_by_name_0_links_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_0_links_creation_increasing);

        PART_BEGIN(H5Literate_by_name_0_links_creation_decreasing)
        {
            TESTING_2("H5Literate_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Literate_by_name_0_links_creation_decreasing);
            }

            if (H5Literate_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_ITER_0_LINKS_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, NULL, link_iter_0_links_cb, NULL, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Literate_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Literate_by_name_0_links_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Literate_by_name_0_links_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * only hard links and where there are no cyclic
 * links. Iteration is done in increasing and
 * decreasing order of both link name and link
 * creation order.
 */
static void
test_link_visit_hard_links_no_cycles(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup_id = H5I_INVALID_HID;
    hid_t  gcpl_id     = H5I_INVALID_HID;
    hid_t  dset_id     = H5I_INVALID_HID;
    hid_t  dset_dtype  = H5I_INVALID_HID;
    hid_t  dset_dspace = H5I_INVALID_HID;

    TESTING_MULTIPART("link visiting without cycles (only hard links)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, dataset, or link iterate aren't "
               "supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) {
            H5_FAILED();
            printf("    couldn't enable link creation order tracking and indexing on GCPL\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                               H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, false)) < 0)
        TEST_ERROR;

    if ((dset_dspace = generate_random_dataspace(LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_DSET_SPACE_RANK, NULL,
                                                 NULL, false)) < 0)
        TEST_ERROR;

    for (i = 0; i < LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS; i++) {
        size_t j;
        char   grp_name[LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE];

        /* Create the groups with a reverse-ordering naming scheme to test creation order later */
        snprintf(grp_name, LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                 LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "%d",
                 (int)(LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS - i - 1));

        if ((subgroup_id = H5Gcreate2(group_id, grp_name, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't create subgroup '%s'\n", grp_name);
            goto error;
        }

        for (j = 0; j < LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP; j++) {
            char dset_name[LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE];

            /* Create the datasets with a reverse-ordering naming scheme to test creation order later */
            snprintf(dset_name, LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP - j - 1));

            if ((dset_id = H5Dcreate2(subgroup_id, dset_name, dset_dtype, dset_dspace, H5P_DEFAULT,
                                      H5P_DEFAULT, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", dset_name);
                goto error;
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(subgroup_id, dset_name, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", dset_name);
                goto error;
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", dset_name);
                goto error;
            }

            if (H5Dclose(dset_id) < 0) {
                H5_FAILED();
                printf("    couldn't close dataset '%s'\n", dset_name);
                goto error;
            }
        }

        if (H5Gclose(subgroup_id) < 0) {
            H5_FAILED();
            printf("    couldn't close subgroup '%s'\n", grp_name);
            goto error;
        }
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Lvisit_no_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit2 by link name in increasing order");

            i = 0;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_INC, link_visit_hard_links_no_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_DEC, link_visit_hard_links_no_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_no_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_hard_links_no_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_hard_links_no_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_creation_decreasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in increasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = 0;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, link_visit_hard_links_no_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, link_visit_hard_links_no_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_hard_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_hard_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Sclose(dset_dspace) < 0)
        TEST_ERROR;
    if (H5Tclose(dset_dtype) < 0)
        TEST_ERROR;
    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Sclose(dset_dspace);
        H5Tclose(dset_dtype);
        H5Dclose(dset_id);
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * only soft links and where there are no cyclic
 * links. Iteration is done in increasing and
 * decreasing order of both link name and link
 * creation order.
 */
static void
test_link_visit_soft_links_no_cycles(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup_id = H5I_INVALID_HID;
    hid_t  gcpl_id     = H5I_INVALID_HID;

    TESTING_MULTIPART("link visiting without cycles (only soft links)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, soft link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) {
            H5_FAILED();
            printf("    couldn't enable link creation order tracking and indexing on GCPL\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                               H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME);
        goto error;
    }

    for (i = 0; i < LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS; i++) {
        size_t j;
        char   grp_name[LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE];

        /* Create the groups with a reverse-ordering naming scheme to test creation order later */
        snprintf(grp_name, LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                 LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "%d",
                 (int)(LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS - i - 1));

        if ((subgroup_id = H5Gcreate2(group_id, grp_name, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't create subgroup '%s'\n", grp_name);
            goto error;
        }

        for (j = 0; j < LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP; j++) {
            char link_name[LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE];
            char link_target[LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE];

            /* Create the links with a reverse-ordering naming scheme to test creation order later */
            snprintf(link_name, LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP - j - 1));

            snprintf(link_target, LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE, "target%d",
                     (int)(LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP - j - 1));

            if (H5Lcreate_soft(link_target, subgroup_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", link_name);
                goto error;
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(subgroup_id, link_name, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", link_name);
                goto error;
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", link_name);
                goto error;
            }
        }

        if (H5Gclose(subgroup_id) < 0) {
            H5_FAILED();
            printf("    couldn't close subgroup '%s'\n", grp_name);
            goto error;
        }
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Lvisit_no_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit2 by link name in increasing order");

            i = 0;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_INC, link_visit_soft_links_no_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_DEC, link_visit_soft_links_no_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_no_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_soft_links_no_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_soft_links_no_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_creation_decreasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in increasing order");

            i = 0;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, link_visit_soft_links_no_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, link_visit_soft_links_no_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_soft_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_soft_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * only external links and where there are no cyclic
 * links. Iteration is done in increasing and
 * decreasing order of both link name and link
 * creation order.
 */
static void
test_link_visit_external_links_no_cycles(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup_id                                        = H5I_INVALID_HID;
    hid_t  gcpl_id                                            = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link visiting without cycles (only external links)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, external link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) {
            H5_FAILED();
            printf("    couldn't enable link creation order tracking and indexing on GCPL\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME);
        goto error;
    }

    for (i = 0; i < LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS; i++) {
        size_t j;
        char   grp_name[LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE];

        /* Create the groups with a reverse-ordering naming scheme to test creation order later */
        snprintf(grp_name, LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                 LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "%d",
                 (int)(LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS - i - 1));

        if ((subgroup_id = H5Gcreate2(group_id, grp_name, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't create subgroup '%s'\n", grp_name);
            goto error;
        }

        for (j = 0; j < LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP; j++) {
            char link_name[LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE];

            /* Create the links with a reverse-ordering naming scheme to test creation order later */
            snprintf(link_name, LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP - j - 1));

            if (H5Lcreate_external(ext_link_filename, "/", subgroup_id, link_name, H5P_DEFAULT, H5P_DEFAULT) <
                0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", link_name);
                goto error;
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(subgroup_id, link_name, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", link_name);
                goto error;
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", link_name);
                goto error;
            }
        }

        if (H5Gclose(subgroup_id) < 0) {
            H5_FAILED();
            printf("    couldn't close subgroup '%s'\n", grp_name);
            goto error;
        }
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Lvisit_no_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit2 by link name in increasing order");

            i = 0;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_INC, link_visit_external_links_no_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_DEC, link_visit_external_links_no_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_no_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_external_links_no_cycles_cb,
                          &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_external_links_no_cycles_cb,
                          &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_creation_decreasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in increasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = 0;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, link_visit_external_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, link_visit_external_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_external_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_external_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * only user-defined links and where there are no
 * cyclic links. Iteration is done in increasing
 * and decreasing order of both link name and link
 * creation order.
 *
 * TODO refactor test so that creation order tests
 * actually test the order that objects were created in.
 */
static void
test_link_visit_ud_links_no_cycles(void H5_ATTR_UNUSED *params)
{
    TESTING("link visiting without cycles (only user-defined links)");

    SKIPPED();

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * mixed link types and where there are no cyclic
 * links. Iteration is done in increasing and
 * decreasing order of both link name and link
 * creation order.
 *
 * TODO refactor test so that creation order tests
 * actually test the order that objects were created in.
 *
 * TODO add UD links
 *
 * TODO refactor test to create a macroed number of subgroups
 */
static void
test_link_visit_mixed_links_no_cycles(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup1 = H5I_INVALID_HID, subgroup2 = H5I_INVALID_HID;
    hid_t  gcpl_id                                            = H5I_INVALID_HID;
    hid_t  dset_id                                            = H5I_INVALID_HID;
    hid_t  dset_dtype                                         = H5I_INVALID_HID;
    hid_t  fspace_id                                          = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link visiting without cycles (mixed link types)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
        SKIPPED();
        printf(
            "    API functions for basic file, group, link, hard link, soft link, external link, or iterate "
            "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) {
            H5_FAILED();
            printf("    couldn't enable link creation order tracking and indexing on GCPL\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                               H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((subgroup1 = H5Gcreate2(group_id, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2, H5P_DEFAULT,
                                gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create first subgroup '%s'\n",
               LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2);
        goto error;
    }

    if ((subgroup2 = H5Gcreate2(group_id, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3, H5P_DEFAULT,
                                gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create second subgroup '%s'\n",
               LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3);
        goto error;
    }

    if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, false)) < 0)
        TEST_ERROR;

    if ((fspace_id = generate_random_dataspace(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_SPACE_RANK, NULL,
                                               NULL, false)) < 0)
        TEST_ERROR;

    if ((dset_id = H5Dcreate2(subgroup1, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME, dset_dtype,
                              fspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create first dataset '%s'\n", LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME);
    }

    if (H5Dclose(dset_id) < 0)
        TEST_ERROR;

    if ((dset_id = H5Dcreate2(subgroup2, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME2, dset_dtype,
                              fspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create second dataset '%s'\n", LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME);
    }

    if (H5Dclose(dset_id) < 0)
        TEST_ERROR;

    if (H5Lcreate_hard(subgroup1, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME, subgroup1,
                       LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME1, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create first hard link '%s'\n", LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME1);
        goto error;
    }

    if (H5Lcreate_soft(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME, subgroup1,
                       LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME2);
        goto error;
    }

    if (H5Lcreate_external(ext_link_filename, "/", subgroup2, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME3,
                           H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create external link '%s'\n", LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME3);
        goto error;
    }

    if (H5Lcreate_hard(subgroup2, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME2, subgroup2,
                       LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME4, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create second hard link '%s'\n",
               LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME4);
        goto error;
    }

    /* Verify the links have been created */
    if ((link_exists = H5Lexists(subgroup1, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME1, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if first link '%s' exists\n",
               LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME1);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 1 did not exist\n");
        goto error;
    }

    if ((link_exists = H5Lexists(subgroup1, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME2, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if second link '%s' exists\n",
               LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME2);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 2 did not exist\n");
        goto error;
    }

    if ((link_exists = H5Lexists(subgroup2, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME3, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if third link '%s' exists\n",
               LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME3);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 3 did not exist\n");
        goto error;
    }

    if ((link_exists = H5Lexists(subgroup2, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME4, H5P_DEFAULT)) <
        0) {
        H5_FAILED();
        printf("    couldn't determine if fourth link '%s' exists\n",
               LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME4);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 4 did not exist\n");
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Lvisit_no_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit2 by link name in increasing order");

            i = 0;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_INC, link_visit_mixed_links_no_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_DEC, link_visit_mixed_links_no_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_no_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_mixed_links_no_cycles_cb,
                          &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_no_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_mixed_links_no_cycles_cb,
                          &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_no_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_no_cycles_link_creation_decreasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in increasing order");

            i = 0;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, link_visit_mixed_links_no_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, link_visit_mixed_links_no_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_mixed_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_by_name_no_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_mixed_links_no_cycles_cb, &i,
                    H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_no_cycles_link_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Sclose(fspace_id) < 0)
        TEST_ERROR;
    if (H5Tclose(dset_dtype) < 0)
        TEST_ERROR;
    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(subgroup1) < 0)
        TEST_ERROR;
    if (H5Gclose(subgroup2) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Sclose(fspace_id);
        H5Tclose(dset_dtype);
        H5Dclose(dset_id);
        H5Pclose(gcpl_id);
        H5Gclose(subgroup1);
        H5Gclose(subgroup2);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * only hard links and where there are cyclic links.
 * Iteration is done in increasing and decreasing
 * order of both link name and link creation order.
 */
static void
test_link_visit_hard_links_cycles(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup_id = H5I_INVALID_HID;
    hid_t  gcpl_id     = H5I_INVALID_HID;

    TESTING_MULTIPART("link visiting with cycles (only hard links)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, hard link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) {
            H5_FAILED();
            printf("    couldn't enable link creation order tracking and indexing on GCPL\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_HARD_LINKS_CYCLE_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               LINK_VISIT_HARD_LINKS_CYCLE_TEST_SUBGROUP_NAME);
        goto error;
    }

    for (i = 0; i < LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_SUBGROUPS; i++) {
        size_t j;
        char   grp_name[LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE];

        /* Create the groups with a reverse-ordering naming scheme to test creation order later */
        snprintf(grp_name, LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE,
                 LINK_VISIT_HARD_LINKS_CYCLE_TEST_NESTED_GRP_NAME "%d",
                 (int)(LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_SUBGROUPS - i - 1));

        if ((subgroup_id = H5Gcreate2(group_id, grp_name, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't create subgroup '%s'\n", grp_name);
            goto error;
        }

        for (j = 0; j < LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP; j++) {
            char link_name[LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE];

            /* Create the links with a reverse-ordering naming scheme to test creation order later */
            snprintf(link_name, LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP - j - 1));

            if (H5Lcreate_hard(subgroup_id, ".", subgroup_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create hard link '%s'\n", link_name);
                goto error;
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(subgroup_id, link_name, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", link_name);
                goto error;
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", link_name);
                goto error;
            }
        }

        if (H5Gclose(subgroup_id) < 0) {
            H5_FAILED();
            printf("    couldn't close subgroup '%s'\n", grp_name);
            goto error;
        }
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Lvisit_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit2 by link name in increasing order");

            i = 0;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_INC, link_visit_hard_links_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_DEC, link_visit_hard_links_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_hard_links_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_hard_links_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_creation_decreasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in increasing order");

            i = 0;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_HARD_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, link_visit_hard_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_HARD_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, link_visit_hard_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_HARD_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_hard_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_HARD_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_hard_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * only soft links and where there are cyclic links.
 * Iteration is done in increasing and decreasing
 * order of both link name and link creation order.
 */
static void
test_link_visit_soft_links_cycles(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup_id = H5I_INVALID_HID;
    hid_t  gcpl_id     = H5I_INVALID_HID;

    TESTING_MULTIPART("link visiting with cycles (only soft links)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, soft link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) {
            H5_FAILED();
            printf("    couldn't enable link creation order tracking and indexing on GCPL\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_SOFT_LINKS_CYCLE_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               LINK_VISIT_SOFT_LINKS_CYCLE_TEST_SUBGROUP_NAME);
        goto error;
    }

    for (i = 0; i < LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_SUBGROUPS; i++) {
        size_t j;
        char   grp_name[LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE];

        /* Create the groups with a reverse-ordering naming scheme to test creation order later */
        snprintf(grp_name, LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE,
                 LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NESTED_GRP_NAME "%d",
                 (int)(LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_SUBGROUPS - i - 1));

        if ((subgroup_id = H5Gcreate2(group_id, grp_name, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't create subgroup '%s'\n", grp_name);
            goto error;
        }

        for (j = 0; j < LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP; j++) {
            char link_name[LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE];
            char link_target[2 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE];

            /* Create the links with a reverse-ordering naming scheme to test creation order later */
            snprintf(link_name, LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP - j - 1));

            snprintf(link_target, 2 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE,
                     "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_SOFT_LINKS_CYCLE_TEST_SUBGROUP_NAME "/%s",
                     grp_name);

            if (H5Lcreate_soft(link_target, subgroup_id, link_name, H5P_DEFAULT, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create soft link '%s'\n", link_name);
                goto error;
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(subgroup_id, link_name, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", link_name);
                goto error;
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", link_name);
                goto error;
            }
        }

        if (H5Gclose(subgroup_id) < 0) {
            H5_FAILED();
            printf("    couldn't close subgroup '%s'\n", grp_name);
            goto error;
        }
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Lvisit_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit2 by link name in increasing order");

            i = 0;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_INC, link_visit_soft_links_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_DEC, link_visit_soft_links_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_soft_links_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_soft_links_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_creation_decreasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in increasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = 0;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_SOFT_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, link_visit_soft_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_SOFT_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, link_visit_soft_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_SOFT_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_soft_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_SOFT_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_soft_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * only external links and where there are cyclic
 * links. Iteration is done in increasing and
 * decreasing order of both link name and link
 * creation order.
 */
static void
test_link_visit_external_links_cycles(void H5_ATTR_UNUSED *params)
{
    size_t i;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup_id = H5I_INVALID_HID;
    hid_t  gcpl_id     = H5I_INVALID_HID;

    TESTING_MULTIPART("link visiting with cycles (only external links)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, external link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) {
            H5_FAILED();
            printf("    couldn't enable link creation order tracking and indexing on GCPL\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_EXT_LINKS_CYCLE_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               LINK_VISIT_EXT_LINKS_CYCLE_TEST_SUBGROUP_NAME);
        goto error;
    }

    for (i = 0; i < LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_SUBGROUPS; i++) {
        size_t j;
        char   grp_name[LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE];

        /* Create the groups with a reverse-ordering naming scheme to test creation order later */
        snprintf(grp_name, LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE,
                 LINK_VISIT_EXT_LINKS_CYCLE_TEST_NESTED_GRP_NAME "%d",
                 (int)(LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_SUBGROUPS - i - 1));

        if ((subgroup_id = H5Gcreate2(group_id, grp_name, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < 0) {
            H5_FAILED();
            printf("    couldn't create subgroup '%s'\n", grp_name);
            goto error;
        }

        for (j = 0; j < LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP; j++) {
            char link_name[LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE];
            char link_target_obj[2 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE];

            /* Create the links with a reverse-ordering naming scheme to test creation order later */
            snprintf(link_name, LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP - j - 1));

            snprintf(link_target_obj, 2 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE,
                     "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_EXT_LINKS_CYCLE_TEST_SUBGROUP_NAME "/%s",
                     grp_name);

            if (H5Lcreate_external(H5_api_test_filename, link_target_obj, subgroup_id, link_name, H5P_DEFAULT,
                                   H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    couldn't create external link '%s'\n", link_name);
                goto error;
            }

            /* Verify the link has been created */
            if ((link_exists = H5Lexists(subgroup_id, link_name, H5P_DEFAULT)) < 0) {
                H5_FAILED();
                printf("    couldn't determine if link '%s' exists\n", link_name);
                goto error;
            }

            if (!link_exists) {
                H5_FAILED();
                printf("    link '%s' did not exist\n", link_name);
                goto error;
            }
        }

        if (H5Gclose(subgroup_id) < 0) {
            H5_FAILED();
            printf("    couldn't close subgroup '%s'\n", grp_name);
            goto error;
        }
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Lvisit_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit2 by link name in increasing order");

            i = 0;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_INC, link_visit_external_links_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_DEC, link_visit_external_links_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_external_links_cycles_cb,
                          &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_external_links_cycles_cb,
                          &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_creation_decreasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in increasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = 0;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_EXT_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, link_visit_external_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_EXT_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, link_visit_external_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(file_id,
                                  "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_EXT_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                                  H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_external_links_cycles_cb, &i,
                                  H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

            if (H5Lvisit_by_name2(file_id,
                                  "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_EXT_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                                  H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_external_links_cycles_cb, &i,
                                  H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * only user-defined links and where there are
 * cyclic links. Iteration is done in increasing
 * and decreasing order of both link name and link
 * creation order.
 *
 * TODO refactor test so that creation order tests
 * actually test the order that objects were created in.
 */
static void
test_link_visit_ud_links_cycles(void H5_ATTR_UNUSED *params)
{
    TESTING("link visiting with cycles (only user-defined links)");

    SKIPPED();

    return;
}

/*
 * A test to check the functionality of recursive
 * link iteration using H5Lvisit(_by_name)2 with
 * mixed link types and where there are cyclic links.
 * Iteration is done in increasing and decreasing
 * order of both link name and link creation order.
 *
 * TODO refactor test so that creation order tests
 * actually test the order that objects were created in.
 */
static void
test_link_visit_mixed_links_cycles(void H5_ATTR_UNUSED *params)
{
    htri_t link_exists;
    size_t i;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup1 = H5I_INVALID_HID, subgroup2 = H5I_INVALID_HID;
    hid_t  gcpl_id                                            = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link visiting with cycles (mixed link types)");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_HARD_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
        SKIPPED();
        printf("    API functions for basic file, group, link, hard link, soft link, external link, iterate, "
               "or user defined link aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) {
            H5_FAILED();
            printf("    couldn't enable link creation order tracking and indexing on GCPL\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n",
               LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((subgroup1 = H5Gcreate2(group_id, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2, H5P_DEFAULT,
                                gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create first subgroup '%s'\n", LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2);
        goto error;
    }

    if ((subgroup2 = H5Gcreate2(group_id, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3, H5P_DEFAULT,
                                gcpl_id, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create second subgroup '%s'\n",
               LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3);
        goto error;
    }

    if (H5Lcreate_hard(group_id, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2, subgroup1,
                       LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME1, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create first hard link '%s'\n", LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME1);
        goto error;
    }

    if (H5Lcreate_soft("/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME
                       "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2,
                       subgroup1, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME2, H5P_DEFAULT,
                       H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME2);
        goto error;
    }

    if (H5Lcreate_external(ext_link_filename, "/", subgroup2, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME3,
                           H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create external link '%s'\n", LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME3);
        goto error;
    }

    if (H5Lcreate_hard(group_id, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3, subgroup2,
                       LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME4, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create second hard link '%s'\n", LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME4);
        goto error;
    }

    /* Verify the links have been created */
    if ((link_exists = H5Lexists(subgroup1, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME1, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if first link '%s' exists\n",
               LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME1);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    first link '%s' did not exist\n", LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME1);
        goto error;
    }

    if ((link_exists = H5Lexists(subgroup1, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME2, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if second link '%s' exists\n",
               LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME2);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    second link '%s' did not exist\n", LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME2);
        goto error;
    }

    if ((link_exists = H5Lexists(subgroup2, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME3, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if third link '%s' exists\n",
               LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME3);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    third link '%s' did not exist\n", LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME3);
        goto error;
    }

    if ((link_exists = H5Lexists(subgroup2, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME4, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if fourth link '%s' exists\n",
               LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME4);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    fourth link '%s' did not exist\n", LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME4);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        /*
         * NOTE: A counter is passed to the iteration callback to try to match up the
         * expected links with a given step throughout all of the following
         * iterations. This is to try and check that the links are indeed being
         * returned in the correct order.
         */

        PART_BEGIN(H5Lvisit_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit2 by link name in increasing order");

            i = 0;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_INC, link_visit_mixed_links_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_DEC, link_visit_mixed_links_cycles_cb, &i) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_mixed_links_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_mixed_links_cycles_cb, &i) <
                0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_cycles_link_creation_decreasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_name_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in increasing order");

            i = 0;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, link_visit_mixed_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_increasing);
            }

            if (i != LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_name_increasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_name_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in decreasing order");

            /* Reset the counter to the appropriate value for the next test */
            i = LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_DEC, link_visit_mixed_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_decreasing);
            }

            if (i != 2 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_name_decreasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_creation_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 2 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_mixed_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            if (i != 3 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_creation_increasing);

        PART_BEGIN(H5Lvisit_by_name_cycles_link_creation_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            /* Reset the counter to the appropriate value for the next test */
            i = 3 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS;

            if (H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME,
                    H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_mixed_links_cycles_cb, &i, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            if (i != 4 * LINK_VISIT_MIXED_LINKS_CYCLE_TEST_NUM_LINKS) {
                H5_FAILED();
                printf("    some links were not visited!\n");
                PART_ERROR(H5Lvisit_by_name_cycles_link_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_cycles_link_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(subgroup1) < 0)
        TEST_ERROR;
    if (H5Gclose(subgroup2) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(subgroup1);
        H5Gclose(subgroup2);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that H5Lvisit(_by_name)2 fails when
 * it is given invalid parameters.
 */
static void
test_link_visit_invalid_params(void H5_ATTR_UNUSED *params)
{
    herr_t err_ret = -1;
    htri_t link_exists;
    hid_t  file_id         = H5I_INVALID_HID;
    hid_t  container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t  subgroup1 = H5I_INVALID_HID, subgroup2 = H5I_INVALID_HID;
    hid_t  dset_id                                            = H5I_INVALID_HID;
    hid_t  dset_dtype                                         = H5I_INVALID_HID;
    hid_t  fspace_id                                          = H5I_INVALID_HID;
    char   ext_link_filename[H5_API_TEST_FILENAME_MAX_LENGTH] = {0};

    TESTING_MULTIPART("link visiting with invalid parameters");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, dataset, link, external link, or iterate "
               "aren't supported with this connector\n");
        return;
    }

    TESTING_2("test setup");

    snprintf(ext_link_filename, H5_API_TEST_FILENAME_MAX_LENGTH, "%s%s", test_path_prefix,
             EXTERNAL_LINK_TEST_FILE_NAME);

    if ((file_id = H5Fcreate(ext_link_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create file '%s' for external link to reference\n", ext_link_filename);
        goto error;
    }

    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME, H5P_DEFAULT,
                               H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME);
        goto error;
    }

    if ((subgroup1 = H5Gcreate2(group_id, LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME2, H5P_DEFAULT,
                                H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create first subgroup '%s'\n", LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME2);
        goto error;
    }

    if ((subgroup2 = H5Gcreate2(group_id, LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME3, H5P_DEFAULT,
                                H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create second subgroup '%s'\n", LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME3);
        goto error;
    }

    if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, false)) < 0)
        TEST_ERROR;

    if ((fspace_id = generate_random_dataspace(LINK_VISIT_INVALID_PARAMS_TEST_DSET_SPACE_RANK, NULL, NULL,
                                               false)) < 0)
        TEST_ERROR;

    if ((dset_id = H5Dcreate2(subgroup1, LINK_VISIT_INVALID_PARAMS_TEST_DSET_NAME, dset_dtype, fspace_id,
                              H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create first dataset '%s'\n", LINK_VISIT_INVALID_PARAMS_TEST_DSET_NAME);
    }

    if (H5Dclose(dset_id) < 0)
        TEST_ERROR;

    if ((dset_id = H5Dcreate2(subgroup2, LINK_VISIT_INVALID_PARAMS_TEST_DSET_NAME, dset_dtype, fspace_id,
                              H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create second dataset '%s'\n", LINK_VISIT_INVALID_PARAMS_TEST_DSET_NAME);
    }

    if (H5Dclose(dset_id) < 0)
        TEST_ERROR;

    if (H5Lcreate_hard(subgroup1, LINK_VISIT_INVALID_PARAMS_TEST_DSET_NAME, subgroup1,
                       LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME1, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create first hard link '%s'\n", LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME1);
        goto error;
    }

    if (H5Lcreate_soft(LINK_VISIT_INVALID_PARAMS_TEST_DSET_NAME, subgroup1,
                       LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create soft link '%s'\n", LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME2);
        goto error;
    }
    if (H5Lcreate_external(ext_link_filename, "/", subgroup2, LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME3,
                           H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create external link '%s'\n", LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME3);
        goto error;
    }
    if (H5Lcreate_hard(subgroup2, LINK_VISIT_INVALID_PARAMS_TEST_DSET_NAME, subgroup2,
                       LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME4, H5P_DEFAULT, H5P_DEFAULT) < 0) {
        H5_FAILED();
        printf("    couldn't create second hard link '%s'\n", LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME4);
        goto error;
    }

    /* Verify the links have been created */
    if ((link_exists = H5Lexists(subgroup1, LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME1, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if first link '%s' exists\n",
               LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME1);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 1 did not exist\n");
        goto error;
    }

    if ((link_exists = H5Lexists(subgroup1, LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME2, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if second link '%s' exists\n",
               LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME2);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 2 did not exist\n");
        goto error;
    }

    if ((link_exists = H5Lexists(subgroup2, LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME3, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if third link '%s' exists\n",
               LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME3);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 3 did not exist\n");
        goto error;
    }

    if ((link_exists = H5Lexists(subgroup2, LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME4, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't determine if fourth link '%s' exists\n",
               LINK_VISIT_INVALID_PARAMS_TEST_LINK_NAME4);
        goto error;
    }

    if (!link_exists) {
        H5_FAILED();
        printf("    link 4 did not exist\n");
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lvisit_invalid_grp_id)
        {
            TESTING_2("H5Lvisit2 with an invalid group ID");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit2(H5I_INVALID_HID, H5_INDEX_NAME, H5_ITER_INC, link_visit_invalid_params_cb,
                                    NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit2 succeeded with an invalid group ID!\n");
                PART_ERROR(H5Lvisit_invalid_grp_id);
            }

            PASSED();
        }
        PART_END(H5Lvisit_invalid_grp_id);

        PART_BEGIN(H5Lvisit_invalid_index_type)
        {
            TESTING_2("H5Lvisit2 with an invalid index type");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lvisit2(group_id, H5_INDEX_UNKNOWN, H5_ITER_INC, link_visit_invalid_params_cb, NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit2 succeeded with invalid index type H5_INDEX_UNKNOWN!\n");
                PART_ERROR(H5Lvisit_invalid_index_type);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit2(group_id, H5_INDEX_N, H5_ITER_INC, link_visit_invalid_params_cb, NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit2 succeeded with invalid index type H5_INDEX_N!\n");
                PART_ERROR(H5Lvisit_invalid_index_type);
            }

            PASSED();
        }
        PART_END(H5Lvisit_invalid_index_type);

        PART_BEGIN(H5Lvisit_invalid_iter_order)
        {
            TESTING_2("H5Lvisit2 with an invalid iteration ordering");

            H5E_BEGIN_TRY
            {
                err_ret =
                    H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_UNKNOWN, link_visit_invalid_params_cb, NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit2 succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n");
                PART_ERROR(H5Lvisit_invalid_iter_order);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_N, link_visit_invalid_params_cb, NULL);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit2 succeeded with invalid iteration ordering H5_ITER_N!\n");
                PART_ERROR(H5Lvisit_invalid_iter_order);
            }

            PASSED();
        }
        PART_END(H5Lvisit_invalid_iter_order);

        PART_BEGIN(H5Lvisit_by_name_invalid_loc_id)
        {
            TESTING_2("H5Lvisit_by_name2 with an invalid location ID");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit_by_name2(
                    H5I_INVALID_HID,
                    "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME, H5_INDEX_NAME,
                    H5_ITER_INC, link_visit_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 succeeded with an invalid location ID!\n");
                PART_ERROR(H5Lvisit_by_name_invalid_loc_id);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_invalid_loc_id);

        PART_BEGIN(H5Lvisit_by_name_invalid_grp_name)
        {
            TESTING_2("H5Lvisit_by_name2 with an invalid group name");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit_by_name2(file_id, NULL, H5_INDEX_NAME, H5_ITER_INC,
                                            link_visit_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 succeeded with a NULL group name!\n");
                PART_ERROR(H5Lvisit_by_name_invalid_grp_name);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit_by_name2(file_id, "", H5_INDEX_NAME, H5_ITER_INC,
                                            link_visit_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 succeeded with an invalid group name of ''!\n");
                PART_ERROR(H5Lvisit_by_name_invalid_grp_name);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_invalid_grp_name);

        PART_BEGIN(H5Lvisit_by_name_invalid_index_type)
        {
            TESTING_2("H5Lvisit_by_name2 with an invalid index type");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_UNKNOWN, H5_ITER_INC, link_visit_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 succeeded with invalid index type H5_INDEX_UNKNOWN!\n");
                PART_ERROR(H5Lvisit_by_name_invalid_index_type);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_N, H5_ITER_INC, link_visit_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 succeeded with invalid index type H5_INDEX_N!\n");
                PART_ERROR(H5Lvisit_by_name_invalid_index_type);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_invalid_index_type);

        PART_BEGIN(H5Lvisit_by_name_invalid_iter_order)
        {
            TESTING_2("H5Lvisit_by_name2 with an invalid iteration ordering");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_UNKNOWN, link_visit_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n");
                PART_ERROR(H5Lvisit_by_name_invalid_iter_order);
            }

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_N, link_visit_invalid_params_cb, NULL, H5P_DEFAULT);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 succeeded with invalid iteration ordering H5_ITER_N!\n");
                PART_ERROR(H5Lvisit_by_name_invalid_iter_order);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_invalid_iter_order);

        PART_BEGIN(H5Lvisit_by_name_invalid_lapl)
        {
            TESTING_2("H5Lvisit_by_name2 with an invalid LAPL");

            H5E_BEGIN_TRY
            {
                err_ret = H5Lvisit_by_name2(
                    file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME,
                    H5_INDEX_NAME, H5_ITER_INC, link_visit_invalid_params_cb, NULL, H5I_INVALID_HID);
            }
            H5E_END_TRY

            if (err_ret >= 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 succeeded with an invalid LAPL!\n");
                PART_ERROR(H5Lvisit_by_name_invalid_lapl);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_invalid_lapl);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Sclose(fspace_id) < 0)
        TEST_ERROR;
    if (H5Tclose(dset_dtype) < 0)
        TEST_ERROR;
    if (H5Gclose(subgroup1) < 0)
        TEST_ERROR;
    if (H5Gclose(subgroup2) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;
    if (remove_test_file(NULL, ext_link_filename) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Sclose(fspace_id);
        H5Tclose(dset_dtype);
        H5Dclose(dset_id);
        H5Gclose(subgroup1);
        H5Gclose(subgroup2);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
        remove_test_file(NULL, ext_link_filename);
    }
    H5E_END_TRY

    return;
}

/*
 * A test to check that recursive link iteration
 * performed on a group with no links in it is
 * not problematic.
 */
static void
test_link_visit_0_links(void H5_ATTR_UNUSED *params)
{
    hid_t file_id         = H5I_INVALID_HID;
    hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID;
    hid_t gcpl_id = H5I_INVALID_HID;

    TESTING_MULTIPART("link visiting on group with subgroups containing 0 links");

    /* Make sure the connector supports the API functions being tested */
    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) ||
        !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) {
        SKIPPED();
        printf("    API functions for basic file, group, or link iterate aren't supported "
               "with this connector\n");
        return;
    }

    TESTING_2("test setup");

    if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open file '%s'\n", H5_api_test_filename);
        goto error;
    }

    if ((container_group = H5Gopen2(file_id, LINK_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't open container group '%s'\n", LINK_TEST_GROUP_NAME);
        goto error;
    }

    if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) {
        H5_FAILED();
        printf("    couldn't create a GCPL\n");
        goto error;
    }

    if (vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) {
        if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) {
            H5_FAILED();
            printf("    couldn't enable link creation order tracking and indexing on GCPL\n");
            goto error;
        }
    }

    if ((group_id = H5Gcreate2(container_group, LINK_VISIT_0_LINKS_TEST_SUBGROUP_NAME, H5P_DEFAULT, gcpl_id,
                               H5P_DEFAULT)) < 0) {
        H5_FAILED();
        printf("    couldn't create container subgroup '%s'\n", LINK_VISIT_0_LINKS_TEST_SUBGROUP_NAME);
        goto error;
    }

    PASSED();

    BEGIN_MULTIPART
    {
        PART_BEGIN(H5Lvisit_0_links_name_increasing)
        {
            TESTING_2("H5Lvisit2 by link name in increasing order");

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_INC, link_visit_0_links_cb, NULL) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_0_links_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_0_links_name_increasing);

        PART_BEGIN(H5Lvisit_0_links_name_decreasing)
        {
            TESTING_2("H5Lvisit2 by link name in decreasing order");

            if (H5Lvisit2(group_id, H5_INDEX_NAME, H5_ITER_DEC, link_visit_0_links_cb, NULL) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_0_links_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_0_links_name_decreasing);

        PART_BEGIN(H5Lvisit_0_links_creation_increasing)
        {
            TESTING_2("H5Lvisit2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_0_links_creation_increasing);
            }

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_0_links_cb, NULL) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_0_links_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_0_links_creation_increasing);

        PART_BEGIN(H5Lvisit_0_links_creation_decreasing)
        {
            TESTING_2("H5Lvisit2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_0_links_creation_decreasing);
            }

            if (H5Lvisit2(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_0_links_cb, NULL) < 0) {
                H5_FAILED();
                printf("    H5Lvisit2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_0_links_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_0_links_creation_decreasing);

        PART_BEGIN(H5Lvisit_by_name_0_links_name_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in increasing order");

            if (H5Lvisit_by_name2(file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_0_LINKS_TEST_SUBGROUP_NAME,
                                  H5_INDEX_NAME, H5_ITER_INC, link_visit_0_links_cb, NULL, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_0_links_name_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_0_links_name_increasing);

        PART_BEGIN(H5Lvisit_by_name_0_links_name_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by link name in decreasing order");

            if (H5Lvisit_by_name2(file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_0_LINKS_TEST_SUBGROUP_NAME,
                                  H5_INDEX_NAME, H5_ITER_DEC, link_visit_0_links_cb, NULL, H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type name in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_0_links_name_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_0_links_name_decreasing);

        PART_BEGIN(H5Lvisit_by_name_0_links_creation_increasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in increasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_0_links_creation_increasing);
            }

            if (H5Lvisit_by_name2(file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_0_LINKS_TEST_SUBGROUP_NAME,
                                  H5_INDEX_CRT_ORDER, H5_ITER_INC, link_visit_0_links_cb, NULL,
                                  H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in increasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_0_links_creation_increasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_0_links_creation_increasing);

        PART_BEGIN(H5Lvisit_by_name_0_links_creation_decreasing)
        {
            TESTING_2("H5Lvisit_by_name2 by creation order in decreasing order");

            if (!(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) {
                SKIPPED();
                printf("    creation order tracking isn't supported with this VOL connector\n");
                PART_EMPTY(H5Lvisit_by_name_0_links_creation_decreasing);
            }

            if (H5Lvisit_by_name2(file_id, "/" LINK_TEST_GROUP_NAME "/" LINK_VISIT_0_LINKS_TEST_SUBGROUP_NAME,
                                  H5_INDEX_CRT_ORDER, H5_ITER_DEC, link_visit_0_links_cb, NULL,
                                  H5P_DEFAULT) < 0) {
                H5_FAILED();
                printf("    H5Lvisit_by_name2 by index type creation order in decreasing order failed\n");
                PART_ERROR(H5Lvisit_by_name_0_links_creation_decreasing);
            }

            PASSED();
        }
        PART_END(H5Lvisit_by_name_0_links_creation_decreasing);
    }
    END_MULTIPART;

    TESTING_2("test cleanup");

    if (H5Pclose(gcpl_id) < 0)
        TEST_ERROR;
    if (H5Gclose(group_id) < 0)
        TEST_ERROR;
    if (H5Gclose(container_group) < 0)
        TEST_ERROR;
    if (H5Fclose(file_id) < 0)
        TEST_ERROR;

    PASSED();

    return;

error:
    H5E_BEGIN_TRY
    {
        H5Pclose(gcpl_id);
        H5Gclose(group_id);
        H5Gclose(container_group);
        H5Fclose(file_id);
    }
    H5E_END_TRY

    return;
}

/*
 * Link iteration callback for the hard links test which iterates
 * through all of the links in the test group and checks to make sure
 * their names and link classes match what is expected.
 */
static herr_t
link_iter_hard_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    size_t  test_iteration;
    char    expected_link_name[LINK_ITER_HARD_LINKS_TEST_BUF_SIZE];
    herr_t  ret_val = H5_ITER_CONT;

    UNUSED(group_id);
    UNUSED(op_data);

    if (H5L_TYPE_HARD != info->type) {
        ret_val = H5_ITER_ERROR;
        printf("    link type for link '%s' was not H5L_TYPE_HARD!\n", name);
        goto done;
    }

    /*
     * Four tests are run in the following order per link iteration API call:
     *
     *  - iteration by link name in increasing order
     *  - iteration by link name in decreasing order
     *  - iteration by link creation order in increasing order
     *  - iteration by link creation order in decreasing order
     *
     * Based on how the test is written, this will mean that the dataset names
     * will run in increasing order on the first and fourth tests and decreasing
     * order on the second and third tests.
     */
    test_iteration = (counter_val / LINK_ITER_HARD_LINKS_TEST_NUM_LINKS);
    if (test_iteration == 0 || test_iteration == 3) {
        snprintf(expected_link_name, LINK_ITER_HARD_LINKS_TEST_BUF_SIZE,
                 LINK_ITER_HARD_LINKS_TEST_LINK_NAME "%d",
                 (int)(counter_val % LINK_ITER_HARD_LINKS_TEST_NUM_LINKS));
    }
    else {
        snprintf(expected_link_name, LINK_ITER_HARD_LINKS_TEST_BUF_SIZE,
                 LINK_ITER_HARD_LINKS_TEST_LINK_NAME "%d",
                 (int)(LINK_ITER_HARD_LINKS_TEST_NUM_LINKS -
                       (counter_val % LINK_ITER_HARD_LINKS_TEST_NUM_LINKS) - 1));
    }

    if (strncmp(name, expected_link_name, LINK_ITER_HARD_LINKS_TEST_BUF_SIZE)) {
        printf("    link name '%s' didn't match expected name '%s'\n", name, expected_link_name);
        ret_val = H5_ITER_ERROR;
        goto done;
    }

done:
    (*i)++;

    return ret_val;
}

/*
 * Link iteration callback for the soft links test which iterates
 * through all of the links in the test group and checks to make sure
 * their names and link classes match what is expected.
 */
static herr_t
link_iter_soft_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    size_t  test_iteration;
    char    expected_link_name[LINK_ITER_SOFT_LINKS_TEST_BUF_SIZE];
    herr_t  ret_val = H5_ITER_CONT;

    UNUSED(group_id);
    UNUSED(op_data);

    if (H5L_TYPE_SOFT != info->type) {
        ret_val = H5_ITER_ERROR;
        printf("    link type for link '%s' was not H5L_TYPE_SOFT!\n", name);
        goto done;
    }

    /*
     * Four tests are run in the following order per link iteration API call:
     *
     *  - iteration by link name in increasing order
     *  - iteration by link name in decreasing order
     *  - iteration by link creation order in increasing order
     *  - iteration by link creation order in decreasing order
     *
     * Based on how the test is written, this will mean that the link names
     * will run in increasing order on the first and fourth tests and decreasing
     * order on the second and third tests.
     */
    test_iteration = (counter_val / LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS);
    if (test_iteration == 0 || test_iteration == 3) {
        snprintf(expected_link_name, LINK_ITER_SOFT_LINKS_TEST_BUF_SIZE,
                 LINK_ITER_SOFT_LINKS_TEST_LINK_NAME "%d",
                 (int)(counter_val % LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS));
    }
    else {
        snprintf(expected_link_name, LINK_ITER_SOFT_LINKS_TEST_BUF_SIZE,
                 LINK_ITER_SOFT_LINKS_TEST_LINK_NAME "%d",
                 (int)(LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS -
                       (counter_val % LINK_ITER_SOFT_LINKS_TEST_NUM_LINKS) - 1));
    }

    if (strncmp(name, expected_link_name, LINK_ITER_SOFT_LINKS_TEST_BUF_SIZE)) {
        printf("    link name '%s' didn't match expected name '%s'\n", name, expected_link_name);
        ret_val = H5_ITER_ERROR;
        goto done;
    }

done:
    (*i)++;

    return ret_val;
}

/*
 * Link iteration callback for the external links test which iterates
 * through all of the links in the test group and checks to make sure
 * their names and link classes match what is expected.
 */
static herr_t
link_iter_external_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    size_t  test_iteration;
    char    expected_link_name[LINK_ITER_EXT_LINKS_TEST_BUF_SIZE];
    herr_t  ret_val = H5_ITER_CONT;

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
        printf("    API functions for external links aren't supported with this "
               "connector\n");
        return 1;
    }

    UNUSED(group_id);
    UNUSED(op_data);

    if (H5L_TYPE_EXTERNAL != info->type) {
        ret_val = H5_ITER_ERROR;
        printf("    link type for link '%s' was not H5L_TYPE_EXTERNAL!\n", name);
        goto done;
    }

    /*
     * Four tests are run in the following order per link iteration API call:
     *
     *  - iteration by link name in increasing order
     *  - iteration by link name in decreasing order
     *  - iteration by link creation order in increasing order
     *  - iteration by link creation order in decreasing order
     *
     * Based on how the test is written, this will mean that the link names
     * will run in increasing order on the first and fourth tests and decreasing
     * order on the second and third tests.
     */
    test_iteration = (counter_val / LINK_ITER_EXT_LINKS_TEST_NUM_LINKS);
    if (test_iteration == 0 || test_iteration == 3) {
        snprintf(expected_link_name, LINK_ITER_EXT_LINKS_TEST_BUF_SIZE,
                 LINK_ITER_EXT_LINKS_TEST_LINK_NAME "%d",
                 (int)(counter_val % LINK_ITER_EXT_LINKS_TEST_NUM_LINKS));
    }
    else {
        snprintf(expected_link_name, LINK_ITER_EXT_LINKS_TEST_BUF_SIZE,
                 LINK_ITER_EXT_LINKS_TEST_LINK_NAME "%d",
                 (int)(LINK_ITER_EXT_LINKS_TEST_NUM_LINKS -
                       (counter_val % LINK_ITER_EXT_LINKS_TEST_NUM_LINKS) - 1));
    }

    if (strncmp(name, expected_link_name, LINK_ITER_EXT_LINKS_TEST_BUF_SIZE)) {
        printf("    link name '%s' didn't match expected name '%s'\n", name, expected_link_name);
        ret_val = H5_ITER_ERROR;
        goto done;
    }

done:
    (*i)++;

    return ret_val;
}

/*
 * Link iteration callback for the mixed link types test which iterates
 * through all of the links in the test group and checks to make sure
 * their names and link classes match what is expected.
 */
static herr_t
link_iter_mixed_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    herr_t  ret_val     = 0;

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
        printf("    API functions for external or user-defined link aren't supported with this "
               "connector\n");
        return 1;
    }

    UNUSED(group_id);

    if (!strncmp(name, LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME,
                 strlen(LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME) + 1) &&
        (counter_val == 1 || counter_val == 4 || counter_val == 6 || counter_val == 11)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n", name);
        }

        goto done;
    }
    else if (!strncmp(name, LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME,
                      strlen(LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME) + 1) &&
             (counter_val == 2 || counter_val == 3 || counter_val == 7 || counter_val == 10)) {
        if (H5L_TYPE_SOFT != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_SOFT!\n", name);
        }

        goto done;
    }
    else if (!strncmp(name, LINK_ITER_MIXED_LINKS_TEST_EXT_LINK_NAME,
                      strlen(LINK_ITER_MIXED_LINKS_TEST_EXT_LINK_NAME) + 1) &&
             (counter_val == 0 || counter_val == 5 || counter_val == 8 || counter_val == 9)) {
        if (H5L_TYPE_EXTERNAL != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_EXTERNAL!\n", name);
        }

        goto done;
    }

    printf("    link name '%s' didn't match known names or came in an incorrect order\n", name);

    ret_val = -1;

done:
    (*i)++;

    return ret_val;
}

/*
 * Link iteration callback for the H5Literate(_by_name)2 invalid
 * parameters test which simply does nothing.
 */
static herr_t
link_iter_invalid_params_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    UNUSED(group_id);
    UNUSED(name);
    UNUSED(info);
    UNUSED(op_data);

    return 0;
}

/*
 * Link iteration callback for the 0 links iteration test which
 * simply does nothing.
 */
static herr_t
link_iter_0_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    UNUSED(group_id);
    UNUSED(name);
    UNUSED(info);
    UNUSED(op_data);

    return 0;
}

/*
 * Link iteration callback to test that the index-saving behavior of H5Literate2
 * works correctly.
 */
static herr_t
link_iter_idx_saving_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    int *broken = (int *)op_data;

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
        printf("    API functions for external or user-defined link aren't supported with this "
               "connector\n");
        return 1;
    }

    UNUSED(group_id);

    if (broken && !*broken &&
        !strncmp(name, LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME,
                 strlen(LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME) + 1)) {
        return (*broken = 1);
    }

    if (!strncmp(name, LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME,
                 strlen(LINK_ITER_MIXED_LINKS_TEST_HARD_LINK_NAME) + 1)) {
        if (H5L_TYPE_HARD != info->type) {
            H5_FAILED();
            printf("    link type did not match\n");
            goto error;
        }
    }
    else if (!strncmp(name, LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME,
                      strlen(LINK_ITER_MIXED_LINKS_TEST_SOFT_LINK_NAME) + 1)) {
        if (H5L_TYPE_SOFT != info->type) {
            H5_FAILED();
            printf("    link type did not match\n");
            goto error;
        }
    }
    else if (!strncmp(name, LINK_ITER_MIXED_LINKS_TEST_EXT_LINK_NAME,
                      strlen(LINK_ITER_MIXED_LINKS_TEST_EXT_LINK_NAME) + 1)) {
        if (H5L_TYPE_EXTERNAL != info->type) {
            H5_FAILED();
            printf("    link type did not match\n");
            goto error;
        }
    }
    else {
        H5_FAILED();
        printf("    link name didn't match known names\n");
        goto error;
    }

    return 0;

error:
    return -1;
}

/*
 * Link visiting callback for the hard links + no cycles test which
 * iterates recursively through all of the links in the test group and
 * checks to make sure their names and link classes match what is expected.
 */
static herr_t
link_visit_hard_links_no_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    bool    is_subgroup_link;
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    size_t  test_iteration;
    size_t  subgroup_number;
    size_t  link_idx_val;
    char    expected_link_name[LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE];
    herr_t  ret_val = H5_ITER_CONT;

    UNUSED(group_id);
    UNUSED(op_data);

    if (H5L_TYPE_HARD != info->type) {
        ret_val = H5_ITER_ERROR;
        printf("    link type for link '%s' was not H5L_TYPE_HARD!\n", name);
        goto done;
    }

    /*
     * Four tests are run in the following order per link visiting API call:
     *
     *  - visitation by link name in increasing order
     *  - visitation by link name in decreasing order
     *  - visitation by link creation order in increasing order
     *  - visitation by link creation order in decreasing order
     *
     * Based on how the test is written, this will mean that the dataset and group
     * names will run in increasing order on the first and fourth tests and decreasing
     * order on the second and third tests.
     */
    test_iteration = counter_val / LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

    /* Determine which subgroup is currently being processed */
    subgroup_number =
        /* Take the current counter value modulo the total number of links per test iteration (datasets +
           subgroups) */
        (counter_val % LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST)
        /* and divide it by the number of links per subgroup + 1 to get the subgroup's index number. */
        / (LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1);

    /* Determine whether the current link points to the current subgroup itself */
    is_subgroup_link = (counter_val % (LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) == 0);
    if (!is_subgroup_link) {
        /* Determine the index number of this link within its containing subgroup */
        link_idx_val =
            /* Take the current counter value modulo the total number of links per test iteration (datasets +
               subgroups) */
            (counter_val % LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST)
                /* and take it modulo the number of links per subgroup + 1, finally subtracting 1 to get the
                   link's index number. */
                % (LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) -
            1;
    }

    if (test_iteration == 0 || test_iteration == 3) {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "%d", (int)subgroup_number);
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_LINK_NAME "%d",
                     (int)subgroup_number, (int)link_idx_val);
        }
    }
    else {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "%d",
                     (int)(LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1));
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1),
                     (int)(LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP - link_idx_val - 1));
        }
    }

    if (strncmp(name, expected_link_name, LINK_VISIT_HARD_LINKS_NO_CYCLE_TEST_BUF_SIZE)) {
        printf("    link name '%s' didn't match expected name '%s'\n", name, expected_link_name);
        ret_val = H5_ITER_ERROR;
        goto done;
    }

done:
    (*i)++;

    return ret_val;
}

/*
 * Link visiting callback for the soft links + no cycles test which
 * iterates recursively through all of the links in the test group and
 * checks to make sure their names and link classes match what is expected.
 */
static herr_t
link_visit_soft_links_no_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    bool    is_subgroup_link;
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    size_t  test_iteration;
    size_t  subgroup_number;
    size_t  link_idx_val;
    char    expected_link_name[LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE];
    herr_t  ret_val = H5_ITER_CONT;

    UNUSED(group_id);
    UNUSED(op_data);

    /* Determine whether the current link points to the current subgroup itself */
    is_subgroup_link = (counter_val % (LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) == 0);

    if (is_subgroup_link) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = H5_ITER_ERROR;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n", name);
            goto done;
        }
    }
    else {
        if (H5L_TYPE_SOFT != info->type) {
            ret_val = H5_ITER_ERROR;
            printf("    link type for link '%s' was not H5L_TYPE_SOFT!\n", name);
            goto done;
        }
    }

    /*
     * Four tests are run in the following order per link visiting API call:
     *
     *  - visitation by link name in increasing order
     *  - visitation by link name in decreasing order
     *  - visitation by link creation order in increasing order
     *  - visitation by link creation order in decreasing order
     *
     * Based on how the test is written, this will mean that the link names will
     * run in increasing order on the first and fourth tests and decreasing
     * order on the second and third tests.
     */
    test_iteration = counter_val / LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

    /* Determine which subgroup is currently being processed */
    subgroup_number =
        /* Take the current counter value modulo the total number of links per test iteration (links +
           subgroups) */
        (counter_val % LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST)
        /* and divide it by the number of links per subgroup + 1 to get the subgroup's index number. */
        / (LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1);

    if (!is_subgroup_link) {
        /* Determine the index number of this link within its containing subgroup */
        link_idx_val =
            /* Take the current counter value modulo the total number of links per test iteration (links +
               subgroups) */
            (counter_val % LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST)
                /* and take it modulo the number of links per subgroup + 1, finally subtracting 1 to get the
                   link's index number. */
                % (LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) -
            1;
    }

    if (test_iteration == 0 || test_iteration == 3) {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "%d", (int)subgroup_number);
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_LINK_NAME "%d",
                     (int)subgroup_number, (int)link_idx_val);
        }
    }
    else {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "%d",
                     (int)(LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1));
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1),
                     (int)(LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP - link_idx_val - 1));
        }
    }

    if (strncmp(name, expected_link_name, LINK_VISIT_SOFT_LINKS_NO_CYCLE_TEST_BUF_SIZE)) {
        printf("    link name '%s' didn't match expected name '%s'\n", name, expected_link_name);
        ret_val = H5_ITER_ERROR;
        goto done;
    }

done:
    (*i)++;

    return ret_val;
}

/*
 * Link visiting callback for the external links + no cycles test which
 * iterates recursively through all of the links in the test group and
 * checks to make sure their names and link classes match what is expected.
 */
static herr_t
link_visit_external_links_no_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info,
                                       void *op_data)
{
    bool    is_subgroup_link;
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    size_t  test_iteration;
    size_t  subgroup_number;
    size_t  link_idx_val;
    char    expected_link_name[LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE];
    herr_t  ret_val = H5_ITER_CONT;

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
        SKIPPED();
        printf("    API functions for external links aren't supported with this "
               "connector\n");
        return 1;
    }

    UNUSED(group_id);
    UNUSED(op_data);

    /* Determine whether the current link points to the current subgroup itself */
    is_subgroup_link = (counter_val % (LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) == 0);

    if (is_subgroup_link) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = H5_ITER_ERROR;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n", name);
            goto done;
        }
    }
    else {
        if (H5L_TYPE_EXTERNAL != info->type) {
            ret_val = H5_ITER_ERROR;
            printf("    link type for link '%s' was not H5L_TYPE_EXTERNAL!\n", name);
            goto done;
        }
    }

    /*
     * Four tests are run in the following order per link visiting API call:
     *
     *  - visitation by link name in increasing order
     *  - visitation by link name in decreasing order
     *  - visitation by link creation order in increasing order
     *  - visitation by link creation order in decreasing order
     *
     * Based on how the test is written, this will mean that the link names will
     * run in increasing order on the first and fourth tests and decreasing
     * order on the second and third tests.
     */
    test_iteration = counter_val / LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST;

    /* Determine which subgroup is currently being processed */
    subgroup_number =
        /* Take the current counter value modulo the total number of links per test iteration (links +
           subgroups) */
        (counter_val % LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST)
        /* and divide it by the number of links per subgroup + 1 to get the subgroup's index number. */
        / (LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1);

    if (!is_subgroup_link) {
        /* Determine the index number of this link within its containing subgroup */
        link_idx_val =
            /* Take the current counter value modulo the total number of links per test iteration (links +
               subgroups) */
            (counter_val % LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_TEST)
                /* and take it modulo the number of links per subgroup + 1, finally subtracting 1 to get the
                   link's index number. */
                % (LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) -
            1;
    }

    if (test_iteration == 0 || test_iteration == 3) {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "%d", (int)subgroup_number);
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_LINK_NAME "%d",
                     (int)subgroup_number, (int)link_idx_val);
        }
    }
    else {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME "%d",
                     (int)(LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1));
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1),
                     (int)(LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_NUM_LINKS_PER_GROUP - link_idx_val - 1));
        }
    }

    if (strncmp(name, expected_link_name, LINK_VISIT_EXT_LINKS_NO_CYCLE_TEST_BUF_SIZE)) {
        printf("    link name '%s' didn't match expected name '%s'\n", name, expected_link_name);
        ret_val = H5_ITER_ERROR;
        goto done;
    }

done:
    (*i)++;

    return ret_val;
}

/*
 * Link visiting callback for the mixed link types + no cycles test which
 * iterates recursively through all of the links in the test group and
 * checks to make sure their names and link classes match what is expected.
 */
static herr_t
link_visit_mixed_links_no_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    herr_t  ret_val     = 0;

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
        SKIPPED();
        printf("    API functions for external or user-defined link aren't supported with this "
               "connector\n");
        return 1;
    }

    UNUSED(group_id);
    UNUSED(op_data);

    if (!strncmp(name,
                 LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2
                 "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME1,
                 strlen(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2
                        "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME1) +
                     1) &&
        (counter_val == 2 || counter_val == 14 || counter_val == 18 || counter_val == 30)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2
                   "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME1);
        }

        goto done;
    }
    else if (!strncmp(name,
                      LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2
                      "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME2,
                      strlen(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2
                             "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME2) +
                          1) &&
             (counter_val == 3 || counter_val == 13 || counter_val == 19 || counter_val == 29)) {
        if (H5L_TYPE_SOFT != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_SOFT!\n",
                   LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2
                   "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME2);
        }

        goto done;
    }
    else if (!strncmp(name,
                      LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3
                      "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME3,
                      strlen(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3
                             "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME3) +
                          1) &&
             (counter_val == 6 || counter_val == 10 || counter_val == 22 || counter_val == 26)) {
        if (H5L_TYPE_EXTERNAL != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_EXTERNAL!\n",
                   LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3
                   "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME3);
        }

        goto done;
    }
    else if (!strncmp(name,
                      LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3
                      "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME4,
                      strlen(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3
                             "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME4) +
                          1) &&
             (counter_val == 7 || counter_val == 9 || counter_val == 23 || counter_val == 25)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3
                   "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_LINK_NAME4);
        }

        goto done;
    }
    else if (!strncmp(name,
                      LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2
                      "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME,
                      strlen(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2
                             "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME) +
                          1) &&
             (counter_val == 1 || counter_val == 15 || counter_val == 17 || counter_val == 31)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2
                   "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME);
        }

        goto done;
    }
    else if (!strncmp(name,
                      LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3
                      "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME2,
                      strlen(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3
                             "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME2) +
                          1) &&
             (counter_val == 5 || counter_val == 11 || counter_val == 21 || counter_val == 27)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3
                   "/" LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_DSET_NAME2);
        }

        goto done;
    }
    else if (!strncmp(name, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2,
                      strlen(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2) + 1) &&
             (counter_val == 0 || counter_val == 12 || counter_val == 16 || counter_val == 28)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME2);
        }

        goto done;
    }
    else if (!strncmp(name, LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3,
                      strlen(LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3) + 1) &&
             (counter_val == 4 || counter_val == 8 || counter_val == 20 || counter_val == 24)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_NO_CYCLE_TEST_SUBGROUP_NAME3);
        }

        goto done;
    }

    printf("    link name '%s' didn't match known names or came in an incorrect order\n", name);

    ret_val = -1;

done:
    (*i)++;

    return ret_val;
}

/*
 * Link visiting callback for the hard links + cycles test which
 * iterates recursively through all of the links in the test group and
 * checks to make sure their names and link classes match what is expected.
 */
static herr_t
link_visit_hard_links_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    bool    is_subgroup_link;
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    size_t  test_iteration;
    size_t  subgroup_number;
    size_t  link_idx_val;
    char    expected_link_name[LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE];
    herr_t  ret_val = H5_ITER_CONT;

    UNUSED(group_id);
    UNUSED(op_data);

    if (H5L_TYPE_HARD != info->type) {
        ret_val = H5_ITER_ERROR;
        printf("    link type for link '%s' was not H5L_TYPE_HARD!\n", name);
        goto done;
    }

    /*
     * Four tests are run in the following order per link visiting API call:
     *
     *  - visitation by link name in increasing order
     *  - visitation by link name in decreasing order
     *  - visitation by link creation order in increasing order
     *  - visitation by link creation order in decreasing order
     *
     * Based on how the test is written, this will mean that the link and group
     * names will run in increasing order on the first and fourth tests and decreasing
     * order on the second and third tests.
     */
    test_iteration = counter_val / LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

    /* Determine which subgroup is currently being processed */
    subgroup_number =
        /* Take the current counter value modulo the total number of links per test iteration (links +
           subgroups) */
        (counter_val % LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST)
        /* and divide it by the number of links per subgroup + 1 to get the subgroup's index number. */
        / (LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1);

    /* Determine whether the current link points to the current subgroup itself */
    is_subgroup_link = (counter_val % (LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) == 0);
    if (!is_subgroup_link) {
        /* Determine the index number of this link within its containing subgroup */
        link_idx_val =
            /* Take the current counter value modulo the total number of links per test iteration (links +
               subgroups) */
            (counter_val % LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST)
                /* and take it modulo the number of links per subgroup + 1, finally subtracting 1 to get the
                   link's index number. */
                % (LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) -
            1;
    }

    if (test_iteration == 0 || test_iteration == 3) {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_CYCLE_TEST_NESTED_GRP_NAME "%d", (int)subgroup_number);
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_HARD_LINKS_CYCLE_TEST_LINK_NAME "%d",
                     (int)subgroup_number, (int)link_idx_val);
        }
    }
    else {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_CYCLE_TEST_NESTED_GRP_NAME "%d",
                     (int)(LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1));
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_HARD_LINKS_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_HARD_LINKS_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1),
                     (int)(LINK_VISIT_HARD_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP - link_idx_val - 1));
        }
    }

    if (strncmp(name, expected_link_name, LINK_VISIT_HARD_LINKS_CYCLE_TEST_BUF_SIZE)) {
        printf("    link name '%s' didn't match expected name '%s'\n", name, expected_link_name);
        ret_val = H5_ITER_ERROR;
        goto done;
    }

done:
    (*i)++;

    return ret_val;
}

/*
 * Link visiting callback for the soft links + cycles test which
 * iterates recursively through all of the links in the test group and
 * checks to make sure their names and link classes match what is expected.
 */
static herr_t
link_visit_soft_links_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    bool    is_subgroup_link;
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    size_t  test_iteration;
    size_t  subgroup_number;
    size_t  link_idx_val;
    char    expected_link_name[LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE];
    herr_t  ret_val = H5_ITER_CONT;

    UNUSED(group_id);
    UNUSED(op_data);

    /* Determine whether the current link points to the current subgroup itself */
    is_subgroup_link = (counter_val % (LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) == 0);

    if (is_subgroup_link) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = H5_ITER_ERROR;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n", name);
            goto done;
        }
    }
    else {
        if (H5L_TYPE_SOFT != info->type) {
            ret_val = H5_ITER_ERROR;
            printf("    link type for link '%s' was not H5L_TYPE_SOFT!\n", name);
            goto done;
        }
    }

    /*
     * Four tests are run in the following order per link visiting API call:
     *
     *  - visitation by link name in increasing order
     *  - visitation by link name in decreasing order
     *  - visitation by link creation order in increasing order
     *  - visitation by link creation order in decreasing order
     *
     * Based on how the test is written, this will mean that the link and group
     * names will run in increasing order on the first and fourth tests and decreasing
     * order on the second and third tests.
     */
    test_iteration = counter_val / LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

    /* Determine which subgroup is currently being processed */
    subgroup_number =
        /* Take the current counter value modulo the total number of links per test iteration (links +
           subgroups) */
        (counter_val % LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST)
        /* and divide it by the number of links per subgroup + 1 to get the subgroup's index number. */
        / (LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1);

    if (!is_subgroup_link) {
        /* Determine the index number of this link within its containing subgroup */
        link_idx_val =
            /* Take the current counter value modulo the total number of links per test iteration (links +
               subgroups) */
            (counter_val % LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST)
                /* and take it modulo the number of links per subgroup + 1, finally subtracting 1 to get the
                   link's index number. */
                % (LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) -
            1;
    }

    if (test_iteration == 0 || test_iteration == 3) {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NESTED_GRP_NAME "%d", (int)subgroup_number);
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_SOFT_LINKS_CYCLE_TEST_LINK_NAME "%d",
                     (int)subgroup_number, (int)link_idx_val);
        }
    }
    else {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NESTED_GRP_NAME "%d",
                     (int)(LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1));
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_SOFT_LINKS_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1),
                     (int)(LINK_VISIT_SOFT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP - link_idx_val - 1));
        }
    }

    if (strncmp(name, expected_link_name, LINK_VISIT_SOFT_LINKS_CYCLE_TEST_BUF_SIZE)) {
        printf("    link name '%s' didn't match expected name '%s'\n", name, expected_link_name);
        ret_val = H5_ITER_ERROR;
        goto done;
    }

done:
    (*i)++;

    return ret_val;
}

/*
 * Link visiting callback for the external links + cycles test which
 * iterates recursively through all of the links in the test group and
 * checks to make sure their names and link classes match what is expected.
 */
static herr_t
link_visit_external_links_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    bool    is_subgroup_link;
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    size_t  test_iteration;
    size_t  subgroup_number;
    size_t  link_idx_val;
    char    expected_link_name[LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE];
    herr_t  ret_val = H5_ITER_CONT;

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS)) {
        SKIPPED();
        printf("    API functions for external links aren't supported with this "
               "connector\n");
        return 1;
    }

    UNUSED(group_id);
    UNUSED(op_data);

    /* Determine whether the current link points to the current subgroup itself */
    is_subgroup_link = (counter_val % (LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) == 0);

    if (is_subgroup_link) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = H5_ITER_ERROR;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n", name);
            goto done;
        }
    }
    else {
        if (H5L_TYPE_EXTERNAL != info->type) {
            ret_val = H5_ITER_ERROR;
            printf("    link type for link '%s' was not H5L_TYPE_EXTERNAL!\n", name);
            goto done;
        }
    }

    /*
     * Four tests are run in the following order per link visiting API call:
     *
     *  - visitation by link name in increasing order
     *  - visitation by link name in decreasing order
     *  - visitation by link creation order in increasing order
     *  - visitation by link creation order in decreasing order
     *
     * Based on how the test is written, this will mean that the link and group
     * names will run in increasing order on the first and fourth tests and decreasing
     * order on the second and third tests.
     */
    test_iteration = counter_val / LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST;

    /* Determine which subgroup is currently being processed */
    subgroup_number =
        /* Take the current counter value modulo the total number of links per test iteration (links +
           subgroups) */
        (counter_val % LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST)
        /* and divide it by the number of links per subgroup + 1 to get the subgroup's index number. */
        / (LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1);

    if (!is_subgroup_link) {
        /* Determine the index number of this link within its containing subgroup */
        link_idx_val =
            /* Take the current counter value modulo the total number of links per test iteration (links +
               subgroups) */
            (counter_val % LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_TEST)
                /* and take it modulo the number of links per subgroup + 1, finally subtracting 1 to get the
                   link's index number. */
                % (LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP + 1) -
            1;
    }

    if (test_iteration == 0 || test_iteration == 3) {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_CYCLE_TEST_NESTED_GRP_NAME "%d", (int)subgroup_number);
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_EXT_LINKS_CYCLE_TEST_LINK_NAME "%d",
                     (int)subgroup_number, (int)link_idx_val);
        }
    }
    else {
        if (is_subgroup_link) {
            snprintf(expected_link_name, LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_CYCLE_TEST_NESTED_GRP_NAME "%d",
                     (int)(LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1));
        }
        else {
            snprintf(expected_link_name, LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE,
                     LINK_VISIT_EXT_LINKS_CYCLE_TEST_NESTED_GRP_NAME
                     "%d"
                     "/" LINK_VISIT_EXT_LINKS_CYCLE_TEST_LINK_NAME "%d",
                     (int)(LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_SUBGROUPS - subgroup_number - 1),
                     (int)(LINK_VISIT_EXT_LINKS_CYCLE_TEST_NUM_LINKS_PER_GROUP - link_idx_val - 1));
        }
    }

    if (strncmp(name, expected_link_name, LINK_VISIT_EXT_LINKS_CYCLE_TEST_BUF_SIZE)) {
        printf("    link name '%s' didn't match expected name '%s'\n", name, expected_link_name);
        ret_val = H5_ITER_ERROR;
        goto done;
    }

done:
    (*i)++;

    return ret_val;
}

/*
 * Link visiting callback for the mixed link types + cycles test which
 * iterates recursively through all of the links in the test group and
 * checks to make sure their names and link classes match what is expected.
 */
static herr_t
link_visit_mixed_links_cycles_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    size_t *i           = (size_t *)op_data;
    size_t  counter_val = *((size_t *)op_data);
    herr_t  ret_val     = 0;

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_EXTERNAL_LINKS) || !(vol_cap_flags_g & H5VL_CAP_FLAG_UD_LINKS)) {
        SKIPPED();
        printf("    API functions for external or user-defined link aren't supported with this "
               "connector\n");
        return 1;
    }

    UNUSED(group_id);
    UNUSED(op_data);

    if (!strncmp(name,
                 LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2
                 "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME1,
                 strlen(LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2
                        "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME1) +
                     1) &&
        (counter_val == 1 || counter_val == 11 || counter_val == 13 || counter_val == 23)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2
                   "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME1);
        }

        goto done;
    }
    else if (!strncmp(name,
                      LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2
                      "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME2,
                      strlen(LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2
                             "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME2) +
                          1) &&
             (counter_val == 2 || counter_val == 10 || counter_val == 14 || counter_val == 22)) {
        if (H5L_TYPE_SOFT != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_SOFT!\n",
                   LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2
                   "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME2);
        }

        goto done;
    }
    else if (!strncmp(name,
                      LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3
                      "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME3,
                      strlen(LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3
                             "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME3) +
                          1) &&
             (counter_val == 4 || counter_val == 8 || counter_val == 16 || counter_val == 20)) {
        if (H5L_TYPE_EXTERNAL != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_EXTERNAL!\n",
                   LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3
                   "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME3);
        }

        goto done;
    }
    else if (!strncmp(name,
                      LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3
                      "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME4,
                      strlen(LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3
                             "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME4) +
                          1) &&
             (counter_val == 5 || counter_val == 7 || counter_val == 17 || counter_val == 19)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3
                   "/" LINK_VISIT_MIXED_LINKS_CYCLE_TEST_LINK_NAME4);
        }

        goto done;
    }
    else if (!strncmp(name, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2,
                      strlen(LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2) + 1) &&
             (counter_val == 0 || counter_val == 9 || counter_val == 12 || counter_val == 21)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME2);
        }

        goto done;
    }
    else if (!strncmp(name, LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3,
                      strlen(LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3) + 1) &&
             (counter_val == 3 || counter_val == 6 || counter_val == 15 || counter_val == 18)) {
        if (H5L_TYPE_HARD != info->type) {
            ret_val = -1;
            printf("    link type for link '%s' was not H5L_TYPE_HARD!\n",
                   LINK_VISIT_MIXED_LINKS_CYCLE_TEST_SUBGROUP_NAME3);
        }

        goto done;
    }

    printf("    link name '%s' didn't match known names or came in an incorrect order\n", name);

    ret_val = -1;

done:
    (*i)++;

    return ret_val;
}

/*
 * Link visiting callback for the H5Lvisit(_by_name)2 invalid
 * parameters test which simply does nothing.
 */
static herr_t
link_visit_invalid_params_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    UNUSED(group_id);
    UNUSED(name);
    UNUSED(info);
    UNUSED(op_data);

    return 0;
}

/*
 * Link visiting callback for the 0 links visiting test which
 * simply does nothing.
 */
static herr_t
link_visit_0_links_cb(hid_t group_id, const char *name, const H5L_info2_t *info, void *op_data)
{
    UNUSED(group_id);
    UNUSED(name);
    UNUSED(info);
    UNUSED(op_data);

    return 0;
}

void
H5_api_link_test_add(void)
{
    /* Add a fake test to print out a header to distinguish different test interfaces */
    AddTest("print_link_test_header", print_link_test_header, NULL, NULL, NULL, 0,
            "Prints header for link tests");

    AddTest("test_create_hard_link", test_create_hard_link, NULL, NULL, NULL, 0, "hard link creation");
    AddTest("test_create_hard_link_long_name", test_create_hard_link_long_name, NULL, NULL, NULL, 0,
            "hard link creation with a long name");
    AddTest("test_create_hard_link_many", test_create_hard_link_many, NULL, NULL, NULL, 0,
            "hard link creation of many links");
    AddTest("test_create_hard_link_same_loc", test_create_hard_link_same_loc, NULL, NULL, NULL, 0,
            "hard link creation with H5L_SAME_LOC");
    AddTest("test_create_hard_link_invalid_params", test_create_hard_link_invalid_params, NULL, NULL, NULL, 0,
            "hard link creation with invalid parameters");
    AddTest("test_create_soft_link_existing_relative", test_create_soft_link_existing_relative, NULL, NULL,
            NULL, 0, "soft link creation to existing object by relative path");
    AddTest("test_create_soft_link_existing_absolute", test_create_soft_link_existing_absolute, NULL, NULL,
            NULL, 0, "soft link creation to existing object by absolute path");
    AddTest("test_create_soft_link_dangling_relative", test_create_soft_link_dangling_relative, NULL, NULL,
            NULL, 0, "dangling soft link creation to object by relative path");
    AddTest("test_create_soft_link_dangling_absolute", test_create_soft_link_dangling_absolute, NULL, NULL,
            NULL, 0, "dangling soft link creation to object by absolute path");
    AddTest("test_create_soft_link_long_name", test_create_soft_link_long_name, NULL, NULL, NULL, 0,
            "soft link creation with a long name");
    AddTest("test_create_soft_link_many", test_create_soft_link_many, NULL, NULL, NULL, 0,
            "soft link creation of many links");
    AddTest("test_create_soft_link_invalid_params", test_create_soft_link_invalid_params, NULL, NULL, NULL, 0,
            "soft link creation with invalid parameters");
    AddTest("test_create_external_link", test_create_external_link, NULL, NULL, NULL, 0,
            "external link creation to existing object");
    AddTest("test_create_external_link_dangling", test_create_external_link_dangling, NULL, NULL, NULL, 0,
            "dangling external link creation");
    AddTest("test_create_external_link_multi", test_create_external_link_multi, NULL, NULL, NULL, 0,
            "external link creation to an object across several files");
    AddTest("test_create_external_link_ping_pong", test_create_external_link_ping_pong, NULL, NULL, NULL, 0,
            "external link creation to an object in ping pong style");
    AddTest("test_create_external_link_invalid_params", test_create_external_link_invalid_params, NULL, NULL,
            NULL, 0, "H5Lcreate_external with invalid parameters");
    AddTest("test_create_user_defined_link", test_create_user_defined_link, NULL, NULL, NULL, 0,
            "user-defined link creation");
    AddTest("test_create_user_defined_link_invalid_params", test_create_user_defined_link_invalid_params,
            NULL, NULL, NULL, 0, "H5Lcreate_ud with invalid parameters");
    AddTest("test_delete_link", test_delete_link, NULL, NULL, NULL, 0, "link deletion");
    AddTest("test_delete_link_reset_grp_max_crt_order", test_delete_link_reset_grp_max_crt_order, NULL, NULL,
            NULL, 0, "H5Ldelete of all links in group resets group's maximum link creation order value");
    AddTest("test_delete_link_invalid_params", test_delete_link_invalid_params, NULL, NULL, NULL, 0,
            "H5Ldelete with invalid parameters");
    AddTest("test_copy_link", test_copy_link, NULL, NULL, NULL, 0, "link copying");
    AddTest("test_copy_links_into_group_with_links", test_copy_links_into_group_with_links, NULL, NULL, NULL,
            0, "H5Lcopy adjusting creation order values for copied links");
    AddTest("test_copy_link_across_files", test_copy_link_across_files, NULL, NULL, NULL, 0,
            "link copying across files");
    AddTest("test_copy_link_invalid_params", test_copy_link_invalid_params, NULL, NULL, NULL, 0,
            "H5Lcopy with invalid parameters");
    AddTest("test_move_link", test_move_link, NULL, NULL, NULL, 0, "link moving");
    AddTest("test_move_links_into_group_with_links", test_move_links_into_group_with_links, NULL, NULL, NULL,
            0, "H5Lmove adjusting creation order values for moved links");
    AddTest("test_move_link_across_files", test_move_link_across_files, NULL, NULL, NULL, 0,
            "link moving across files");
    AddTest("test_move_link_reset_grp_max_crt_order", test_move_link_reset_grp_max_crt_order, NULL, NULL,
            NULL, 0, "H5Lmove of all links out of group resets group's maximum link creation order value");
    AddTest("test_move_link_invalid_params", test_move_link_invalid_params, NULL, NULL, NULL, 0,
            "H5Lmove with invalid parameters");
    AddTest("test_get_link_val", test_get_link_val, NULL, NULL, NULL, 0, "link value retrieval");
    AddTest("test_get_link_val_invalid_params", test_get_link_val_invalid_params, NULL, NULL, NULL, 0,
            "link value retrieval with invalid parameters");
    AddTest("test_get_link_info", test_get_link_info, NULL, NULL, NULL, 0, "link info retrieval");
    AddTest("test_get_link_info_invalid_params", test_get_link_info_invalid_params, NULL, NULL, NULL, 0,
            "link info retrieval with invalid parameters");
    AddTest("test_get_link_name", test_get_link_name, NULL, NULL, NULL, 0, "link name retrieval");
    AddTest("test_get_link_name_invalid_params", test_get_link_name_invalid_params, NULL, NULL, NULL, 0,
            "link name retrieval with invalid parameters");
    AddTest("test_link_iterate_hard_links", test_link_iterate_hard_links, NULL, NULL, NULL, 0,
            "link iteration (only hard links)");
    AddTest("test_link_iterate_soft_links", test_link_iterate_soft_links, NULL, NULL, NULL, 0,
            "link iteration (only soft links)");
    AddTest("test_link_iterate_external_links", test_link_iterate_external_links, NULL, NULL, NULL, 0,
            "link iteration (only external links)");
    AddTest("test_link_iterate_ud_links", test_link_iterate_ud_links, NULL, NULL, NULL, 0,
            "link iteration (only user-defined links)");
    AddTest("test_link_iterate_mixed_links", test_link_iterate_mixed_links, NULL, NULL, NULL, 0,
            "link iteration (mixed link types)");
    AddTest("test_link_iterate_invalid_params", test_link_iterate_invalid_params, NULL, NULL, NULL, 0,
            "link iteration with invalid parameters");
    AddTest("test_link_iterate_0_links", test_link_iterate_0_links, NULL, NULL, NULL, 0,
            "link iteration on group with 0 links");
    AddTest("test_link_visit_hard_links_no_cycles", test_link_visit_hard_links_no_cycles, NULL, NULL, NULL, 0,
            "link visiting without cycles (only hard links)");
    AddTest("test_link_visit_soft_links_no_cycles", test_link_visit_soft_links_no_cycles, NULL, NULL, NULL, 0,
            "link visiting without cycles (only soft links)");
    AddTest("test_link_visit_external_links_no_cycles", test_link_visit_external_links_no_cycles, NULL, NULL,
            NULL, 0, "link visiting without cycles (only external links)");
    AddTest("test_link_visit_ud_links_no_cycles", test_link_visit_ud_links_no_cycles, NULL, NULL, NULL, 0,
            "link visiting without cycles (only user-defined links)");
    AddTest("test_link_visit_mixed_links_no_cycles", test_link_visit_mixed_links_no_cycles, NULL, NULL, NULL,
            0, "link visiting without cycles (mixed link types)");
    AddTest("test_link_visit_hard_links_cycles", test_link_visit_hard_links_cycles, NULL, NULL, NULL, 0,
            "link visiting with cycles (only hard links)");
    AddTest("test_link_visit_soft_links_cycles", test_link_visit_soft_links_cycles, NULL, NULL, NULL, 0,
            "link visiting with cycles (only soft links)");
    AddTest("test_link_visit_external_links_cycles", test_link_visit_external_links_cycles, NULL, NULL, NULL,
            0, "link visiting with cycles (only external links)");
    AddTest("test_link_visit_ud_links_cycles", test_link_visit_ud_links_cycles, NULL, NULL, NULL, 0,
            "link visiting with cycles (only user-defined links)");
    AddTest("test_link_visit_mixed_links_cycles", test_link_visit_mixed_links_cycles, NULL, NULL, NULL, 0,
            "link visiting with cycles (mixed link types)");
    AddTest("test_link_visit_invalid_params", test_link_visit_invalid_params, NULL, NULL, NULL, 0,
            "link visiting with invalid parameters");
    AddTest("test_link_visit_0_links", test_link_visit_0_links, NULL, NULL, NULL, 0,
            "link visiting on group with subgroups containing 0 links");
}
