/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * 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.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/***********************************************************
 *
 * Test program:     tfile
 *
 * Test the low-level file I/O features.
 *
 *************************************************************/

#include "testhdf5.h"
#include "H5srcdir.h"

#include "H5Iprivate.h"
#include "H5Pprivate.h"
#include "H5VLprivate.h" /* Virtual Object Layer                     */
#include "H5private.h"

/*
 * This file needs to access private information from the H5F package.
 * This file also needs to access the file testing code.
 */
#define H5F_FRIEND /*suppress error about including H5Fpkg */
#define H5F_TESTING
#include "H5Fpkg.h" /* File access                             */

#define H5FD_FRIEND /*suppress error about including H5FDpkg.h */
#define H5FD_TESTING
#include "H5FDpkg.h"

#define H5D_FRIEND  /*suppress error about including H5Dpkg */
#include "H5Dpkg.h" /* Dataset access                       */

#define H5S_FRIEND  /*suppress error about including H5Spkg */
#include "H5Spkg.h" /* Dataspace                            */

#define H5T_FRIEND  /*suppress error about including H5Tpkg */
#include "H5Tpkg.h" /* Datatype                             */

#define H5A_FRIEND  /*suppress error about including H5Apkg */
#include "H5Apkg.h" /* Attributes                           */

#define H5O_FRIEND  /*suppress error about including H5Opkg */
#include "H5Opkg.h" /* Object headers                       */

#define BAD_USERBLOCK_SIZE1 (hsize_t)1
#define BAD_USERBLOCK_SIZE2 (hsize_t)2
#define BAD_USERBLOCK_SIZE3 (hsize_t)3
#define BAD_USERBLOCK_SIZE4 (hsize_t)64
#define BAD_USERBLOCK_SIZE5 (hsize_t)511
#define BAD_USERBLOCK_SIZE6 (hsize_t)513
#define BAD_USERBLOCK_SIZE7 (hsize_t)6144

#define F1_USERBLOCK_SIZE (hsize_t)0
#define F1_OFFSET_SIZE    sizeof(haddr_t)
#define F1_LENGTH_SIZE    sizeof(hsize_t)
#define F1_SYM_LEAF_K     4
#define F1_SYM_INTERN_K   16
#define FILE1             "tfile1.h5"
#define SFILE1            "sys_file1"

#define REOPEN_FILE "tfile_reopen.h5"
#define REOPEN_DSET "dset"

#define F2_USERBLOCK_SIZE (hsize_t)512
#define F2_OFFSET_SIZE    8
#define F2_LENGTH_SIZE    8
#define F2_SYM_LEAF_K     8
#define F2_SYM_INTERN_K   32
#define F2_RANK           2
#define F2_DIM0           4
#define F2_DIM1           6
#define F2_DSET           "dset"
#define FILE2             "tfile2.h5"

#define F3_USERBLOCK_SIZE (hsize_t)0
#define F3_OFFSET_SIZE    F2_OFFSET_SIZE
#define F3_LENGTH_SIZE    F2_LENGTH_SIZE
#define F3_SYM_LEAF_K     F2_SYM_LEAF_K
#define F3_SYM_INTERN_K   F2_SYM_INTERN_K
#define FILE3             "tfile3.h5"

#define GRP_NAME  "/group"
#define DSET_NAME "dataset"
#define ATTR_NAME "attr"
#define TYPE_NAME "type"
#define FILE4     "tfile4.h5"

#define OBJ_ID_COUNT_0 0
#define OBJ_ID_COUNT_1 1
#define OBJ_ID_COUNT_2 2
#define OBJ_ID_COUNT_3 3
#define OBJ_ID_COUNT_4 4
#define OBJ_ID_COUNT_6 6
#define OBJ_ID_COUNT_8 8

#define GROUP1 "Group1"
#define DSET1  "Dataset1"
#define DSET2  "/Group1/Dataset2"

#define TESTA_GROUPNAME     "group"
#define TESTA_DSETNAME      "dataset"
#define TESTA_ATTRNAME      "attribute"
#define TESTA_DTYPENAME     "compound"
#define TESTA_NAME_BUF_SIZE 64
#define TESTA_RANK          2
#define TESTA_NX            4
#define TESTA_NY            5

#define USERBLOCK_SIZE ((hsize_t)512)

/* Declarations for test_filespace_*() */
#define FILENAME_LEN     1024                       /* length of file name */
#define DSETNAME         "dset"                     /* Name of dataset */
#define NELMTS(X)        (sizeof(X) / sizeof(X[0])) /* # of elements */
#define READ_OLD_BUFSIZE 1024                       /* Buffer for holding file data */
#define FILE5            "tfile5.h5"                /* Test file */
#define TEST_THRESHOLD10 10                         /* Free space section threshold */
#define FSP_SIZE_DEF     4096                       /* File space page size default */
#define FSP_SIZE512      512                        /* File space page size */
#define FSP_SIZE1G       (1024 * 1024 * 1024)       /* File space page size */

/* Declaration for test_libver_macros2() */
#define FILE6 "tfile6.h5" /* Test file */

/* Declaration for test_get_obj_ids() */
#define FILE7   "tfile7.h5" /* Test file */
#define NGROUPS 2
#define NDSETS  4

/* Declaration for libver bounds tests */
#define FILE8 "tfile8.h5" /* Test file */

/* Declaration for test_file_double_file_dataset_open() */
#define FILE_DOUBLE_OPEN "tfile_double_open"

/* Declaration for test_incr_filesize() */
#define FILE_INCR_FILESIZE "tfile_incr_filesize"

/* Files created under 1.6 branch and 1.8 branch--used in test_filespace_compatible() */
static const char *OLD_FILENAME[] = {
    "filespace_1_6.h5", /* 1.6 HDF5 file */
    "filespace_1_8.h5"  /* 1.8 HDF5 file */
};

/* Files created in 1.10.0 release --used in test_filespace_1.10.0_compatible() */
/* These files are copied from release 1.10.0 tools/h5format_convert/testfiles */
static const char *OLD_1_10_0_FILENAME[] = {
    "h5fc_ext1_i.h5",   /* 0 */
    "h5fc_ext1_f.h5",   /* 1 */
    "h5fc_ext2_if.h5",  /* 2 */
    "h5fc_ext2_sf.h5",  /* 3 */
    "h5fc_ext3_isf.h5", /* 4 */
    "h5fc_ext_none.h5"  /* 5 */
};

/* Files used in test_filespace_round_compatible() */
static const char *FSPACE_FILENAMES[] = {
    "fsm_aggr_nopersist.h5", /* H5F_FILE_SPACE_AGGR, not persisting free-space */
    "fsm_aggr_persist.h5",   /* H5F_FILE_SPACE_AGGR, persisting free-space */
    "paged_nopersist.h5",    /* H5F_FILE_SPACE_PAGE, not persisting free-space */
    "paged_persist.h5",      /* H5F_FILE_SPACE_PAGE, persisting free-space */
    "aggr.h5",               /* H5F_FILE_SPACE_AGGR */
    "none.h5"                /* H5F_FILE_SPACE_NONE */
};

static const char *FILESPACE_NAME[] = {"tfilespace", NULL};

/* Declarations for test_libver_bounds_copy():                          */
/* SRC_FILE: source file created under 1.8 branch with latest format    */
/* DST_FILE: destination file for copying the dataset in SRC_FILE       */
/* DSET_DS1: the dataset created in SRC_FILE to be copied to DST_FILE   */
#define SRC_FILE "fill18.h5"
#define DST_FILE "fill18_copy.h5"
#define DSET_DS1 "DS1"

/* Local test function declarations for version bounds */
static void test_libver_bounds_low_high(const char *driver_name);
static void test_libver_bounds_super(hid_t fapl, const char *driver_name);
static void test_libver_bounds_super_create(hid_t fapl, hid_t fcpl, htri_t is_swmr, htri_t non_def_fsm);
static void test_libver_bounds_super_open(hid_t fapl, hid_t fcpl, htri_t is_swmr, htri_t non_def_fsm);
static void test_libver_bounds_obj(hid_t fapl);
static void test_libver_bounds_dataset(hid_t fapl);
static void test_libver_bounds_dataspace(hid_t fapl);
static void test_libver_bounds_datatype(hid_t fapl);
static void test_libver_bounds_datatype_check(hid_t fapl, hid_t tid);
static void test_libver_bounds_attributes(hid_t fapl);

#define DSET_NULL "DSET_NULL"
#define DSET      "DSET"
#define DSETA     "DSETA"
#define DSETB     "DSETB"
#define DSETC     "DSETC"

static void create_objects(hid_t, hid_t, hid_t *, hid_t *, hid_t *, hid_t *);
static void test_obj_count_and_id(hid_t, hid_t, hid_t, hid_t, hid_t, hid_t);
static void check_file_id(hid_t, hid_t);

/* Helper routine used by test_rw_noupdate() */
static int cal_chksum(const char *file, uint32_t *chksum);

static void test_rw_noupdate(void);

/****************************************************************
**
**  test_file_create(): Low-level file creation I/O test routine.
**
****************************************************************/
static void
test_file_create(void)
{
    hid_t    fid1 = H5I_INVALID_HID;
    hid_t    fid2 = H5I_INVALID_HID;
    hid_t    fid3 = H5I_INVALID_HID; /* HDF5 File IDs               */
    hid_t    tmpl1, tmpl2;           /* file creation templates     */
    hsize_t  ublock;                 /* sizeof userblock            */
    size_t   parm;                   /* file-creation parameters    */
    size_t   parm2;                  /* file-creation parameters    */
    unsigned iparm;
    unsigned iparm2;
    herr_t   ret; /*generic return value        */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Low-Level File Creation I/O\n"));

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC)) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* First ensure the file does not exist */
    H5E_BEGIN_TRY
    {
        H5Fdelete(FILE1, H5P_DEFAULT);
    }
    H5E_END_TRY

    /* Try opening a non-existent file */
    H5E_BEGIN_TRY
    {
        fid1 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(fid1, FAIL, "H5Fopen");

    /* Test create with various sequences of H5F_ACC_EXCL and */
    /* H5F_ACC_TRUNC flags */

    /* Create with H5F_ACC_EXCL */
    fid1 = H5Fcreate(FILE1, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid1, FAIL, "H5Fcreate");

    /*
     * try to create the same file with H5F_ACC_TRUNC. This should fail
     * because fid1 is the same file and is currently open.
     */
    H5E_BEGIN_TRY
    {
        fid2 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(fid2, FAIL, "H5Fcreate");

    /* Close all files */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    H5E_BEGIN_TRY
    {
        ret = H5Fclose(fid2);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Fclose"); /*file should not have been open */

    /*
     * Try again with H5F_ACC_EXCL. This should fail because the file already
     * exists from the previous steps.
     */
    H5E_BEGIN_TRY
    {
        fid1 = H5Fcreate(FILE1, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(fid1, FAIL, "H5Fcreate");

    /* Test create with H5F_ACC_TRUNC. This will truncate the existing file. */
    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid1, FAIL, "H5Fcreate");

    /*
     * Try to truncate first file again. This should fail because fid1 is the
     * same file and is currently open.
     */
    H5E_BEGIN_TRY
    {
        fid2 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(fid2, FAIL, "H5Fcreate");

    /*
     * Try with H5F_ACC_EXCL. This should fail too because the file already
     * exists.
     */
    H5E_BEGIN_TRY
    {
        fid2 = H5Fcreate(FILE1, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(fid2, FAIL, "H5Fcreate");

    /* Get the file-creation template */
    tmpl1 = H5Fget_create_plist(fid1);
    CHECK(tmpl1, FAIL, "H5Fget_create_plist");

    /* Get the file-creation parameters */
    ret = H5Pget_userblock(tmpl1, &ublock);
    CHECK(ret, FAIL, "H5Pget_userblock");
    VERIFY(ublock, F1_USERBLOCK_SIZE, "H5Pget_userblock");

    ret = H5Pget_sizes(tmpl1, &parm, &parm2);
    CHECK(ret, FAIL, "H5Pget_sizes");
    VERIFY(parm, F1_OFFSET_SIZE, "H5Pget_sizes");
    VERIFY(parm2, F1_LENGTH_SIZE, "H5Pget_sizes");

    ret = H5Pget_sym_k(tmpl1, &iparm, &iparm2);
    CHECK(ret, FAIL, "H5Pget_sym_k");
    VERIFY(iparm, F1_SYM_INTERN_K, "H5Pget_sym_k");
    VERIFY(iparm2, F1_SYM_LEAF_K, "H5Pget_sym_k");

    /* Release file-creation template */
    ret = H5Pclose(tmpl1);
    CHECK(ret, FAIL, "H5Pclose");

    if (h5_using_default_driver(NULL)) {

        /* Create a new file with a non-standard file-creation template */
        tmpl1 = H5Pcreate(H5P_FILE_CREATE);
        CHECK(tmpl1, FAIL, "H5Pcreate");

        /* Try setting some bad userblock sizes */
        H5E_BEGIN_TRY
        {
            ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE1);
        }
        H5E_END_TRY
        VERIFY(ret, FAIL, "H5Pset_userblock");
        H5E_BEGIN_TRY
        {
            ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE2);
        }
        H5E_END_TRY
        VERIFY(ret, FAIL, "H5Pset_userblock");
        H5E_BEGIN_TRY
        {
            ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE3);
        }
        H5E_END_TRY
        VERIFY(ret, FAIL, "H5Pset_userblock");
        H5E_BEGIN_TRY
        {
            ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE4);
        }
        H5E_END_TRY
        VERIFY(ret, FAIL, "H5Pset_userblock");
        H5E_BEGIN_TRY
        {
            ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE5);
        }
        H5E_END_TRY
        VERIFY(ret, FAIL, "H5Pset_userblock");
        H5E_BEGIN_TRY
        {
            ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE6);
        }
        H5E_END_TRY
        VERIFY(ret, FAIL, "H5Pset_userblock");
        H5E_BEGIN_TRY
        {
            ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE7);
        }
        H5E_END_TRY
        VERIFY(ret, FAIL, "H5Pset_userblock");

        /* Set the new file-creation parameters */
        ret = H5Pset_userblock(tmpl1, F2_USERBLOCK_SIZE);
        CHECK(ret, FAIL, "H5Pset_userblock");

        ret = H5Pset_sizes(tmpl1, (size_t)F2_OFFSET_SIZE, (size_t)F2_LENGTH_SIZE);
        CHECK(ret, FAIL, "H5Pset_sizes");

        ret = H5Pset_sym_k(tmpl1, F2_SYM_INTERN_K, F2_SYM_LEAF_K);
        CHECK(ret, FAIL, "H5Pset_sym_k");

        /*
         * Try to create second file, with non-standard file-creation template
         * params.
         */
        fid2 = H5Fcreate(FILE2, H5F_ACC_TRUNC, tmpl1, H5P_DEFAULT);
        CHECK(fid2, FAIL, "H5Fcreate");

        /* Release file-creation template */
        ret = H5Pclose(tmpl1);
        CHECK(ret, FAIL, "H5Pclose");

        /* Make certain we can create a dataset properly in the file with the userblock */
        {
            hid_t    dataset_id, dataspace_id; /* identifiers */
            hsize_t  dims[F2_RANK];
            unsigned data[F2_DIM0][F2_DIM1];
            unsigned i, j;

            /* Create the data space for the dataset. */
            dims[0]      = F2_DIM0;
            dims[1]      = F2_DIM1;
            dataspace_id = H5Screate_simple(F2_RANK, dims, NULL);
            CHECK(dataspace_id, FAIL, "H5Screate_simple");

            /* Create the dataset. */
            dataset_id = H5Dcreate2(fid2, F2_DSET, H5T_NATIVE_UINT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT,
                                    H5P_DEFAULT);
            CHECK(dataset_id, FAIL, "H5Dcreate2");

            for (i = 0; i < F2_DIM0; i++)
                for (j = 0; j < F2_DIM1; j++)
                    data[i][j] = i * 10 + j;

            /* Write data to the new dataset */
            ret = H5Dwrite(dataset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
            CHECK(ret, FAIL, "H5Dwrite");

            /* End access to the dataset and release resources used by it. */
            ret = H5Dclose(dataset_id);
            CHECK(ret, FAIL, "H5Dclose");

            /* Terminate access to the data space. */
            ret = H5Sclose(dataspace_id);
            CHECK(ret, FAIL, "H5Sclose");
        }

        /* Get the file-creation template */
        tmpl1 = H5Fget_create_plist(fid2);
        CHECK(tmpl1, FAIL, "H5Fget_create_plist");

        /* Get the file-creation parameters */
        ret = H5Pget_userblock(tmpl1, &ublock);
        CHECK(ret, FAIL, "H5Pget_userblock");
        VERIFY(ublock, F2_USERBLOCK_SIZE, "H5Pget_userblock");

        ret = H5Pget_sizes(tmpl1, &parm, &parm2);
        CHECK(ret, FAIL, "H5Pget_sizes");
        VERIFY(parm, F2_OFFSET_SIZE, "H5Pget_sizes");
        VERIFY(parm2, F2_LENGTH_SIZE, "H5Pget_sizes");

        ret = H5Pget_sym_k(tmpl1, &iparm, &iparm2);
        CHECK(ret, FAIL, "H5Pget_sym_k");
        VERIFY(iparm, F2_SYM_INTERN_K, "H5Pget_sym_k");
        VERIFY(iparm2, F2_SYM_LEAF_K, "H5Pget_sym_k");

        /* Clone the file-creation template */
        tmpl2 = H5Pcopy(tmpl1);
        CHECK(tmpl2, FAIL, "H5Pcopy");

        /* Release file-creation template */
        ret = H5Pclose(tmpl1);
        CHECK(ret, FAIL, "H5Pclose");

        /* Set the new file-creation parameter */
        ret = H5Pset_userblock(tmpl2, F3_USERBLOCK_SIZE);
        CHECK(ret, FAIL, "H5Pset_userblock");

        /*
         * Try to create second file, with non-standard file-creation template
         * params
         */
        fid3 = H5Fcreate(FILE3, H5F_ACC_TRUNC, tmpl2, H5P_DEFAULT);
        CHECK(fid3, FAIL, "H5Fcreate");

        /* Release file-creation template */
        ret = H5Pclose(tmpl2);
        CHECK(ret, FAIL, "H5Pclose");

        /* Get the file-creation template */
        tmpl1 = H5Fget_create_plist(fid3);
        CHECK(tmpl1, FAIL, "H5Fget_create_plist");

        /* Get the file-creation parameters */
        ret = H5Pget_userblock(tmpl1, &ublock);
        CHECK(ret, FAIL, "H5Pget_userblock");
        VERIFY(ublock, F3_USERBLOCK_SIZE, "H5Pget_userblock");

        ret = H5Pget_sizes(tmpl1, &parm, &parm2);
        CHECK(ret, FAIL, "H5Pget_sizes");
        VERIFY(parm, F3_OFFSET_SIZE, "H5Pget_sizes");
        VERIFY(parm2, F3_LENGTH_SIZE, "H5Pget_sizes");

        ret = H5Pget_sym_k(tmpl1, &iparm, &iparm2);
        CHECK(ret, FAIL, "H5Pget_sym_k");
        VERIFY(iparm, F3_SYM_INTERN_K, "H5Pget_sym_k");
        VERIFY(iparm2, F3_SYM_LEAF_K, "H5Pget_sym_k");

        /* Release file-creation template */
        ret = H5Pclose(tmpl1);
        CHECK(ret, FAIL, "H5Pclose");

        /* Close second file */
        ret = H5Fclose(fid2);
        CHECK(ret, FAIL, "H5Fclose");

        /* Close third file */
        ret = H5Fclose(fid3);
        CHECK(ret, FAIL, "H5Fclose");
    }

    /* Close first file */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");
} /* test_file_create() */

/****************************************************************
**
**  test_file_open(): Low-level file open I/O test routine.
**
****************************************************************/
static void
test_file_open(const char *driver_name)
{
    hid_t    fid1, fid2; /*HDF5 File IDs            */
    hid_t    did;        /*dataset ID                    */
    hid_t    fapl_id;    /*file access property list ID  */
    hid_t    tmpl1;      /*file creation templates    */
    hsize_t  ublock;     /*sizeof user block        */
    size_t   parm;       /*file-creation parameters    */
    size_t   parm2;      /*file-creation parameters    */
    unsigned iparm;
    unsigned iparm2;
    unsigned intent;
    bool     vol_is_native;
    herr_t   ret; /*generic return value        */

    /*
     * Test single file open
     */

    /* Only run this test with sec2/default driver */
    if (!h5_using_default_driver(driver_name))
        return;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Low-Level File Opening I/O\n"));

    /* Open first file */
    fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT);
    CHECK(fid1, FAIL, "H5Fopen");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, fid1, &vol_is_native), FAIL, "h5_using_native_vol");

    /* Get the intent */
    ret = H5Fget_intent(fid1, &intent);
    CHECK(ret, FAIL, "H5Fget_intent");
    VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent");

    /* Get the file-creation template */
    tmpl1 = H5Fget_create_plist(fid1);
    CHECK(tmpl1, FAIL, "H5Fget_create_plist");

    /* Get the file-creation parameters */
    ret = H5Pget_userblock(tmpl1, &ublock);
    CHECK(ret, FAIL, "H5Pget_userblock");
    VERIFY(ublock, F2_USERBLOCK_SIZE, "H5Pget_userblock");

    ret = H5Pget_sizes(tmpl1, &parm, &parm2);
    CHECK(ret, FAIL, "H5Pget_sizes");
    VERIFY(parm, F2_OFFSET_SIZE, "H5Pget_sizes");
    VERIFY(parm2, F2_LENGTH_SIZE, "H5Pget_sizes");

    ret = H5Pget_sym_k(tmpl1, &iparm, &iparm2);
    CHECK(ret, FAIL, "H5Pget_sym_k");
    VERIFY(iparm, F2_SYM_INTERN_K, "H5Pget_sym_k");
    VERIFY(iparm2, F2_SYM_LEAF_K, "H5Pget_sym_k");

    /* Release file-creation template */
    ret = H5Pclose(tmpl1);
    CHECK(ret, FAIL, "H5Pclose");

    /* Close first file */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /*
     * Test two file opens: one is opened H5F_ACC_RDONLY and H5F_CLOSE_WEAK.
     * It's closed with an object left open.  Then another is opened
     * H5F_ACC_RDWR, which should fail.
     */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing 2 File Openings\n"));

    if (vol_is_native) {
        /* Create file access property list */
        fapl_id = H5Pcreate(H5P_FILE_ACCESS);
        CHECK(fapl_id, FAIL, "H5Pcreate");

        /* Set file close mode to H5F_CLOSE_WEAK */
        ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK);
        CHECK(ret, FAIL, "H5Pset_fclose_degree");

        /* Open file for first time */
        fid1 = H5Fopen(FILE2, H5F_ACC_RDONLY, fapl_id);
        CHECK(fid1, FAIL, "H5Fopen");

        /* Check the intent */
        ret = H5Fget_intent(fid1, &intent);
        CHECK(ret, FAIL, "H5Fget_intent");
        VERIFY(intent, H5F_ACC_RDONLY, "H5Fget_intent");

        /* Open dataset */
        did = H5Dopen2(fid1, F2_DSET, H5P_DEFAULT);
        CHECK(did, FAIL, "H5Dopen2");

        /* Check that the intent works even if NULL is passed in */
        ret = H5Fget_intent(fid1, NULL);
        CHECK(ret, FAIL, "H5Fget_intent");

        /* Close first open */
        ret = H5Fclose(fid1);
        CHECK(ret, FAIL, "H5Fclose");

        /* Open file for second time, which should fail. */
        H5E_BEGIN_TRY
        {
            fid2 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl_id);
        }
        H5E_END_TRY
        VERIFY(fid2, FAIL, "H5Fopen");

        /* Check that the intent fails for an invalid ID */
        H5E_BEGIN_TRY
        {
            ret = H5Fget_intent(fid1, &intent);
        }
        H5E_END_TRY
        VERIFY(ret, FAIL, "H5Fget_intent");

        /* Close dataset from first open */
        ret = H5Dclose(did);
        CHECK(ret, FAIL, "H5Dclose");

        ret = H5Pclose(fapl_id);
        CHECK(ret, FAIL, "H5Pclose");
    }
} /* test_file_open() */

/****************************************************************
**
**  test_file_reopen(): File reopen test routine.
**
****************************************************************/
static void
test_file_reopen(void)
{
    hid_t   fid  = H5I_INVALID_HID; /* file ID from initial open            */
    hid_t   rfid = H5I_INVALID_HID; /* file ID from reopen                  */
    hid_t   did  = H5I_INVALID_HID; /* dataset ID (both opens)              */
    hid_t   sid  = H5I_INVALID_HID; /* dataspace ID for dataset creation    */
    hsize_t dims = 6;               /* dataspace size                       */
    herr_t  ret;                    /* Generic return value                 */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing File Re-opening\n"));

    /* Create file via first ID */
    fid = H5Fcreate(REOPEN_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK_I(fid, "H5Fcreate");

    /* Create a dataset in the file */
    sid = H5Screate_simple(1, &dims, &dims);
    CHECK_I(sid, "H5Screate_simple");
    did = H5Dcreate2(fid, REOPEN_DSET, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK_I(did, "H5Dcreate2");

    /* Close dataset and dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");
    ret = H5Dclose(did);
    CHECK(ret, FAIL, "H5Dclose");

    /* Reopen the file with a different file ID */
    rfid = H5Freopen(fid);
    CHECK_I(rfid, "H5Freopen");

    /* Reopen the dataset through the reopen file ID */
    did = H5Dopen2(rfid, REOPEN_DSET, H5P_DEFAULT);
    CHECK_I(did, "H5Dopen2");

    /* Close and clean up */
    ret = H5Dclose(did);
    CHECK(ret, FAIL, "H5Dclose");
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(rfid);
    CHECK(ret, FAIL, "H5Fclose");

    H5E_BEGIN_TRY
    {
        H5Fdelete(REOPEN_FILE, H5P_DEFAULT);
    }
    H5E_END_TRY

} /* test_file_reopen() */

/****************************************************************
**
**  test_file_close():  low-level file close test routine.
**                      It mainly tests behavior with close degree.
**
*****************************************************************/
static void
test_file_close(void)
{
    hid_t              fid1, fid2;
    hid_t              fapl_id, access_id;
    hid_t              dataset_id, group_id1, group_id2, group_id3;
    H5F_close_degree_t fc_degree;
    bool               vol_is_native;
    herr_t             ret;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing File Closing with file close degrees\n"));

    /* Test behavior while opening file multiple times with different
     * file close degree value
     */
    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid1, FAIL, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, fid1, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Fclose(fid1), FAIL, "H5Fclose");
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    fapl_id = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl_id, FAIL, "H5Pcreate");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    ret = H5Pget_fclose_degree(fapl_id, &fc_degree);
    VERIFY(fc_degree, H5F_CLOSE_STRONG, "H5Pget_fclose_degree");

    /* should fail */
    H5E_BEGIN_TRY
    {
        fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    }
    H5E_END_TRY
    VERIFY(fid2, FAIL, "H5Fopen");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    /* should succeed */
    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Close first open */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close second open */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");

    /* Test behavior while opening file multiple times with different file
     * close degree
     */
    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid1, FAIL, "H5Fcreate");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    ret = H5Pget_fclose_degree(fapl_id, &fc_degree);
    VERIFY(fc_degree, H5F_CLOSE_WEAK, "H5Pget_fclose_degree");

    /* should succeed */
    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Close first open */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close second open */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");

    /* Test behavior while opening file multiple times with file close
     * degree STRONG */
    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    CHECK(fid1, FAIL, "H5Fcreate");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    /* should fail */
    H5E_BEGIN_TRY
    {
        fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    }
    H5E_END_TRY
    VERIFY(fid2, FAIL, "H5Fopen");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    /* should succeed */
    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Create a dataset and a group in each file open respectively */
    create_objects(fid1, fid2, NULL, NULL, NULL, NULL);

    /* Close first open */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close second open */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");

    /* Test behavior while opening file multiple times with file close
     * degree SEMI */
    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    CHECK(fid1, FAIL, "H5Fcreate");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    /* should fail */
    H5E_BEGIN_TRY
    {
        fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    }
    H5E_END_TRY
    VERIFY(fid2, FAIL, "H5Fopen");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    /* should succeed */
    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Create a dataset and a group in each file open respectively */
    create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3);

    /* Close first open, should fail since it is SEMI and objects are
     * still open. */
    H5E_BEGIN_TRY
    {
        ret = H5Fclose(fid1);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Fclose");

    /* Close second open, should fail since it is SEMI and objects are
     * still open. */
    H5E_BEGIN_TRY
    {
        ret = H5Fclose(fid2);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Fclose");

    ret = H5Dclose(dataset_id);
    CHECK(ret, FAIL, "H5Dclose");

    /* Close first open */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    ret = H5Gclose(group_id1);
    CHECK(ret, FAIL, "H5Gclose");

    ret = H5Gclose(group_id2);
    CHECK(ret, FAIL, "H5Gclose");

    /* Close second open, should fail since it is SEMI and one group ID is
     * still open. */
    H5E_BEGIN_TRY
    {
        ret = H5Fclose(fid2);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Fclose");

    /* Same check with H5Idec_ref() (should fail also) */
    H5E_BEGIN_TRY
    {
        ret = H5Idec_ref(fid2);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Idec_ref");

    ret = H5Gclose(group_id3);
    CHECK(ret, FAIL, "H5Gclose");

    /* Close second open again.  Should succeed. */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");

    /* Test behavior while opening file multiple times with file close
     * degree WEAK */
    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    CHECK(fid1, FAIL, "H5Fcreate");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    /* should fail */
    H5E_BEGIN_TRY
    {
        fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    }
    H5E_END_TRY
    VERIFY(fid2, FAIL, "H5Fopen");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    /* should succeed */
    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Create a dataset and a group in each file open respectively */
    create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3);

    /* Create more new files and test object count and ID list functions */
    test_obj_count_and_id(fid1, fid2, dataset_id, group_id1, group_id2, group_id3);

    /* Close first open */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close second open.  File will be finally closed after all objects
     * are closed. */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");

    ret = H5Dclose(dataset_id);
    CHECK(ret, FAIL, "H5Dclose");

    ret = H5Gclose(group_id1);
    CHECK(ret, FAIL, "H5Gclose");

    ret = H5Gclose(group_id2);
    CHECK(ret, FAIL, "H5Gclose");

    ret = H5Gclose(group_id3);
    CHECK(ret, FAIL, "H5Gclose");

    /* Test behavior while opening file multiple times with file close
     * degree DEFAULT */
    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    CHECK(fid1, FAIL, "H5Fcreate");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    /* should fail */
    H5E_BEGIN_TRY
    {
        fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    }
    H5E_END_TRY
    VERIFY(fid2, FAIL, "H5Fopen");

    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT);
    CHECK(ret, FAIL, "H5Pset_fclose_degree");

    /* should succeed */
    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Create a dataset and a group in each file open respectively */
    create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3);

    access_id = H5Fget_access_plist(fid1);
    CHECK(access_id, FAIL, "H5Fget_access_plist");

    ret = H5Pget_fclose_degree(access_id, &fc_degree);
    CHECK(ret, FAIL, "H5Pget_fclose_degree");

    switch (fc_degree) {
        case H5F_CLOSE_STRONG:
            /* Close first open */
            ret = H5Fclose(fid1);
            CHECK(ret, FAIL, "H5Fclose");
            /* Close second open */
            ret = H5Fclose(fid2);
            CHECK(ret, FAIL, "H5Fclose");
            break;
        case H5F_CLOSE_SEMI:
            /* Close first open */
            ret = H5Fclose(fid1);
            CHECK(ret, FAIL, "H5Fclose");
            ret = H5Dclose(dataset_id);
            CHECK(ret, FAIL, "H5Dclose");
            ret = H5Gclose(group_id1);
            CHECK(ret, FAIL, "H5Gclose");
            ret = H5Gclose(group_id2);
            CHECK(ret, FAIL, "H5Gclose");
            ret = H5Gclose(group_id3);
            CHECK(ret, FAIL, "H5Gclose");
            /* Close second open */
            ret = H5Fclose(fid2);
            CHECK(ret, FAIL, "H5Fclose");
            break;
        case H5F_CLOSE_WEAK:
            /* Close first open */
            ret = H5Fclose(fid1);
            CHECK(ret, FAIL, "H5Fclose");
            /* Close second open */
            ret = H5Fclose(fid2);
            CHECK(ret, FAIL, "H5Fclose");
            ret = H5Dclose(dataset_id);
            CHECK(ret, FAIL, "H5Dclose");
            ret = H5Gclose(group_id1);
            CHECK(ret, FAIL, "H5Gclose");
            ret = H5Gclose(group_id2);
            CHECK(ret, FAIL, "H5Gclose");
            ret = H5Gclose(group_id3);
            CHECK(ret, FAIL, "H5Gclose");
            break;
        case H5F_CLOSE_DEFAULT:
        default:
            CHECK(fc_degree, H5F_CLOSE_DEFAULT, "H5Pget_fclose_degree");
            break;
    }

    /* Close file access property list */
    ret = H5Pclose(fapl_id);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(access_id);
    CHECK(ret, FAIL, "H5Pclose");
}

/****************************************************************
**
**  create_objects(): routine called by test_file_close to create
**                    a dataset and a group in file.
**
****************************************************************/
static void
create_objects(hid_t fid1, hid_t fid2, hid_t *ret_did, hid_t *ret_gid1, hid_t *ret_gid2, hid_t *ret_gid3)
{
    ssize_t oid_count;
    herr_t  ret;

    /* Check reference counts of file IDs and opened object IDs.
     * The verification is hard-coded.  If in any case, this testing
     * is changed, remember to check this part and update the macros.
     */
    {
        oid_count = H5Fget_obj_count(fid1, H5F_OBJ_ALL);
        CHECK(oid_count, FAIL, "H5Fget_obj_count");
        VERIFY(oid_count, OBJ_ID_COUNT_2, "H5Fget_obj_count");

        oid_count = H5Fget_obj_count(fid1, H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_DATATYPE | H5F_OBJ_ATTR);
        CHECK(oid_count, FAIL, "H5Fget_obj_count");
        VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count");

        oid_count = H5Fget_obj_count(fid2, H5F_OBJ_ALL);
        CHECK(oid_count, FAIL, "H5Fget_obj_count");
        VERIFY(oid_count, OBJ_ID_COUNT_2, "H5Fget_obj_count");

        oid_count = H5Fget_obj_count(fid2, H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_DATATYPE | H5F_OBJ_ATTR);
        CHECK(oid_count, FAIL, "H5Fget_obj_count");
        VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count");
    }

    /* create a dataset in the first file open */
    {
        hid_t    dataset_id, dataspace_id; /* identifiers */
        hsize_t  dims[F2_RANK];
        unsigned data[F2_DIM0][F2_DIM1];
        unsigned i, j;

        /* Create the data space for the dataset. */
        dims[0]      = F2_DIM0;
        dims[1]      = F2_DIM1;
        dataspace_id = H5Screate_simple(F2_RANK, dims, NULL);
        CHECK(dataspace_id, FAIL, "H5Screate_simple");

        /* Create the dataset. */
        dataset_id =
            H5Dcreate2(fid1, "/dset", H5T_NATIVE_UINT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        CHECK(dataset_id, FAIL, "H5Dcreate2");

        for (i = 0; i < F2_DIM0; i++)
            for (j = 0; j < F2_DIM1; j++)
                data[i][j] = i * 10 + j;

        /* Write data to the new dataset */
        ret = H5Dwrite(dataset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
        CHECK(ret, FAIL, "H5Dwrite");

        if (ret_did != NULL)
            *ret_did = dataset_id;

        /* Terminate access to the data space. */
        ret = H5Sclose(dataspace_id);
        CHECK(ret, FAIL, "H5Sclose");
    }

    /* Create a group in the second file open */
    {
        hid_t gid1, gid2, gid3;
        gid1 = H5Gcreate2(fid2, "/group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        CHECK(gid1, FAIL, "H5Gcreate2");
        if (ret_gid1 != NULL)
            *ret_gid1 = gid1;

        gid2 = H5Gopen2(fid2, "/group", H5P_DEFAULT);
        CHECK(gid2, FAIL, "H5Gopen2");
        if (ret_gid2 != NULL)
            *ret_gid2 = gid2;

        gid3 = H5Gopen2(fid2, "/group", H5P_DEFAULT);
        CHECK(gid3, FAIL, "H5Gopen2");
        if (ret_gid3 != NULL)
            *ret_gid3 = gid3;
    }

    /* Check reference counts of file IDs and opened object IDs.
     * The verification is hard-coded.  If in any case, this testing
     * is changed, remember to check this part and update the macros.
     */
    {
        oid_count = H5Fget_obj_count(fid1, H5F_OBJ_ALL);
        CHECK(oid_count, FAIL, "H5Fget_obj_count");
        VERIFY(oid_count, OBJ_ID_COUNT_6, "H5Fget_obj_count");

        oid_count = H5Fget_obj_count(fid1, H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_DATATYPE | H5F_OBJ_ATTR);
        CHECK(oid_count, FAIL, "H5Fget_obj_count");
        VERIFY(oid_count, OBJ_ID_COUNT_4, "H5Fget_obj_count");

        oid_count = H5Fget_obj_count(fid2, H5F_OBJ_ALL);
        CHECK(oid_count, FAIL, "H5Fget_obj_count");
        VERIFY(oid_count, OBJ_ID_COUNT_6, "H5Fget_obj_count");

        oid_count = H5Fget_obj_count(fid2, H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_DATATYPE | H5F_OBJ_ATTR);
        CHECK(oid_count, FAIL, "H5Fget_obj_count");
        VERIFY(oid_count, OBJ_ID_COUNT_4, "H5Fget_obj_count");
    }
}

/****************************************************************
**
**  test_obj_count_and_id(): test object count and ID list functions.
**
****************************************************************/
static void
test_obj_count_and_id(hid_t fid1, hid_t fid2, hid_t did, hid_t gid1, hid_t gid2, hid_t gid3)
{
    hid_t   fid3, fid4;
    ssize_t oid_count, ret_count;
    herr_t  ret;

    /* Create two new files */
    fid3 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid3, FAIL, "H5Fcreate");
    fid4 = H5Fcreate(FILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid4, FAIL, "H5Fcreate");

    /* test object count of all files IDs open */
    oid_count = H5Fget_obj_count((hid_t)H5F_OBJ_ALL, H5F_OBJ_FILE);
    CHECK(oid_count, FAIL, "H5Fget_obj_count");
    VERIFY(oid_count, OBJ_ID_COUNT_4, "H5Fget_obj_count");

    /* test object count of all datasets open */
    oid_count = H5Fget_obj_count((hid_t)H5F_OBJ_ALL, H5F_OBJ_DATASET);
    CHECK(oid_count, FAIL, "H5Fget_obj_count");
    VERIFY(oid_count, OBJ_ID_COUNT_1, "H5Fget_obj_count");

    /* test object count of all groups open */
    oid_count = H5Fget_obj_count((hid_t)H5F_OBJ_ALL, H5F_OBJ_GROUP);
    CHECK(oid_count, FAIL, "H5Fget_obj_count");
    VERIFY(oid_count, OBJ_ID_COUNT_3, "H5Fget_obj_count");

    /* test object count of all named datatypes open */
    oid_count = H5Fget_obj_count((hid_t)H5F_OBJ_ALL, H5F_OBJ_DATATYPE);
    CHECK(oid_count, FAIL, "H5Fget_obj_count");
    VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count");

    /* test object count of all attributes open */
    oid_count = H5Fget_obj_count((hid_t)H5F_OBJ_ALL, H5F_OBJ_ATTR);
    CHECK(oid_count, FAIL, "H5Fget_obj_count");
    VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count");

    /* test object count of all objects currently open */
    oid_count = H5Fget_obj_count((hid_t)H5F_OBJ_ALL, H5F_OBJ_ALL);
    CHECK(oid_count, FAIL, "H5Fget_obj_count");
    VERIFY(oid_count, OBJ_ID_COUNT_8, "H5Fget_obj_count");

    if (oid_count > 0) {
        hid_t *oid_list;

        oid_list = (hid_t *)calloc((size_t)oid_count, sizeof(hid_t));
        if (oid_list != NULL) {
            int i;

            ret_count = H5Fget_obj_ids((hid_t)H5F_OBJ_ALL, H5F_OBJ_ALL, (size_t)oid_count, oid_list);
            CHECK(ret_count, FAIL, "H5Fget_obj_ids");

            for (i = 0; i < oid_count; i++) {
                H5I_type_t id_type;

                id_type = H5Iget_type(oid_list[i]);
                switch (id_type) {
                    case H5I_FILE:
                        if (oid_list[i] != fid1 && oid_list[i] != fid2 && oid_list[i] != fid3 &&
                            oid_list[i] != fid4)
                            ERROR("H5Fget_obj_ids");
                        break;

                    case H5I_GROUP:
                        if (oid_list[i] != gid1 && oid_list[i] != gid2 && oid_list[i] != gid3)
                            ERROR("H5Fget_obj_ids");
                        break;

                    case H5I_DATASET:
                        VERIFY(oid_list[i], did, "H5Fget_obj_ids");
                        break;

                    case H5I_MAP:
                        /* TODO: Not supported in native VOL connector yet */

                    case H5I_UNINIT:
                    case H5I_BADID:
                    case H5I_DATATYPE:
                    case H5I_DATASPACE:
                    case H5I_ATTR:
                    case H5I_VFL:
                    case H5I_VOL:
                    case H5I_GENPROP_CLS:
                    case H5I_GENPROP_LST:
                    case H5I_ERROR_CLASS:
                    case H5I_ERROR_MSG:
                    case H5I_ERROR_STACK:
                    case H5I_SPACE_SEL_ITER:
                    case H5I_EVENTSET:
                    case H5I_NTYPES:
                    default:
                        ERROR("H5Fget_obj_ids");
                } /* end switch */
            }     /* end for */

            free(oid_list);
        } /* end if */
    }     /* end if */

    /* close the two new files */
    ret = H5Fclose(fid3);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(fid4);
    CHECK(ret, FAIL, "H5Fclose");
}

/****************************************************************
**
**  test_get_obj_ids(): Test the bug and the fix for Jira 8528.
**                      H5Fget_obj_ids overfilled the list of
**                      object IDs by one.  This is an enhancement
**                      for test_obj_count_and_id().
**
****************************************************************/
static void
test_get_obj_ids(void)
{
    hid_t   fid, gid[NGROUPS], dset[NDSETS];
    hid_t   filespace;
    hsize_t file_dims[F2_RANK] = {F2_DIM0, F2_DIM1};
    ssize_t oid_count, ret_count;
    hid_t  *oid_list = NULL;
    herr_t  ret;
    int     i, m, n;
    ssize_t oid_list_size = NDSETS;
    char    gname[64], dname[64];

    MESSAGE(5, ("Testing retrieval of object IDs\n"));

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_MORE)) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Create a new file */
    fid = H5Fcreate(FILE7, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid, FAIL, "H5Fcreate");

    filespace = H5Screate_simple(F2_RANK, file_dims, NULL);
    CHECK(filespace, FAIL, "H5Screate_simple");

    /* creates NGROUPS groups under the root group */
    for (m = 0; m < NGROUPS; m++) {
        snprintf(gname, sizeof(gname), "group%d", m);
        gid[m] = H5Gcreate2(fid, gname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        CHECK(gid[m], FAIL, "H5Gcreate2");
    }

    /* create NDSETS datasets under the root group */
    for (n = 0; n < NDSETS; n++) {
        snprintf(dname, sizeof(dname), "dataset%d", n);
        dset[n] = H5Dcreate2(fid, dname, H5T_NATIVE_INT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        CHECK(dset[n], FAIL, "H5Dcreate2");
    }

    /* The number of opened objects should be NGROUPS + NDSETS + 1.  One is opened file. */
    oid_count = H5Fget_obj_count(fid, H5F_OBJ_ALL);
    CHECK(oid_count, FAIL, "H5Fget_obj_count");
    VERIFY(oid_count, (NGROUPS + NDSETS + 1), "H5Fget_obj_count");

    oid_list = (hid_t *)calloc((size_t)oid_list_size, sizeof(hid_t));
    CHECK_PTR(oid_list, "calloc");

    /* Call the public function H5F_get_obj_ids to use H5F__get_objects.  User reported having problem here.
     * that the returned size (ret_count) from H5Fget_obj_ids is one greater than the size passed in
     * (oid_list_size) */
    ret_count = H5Fget_obj_ids(fid, H5F_OBJ_ALL, (size_t)oid_list_size, oid_list);
    CHECK(ret_count, FAIL, "H5Fget_obj_ids");
    VERIFY(ret_count, oid_list_size, "H5Fget_obj_count");

    /* Close all object IDs on the list except the file ID. The first ID is supposed to be file ID according
     * to the library design */
    for (i = 0; i < ret_count; i++) {
        if (fid != oid_list[i]) {
            ret = H5Oclose(oid_list[i]);
            CHECK(ret, FAIL, "H5Oclose");
        }
    }

    /* The number of opened objects should be NGROUPS + 1 + 1.  The first one is opened file. The second one
     * is the dataset ID left open from the previous around of H5Fget_obj_ids */
    oid_count = H5Fget_obj_count(fid, H5F_OBJ_ALL);
    CHECK(oid_count, FAIL, "H5Fget_obj_count");
    VERIFY(oid_count, NGROUPS + 2, "H5Fget_obj_count");

    /* Get the IDs of the left opened objects */
    ret_count = H5Fget_obj_ids(fid, H5F_OBJ_ALL, (size_t)oid_list_size, oid_list);
    CHECK(ret_count, FAIL, "H5Fget_obj_ids");
    VERIFY(ret_count, oid_list_size, "H5Fget_obj_count");

    /* Close all object IDs on the list except the file ID. The first ID is still the file ID */
    for (i = 0; i < ret_count; i++) {
        if (fid != oid_list[i]) {
            ret = H5Oclose(oid_list[i]);
            CHECK(ret, FAIL, "H5Oclose");
        }
    }

    H5Sclose(filespace);
    H5Fclose(fid);

    free(oid_list);

    /* Reopen the file to check whether H5Fget_obj_count and H5Fget_obj_ids still works
     * when the file is closed first */
    fid = H5Fopen(FILE7, H5F_ACC_RDONLY, H5P_DEFAULT);
    CHECK(fid, FAIL, "H5Fopen");

    /* Open NDSETS datasets under the root group */
    for (n = 0; n < NDSETS; n++) {
        snprintf(dname, sizeof(dname), "dataset%d", n);
        dset[n] = H5Dopen2(fid, dname, H5P_DEFAULT);
        CHECK(dset[n], FAIL, "H5Dcreate2");
    }

    /* Close the file first */
    H5Fclose(fid);

    /* Get the number of all opened objects */
    oid_count = H5Fget_obj_count((hid_t)H5F_OBJ_ALL, H5F_OBJ_ALL);
    CHECK(oid_count, FAIL, "H5Fget_obj_count");
    VERIFY(oid_count, NDSETS, "H5Fget_obj_count");

    oid_list = (hid_t *)calloc((size_t)oid_count, sizeof(hid_t));
    CHECK_PTR(oid_list, "calloc");

    /* Get the list of all opened objects */
    ret_count = H5Fget_obj_ids((hid_t)H5F_OBJ_ALL, H5F_OBJ_ALL, (size_t)oid_count, oid_list);
    CHECK(ret_count, FAIL, "H5Fget_obj_ids");
    VERIFY(ret_count, NDSETS, "H5Fget_obj_ids");

    H5E_BEGIN_TRY
    {
        /* Close all open objects with H5Oclose */
        for (n = 0; n < oid_count; n++)
            H5Oclose(oid_list[n]);
    }
    H5E_END_TRY

    free(oid_list);
}

/****************************************************************
**
**  test_get_file_id(): Test H5Iget_file_id()
**
*****************************************************************/
static void
test_get_file_id(void)
{
    hid_t    fid, fid2, fid3;
    hid_t    datatype_id, dataset_id, dataspace_id, group_id, attr_id;
    hid_t    plist;
    hsize_t  dims[F2_RANK];
    unsigned intent;
    herr_t   ret;

    MESSAGE(5, ("Testing H5Iget_file_id\n"));

    /* Create a file */
    fid = H5Fcreate(FILE4, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid, FAIL, "H5Fcreate");

    /* Check the intent */
    ret = H5Fget_intent(fid, &intent);
    CHECK(ret, FAIL, "H5Fget_intent");
    VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent");

    /* Test H5Iget_file_id() */
    check_file_id(fid, fid);

    /* Create a group in the file.  Make a duplicated file ID from the group.
     * And close this duplicated ID
     */
    group_id = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(group_id, FAIL, "H5Gcreate2");

    /* Test H5Iget_file_id() */
    check_file_id(fid, group_id);

    /* Close the file and get file ID from the group ID */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Test H5Iget_file_id() */
    check_file_id((hid_t)-1, group_id);

    ret = H5Gclose(group_id);
    CHECK(ret, FAIL, "H5Gclose");

    /* Open the file again.  Test H5Iget_file_id() */
    fid = H5Fopen(FILE4, H5F_ACC_RDWR, H5P_DEFAULT);
    CHECK(fid, FAIL, "H5Fcreate");

    group_id = H5Gopen2(fid, GRP_NAME, H5P_DEFAULT);
    CHECK(group_id, FAIL, "H5Gopen2");

    /* Test H5Iget_file_id() */
    check_file_id(fid, group_id);

    /* Open the file for second time.  Test H5Iget_file_id() */
    fid3 = H5Freopen(fid);
    CHECK(fid3, FAIL, "H5Freopen");

    /* Test H5Iget_file_id() */
    check_file_id(fid3, fid3);

    ret = H5Fclose(fid3);
    CHECK(ret, FAIL, "H5Fclose");

    /* Create a dataset in the group.  Make a duplicated file ID from the
     * dataset.  And close this duplicated ID.
     */
    dims[0]      = F2_DIM0;
    dims[1]      = F2_DIM1;
    dataspace_id = H5Screate_simple(F2_RANK, dims, NULL);
    CHECK(dataspace_id, FAIL, "H5Screate_simple");

    dataset_id =
        H5Dcreate2(group_id, DSET_NAME, H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(dataset_id, FAIL, "H5Dcreate2");

    /* Test H5Iget_file_id() */
    check_file_id(fid, dataset_id);

    /* Create an attribute for the dataset.  Make a duplicated file ID from
     * this attribute.  And close it.
     */
    attr_id = H5Acreate2(dataset_id, ATTR_NAME, H5T_NATIVE_INT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Acreate2");

    /* Test H5Iget_file_id() */
    check_file_id(fid, attr_id);

    /* Create a named datatype.  Make a duplicated file ID from
     * this attribute.  And close it.
     */
    datatype_id = H5Tcopy(H5T_NATIVE_INT);
    CHECK(ret, FAIL, "H5Tcopy");

    ret = H5Tcommit2(fid, TYPE_NAME, datatype_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Tcommit2");

    /* Test H5Iget_file_id() */
    check_file_id(fid, datatype_id);

    /* Create a property list and try to get file ID from it.
     * Supposed to fail.
     */
    plist = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(plist, FAIL, "H5Pcreate");

    H5E_BEGIN_TRY
    {
        fid2 = H5Iget_file_id(plist);
    }
    H5E_END_TRY
    VERIFY(fid2, FAIL, "H5Iget_file_id");

    /* Close objects */
    ret = H5Pclose(plist);
    CHECK(ret, FAIL, "H5Pclose");

    ret = H5Tclose(datatype_id);
    CHECK(ret, FAIL, "H5Tclose");

    ret = H5Aclose(attr_id);
    CHECK(ret, FAIL, "H5Aclose");

    ret = H5Sclose(dataspace_id);
    CHECK(ret, FAIL, "H5Sclose");

    ret = H5Dclose(dataset_id);
    CHECK(ret, FAIL, "H5Dclose");

    ret = H5Gclose(group_id);
    CHECK(ret, FAIL, "H5Gclose");

    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");
}

/****************************************************************
**
**  check_file_id(): Internal function of test_get_file_id()
**
*****************************************************************/
static void
check_file_id(hid_t fid, hid_t object_id)
{
    hid_t  new_fid;
    herr_t ret;

    /* Return a duplicated file ID even not expecting user to do it.
     * And close this duplicated ID
     */
    new_fid = H5Iget_file_id(object_id);

    if (fid >= 0)
        VERIFY(new_fid, fid, "H5Iget_file_id");
    else
        CHECK(new_fid, FAIL, "H5Iget_file_id");

    ret = H5Fclose(new_fid);
    CHECK(ret, FAIL, "H5Fclose");
}

/****************************************************************
**
**  test_file_perm(): low-level file test routine.
**      This test verifies that a file can be opened for both
**      read-only and read-write access and things will be handled
**      appropriately.
**
*****************************************************************/
static void
test_file_perm(void)
{
    hid_t  file;   /* File opened with read-write permission */
    hid_t  filero; /* Same file opened with read-only permission */
    hid_t  dspace; /* Dataspace ID */
    hid_t  dset;   /* Dataset ID */
    herr_t ret;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Low-Level File Permissions\n"));

    dspace = H5Screate(H5S_SCALAR);
    CHECK(dspace, FAIL, "H5Screate");

    /* Create the file (with read-write permission) */
    file = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file, FAIL, "H5Fcreate");

    /* Create a dataset with the read-write file handle */
    dset = H5Dcreate2(file, F2_DSET, H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(dset, FAIL, "H5Dcreate2");

    ret = H5Dclose(dset);
    CHECK(ret, FAIL, "H5Dclose");

    /* Open the file (with read-only permission) */
    filero = H5Fopen(FILE2, H5F_ACC_RDONLY, H5P_DEFAULT);
    CHECK(filero, FAIL, "H5Fopen");

    /* Create a dataset with the read-only file handle (should fail) */
    H5E_BEGIN_TRY
    {
        dset = H5Dcreate2(filero, F2_DSET, H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(dset, FAIL, "H5Dcreate2");
    if (dset != FAIL) {
        ret = H5Dclose(dset);
        CHECK(ret, FAIL, "H5Dclose");
    } /* end if */

    ret = H5Fclose(filero);
    CHECK(ret, FAIL, "H5Fclose");

    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

    ret = H5Sclose(dspace);
    CHECK(ret, FAIL, "H5Sclose");

} /* end test_file_perm() */

/****************************************************************
**
**  test_file_perm2(): low-level file test routine.
**      This test verifies that no object can be created in a
**      file that is opened for read-only.
**
*****************************************************************/
static void
test_file_perm2(void)
{
    hid_t  file;   /* File opened with read-write permission */
    hid_t  filero; /* Same file opened with read-only permission */
    hid_t  dspace; /* Dataspace ID */
    hid_t  group;  /* Group ID */
    hid_t  dset;   /* Dataset ID */
    hid_t  type;   /* Datatype ID */
    hid_t  attr;   /* Attribute ID */
    herr_t ret;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Low-Level File Permissions again\n"));

    dspace = H5Screate(H5S_SCALAR);
    CHECK(dspace, FAIL, "H5Screate");

    /* Create the file (with read-write permission) */
    file = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file, FAIL, "H5Fcreate");

    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

    /* Open the file (with read-only permission) */
    filero = H5Fopen(FILE2, H5F_ACC_RDONLY, H5P_DEFAULT);
    CHECK(filero, FAIL, "H5Fopen");

    /* Create a group with the read-only file handle (should fail) */
    H5E_BEGIN_TRY
    {
        group = H5Gcreate2(filero, "MY_GROUP", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(group, FAIL, "H5Gcreate2");

    /* Create a dataset with the read-only file handle (should fail) */
    H5E_BEGIN_TRY
    {
        dset = H5Dcreate2(filero, F2_DSET, H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(dset, FAIL, "H5Dcreate2");

    /* Create an attribute with the read-only file handle (should fail) */
    H5E_BEGIN_TRY
    {
        attr = H5Acreate2(filero, "MY_ATTR", H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(attr, FAIL, "H5Acreate2");

    type = H5Tcopy(H5T_NATIVE_SHORT);
    CHECK(type, FAIL, "H5Tcopy");

    /* Commit a datatype with the read-only file handle (should fail) */
    H5E_BEGIN_TRY
    {
        ret = H5Tcommit2(filero, "MY_DTYPE", type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Tcommit2");

    ret = H5Tclose(type);
    CHECK(ret, FAIL, "H5Tclose");

    ret = H5Fclose(filero);
    CHECK(ret, FAIL, "H5Fclose");

    ret = H5Sclose(dspace);
    CHECK(ret, FAIL, "H5Sclose");
} /* end test_file_perm2() */

/****************************************************************
**
**  test_file_is_accessible(): low-level file test routine.
**      Clone of test_file_ishdf5 but uses the newer VOL-enabled
**      H5Fis_accessible() API call.
**
*****************************************************************/
#define FILE_IS_ACCESSIBLE          "tfile_is_accessible"
#define FILE_IS_ACCESSIBLE_NON_HDF5 "tfile_is_accessible_non_hdf5"
static void
test_file_is_accessible(const char *driver_name)
{
    hid_t         fid     = H5I_INVALID_HID;          /* File opened with read-write permission */
    hid_t         fcpl_id = H5I_INVALID_HID;          /* File creation property list */
    hid_t         fapl_id = H5I_INVALID_HID;          /* File access property list */
    int           fd;                                 /* POSIX file descriptor */
    char          filename[FILENAME_LEN];             /* Filename to use */
    char          non_hdf5_filename[FILENAME_LEN];    /* Base name of non-hdf5 file */
    char          non_hdf5_sb_filename[FILENAME_LEN]; /* Name of non-hdf5 superblock file */
    ssize_t       nbytes;                             /* Number of bytes written */
    unsigned      u;                                  /* Local index variable */
    unsigned char buf[1024];                          /* Buffer of data to write */
    htri_t        is_hdf5;                            /* Whether a file is an HDF5 file */
    int           posix_ret;                          /* Return value from POSIX calls */
    bool          vol_is_native;
    bool          driver_is_default_compatible;
    herr_t        ret; /* Return value from HDF5 calls */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Detection of HDF5 Files\n"));

    /* Get FAPL */
    fapl_id = h5_fileaccess();
    CHECK(fapl_id, H5I_INVALID_HID, "H5Pcreate");

    if (h5_driver_is_default_vfd_compatible(fapl_id, &driver_is_default_compatible) < 0) {
        TestErrPrintf("Can't check if VFD is compatible with default VFD");
        return;
    }

    /* Fix up filenames */
    h5_fixname(FILE_IS_ACCESSIBLE, fapl_id, filename, sizeof(filename));
    h5_fixname(FILE_IS_ACCESSIBLE_NON_HDF5, fapl_id, non_hdf5_filename, sizeof(non_hdf5_filename));
    h5_fixname_superblock(FILE_IS_ACCESSIBLE_NON_HDF5, fapl_id, non_hdf5_sb_filename,
                          sizeof(non_hdf5_sb_filename));

    /****************/
    /* Normal usage */
    /****************/

    /* Create a file */
    fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(fapl_id, fid, &vol_is_native), FAIL, "h5_using_native_vol");

    /* Close file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Verify that the file is an HDF5 file */
    is_hdf5 = H5Fis_accessible(filename, fapl_id);
    VERIFY(is_hdf5, true, "H5Fis_accessible");

    /*****************************************/
    /* Newly created file that is still open */
    /*****************************************/

    /* On Windows, file locking is mandatory so this check ensures that
     * H5Fis_accessible() works on files that have an exclusive lock.
     * Previous versions of this API call created an additional file handle
     * and attempted to read through it, which will not work when locks
     * are enforced by the OS.
     */

    /* Create a file and hold it open */
    fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Verify that the file is an HDF5 file */
    is_hdf5 = H5Fis_accessible(filename, fapl_id);
    VERIFY(is_hdf5, true, "H5Fis_accessible");

    /* Close file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /*******************************/
    /* Non-default user block size */
    /*******************************/

    /* This test is not currently working for the family VFD.
     * There are failures when creating files with userblocks.
     */
    if (0 != strcmp(driver_name, "family")) {
        /* Create a file creation property list with a non-default user block size */
        fcpl_id = H5Pcreate(H5P_FILE_CREATE);
        CHECK(fcpl_id, H5I_INVALID_HID, "H5Pcreate");

        ret = H5Pset_userblock(fcpl_id, (hsize_t)2048);
        CHECK(ret, FAIL, "H5Pset_userblock");

        /* Create file with non-default user block */
        fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl_id, fapl_id);
        CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

        /* Release file-creation property list */
        ret = H5Pclose(fcpl_id);
        CHECK(ret, FAIL, "H5Pclose");

        /* Close file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");

        /* Verify that the file is an HDF5 file */
        is_hdf5 = H5Fis_accessible(filename, fapl_id);
        VERIFY(is_hdf5, true, "H5Fis_accessible");
    } /* end if */

    if (vol_is_native && driver_is_default_compatible) {
        /***********************/
        /* EMPTY non-HDF5 file */
        /***********************/

        /* Create non-HDF5 file and check it */
        fd = HDopen(non_hdf5_sb_filename, O_RDWR | O_CREAT | O_TRUNC, H5_POSIX_CREATE_MODE_RW);
        CHECK(fd, (-1), "HDopen");

        /* Close the file */
        posix_ret = HDclose(fd);
        CHECK(posix_ret, (-1), "HDclose");

        /* Verify that the file is NOT an HDF5 file using the base filename */
        is_hdf5 = H5Fis_accessible(non_hdf5_filename, fapl_id);
        VERIFY(is_hdf5, false, "H5Fis_accessible (empty non-HDF5 file)");

        /***************************/
        /* Non-empty non-HDF5 file */
        /***************************/

        /* Create non-HDF5 file and check it */
        fd = HDopen(non_hdf5_sb_filename, O_RDWR | O_CREAT | O_TRUNC, H5_POSIX_CREATE_MODE_RW);
        CHECK(fd, (-1), "HDopen");

        /* Initialize information to write */
        for (u = 0; u < 1024; u++)
            buf[u] = (unsigned char)u;

        /* Write some information */
        nbytes = HDwrite(fd, buf, (size_t)1024);
        VERIFY(nbytes, 1024, "HDwrite");

        /* Close the file */
        posix_ret = HDclose(fd);
        CHECK(posix_ret, (-1), "HDclose");

        /* Verify that the file is not an HDF5 file */
        is_hdf5 = H5Fis_accessible(non_hdf5_filename, fapl_id);
        VERIFY(is_hdf5, false, "H5Fis_accessible (non-HDF5 file)");
    }

    /* Clean up files */
    h5_delete_test_file(filename, fapl_id);
    h5_delete_test_file(non_hdf5_filename, fapl_id);

    /* Close property list */
    ret = H5Pclose(fapl_id);
    CHECK(ret, FAIL, "H5Pclose");

} /* end test_file_is_accessible() */

/****************************************************************
**
**  test_file_ishdf5(): low-level file test routine.
**      This test checks whether the H5Fis_hdf5() routine is working
**      correctly in various situations.
**
*****************************************************************/
#ifndef H5_NO_DEPRECATED_SYMBOLS
static void
test_file_ishdf5(const char *driver_name)
{
    hid_t         fid     = H5I_INVALID_HID; /* File opened with read-write permission */
    hid_t         fcpl_id = H5I_INVALID_HID; /* File creation property list */
    hid_t         fapl_id = H5I_INVALID_HID; /* File access property list */
    int           fd;                        /* POSIX file descriptor */
    char          filename[FILENAME_LEN];    /* Filename to use */
    char          sb_filename[FILENAME_LEN]; /* Name of file w/ superblock */
    ssize_t       nbytes;                    /* Number of bytes written */
    unsigned      u;                         /* Local index variable */
    unsigned char buf[1024];                 /* Buffer of data to write */
    htri_t        is_hdf5;                   /* Whether a file is an HDF5 file */
    int           posix_ret;                 /* Return value from POSIX calls */
    bool          vol_is_native;
    herr_t        ret; /* Return value from HDF5 calls */

    if (!h5_using_default_driver(driver_name))
        return;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Detection of HDF5 Files (using deprecated H5Fis_hdf5() call)\n"));

    /* Get FAPL */
    fapl_id = h5_fileaccess();
    CHECK(fapl_id, H5I_INVALID_HID, "H5Pcreate");

    /* Fix up filenames
     * For VFDs that create multiple files, we also need the name
     * of the file with the superblock. With single-file VFDs, this
     * will be equal to the one from h5_fixname().
     */
    h5_fixname(FILE_IS_ACCESSIBLE, fapl_id, filename, sizeof(filename));
    h5_fixname_superblock(FILE_IS_ACCESSIBLE, fapl_id, sb_filename, sizeof(filename));

    /****************/
    /* Normal usage */
    /****************/

    /* Create a file */
    fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(fapl_id, fid, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Pclose(fapl_id), FAIL, "H5Pclose");
        CHECK(H5Fclose(fid), FAIL, "H5Fclose");
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Close file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Verify that the file is an HDF5 file */
    is_hdf5 = H5Fis_hdf5(sb_filename);
    VERIFY(is_hdf5, true, "H5Fis_hdf5");

    /*******************************/
    /* Non-default user block size */
    /*******************************/

    /* Create a file creation property list with a non-default user block size */
    fcpl_id = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl_id, H5I_INVALID_HID, "H5Pcreate");

    ret = H5Pset_userblock(fcpl_id, (hsize_t)2048);
    CHECK(ret, FAIL, "H5Pset_userblock");

    /* Create file with non-default user block */
    fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl_id, fapl_id);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Release file creation property list */
    ret = H5Pclose(fcpl_id);
    CHECK(ret, FAIL, "H5Pclose");

    /* Close file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Verify that the file is an HDF5 file */
    is_hdf5 = H5Fis_hdf5(sb_filename);
    VERIFY(is_hdf5, true, "H5Fis_hdf5");

    /***************************/
    /* Non-empty non-HDF5 file */
    /***************************/

    /* Create non-HDF5 file. Use the calculated superblock
     * filename to avoid the format strings that will make
     * open(2) sad.
     */
    fd = HDopen(sb_filename, O_RDWR | O_CREAT | O_TRUNC, H5_POSIX_CREATE_MODE_RW);
    CHECK(fd, (-1), "HDopen");

    /* Initialize information to write */
    for (u = 0; u < 1024; u++)
        buf[u] = (unsigned char)u;

    /* Write some information */
    nbytes = HDwrite(fd, buf, (size_t)1024);
    VERIFY(nbytes, 1024, "HDwrite");

    /* Close the file */
    posix_ret = HDclose(fd);
    CHECK(posix_ret, (-1), "HDclose");

    /* Verify that the file is not an HDF5 file */
    is_hdf5 = H5Fis_hdf5(sb_filename);
    VERIFY(is_hdf5, false, "H5Fis_hdf5");

    /* Clean up files */
    h5_delete_test_file(filename, fapl_id);

    /* Close property list */
    ret = H5Pclose(fapl_id);
    CHECK(ret, FAIL, "H5Pclose");

} /* end test_file_ishdf5() */
#endif /* H5_NO_DEPRECATED_SYMBOLS */

/****************************************************************
**
**  test_file_delete(): tests H5Fdelete for all VFDs
**
*****************************************************************/
#define FILE_DELETE          "test_file_delete"
#define FILE_DELETE_NOT_HDF5 "test_file_delete_not_hdf5"
static void
test_file_delete(hid_t fapl_id)
{
    hid_t  fid = H5I_INVALID_HID;  /* File to be deleted */
    char   filename[FILENAME_LEN]; /* Filename to use */
    htri_t is_hdf5;                /* Whether a file is an HDF5 file */
    int    fd;                     /* POSIX file descriptor */
    int    iret;
    bool   vol_is_native;
    herr_t ret;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Deletion of HDF5 Files\n"));

    /*************/
    /* HDF5 FILE */
    /*************/

    /* Get fapl-dependent filename */
    h5_fixname(FILE_DELETE, fapl_id, filename, sizeof(filename));

    /* Create a file */
    fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(fapl_id, fid, &vol_is_native), FAIL, "h5_using_native_vol");

    /* Close file */
    ret = H5Fclose(fid);
    VERIFY(ret, SUCCEED, "H5Fclose");

    /* Verify that the file is an HDF5 file */
    is_hdf5 = H5Fis_accessible(filename, fapl_id);
    VERIFY(is_hdf5, true, "H5Fis_accessible");

    /* Delete the file */
    ret = H5Fdelete(filename, fapl_id);
    VERIFY(ret, SUCCEED, "H5Fdelete");

    /* Verify that the file is NO LONGER an HDF5 file */
    /* This should fail since there is no file */
    H5E_BEGIN_TRY
    {
        is_hdf5 = H5Fis_accessible(filename, fapl_id);
    }
    H5E_END_TRY
    VERIFY(is_hdf5, FAIL, "H5Fis_accessible");

    if (vol_is_native) {
        /* Just in case deletion fails - silent on errors */
        h5_delete_test_file(FILE_DELETE, fapl_id);

        /*****************/
        /* NON-HDF5 FILE */
        /*****************/

        /* Get fapl-dependent filename */
        h5_fixname(FILE_DELETE_NOT_HDF5, fapl_id, filename, sizeof(filename));

        /* Create a non-HDF5 file */
        fd = HDopen(filename, O_RDWR | O_CREAT | O_TRUNC, H5_POSIX_CREATE_MODE_RW);
        CHECK_I(fd, "HDopen");

        /* Close the file */
        ret = HDclose(fd);
        VERIFY(ret, 0, "HDclose");

        /* Verify that the file is not an HDF5 file */
        /* Note that you can get a FAIL result when h5_fixname()
         * perturbs the filename as a file with that exact name
         * may not have been created since we created it with
         * open(2) and not the library.
         */
        H5E_BEGIN_TRY
        {
            is_hdf5 = H5Fis_accessible(filename, fapl_id);
        }
        H5E_END_TRY
        CHECK(is_hdf5, true, "H5Fis_accessible");

        /* Try to delete it (should fail) */
        H5E_BEGIN_TRY
        {
            ret = H5Fdelete(filename, fapl_id);
        }
        H5E_END_TRY
        VERIFY(ret, FAIL, "H5Fdelete");

        /* Delete the file */
        iret = HDremove(filename);
        VERIFY(iret, 0, "HDremove");
    }
} /* end test_file_delete() */

/****************************************************************
**
**  test_file_open_dot(): low-level file test routine.
**      This test checks whether opening objects with "." for a name
**      works correctly in various situations.
**
*****************************************************************/
static void
test_file_open_dot(void)
{
    hid_t  fid;       /* File ID */
    hid_t  gid, gid2; /* Group IDs */
    hid_t  did;       /* Dataset ID */
    hid_t  sid;       /* Dataspace ID */
    hid_t  tid, tid2; /* Datatype IDs */
    herr_t ret;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing opening objects with \".\" for a name\n"));

    /* Create a new HDF5 file to work with */
    fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid, FAIL, "H5Fcreate");

    /* Create a group in the HDF5 file */
    gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(gid, FAIL, "H5Gcreate2");

    /* Create a dataspace for creating datasets */
    sid = H5Screate(H5S_SCALAR);
    CHECK(sid, FAIL, "H5Screate");

    /* Create a dataset with no name using the file ID */
    H5E_BEGIN_TRY
    {
        did = H5Dcreate2(fid, ".", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(did, FAIL, "H5Dcreate2");

    /* Create a dataset with no name using the group ID */
    H5E_BEGIN_TRY
    {
        did = H5Dcreate2(gid, ".", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(did, FAIL, "H5Dcreate2");

    /* Open a dataset with no name using the file ID */
    H5E_BEGIN_TRY
    {
        did = H5Dopen2(fid, ".", H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(did, FAIL, "H5Dopen2");

    /* Open a dataset with no name using the group ID */
    H5E_BEGIN_TRY
    {
        did = H5Dopen2(gid, ".", H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(did, FAIL, "H5Dopen2");

    /* Make a copy of a datatype to use for creating a named datatype */
    tid = H5Tcopy(H5T_NATIVE_INT);
    CHECK(tid, FAIL, "H5Tcopy");

    /* Create a named datatype with no name using the file ID */
    H5E_BEGIN_TRY
    {
        ret = H5Tcommit2(fid, ".", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Tcommit2");

    /* Create a named datatype with no name using the group ID */
    H5E_BEGIN_TRY
    {
        ret = H5Tcommit2(gid, ".", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Tcommit2");

    /* Open a named datatype with no name using the file ID */
    H5E_BEGIN_TRY
    {
        tid2 = H5Topen2(fid, ".", H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(tid2, FAIL, "H5Topen2");

    /* Open a named datatype with no name using the group ID */
    H5E_BEGIN_TRY
    {
        tid2 = H5Topen2(gid, ".", H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(tid2, FAIL, "H5Topen2");

    /* Create a group with no name using the file ID */
    H5E_BEGIN_TRY
    {
        gid2 = H5Gcreate2(fid, ".", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(gid2, FAIL, "H5Gcreate2");

    /* Create a group with no name using the group ID */
    H5E_BEGIN_TRY
    {
        gid2 = H5Gcreate2(gid, ".", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    }
    H5E_END_TRY
    VERIFY(gid2, FAIL, "H5Gcreate2");

    /* Open a group with no name using the file ID (should open the root group) */
    gid2 = H5Gopen2(fid, ".", H5P_DEFAULT);
    CHECK(gid2, FAIL, "H5Gopen2");

    ret = H5Gclose(gid2);
    CHECK(ret, FAIL, "H5Gclose");

    /* Open a group with no name using the group ID (should open the group again) */
    gid2 = H5Gopen2(gid, ".", H5P_DEFAULT);
    CHECK(gid2, FAIL, "H5Gopen2");

    ret = H5Gclose(gid2);
    CHECK(ret, FAIL, "H5Gclose");

    /* Close everything */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");

    ret = H5Gclose(gid);
    CHECK(ret, FAIL, "H5Gclose");

    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

} /* end test_file_open_dot() */

/****************************************************************
**
**  test_file_open_overlap(): low-level file test routine.
**      This test checks whether opening files in an overlapping way
**      (as opposed to a nested manner) works correctly.
**
*****************************************************************/
static void
test_file_open_overlap(void)
{
    hid_t         fid1, fid2;
    hid_t         did1, did2;
    hid_t         gid;
    hid_t         sid;
    ssize_t       nobjs; /* # of open objects */
    unsigned      intent;
    unsigned long fileno1, fileno2; /* File number */
    herr_t        ret;              /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing opening overlapping file opens\n"));

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_MORE)) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Create file */
    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid1, FAIL, "H5Fcreate");

    /* Open file also */
    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Check the intent */
    ret = H5Fget_intent(fid1, &intent);
    CHECK(ret, FAIL, "H5Fget_intent");
    VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent");

    /* Check the file numbers */
    fileno1 = 0;
    ret     = H5Fget_fileno(fid1, &fileno1);
    CHECK(ret, FAIL, "H5Fget_fileno");
    fileno2 = 0;
    ret     = H5Fget_fileno(fid2, &fileno2);
    CHECK(ret, FAIL, "H5Fget_fileno");
    VERIFY(fileno1, fileno2, "H5Fget_fileno");

    /* Check that a file number pointer of NULL is ignored */
    ret = H5Fget_fileno(fid1, NULL);
    CHECK(ret, FAIL, "H5Fget_fileno");

    /* Create a group in file */
    gid = H5Gcreate2(fid1, GROUP1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(gid, FAIL, "H5Gcreate2");

    /* Create dataspace for dataset */
    sid = H5Screate(H5S_SCALAR);
    CHECK(sid, FAIL, "H5Screate");

    /* Create dataset in group w/first file ID */
    did1 = H5Dcreate2(gid, DSET1, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(did1, FAIL, "H5Dcreate2");

    /* Check number of objects opened in first file */
    nobjs = H5Fget_obj_count(fid1, H5F_OBJ_LOCAL | H5F_OBJ_ALL);
    VERIFY(nobjs, 3, "H5Fget_obj_count"); /* 3 == file, dataset & group */

    /* Close dataset */
    ret = H5Dclose(did1);
    CHECK(ret, FAIL, "H5Dclose");

    /* Close group */
    ret = H5Gclose(gid);
    CHECK(ret, FAIL, "H5Gclose");

    /* Close first file ID */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /* Create dataset with second file ID */
    did2 = H5Dcreate2(fid2, DSET2, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(did2, FAIL, "H5Dcreate2");

    /* Check number of objects opened in first file */
    nobjs = H5Fget_obj_count(fid2, H5F_OBJ_ALL);
    VERIFY(nobjs, 2, "H5Fget_obj_count"); /* 3 == file & dataset */

    /* Close dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");

    /* Close second dataset */
    ret = H5Dclose(did2);
    CHECK(ret, FAIL, "H5Dclose");

    /* Close second file */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");
} /* end test_file_open_overlap() */

/****************************************************************
**
**  test_file_getname(): low-level file test routine.
**      This test checks whether H5Fget_name works correctly.
**
*****************************************************************/
static void
test_file_getname(void)
{
    /* Compound datatype */
    typedef struct s1_t {
        unsigned int a;
        float        b;
    } s1_t;

    hid_t   file_id;
    hid_t   group_id;
    hid_t   dataset_id;
    hid_t   space_id;
    hid_t   type_id;
    hid_t   attr_id;
    hsize_t dims[TESTA_RANK] = {TESTA_NX, TESTA_NY};
    char    name[TESTA_NAME_BUF_SIZE];
    ssize_t name_len;
    herr_t  ret; /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing H5Fget_name() functionality\n"));

    /* Create a new file_id using default properties. */
    file_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file_id, FAIL, "H5Fcreate");

    /* Get and verify file name and its length */
    name_len = H5Fget_name(file_id, name, (size_t)TESTA_NAME_BUF_SIZE);
    CHECK(name_len, FAIL, "H5Fget_name");
    VERIFY_STR(name, FILE1, "H5Fget_name");
    VERIFY(name_len, strlen(FILE1), "H5Fget_name");

    /* Create a group in the root group */
    group_id = H5Gcreate2(file_id, TESTA_GROUPNAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(group_id, FAIL, "H5Gcreate2");

    /* Get and verify file name */
    name_len = H5Fget_name(group_id, name, (size_t)TESTA_NAME_BUF_SIZE);
    CHECK(name_len, FAIL, "H5Fget_name");
    VERIFY_STR(name, FILE1, "H5Fget_name");

    /* Create the data space  */
    space_id = H5Screate_simple(TESTA_RANK, dims, NULL);
    CHECK(space_id, FAIL, "H5Screate_simple");

    /* Try get file name from data space.  Supposed to fail because
     * it's illegal operation. */
    H5E_BEGIN_TRY
    {
        name_len = H5Fget_name(space_id, name, (size_t)TESTA_NAME_BUF_SIZE);
    }
    H5E_END_TRY
    VERIFY(name_len, FAIL, "H5Fget_name");

    /* Create a new dataset */
    dataset_id =
        H5Dcreate2(file_id, TESTA_DSETNAME, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(dataset_id, FAIL, "H5Dcreate2");

    /* Get and verify file name */
    name_len = H5Fget_name(dataset_id, name, (size_t)TESTA_NAME_BUF_SIZE);
    CHECK(name_len, FAIL, "H5Fget_name");
    VERIFY_STR(name, FILE1, "H5Fget_name");

    /* Create an attribute for the dataset */
    attr_id = H5Acreate2(dataset_id, TESTA_ATTRNAME, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(attr_id, FAIL, "H5Acreate2");

    /* Get and verify file name */
    name_len = H5Fget_name(attr_id, name, (size_t)TESTA_NAME_BUF_SIZE);
    CHECK(name_len, FAIL, "H5Fget_name");
    VERIFY_STR(name, FILE1, "H5Fget_name");

    /* Create a compound datatype */
    type_id = H5Tcreate(H5T_COMPOUND, sizeof(s1_t));
    CHECK(type_id, FAIL, "H5Tcreate");

    /* Insert fields */
    ret = H5Tinsert(type_id, "a", HOFFSET(s1_t, a), H5T_NATIVE_INT);
    CHECK(ret, FAIL, "H5Tinsert");

    ret = H5Tinsert(type_id, "b", HOFFSET(s1_t, b), H5T_NATIVE_FLOAT);
    CHECK(ret, FAIL, "H5Tinsert");

    /* Save it on file */
    ret = H5Tcommit2(file_id, TESTA_DTYPENAME, type_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Tcommit2");

    /* Get and verify file name */
    name_len = H5Fget_name(type_id, name, (size_t)TESTA_NAME_BUF_SIZE);
    CHECK(name_len, FAIL, "H5Fget_name");
    VERIFY_STR(name, FILE1, "H5Fget_name");

    /* Close things down */
    ret = H5Tclose(type_id);
    CHECK(ret, FAIL, "H5Tclose");

    ret = H5Aclose(attr_id);
    CHECK(ret, FAIL, "H5Aclose");

    ret = H5Dclose(dataset_id);
    CHECK(ret, FAIL, "H5Dclose");

    ret = H5Sclose(space_id);
    CHECK(ret, FAIL, "H5Sclose");

    ret = H5Gclose(group_id);
    CHECK(ret, FAIL, "H5Gclose");

    ret = H5Fclose(file_id);
    CHECK(ret, FAIL, "H5Fclose");

} /* end test_file_getname() */

/****************************************************************
**
**  test_file_double_root_open(): low-level file test routine.
**      This test checks whether opening the root group from two
**      different files works correctly.
**
*****************************************************************/
static void
test_file_double_root_open(void)
{
    hid_t  file1_id, file2_id;
    hid_t  grp1_id, grp2_id;
    herr_t ret; /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing double root group open\n"));

    file1_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file1_id, FAIL, "H5Fcreate");
    file2_id = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT);
    CHECK(file2_id, FAIL, "H5Fopen");

    grp1_id = H5Gopen2(file1_id, "/", H5P_DEFAULT);
    CHECK(grp1_id, FAIL, "H5Gopen2");
    grp2_id = H5Gopen2(file2_id, "/", H5P_DEFAULT);
    CHECK(grp2_id, FAIL, "H5Gopen2");

    /* Note "asymmetric" close order */
    ret = H5Gclose(grp1_id);
    CHECK(ret, FAIL, "H5Gclose");
    ret = H5Gclose(grp2_id);
    CHECK(ret, FAIL, "H5Gclose");

    ret = H5Fclose(file1_id);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(file2_id);
    CHECK(ret, FAIL, "H5Fclose");
} /* end test_file_double_root_open() */

/****************************************************************
**
**  test_file_double_group_open(): low-level file test routine.
**      This test checks whether opening the same group from two
**      different files works correctly.
**
*****************************************************************/
static void
test_file_double_group_open(void)
{
    hid_t  file1_id, file2_id;
    hid_t  grp1_id, grp2_id;
    herr_t ret; /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing double non-root group open\n"));

    file1_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file1_id, FAIL, "H5Fcreate");
    file2_id = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT);
    CHECK(file2_id, FAIL, "H5Fopen");

    grp1_id = H5Gcreate2(file1_id, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(grp1_id, FAIL, "H5Gcreate2");
    grp2_id = H5Gopen2(file2_id, GRP_NAME, H5P_DEFAULT);
    CHECK(grp2_id, FAIL, "H5Gopen2");

    /* Note "asymmetric" close order */
    ret = H5Gclose(grp1_id);
    CHECK(ret, FAIL, "H5Gclose");
    ret = H5Gclose(grp2_id);
    CHECK(ret, FAIL, "H5Gclose");

    ret = H5Fclose(file1_id);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(file2_id);
    CHECK(ret, FAIL, "H5Fclose");
} /* end test_file_double_group_open() */

/****************************************************************
**
**  test_file_double_dataset_open(): low-level file test routine.
**      This test checks whether opening the same dataset from two
**      different files works correctly.
**
*****************************************************************/
static void
test_file_double_dataset_open(void)
{
    hid_t  file1_id, file2_id;
    hid_t  dset1_id, dset2_id;
    hid_t  space_id;
    herr_t ret; /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing double dataset open\n"));

    file1_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file1_id, FAIL, "H5Fcreate");
    file2_id = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT);
    CHECK(file2_id, FAIL, "H5Fopen");

    /* Create dataspace for dataset */
    space_id = H5Screate(H5S_SCALAR);
    CHECK(space_id, FAIL, "H5Screate");

    dset1_id =
        H5Dcreate2(file1_id, DSET_NAME, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(dset1_id, FAIL, "H5Dcreate2");
    dset2_id = H5Dopen2(file2_id, DSET_NAME, H5P_DEFAULT);
    CHECK(dset2_id, FAIL, "H5Dopen2");

    /* Close "supporting" dataspace */
    ret = H5Sclose(space_id);
    CHECK(ret, FAIL, "H5Sclose");

    /* Note "asymmetric" close order */
    ret = H5Dclose(dset1_id);
    CHECK(ret, FAIL, "H5Dclose");
    ret = H5Dclose(dset2_id);
    CHECK(ret, FAIL, "H5Dclose");

    ret = H5Fclose(file1_id);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(file2_id);
    CHECK(ret, FAIL, "H5Fclose");
} /* end test_file_double_dataset_open() */

/****************************************************************
**
**  test_file_double_file_dataset_open():
**      This test checks multi-opens of files & datasets:
**    It simulates the multi-thread test program from DLS
**    which exposes the file pointer segmentation fault failure.
**    NOTE: The order on when the files and datasets are open/close
**    is important.
**
*****************************************************************/
static void
test_file_double_file_dataset_open(bool new_format)
{
    hid_t   fapl = H5I_INVALID_HID;                         /* File access property list */
    hid_t   dcpl = H5I_INVALID_HID;                         /* Dataset creation property list */
    hid_t   fid1 = H5I_INVALID_HID, fid2 = H5I_INVALID_HID; /* File IDs */
    hid_t   did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID; /* Dataset IDs */
    hid_t   sid1 = H5I_INVALID_HID, sid2 = H5I_INVALID_HID; /* Dataspace IDs */
    hid_t   tid1 = H5I_INVALID_HID, tid2 = H5I_INVALID_HID; /* Datatype IDs */
    hsize_t dims[1] = {5}, dims2[2] = {1, 4};               /* Dimension sizes */
    hsize_t e_ext_dims[1] = {7};                            /* Expanded dimension sizes */
    hsize_t s_ext_dims[1] = {3};                            /* Shrunk dimension sizes */
    hsize_t max_dims0[1]  = {8};                            /* Maximum dimension sizes */
    hsize_t max_dims1[1]  = {H5S_UNLIMITED}; /* Maximum dimension sizes for extensible array index */
    hsize_t max_dims2[2]  = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dimension sizes for v2 B-tree index */
    hsize_t chunks[1] = {2}, chunks2[2] = {4, 5};           /* Chunk dimension sizes */
    hsize_t size;                                           /* File size */
    char    filename[FILENAME_LEN];                         /* Filename to use */
    const char *data[]   = {"String 1", "String 2", "String 3", "String 4", "String 5"}; /* Input Data */
    const char *e_data[] = {"String 1", "String 2", "String 3", "String 4",
                            "String 5", "String 6", "String 7"}; /* Input Data */
    char       *buffer[5];                                       /* Output buffer */
    int         wbuf[4] = {1, 2, 3, 4};                          /* Input data */
    herr_t      ret;                                             /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing double file and dataset open/close\n"));

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_MORE)) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Setting up test file */
    fapl = h5_fileaccess();
    CHECK(fapl, FAIL, "H5Pcreate");
    if (new_format) {
        ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
        CHECK(ret, FAIL, "H5Pset_libver_bounds");
    }
    h5_fixname(FILE_DOUBLE_OPEN, fapl, filename, sizeof filename);

    /* Create the test file */
    fid1 = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(fid1, FAIL, "H5Fcreate");

    /* Create a chunked dataset with fixed array indexing */
    sid1 = H5Screate_simple(1, dims, max_dims0);
    CHECK(sid1, FAIL, "H5Screate_simple");
    tid1 = H5Tcopy(H5T_C_S1);
    CHECK(tid1, FAIL, "H5Tcopy");
    ret = H5Tset_size(tid1, H5T_VARIABLE);
    CHECK(ret, FAIL, "H5Tset_size");

    dcpl = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl, FAIL, "H5Pcreate");
    ret = H5Pset_chunk(dcpl, 1, chunks);
    CHECK(ret, FAIL, "H5Pset_chunk");

    did1 = H5Dcreate2(fid1, "dset_fa", tid1, sid1, H5P_DEFAULT, dcpl, H5P_DEFAULT);
    CHECK(did1, FAIL, "H5Dcreate2");

    /* Closing */
    ret = H5Dclose(did1);
    CHECK(ret, FAIL, "H5Dclose");
    ret = H5Tclose(tid1);
    CHECK(ret, FAIL, "H5Tclose");
    ret = H5Sclose(sid1);
    CHECK(ret, FAIL, "H5Sclose");
    ret = H5Pclose(dcpl);
    CHECK(ret, FAIL, "H5Dclose");

    /* Create a chunked dataset with extensible array indexing */
    sid1 = H5Screate_simple(1, dims, max_dims1);
    CHECK(sid1, FAIL, "H5Screate_simple");
    tid1 = H5Tcopy(H5T_C_S1);
    CHECK(tid1, FAIL, "H5Tcopy");
    ret = H5Tset_size(tid1, H5T_VARIABLE);
    CHECK(ret, FAIL, "H5Tset_size");

    dcpl = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl, FAIL, "H5Pcreate");
    ret = H5Pset_chunk(dcpl, 1, chunks);
    CHECK(ret, FAIL, "H5Pset_chunk");

    did1 = H5Dcreate2(fid1, "dset_ea", tid1, sid1, H5P_DEFAULT, dcpl, H5P_DEFAULT);
    CHECK(did1, FAIL, "H5Dcreate2");

    /* Write to the dataset */
    ret = H5Dwrite(did1, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
    CHECK(ret, FAIL, "H5Dwrite");

    /* Closing */
    /* (Leave sid1 open for later use) */
    ret = H5Dclose(did1);
    CHECK(ret, FAIL, "H5Dclose");
    ret = H5Tclose(tid1);
    CHECK(ret, FAIL, "H5Tclose");
    ret = H5Pclose(dcpl);
    CHECK(ret, FAIL, "H5Dclose");

    /* Create a chunked dataset with v2 btree indexing */
    sid2 = H5Screate_simple(2, dims2, max_dims2);
    CHECK(sid2, FAIL, "H5Screate_simple");

    dcpl = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl, FAIL, "H5Pcreate");
    ret = H5Pset_chunk(dcpl, 2, chunks2);
    CHECK(ret, FAIL, "H5Pset_chunk");

    did2 = H5Dcreate2(fid1, "dset_bt2", H5T_NATIVE_INT, sid2, H5P_DEFAULT, dcpl, H5P_DEFAULT);
    CHECK(did2, FAIL, "H5Dcreate2");

    /* Write to the dataset */
    ret = H5Dwrite(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf);
    CHECK(ret, FAIL, "H5Dwrite");

    /* Closing */
    ret = H5Dclose(did2);
    CHECK(ret, FAIL, "H5Dclose");

    ret = H5Sclose(sid2);
    CHECK(ret, FAIL, "H5Sclose");
    ret = H5Pclose(dcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /*
     * Scenario 1
     */

    /* First file open */
    fid1 = H5Fopen(filename, H5F_ACC_RDWR, fapl);
    CHECK(fid1, FAIL, "H5Fopen");

    /* First file's dataset open */
    did1 = H5Dopen2(fid1, "/dset_fa", H5P_DEFAULT);
    CHECK(did1, FAIL, "H5Dopen2");

    tid1 = H5Tcopy(did1);
    CHECK(tid1, FAIL, "H5Tcopy");

    /* First file's dataset write */
    ret = H5Dwrite(did1, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
    CHECK(ret, FAIL, "H5Dwrite");

    /* Second file open */
    fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Second file's dataset open */
    did2 = H5Dopen2(fid2, "/dset_fa", H5P_DEFAULT);
    CHECK(did2, FAIL, "H5Dopen2");

    tid2 = H5Tcopy(did2);
    CHECK(tid2, FAIL, "H5Tcopy");

    /* First file's dataset close */
    ret = H5Dclose(did1);
    CHECK(ret, FAIL, "H5Dclose");

    /* First file close */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /* Second file's dataset write */
    ret = H5Dwrite(did2, tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
    CHECK(ret, FAIL, "H5Dwrite");

    /* Second file's dataset close */
    ret = H5Dclose(did2);
    CHECK(ret, FAIL, "H5Dclose");

    /* Second file close */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");

    /* Closing */
    ret = H5Tclose(tid1);
    CHECK(ret, FAIL, "H5Tclose");
    ret = H5Tclose(tid2);
    CHECK(ret, FAIL, "H5Tclose");

    /*
     * Scenario 2
     */

    /* First file open */
    fid1 = H5Fopen(filename, H5F_ACC_RDONLY, fapl);
    CHECK(fid1, FAIL, "H5Fopen");

    /* Second file open */
    fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Second file's dataset open */
    did2 = H5Dopen2(fid2, "/dset_ea", H5P_DEFAULT);
    CHECK(did2, FAIL, "H5Dopen2");

    tid2 = H5Tcopy(did2);
    CHECK(tid2, FAIL, "H5Tcopy");

    /* First file's dataset open */
    did1 = H5Dopen2(fid1, "/dset_ea", H5P_DEFAULT);
    CHECK(did1, FAIL, "H5Dopen2");

    tid1 = H5Tcopy(did1);
    CHECK(tid1, FAIL, "H5Tcopy");

    /* Second file's dataset read */
    memset(buffer, 0, sizeof(char *) * 5);
    ret = H5Dread(did2, tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer);
    CHECK(ret, FAIL, "H5Dread");
    ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, buffer);
    CHECK(ret, FAIL, "H5Treclaim");

    /* Second file's dataset close */
    ret = H5Dclose(did2);
    CHECK(ret, FAIL, "H5Dclose");

    /* Second file close */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");

    /* First file's dataset read */
    memset(buffer, 0, sizeof(char *) * 5);
    ret = H5Dread(did1, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer);
    CHECK(ret, FAIL, "H5Dread");
    ret = H5Treclaim(tid2, sid1, H5P_DEFAULT, buffer);
    CHECK(ret, FAIL, "H5Treclaim");

    /* First file's dataset close */
    ret = H5Dclose(did1);
    CHECK(ret, FAIL, "H5Dclose");

    /* First file close */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /* Closing */
    ret = H5Tclose(tid1);
    CHECK(ret, FAIL, "H5Tclose");
    ret = H5Sclose(sid1);
    CHECK(ret, FAIL, "H5Sclose");

    ret = H5Tclose(tid2);
    CHECK(ret, FAIL, "H5Tclose");

    /*
     * Scenario 3
     */

    /* First file open */
    fid1 = H5Fopen(filename, H5F_ACC_RDONLY, fapl);
    CHECK(fid1, FAIL, "H5Fopen");

    /* First file's dataset open */
    did1 = H5Dopen2(fid1, "/dset_bt2", H5P_DEFAULT);
    CHECK(did1, FAIL, "H5Dopen2");

    /* First file's get storage size */
    size = H5Dget_storage_size(did1);
    CHECK(size, 0, "H5Dget_storage_size");

    /* Second file open */
    fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Second file's dataset open */
    did2 = H5Dopen2(fid2, "/dset_bt2", H5P_DEFAULT);
    CHECK(did2, FAIL, "H5Dopen2");

    /* First file's dataset close */
    ret = H5Dclose(did1);
    CHECK(ret, FAIL, "H5Dclose");

    /* First file close */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /* Second file's get storage size */
    size = H5Dget_storage_size(did2);
    CHECK(size, 0, "H5Dget_storage_size");

    /* Second file's dataset close */
    ret = H5Dclose(did2);
    CHECK(ret, FAIL, "H5Dclose");

    /* Second file close */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");

    /*
     * Scenario 4
     * --trigger H5AC_protect: Assertion `f->shared' failed
     *     from second call to
     * H5Dset_extent->...H5D__earray_idx_remove->H5EA_get...H5EA__iblock_protect...H5AC_protect
     */
    /* First file open */
    fid1 = H5Fopen(filename, H5F_ACC_RDWR, fapl);
    CHECK(fid1, FAIL, "H5Fopen");

    /* First file's dataset open */
    did1 = H5Dopen2(fid1, "/dset_ea", H5P_DEFAULT);
    CHECK(did1, FAIL, "H5Dopen2");

    tid1 = H5Tcopy(did1);
    CHECK(tid1, FAIL, "H5Tcopy");

    /* Extend the dataset */
    ret = H5Dset_extent(did1, e_ext_dims);
    CHECK(ret, FAIL, "H5Dset_extent");

    /* Write to the dataset */
    ret = H5Dwrite(did1, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, e_data);
    CHECK(ret, FAIL, "H5Dwrite");

    /* Second file open */
    fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl);
    CHECK(fid2, FAIL, "H5Fopen");

    /* Second file's dataset open */
    did2 = H5Dopen2(fid2, "/dset_ea", H5P_DEFAULT);
    CHECK(did2, FAIL, "H5Dopen2");

    /* First file's dataset close */
    ret = H5Dclose(did1);
    CHECK(ret, FAIL, "H5Dclose");

    /* First file close */
    ret = H5Fclose(fid1);
    CHECK(ret, FAIL, "H5Fclose");

    /* Shrink the dataset */
    ret = H5Dset_extent(did2, s_ext_dims);
    CHECK(ret, FAIL, "H5Dset_extent");

    /* Second file's dataset close */
    ret = H5Dclose(did2);
    CHECK(ret, FAIL, "H5Dclose");

    /* Second file close */
    ret = H5Fclose(fid2);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close the data type */
    ret = H5Tclose(tid1);
    CHECK(ret, FAIL, "H5Tclose");

    /* Delete the test file */
    h5_delete_test_file(filename, fapl);

    /* Close FAPL */
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");
} /* end test_file_double_dataset_open() */

/****************************************************************
**
**  test_file_double_datatype_open(): low-level file test routine.
**      This test checks whether opening the same named datatype from two
**      different files works correctly.
**
*****************************************************************/
static void
test_file_double_datatype_open(void)
{
    hid_t  file1_id, file2_id;
    hid_t  type1_id, type2_id;
    herr_t ret; /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing double datatype open\n"));

    file1_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file1_id, FAIL, "H5Fcreate");
    file2_id = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT);
    CHECK(file2_id, FAIL, "H5Fopen");

    type1_id = H5Tcopy(H5T_NATIVE_INT);
    CHECK(type1_id, FAIL, "H5Tcopy");
    ret = H5Tcommit2(file1_id, TYPE_NAME, type1_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Tcommit2");
    type2_id = H5Topen2(file2_id, TYPE_NAME, H5P_DEFAULT);
    CHECK(type2_id, FAIL, "H5Topen2");

    /* Note "asymmetric" close order */
    ret = H5Tclose(type1_id);
    CHECK(ret, FAIL, "H5Tclose");
    ret = H5Tclose(type2_id);
    CHECK(ret, FAIL, "H5Tclose");

    ret = H5Fclose(file1_id);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(file2_id);
    CHECK(ret, FAIL, "H5Fclose");
} /* end test_file_double_dataset_open() */

/****************************************************************
**
**  test_userblock_file_size(): low-level file test routine.
**      This test checks that the presence of a userblock
**      affects the file size in the expected manner, and that
**      the filesize is not changed by reopening the file.  It
**      creates two files which are identical except that one
**      contains a userblock, and verifies that their file sizes
**      differ exactly by the userblock size.
**
*****************************************************************/
static void
test_userblock_file_size(const char *driver_name)
{
    hid_t         file1_id, file2_id;
    hid_t         group1_id, group2_id;
    hid_t         dset1_id, dset2_id;
    hid_t         space_id;
    hid_t         fcpl2_id;
    hsize_t       dims[2] = {3, 4};
    hsize_t       filesize1, filesize2, filesize;
    unsigned long fileno1, fileno2; /* File number */
    bool          vol_is_native;
    herr_t        ret; /* Generic return value */

    /* Don't run with multi/split, family or direct drivers */
    if (!strcmp(driver_name, "multi") || !strcmp(driver_name, "split") || !strcmp(driver_name, "family") ||
        !strcmp(driver_name, "direct"))
        return;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing file size with user block\n"));

    if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_MORE)) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Create property list with userblock size set */
    fcpl2_id = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl2_id, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl2_id, USERBLOCK_SIZE);
    CHECK(ret, FAIL, "H5Pset_userblock");

    /* Create files.  Only file2 with have a userblock. */
    file1_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file1_id, FAIL, "H5Fcreate");
    file2_id = H5Fcreate(FILE2, H5F_ACC_TRUNC, fcpl2_id, H5P_DEFAULT);
    CHECK(file2_id, FAIL, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, file1_id, &vol_is_native), FAIL, "h5_using_native_vol");

    /* Check the file numbers */
    fileno1 = 0;
    ret     = H5Fget_fileno(file1_id, &fileno1);
    CHECK(ret, FAIL, "H5Fget_fileno");
    fileno2 = 0;
    ret     = H5Fget_fileno(file2_id, &fileno2);
    CHECK(ret, FAIL, "H5Fget_fileno");
    CHECK(fileno1, fileno2, "H5Fget_fileno");

    /* Create groups */
    group1_id = H5Gcreate2(file1_id, GROUP1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(group1_id, FAIL, "H5Gcreate2");
    group2_id = H5Gcreate2(file2_id, GROUP1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(group2_id, FAIL, "H5Gcreate2");

    /* Create dataspace */
    space_id = H5Screate_simple(2, dims, NULL);
    CHECK(space_id, FAIL, "H5Screate_simple");

    /* Create datasets */
    dset1_id = H5Dcreate2(file1_id, DSET2, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(dset1_id, FAIL, "H5Dcreate2");
    dset2_id = H5Dcreate2(file2_id, DSET2, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(dset2_id, FAIL, "H5Dcreate2");

    /* Close IDs */
    ret = H5Dclose(dset1_id);
    CHECK(ret, FAIL, "H5Dclose");
    ret = H5Dclose(dset2_id);
    CHECK(ret, FAIL, "H5Dclose");
    ret = H5Sclose(space_id);
    CHECK(ret, FAIL, "H5Sclose");
    ret = H5Gclose(group1_id);
    CHECK(ret, FAIL, "H5Gclose");
    ret = H5Gclose(group2_id);
    CHECK(ret, FAIL, "H5Gclose");
    ret = H5Pclose(fcpl2_id);
    CHECK(ret, FAIL, "H5Pclose");

    /* Close files */
    ret = H5Fclose(file1_id);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(file2_id);
    CHECK(ret, FAIL, "H5Fclose");

    /* Reopen files */
    file1_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
    CHECK(file1_id, FAIL, "H5Fopen");
    file2_id = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT);
    CHECK(file2_id, FAIL, "H5Fopen");

    if (vol_is_native) {
        /* Check file sizes */
        ret = H5Fget_filesize(file1_id, &filesize1);
        CHECK(ret, FAIL, "H5Fget_filesize");
        ret = H5Fget_filesize(file2_id, &filesize2);
        CHECK(ret, FAIL, "H5Fget_filesize");

        /* Verify that the file sizes differ exactly by the userblock size */
        VERIFY_TYPE((unsigned long long)filesize2, (unsigned long long)(filesize1 + USERBLOCK_SIZE),
                    unsigned long long, "%llu", "H5Fget_filesize");
    }

    /* Close files */
    ret = H5Fclose(file1_id);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(file2_id);
    CHECK(ret, FAIL, "H5Fclose");

    /* Reopen files */
    file1_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
    CHECK(file1_id, FAIL, "H5Fopen");
    file2_id = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT);
    CHECK(file2_id, FAIL, "H5Fopen");

    if (vol_is_native) {
        /* Verify file sizes did not change */
        ret = H5Fget_filesize(file1_id, &filesize);
        CHECK(ret, FAIL, "H5Fget_filesize");
        VERIFY(filesize, filesize1, "H5Fget_filesize");
        ret = H5Fget_filesize(file2_id, &filesize);
        CHECK(ret, FAIL, "H5Fget_filesize");
        VERIFY(filesize, filesize2, "H5Fget_filesize");
    }

    /* Close files */
    ret = H5Fclose(file1_id);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(file2_id);
    CHECK(ret, FAIL, "H5Fclose");
} /* end test_userblock_file_size() */

/****************************************************************
**
**  test_cached_stab_info(): low-level file test routine.
**      This test checks that new files are created with cached
**      symbol table information in the superblock (when using
**      the old format).  This is necessary to ensure backwards
**      compatibility with versions from 1.3.0 to 1.6.3.
**
*****************************************************************/
static void
test_cached_stab_info(void)
{
    hid_t  file_id;
    hid_t  fapl_id;
    hid_t  group_id;
    bool   vol_is_native;
    herr_t ret; /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing cached symbol table information\n"));

    /* Setup earliest file format */
    fapl_id = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl_id, FAIL, "H5Pcreate");
    ret = H5Pset_libver_bounds(fapl_id, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    /* Create file */
    file_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    CHECK(file_id, FAIL, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, file_id, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Fclose(file_id), FAIL, "H5Fclose");
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Create group */
    group_id = H5Gcreate2(file_id, GROUP1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(group_id, FAIL, "H5Gcreate2");

    /* Close file and group */
    ret = H5Gclose(group_id);
    CHECK(ret, FAIL, "H5Gclose");
    ret = H5Fclose(file_id);
    CHECK(ret, FAIL, "H5Fclose");

    /* Reopen file */
    file_id = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT);
    CHECK(file_id, FAIL, "H5Fopen");

    /* Verify the cached symbol table information */
    ret = H5F__check_cached_stab_test(file_id);
    CHECK(ret, FAIL, "H5F__check_cached_stab_test");

    /* Close file */
    ret = H5Fclose(file_id);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close fapl */
    ret = H5Pclose(fapl_id);
    CHECK(ret, FAIL, "H5Pclose");
} /* end test_cached_stab_info() */

/*
 * To calculate the checksum for a file.
 * This is a helper routine for test_rw_noupdate().
 */
static int
cal_chksum(const char *file, uint32_t *chksum)
{
    int       curr_num_errs = GetTestNumErrs(); /* Retrieve the current # of errors */
    int       fdes          = -1;               /* File descriptor */
    void     *file_data     = NULL;             /* Copy of file data */
    ssize_t   bytes_read;                       /* # of bytes read */
    h5_stat_t sb;                               /* Stat buffer for file */
    herr_t    ret;                              /* Generic return value */

    /* Open the file */
    fdes = HDopen(file, O_RDONLY);
    CHECK(fdes, FAIL, "HDopen");

    /* Retrieve the file's size */
    memset(&sb, 0, sizeof(h5_stat_t));
    ret = HDfstat(fdes, &sb);
    CHECK(fdes, FAIL, "HDfstat");

    /* Allocate space for the file data */
    file_data = malloc((size_t)sb.st_size);
    CHECK_PTR(file_data, "malloc");

    if (file_data) {
        /* Read file's data into memory */
        bytes_read = HDread(fdes, file_data, (size_t)sb.st_size);
        CHECK(bytes_read == sb.st_size, false, "malloc");

        /* Calculate checksum */
        *chksum = H5_checksum_lookup3(file_data, sizeof(file_data), 0);

        /* Free memory */
        free(file_data);
    }

    /* Close the file */
    ret = HDclose(fdes);
    CHECK(ret, FAIL, "HDclose");

    return ((GetTestNumErrs() == curr_num_errs) ? 0 : -1);
} /* cal_chksum() */

/****************************************************************
**
**  test_rw_noupdate(): low-level file test routine.
**      This test checks to ensure that opening and closing a file
**      with read/write permissions does not write anything to the
**      file if the file does not change.
**    Due to the implementation of file locking (status_flags in
**    the superblock is used), this test is changed to use checksum
**    instead of timestamp to verify the file is not changed.
**
*****************************************************************/
static void
test_rw_noupdate(void)
{
    herr_t   ret;              /* Generic return value */
    hid_t    fid;              /* File ID */
    uint32_t chksum1, chksum2; /* Checksum value */
    bool     vol_is_native;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing to verify that nothing is written if nothing is changed.\n"));

    /* Create and Close a HDF5 File */
    fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid, FAIL, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, fid, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Fclose(fid), FAIL, "H5Fclose");
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Close the file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Calculate checksum for the file */
    ret = cal_chksum(FILE1, &chksum1);
    CHECK(ret, FAIL, "cal_chksum");

    /* Open and close File With Read/Write Permission */
    fid = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
    CHECK(fid, FAIL, "H5Fopen");

    /* Close the file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Calculate checksum for the file */
    ret = cal_chksum(FILE1, &chksum2);
    CHECK(ret, FAIL, "cal_chksum");

    /* The two checksums are the same, i.e. the file is not changed */
    VERIFY(chksum1, chksum2, "Checksum");

} /* end test_rw_noupdate() */

/****************************************************************
**
**  test_userblock_alignment_helper1(): helper routine for
**      test_userblock_alignment() test, to handle common testing
**
*****************************************************************/
static int
test_userblock_alignment_helper1(hid_t fcpl, hid_t fapl)
{
    hid_t  fid;                              /* File ID */
    int    curr_num_errs = GetTestNumErrs(); /* Retrieve the current # of errors */
    bool   vol_is_native;
    herr_t ret; /* Generic return value */

    /* Create a file with FAPL & FCPL */
    fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl);
    CHECK(fid, FAIL, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(fapl, fid, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Fclose(fid), FAIL, "H5Fclose");
        return 0;
    }

    /* Only proceed further if file ID is OK */
    if (fid > 0) {
        hid_t gid;     /* Group ID */
        hid_t sid;     /* Dataspace ID */
        hid_t did;     /* Dataset ID */
        int   val = 2; /* Dataset value */

        /* Create a group */
        gid = H5Gcreate2(fid, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        CHECK(gid, FAIL, "H5Gcreate2");

        /* Create a dataset */
        sid = H5Screate(H5S_SCALAR);
        CHECK(sid, FAIL, "H5Screate");
        did = H5Dcreate2(gid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        CHECK(did, FAIL, "H5Dcreate2");

        /* Close dataspace */
        ret = H5Sclose(sid);
        CHECK(ret, FAIL, "H5Sclose");

        /* Write value to dataset */
        ret = H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &val);
        CHECK(ret, FAIL, "H5Dwrite");

        /* Close dataset */
        ret = H5Dclose(did);
        CHECK(ret, FAIL, "H5Dclose");

        /* Close group */
        ret = H5Gclose(gid);
        CHECK(ret, FAIL, "H5Gclose");

        /* Close file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");
    } /* end if */

    return ((GetTestNumErrs() == curr_num_errs) ? 0 : -1);
} /* end test_userblock_alignment_helper1() */

/****************************************************************
**
**  test_userblock_alignment_helper2(): helper routine for
**      test_userblock_alignment() test, to handle common testing
**
*****************************************************************/
static int
test_userblock_alignment_helper2(hid_t fapl, bool open_rw)
{
    hid_t  fid;                              /* File ID */
    int    curr_num_errs = GetTestNumErrs(); /* Retrieve the current # of errors */
    bool   vol_is_native;
    herr_t ret; /* Generic return value */

    /* Re-open file */
    fid = H5Fopen(FILE1, (open_rw ? H5F_ACC_RDWR : H5F_ACC_RDONLY), fapl);
    CHECK(fid, FAIL, "H5Fopen");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(fapl, fid, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Fclose(fid), FAIL, "H5Fclose");
        return 0;
    }

    /* Only proceed further if file ID is OK */
    if (fid > 0) {
        hid_t gid;      /* Group ID */
        hid_t did;      /* Dataset ID */
        int   val = -1; /* Dataset value */

        /* Open group */
        gid = H5Gopen2(fid, "group1", H5P_DEFAULT);
        CHECK(gid, FAIL, "H5Gopen2");

        /* Open dataset */
        did = H5Dopen2(gid, "dataset", H5P_DEFAULT);
        CHECK(did, FAIL, "H5Dopen2");

        /* Read value from dataset */
        ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &val);
        CHECK(ret, FAIL, "H5Dread");
        VERIFY(val, 2, "H5Dread");

        /* Close dataset */
        ret = H5Dclose(did);
        CHECK(ret, FAIL, "H5Dclose");

        /* Only create new objects if file is open R/W */
        if (open_rw) {
            hid_t gid2; /* Group ID */

            /* Create a new group */
            gid2 = H5Gcreate2(gid, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
            CHECK(gid, FAIL, "H5Gcreate2");

            /* Close new group */
            ret = H5Gclose(gid2);
            CHECK(ret, FAIL, "H5Gclose");
        } /* end if */

        /* Close group */
        ret = H5Gclose(gid);
        CHECK(ret, FAIL, "H5Gclose");

        /* Close file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");
    } /* end if */

    return ((GetTestNumErrs() == curr_num_errs) ? 0 : -1);
} /* end test_userblock_alignment_helper2() */

/****************************************************************
**
**  test_userblock_alignment(): low-level file test routine.
**      This test checks to ensure that files with both a userblock and a
**      object [allocation] alignment size set interact properly.
**
*****************************************************************/
static void
test_userblock_alignment(const char *driver_name)
{
    hid_t  fid;  /* File ID */
    hid_t  fcpl; /* File creation property list ID */
    hid_t  fapl; /* File access property list ID */
    herr_t ret;  /* Generic return value */

    /* Only run with sec2 driver */
    if (!h5_using_default_driver(driver_name))
        return;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing that non-zero userblocks and object alignment interact correctly.\n"));

    /* Case 1:
     *  Userblock size = 0, alignment != 0
     * Outcome:
     *  Should succeed
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)0);
    CHECK(ret, FAIL, "H5Pset_userblock");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Case 2:
     *  Userblock size = 512, alignment = 16
     *  (userblock is integral mult. of alignment)
     * Outcome:
     *  Should succeed
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)16);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Case 3:
     *  Userblock size = 512, alignment = 512
     *  (userblock is equal to alignment)
     * Outcome:
     *  Should succeed
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Case 4:
     *  Userblock size = 512, alignment = 3
     *  (userblock & alignment each individually valid, but userblock is
     *          non-integral multiple of alignment)
     * Outcome:
     *  Should fail at file creation
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Create a file with FAPL & FCPL */
    H5E_BEGIN_TRY
    {
        fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl);
    }
    H5E_END_TRY
    VERIFY(fid, FAIL, "H5Fcreate");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Case 5:
     *  Userblock size = 512, alignment = 1024
     *  (userblock & alignment each individually valid, but userblock is
     *          less than alignment)
     * Outcome:
     *  Should fail at file creation
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1024);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Create a file with FAPL & FCPL */
    H5E_BEGIN_TRY
    {
        fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl);
    }
    H5E_END_TRY
    VERIFY(fid, FAIL, "H5Fcreate");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Case 6:
     *  File created with:
     *          Userblock size = 512, alignment = 512
     *  File re-opened for read-only & read-write access with:
     *          Userblock size = 512, alignment = 1024
     * Outcome:
     *  Should succeed
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");

    /* Change alignment in FAPL */
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1024);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper2(fapl, false);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");
} /* end test_userblock_alignment() */

/****************************************************************
**
**  test_userblock_alignment_paged(): low-level file test routine.
**      This test checks to ensure that files with both a userblock and
**      alignment interact properly:
**        -- alignment via H5Pset_alignment
**        -- alignment via paged aggregation
**
*****************************************************************/
static void
test_userblock_alignment_paged(const char *driver_name)
{
    hid_t  fid;  /* File ID */
    hid_t  fcpl; /* File creation property list ID */
    hid_t  fapl; /* File access property list ID */
    herr_t ret;  /* Generic return value */

    /* Only run with sec2 driver */
    if (!h5_using_default_driver(driver_name))
        return;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing interaction between userblock and alignment (via paged aggregation and "
                "H5Pset_alignment)\n"));

    /*
     * Case 1:
     *  Userblock size = 0
     *  Alignment in use = 4096
     *    Strategy = H5F_FILE_SPACE_PAGE; fsp_size = alignment = 4096
     * Outcome:
     *  Should succeed:
     *      userblock is 0 and alignment != 0
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)0);
    CHECK(ret, FAIL, "H5Pset_userblock");

    /* Create file access property list */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");

    /* Set the "use the latest version of the format" bounds */
    ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1);
    CHECK(ret, FAIL, "H5Pset_file_space_strategy");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case 2a:
     *  Userblock size =  1024
     *  Alignment in use = 512
     *    Strategy = H5F_FILE_SPACE_PAGE; fsp_size = alignment = 512
     *    H5Pset_alignment() is 3
     * Outcome:
     *  Should succeed:
     *    userblock (1024) is integral mult. of alignment (512)
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)1024);
    CHECK(ret, FAIL, "H5Pset_userblock");
    ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1);
    ret = H5Pset_file_space_page_size(fcpl, (hsize_t)512);

    /* Create file access property list */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case 2b:
     *  Userblock size =  1024
     *  Alignment in use = 3
     *    Strategy = H5F_FILE_SPACE_AGGR; fsp_size = 512
     *      (via default file creation property)
     *    H5Pset_alignment() is 3
     * Outcome:
     *  Should fail at file creation:
     *      userblock (1024) is non-integral mult. of alignment (3)
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)1024);
    CHECK(ret, FAIL, "H5Pset_userblock");
    ret = H5Pset_file_space_page_size(fcpl, (hsize_t)512);

    /* Create file access property list */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Create a file with FAPL & FCPL */
    H5E_BEGIN_TRY
    {
        fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl);
    }
    H5E_END_TRY
    VERIFY(fid, FAIL, "H5Fcreate");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case 3a:
     *  Userblock size =  512
     *  Alignment in use = 512
     *    Strategy is H5F_FILE_SPACE_PAGE; fsp_size = alignment = 512
     *    H5Pset_alignment() is 3
     * Outcome:
     *  Should succeed:
     *      userblock (512) is equal to alignment (512)
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");
    ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, true, (hsize_t)1);
    CHECK(ret, FAIL, "H5Pset_file_space_strategy");
    ret = H5Pset_file_space_page_size(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_file_space_page_size");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case 3b:
     *  Userblock size =  512
     *  Alignment in use = 3
     *    Strategy is H5F_FILE_SPACE_NONE; fsp_size = 512
     *    H5Pset_alignment() is 3
     * Outcome:
     *  Should fail at file creation:
     *      userblock (512) is non-integral mult. of alignment (3)
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");
    ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_NONE, false, (hsize_t)1);
    CHECK(ret, FAIL, "H5Pset_file_space_strategy");
    ret = H5Pset_file_space_page_size(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_file_space_page_size");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Create a file with FAPL & FCPL */
    H5E_BEGIN_TRY
    {
        fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl);
    }
    H5E_END_TRY
    VERIFY(fid, FAIL, "H5Fcreate");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case 4a:
     *  Userblock size =  1024
     *  Alignment in use = 1023
     *    Strategy is H5F_FILE_SPACE_PAGE; fsp_size = alignment = 1023
     *    H5Pset_alignment() is 16
     * Outcome:
     *  Should fail at file creation:
     *      userblock (1024) is non-integral multiple of alignment (1023)
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)1024);
    CHECK(ret, FAIL, "H5Pset_userblock");
    ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, true, (hsize_t)1);
    CHECK(ret, FAIL, "H5Pset_file_space_strategy");
    ret = H5Pset_file_space_page_size(fcpl, (hsize_t)1023);
    CHECK(ret, FAIL, "H5Pset_file_space_page_size");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)16);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Create a file with FAPL & FCPL */
    H5E_BEGIN_TRY
    {
        fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl);
    }
    H5E_END_TRY
    VERIFY(fid, FAIL, "H5Fcreate");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case 4b:
     *  Userblock size =  1024
     *  Alignment in use = 16
     *    Strategy is H5F_FILE_SPACE_FSM_AGGR; fsp_size = 1023
     *    H5Pset_alignment() is 16
     * Outcome:
     *  Should succeed:
     *      userblock (512) is integral multiple of alignment (16)
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)1024);
    CHECK(ret, FAIL, "H5Pset_userblock");
    ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, false, (hsize_t)1);
    CHECK(ret, FAIL, "H5Pset_file_space_strategy");
    ret = H5Pset_file_space_page_size(fcpl, (hsize_t)1023);
    CHECK(ret, FAIL, "H5Pset_file_space_page_size");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)16);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case 5a:
     *  Userblock size = 512
     *  Alignment in use = 1024
     *    Strategy is H5F_FILE_SPACE_PAGE; fsp_size = alignment = 1024
     *    H5Pset_alignment() is 16
     * Outcome:
     *  Should fail at file creation:
     *      userblock (512) is less than alignment (1024)
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");
    ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1);
    CHECK(ret, FAIL, "H5Pset_file_space_strategy");
    ret = H5Pset_file_space_page_size(fcpl, (hsize_t)1024);
    CHECK(ret, FAIL, "H5Pset_file_space_page_size");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)16);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Create a file with FAPL & FCPL */
    H5E_BEGIN_TRY
    {
        fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl);
    }
    H5E_END_TRY
    VERIFY(fid, FAIL, "H5Fcreate");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case 5b:
     *  Userblock size = 512
     *  Alignment in use = 16
     *    Strategy is H5F_FILE_SPACE_NONE; fsp_size = 1024
     *    H5Pset_alignment() is 16
     * Outcome:
     *  Should succeed:
     *      userblock (512) is integral multiple of alignment (16)
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");
    ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_NONE, false, (hsize_t)1);
    CHECK(ret, FAIL, "H5Pset_file_space_strategy");
    ret = H5Pset_file_space_page_size(fcpl, (hsize_t)1024);
    CHECK(ret, FAIL, "H5Pset_file_space_page_size");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)16);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case 6:
     *  Userblock size = 512
     *  Alignment in use = 512
     *    Strategy is H5F_FILE_SPACE_PAGE; fsp_size = alignment = 512
     *    H5Pset_alignment() is 3
     *      Reopen the file; H5Pset_alignment() is 1024
     * Outcome:
     *  Should succeed:
     *      Userblock (512) is the same as alignment (512);
     *    The H5Pset_alignment() calls have no effect
     */
    /* Create file creation property list with user block */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");
    ret = H5Pset_userblock(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_userblock");
    ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1);
    CHECK(ret, FAIL, "H5Pset_file_space_strategy");
    ret = H5Pset_file_space_page_size(fcpl, (hsize_t)512);
    CHECK(ret, FAIL, "H5Pset_file_space_page_size");

    /* Create file access property list with alignment */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper1(fcpl, fapl);
    CHECK(ret, FAIL, "test_userblock_alignment_helper1");

    /* Change alignment in FAPL */
    ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1024);
    CHECK(ret, FAIL, "H5Pset_alignment");

    /* Call helper routines to perform file manipulations */
    ret = test_userblock_alignment_helper2(fapl, false);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");
    ret = test_userblock_alignment_helper2(fapl, true);
    CHECK(ret, FAIL, "test_userblock_alignment_helper2");

    /* Release property lists */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

} /* end test_userblock_alignment_paged() */

/****************************************************************
**
**  test_filespace_info():
**    Verify the following public routines retrieve and set file space
**    information correctly:
**      (1) H5Pget/set_file_space_strategy():
**          Retrieve and set file space strategy, persisting free-space,
**          and free-space section threshold as specified
**      (2) H5Pget/set_file_space_page_size():
**          Retrieve and set the page size for paged aggregation
**
****************************************************************/
static void
test_filespace_info(const char *driver_name)
{
    hid_t                 fid;                    /* File IDs    */
    hid_t                 fapl, new_fapl;         /* File access property lists */
    hid_t                 fcpl, fcpl1, fcpl2;     /* File creation property lists */
    H5F_fspace_strategy_t strategy;               /* File space strategy */
    bool                  persist;                /* Persist free-space or not */
    hsize_t               threshold;              /* Free-space section threshold */
    unsigned              new_format;             /* New or old format */
    H5F_fspace_strategy_t fs_strategy;            /* File space strategy--iteration variable */
    unsigned              fs_persist;             /* Persist free-space or not--iteration variable */
    hsize_t               fs_threshold;           /* Free-space section threshold--iteration variable */
    hsize_t               fsp_size;               /* File space page size */
    char                  filename[FILENAME_LEN]; /* Filename to use */
    bool                  contig_addr_vfd;        /* Whether VFD used has a contiguous address space */
    bool                  vol_is_native;
    herr_t                ret; /* Return value    */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing file creation public routines: H5Pget/set_file_space_strategy & "
                "H5Pget/set_file_space_page_size\n"));

    contig_addr_vfd = (bool)(strcmp(driver_name, "split") != 0 && strcmp(driver_name, "multi") != 0);

    fapl = h5_fileaccess();
    h5_fixname(FILESPACE_NAME[0], fapl, filename, sizeof filename);

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, H5I_INVALID_HID, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Get a copy of the file access property list */
    new_fapl = H5Pcopy(fapl);
    CHECK(new_fapl, FAIL, "H5Pcopy");

    /* Set the "use the latest version of the format" bounds */
    ret = H5Pset_libver_bounds(new_fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    /*
     * Case (1)
     *  Check file space information from a default file creation property list.
     *  Values expected:
     *      strategy--H5F_FILE_SPACE_AGGR
     *      persist--false
     *      threshold--1
     *      file space page size--4096
     */
    /* Create file creation property list template */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");

    /* Retrieve file space information */
    ret = H5Pget_file_space_strategy(fcpl, &strategy, &persist, &threshold);
    CHECK(ret, FAIL, "H5Pget_file_space_strategy");

    /* Verify file space information */
    VERIFY(strategy, H5F_FSPACE_STRATEGY_FSM_AGGR, "H5Pget_file_space_strategy");
    VERIFY(persist, false, "H5Pget_file_space_strategy");
    VERIFY(threshold, 1, "H5Pget_file_space_strategy");

    /* Retrieve file space page size */
    ret = H5Pget_file_space_page_size(fcpl, &fsp_size);
    CHECK(ret, FAIL, "H5Pget_file_space_page_size");
    VERIFY(fsp_size, FSP_SIZE_DEF, "H5Pget_file_space_page_size");

    /* Close property list */
    H5Pclose(fcpl);

    /*
     * Case (2)
     *  File space page size has a minimum size of 512.
     *  Setting value less than 512 will return an error;
     *      --setting file space page size to 0
     *      --setting file space page size to 511
     *
     *  File space page size has a maximum size of 1 gigabyte.
     *  Setting value greater than 1 gigabyte will return an error.
     */
    /* Create file creation property list template */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");

    /* Setting to 0: should fail */
    H5E_BEGIN_TRY
    {
        ret = H5Pset_file_space_page_size(fcpl, 0);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Pset_file_space_page_size");

    /* Setting to 511: should fail */
    H5E_BEGIN_TRY
    {
        ret = H5Pset_file_space_page_size(fcpl, 511);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Pset_file_space_page_size");

    /* Setting to 1GB+1: should fail */
    H5E_BEGIN_TRY
    {
        ret = H5Pset_file_space_page_size(fcpl, FSP_SIZE1G + 1);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Pset_file_space_page_size");

    /* Setting to 512: should succeed */
    ret = H5Pset_file_space_page_size(fcpl, FSP_SIZE512);
    CHECK(ret, FAIL, "H5Pset_file_space_page_size");
    ret = H5Pget_file_space_page_size(fcpl, &fsp_size);
    CHECK(ret, FAIL, "H5Pget_file_space_page_size");
    VERIFY(fsp_size, FSP_SIZE512, "H5Pget_file_space_page_size");

    /* Setting to 1GB: should succeed */
    ret = H5Pset_file_space_page_size(fcpl, FSP_SIZE1G);
    CHECK(ret, FAIL, "H5Pset_file_space_page_size");
    ret = H5Pget_file_space_page_size(fcpl, &fsp_size);
    CHECK(ret, FAIL, "H5Pget_file_space_page_size");
    VERIFY(fsp_size, FSP_SIZE1G, "H5Pget_file_space_page_size");

    /* Close property list */
    H5Pclose(fcpl);

    /*
     * Case (3)
     *  Check file space information when creating a file with default properties.
     *  Values expected:
     *      strategy--H5F_FILE_SPACE_AGGR
     *      persist--false
     *      threshold--1
     *      file space page size--4096
     */
    /* Create a file with default file creation and access property lists */
    fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(fid, FAIL, "H5Fcreate");

    /* Get the file's creation property list */
    fcpl1 = H5Fget_create_plist(fid);
    CHECK(fcpl1, FAIL, "H5Fget_create_plist");

    /* Retrieve file space information */
    ret = H5Pget_file_space_strategy(fcpl1, &strategy, &persist, &threshold);
    CHECK(ret, FAIL, "H5Pget_file_space_strategy");

    /* Verify file space information */
    VERIFY(strategy, H5F_FSPACE_STRATEGY_FSM_AGGR, "H5Pget_file_space_strategy");
    VERIFY(persist, false, "H5Pget_file_space_strategy");
    VERIFY(threshold, 1, "H5Pget_file_space_strategy");

    /* Retrieve file space page size */
    ret = H5Pget_file_space_page_size(fcpl1, &fsp_size);
    CHECK(ret, FAIL, "H5Pget_file_space_page_size");
    VERIFY(fsp_size, FSP_SIZE_DEF, "H5Pget_file_space_page_size");

    /* Close property lists */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Pclose(fcpl1);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case (4)
     *  Check file space information when creating a file with the
     *  latest library format and default properties.
     *  Values expected:
     *      strategy--H5F_FILE_SPACE_AGGR
     *      persist--false
     *      threshold--1
     *      file space page size--4096
     */
    /* Create a file with the latest library format */
    fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, new_fapl);
    CHECK(fid, FAIL, "H5Fcreate");

    /* Get the file's creation property */
    fcpl1 = H5Fget_create_plist(fid);
    CHECK(fcpl1, FAIL, "H5Fget_create_plist");

    /* Retrieve file space information */
    ret = H5Pget_file_space_strategy(fcpl1, &strategy, &persist, &threshold);
    CHECK(ret, FAIL, "H5Pget_file_space_strategy");

    /* Verify file space information */
    VERIFY(strategy, H5F_FSPACE_STRATEGY_FSM_AGGR, "H5Pget_file_space_strategy");
    VERIFY(persist, false, "H5Pget_file_space_strategy");
    VERIFY(threshold, 1, "H5Pget_file_space_strategy");

    /* Retrieve file space page size */
    ret = H5Pget_file_space_page_size(fcpl1, &fsp_size);
    CHECK(ret, FAIL, "H5Pget_file_space_page_size");
    VERIFY(fsp_size, FSP_SIZE_DEF, "H5Pget_file_space_page_size");

    /* Close property lists */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Pclose(fcpl1);
    CHECK(ret, FAIL, "H5Pclose");

    /*
     * Case (5)
     *  Check file space information with the following combinations:
     *    Create file with --
     *        New or old format
     *        Persist or not persist free-space
     *        Different sizes for free-space section threshold (0 to 10)
     *        The four file space strategies:
     *          H5F_FSPACE_STRATEGY_FSM_AGGR, H5F_FSPACE_STRATEGY_PAGE,
     *        H5F_FSPACE_STRATEGY_AGGR, H5F_FSPACE_STRATEGY_NONE
     *        File space page size: set to 512
     *
     */
    for (new_format = false; new_format <= true; new_format++) {
        hid_t my_fapl;

        /* Set the FAPL for the type of format */
        if (new_format) {
            MESSAGE(5, ("Testing with new group format\n"));
            my_fapl = new_fapl;
        } /* end if */
        else {
            MESSAGE(5, ("Testing with old group format\n"));
            my_fapl = fapl;
        } /* end else */

        /* Test with true or false for persisting free-space */
        for (fs_persist = false; fs_persist <= true; fs_persist++) {

            /* Test with free-space section threshold size: 0 to 10 */
            for (fs_threshold = 0; fs_threshold <= TEST_THRESHOLD10; fs_threshold++) {

                /* Test with 4 file space strategies */
                for (fs_strategy = H5F_FSPACE_STRATEGY_FSM_AGGR; fs_strategy < H5F_FSPACE_STRATEGY_NTYPES;
                     fs_strategy++) {

                    if (!contig_addr_vfd && (fs_strategy == H5F_FSPACE_STRATEGY_PAGE || fs_persist))
                        continue;

                    /* Create file creation property list template */
                    fcpl = H5Pcreate(H5P_FILE_CREATE);
                    CHECK(fcpl, FAIL, "H5Pcreate");

                    /* Set file space information */
                    ret = H5Pset_file_space_strategy(fcpl, fs_strategy, (bool)fs_persist, fs_threshold);
                    CHECK(ret, FAIL, "H5Pset_file_space_strategy");

                    ret = H5Pset_file_space_page_size(fcpl, FSP_SIZE512);
                    CHECK(ret, FAIL, "H5Pset_file_space_strategy");

                    /* Retrieve file space information */
                    ret = H5Pget_file_space_strategy(fcpl, &strategy, &persist, &threshold);
                    CHECK(ret, FAIL, "H5Pget_file_space_strategy");

                    /* Verify file space information */
                    VERIFY(strategy, fs_strategy, "H5Pget_file_space_strategy");

                    if (fs_strategy < H5F_FSPACE_STRATEGY_AGGR) {
                        VERIFY(persist, (bool)fs_persist, "H5Pget_file_space_strategy");
                        VERIFY(threshold, fs_threshold, "H5Pget_file_space_strategy");
                    }
                    else {
                        VERIFY(persist, false, "H5Pget_file_space_strategy");
                        VERIFY(threshold, 1, "H5Pget_file_space_strategy");
                    }

                    /* Retrieve and verify file space page size */
                    ret = H5Pget_file_space_page_size(fcpl, &fsp_size);
                    CHECK(ret, FAIL, "H5Pget_file_space_page_size");
                    VERIFY(fsp_size, FSP_SIZE512, "H5Pget_file_space_page_size");

                    /* Create the file with the specified file space info */
                    fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, my_fapl);
                    CHECK(fid, FAIL, "H5Fcreate");

                    /* Get the file's creation property */
                    fcpl1 = H5Fget_create_plist(fid);
                    CHECK(fcpl1, FAIL, "H5Fget_create_plist");

                    /* Retrieve file space information */
                    ret = H5Pget_file_space_strategy(fcpl1, &strategy, &persist, &threshold);
                    CHECK(ret, FAIL, "H5Pget_file_space_strategy");

                    /* Verify file space information */
                    VERIFY(strategy, fs_strategy, "H5Pget_file_space_strategy");

                    if (fs_strategy < H5F_FSPACE_STRATEGY_AGGR) {
                        VERIFY(persist, fs_persist, "H5Pget_file_space_strategy");
                        VERIFY(threshold, fs_threshold, "H5Pget_file_space_strategy");
                    }
                    else {
                        VERIFY(persist, false, "H5Pget_file_space_strategy");
                        VERIFY(threshold, 1, "H5Pget_file_space_strategy");
                    }

                    /* Retrieve and verify file space page size */
                    ret = H5Pget_file_space_page_size(fcpl1, &fsp_size);
                    CHECK(ret, FAIL, "H5Pget_file_space_page_size");
                    VERIFY(fsp_size, FSP_SIZE512, "H5Pget_file_space_page_size");

                    /* Close the file */
                    ret = H5Fclose(fid);
                    CHECK(ret, FAIL, "H5Fclose");

                    /* Re-open the file */
                    fid = H5Fopen(filename, H5F_ACC_RDWR, my_fapl);
                    CHECK(ret, FAIL, "H5Fopen");

                    /* Get the file's creation property */
                    fcpl2 = H5Fget_create_plist(fid);
                    CHECK(fcpl2, FAIL, "H5Fget_create_plist");

                    /* Retrieve file space information */
                    ret = H5Pget_file_space_strategy(fcpl2, &strategy, &persist, &threshold);
                    CHECK(ret, FAIL, "H5Pget_file_space_strategy");

                    /* Verify file space information */
                    VERIFY(strategy, fs_strategy, "H5Pget_file_space_strategy");
                    if (fs_strategy < H5F_FSPACE_STRATEGY_AGGR) {
                        VERIFY(persist, fs_persist, "H5Pget_file_space_strategy");
                        VERIFY(threshold, fs_threshold, "H5Pget_file_space_strategy");
                    }
                    else {
                        VERIFY(persist, false, "H5Pget_file_space_strategy");
                        VERIFY(threshold, 1, "H5Pget_file_space_strategy");
                    }

                    /* Retrieve and verify file space page size */
                    ret = H5Pget_file_space_page_size(fcpl2, &fsp_size);
                    CHECK(ret, FAIL, "H5Pget_file_space_page_size");
                    VERIFY(fsp_size, FSP_SIZE512, "H5Pget_file_space_page_size");

                    /* Close the file */
                    ret = H5Fclose(fid);
                    CHECK(ret, FAIL, "H5Fclose");

                    /* Release file creation property lists */
                    ret = H5Pclose(fcpl);
                    CHECK(ret, FAIL, "H5Pclose");
                    ret = H5Pclose(fcpl1);
                    CHECK(ret, FAIL, "H5Pclose");
                    ret = H5Pclose(fcpl2);
                    CHECK(ret, FAIL, "H5Pclose");
                } /* end for file space strategy type */
            }     /* end for free-space section threshold */
        }         /* end for fs_persist */

        /* close fapl_ and remove the file */
        h5_delete_all_test_files(FILESPACE_NAME, my_fapl);
        H5Pclose(my_fapl);
    } /* end for new_format */

} /* test_filespace_info() */

/****************************************************************
**
** set_multi_split():
**  Internal routine to set up page-aligned address space for multi/split driver
**  when testing paged aggregation.
**  This is used by test_file_freespace() and test_sects_freespace().
**
*****************************************************************/
static int
set_multi_split(hid_t fapl, hsize_t pagesize, bool split)
{
    H5FD_mem_t memb_map[H5FD_MEM_NTYPES];
    hid_t      memb_fapl_arr[H5FD_MEM_NTYPES];
    char      *memb_name[H5FD_MEM_NTYPES];
    haddr_t    memb_addr[H5FD_MEM_NTYPES];
    bool       relax;
    H5FD_mem_t mt;

    assert(split);

    memset(memb_name, 0, sizeof memb_name);

    /* Get current split settings */
    if (H5Pget_fapl_multi(fapl, memb_map, memb_fapl_arr, memb_name, memb_addr, &relax) < 0)
        TEST_ERROR;

    if (split) {
        /* Set memb_addr aligned */
        memb_addr[H5FD_MEM_SUPER] = ((memb_addr[H5FD_MEM_SUPER] + pagesize - 1) / pagesize) * pagesize;
        memb_addr[H5FD_MEM_DRAW]  = ((memb_addr[H5FD_MEM_DRAW] + pagesize - 1) / pagesize) * pagesize;
    }
    else {
        /* Set memb_addr aligned */
        for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++)
            memb_addr[mt] = ((memb_addr[mt] + pagesize - 1) / pagesize) * pagesize;
    } /* end else */

    /* Set multi driver with new FAPLs */
    if (H5Pset_fapl_multi(fapl, memb_map, memb_fapl_arr, (const char *const *)memb_name, memb_addr, relax) <
        0)
        TEST_ERROR;

    /* Free memb_name */
    for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++)
        free(memb_name[mt]);

    return 0;

error:
    return (-1);

} /* set_multi_split() */

/****************************************************************
**
**  test_file_freespace():
**      This routine checks the free space available in a file as
**      returned by the public routine H5Fget_freespace().
**
**
*****************************************************************/
static void
test_file_freespace(const char *driver_name)
{
    hid_t          file;                   /* File opened with read-write permission */
    h5_stat_size_t empty_filesize;         /* Size of file when empty */
    h5_stat_size_t mod_filesize;           /* Size of file after being modified */
    hssize_t       free_space;             /* Amount of free space in file */
    hid_t          fcpl;                   /* File creation property list */
    hid_t          fapl, new_fapl;         /* File access property list IDs */
    hid_t          dspace;                 /* Dataspace ID */
    hid_t          dset;                   /* Dataset ID */
    hid_t          dcpl;                   /* Dataset creation property list */
    int            k;                      /* Local index variable */
    unsigned       u;                      /* Local index variable */
    char           filename[FILENAME_LEN]; /* Filename to use */
    char           name[32];               /* Dataset name */
    unsigned       new_format;             /* To use old or new format */
    bool           split_vfd, multi_vfd;   /* Indicate multi/split driver */
    hsize_t        expected_freespace;     /* Freespace expected */
    hsize_t        expected_fs_del;        /* Freespace expected after delete */
    bool           vol_is_native;
    herr_t         ret; /* Return value */

    split_vfd = !strcmp(driver_name, "split");
    multi_vfd = !strcmp(driver_name, "multi");

    if (split_vfd || multi_vfd)
        return;

    fapl = h5_fileaccess();
    h5_fixname(FILESPACE_NAME[0], fapl, filename, sizeof filename);

    new_fapl = H5Pcopy(fapl);
    CHECK(new_fapl, FAIL, "H5Pcopy");

    /* Set the "use the earliest version of the format" bounds on fapl */
    ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    /* Set the "use the latest version of the format" bounds on new_fapl */
    ret = H5Pset_libver_bounds(new_fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");

    /* Test with old & new format */
    for (new_format = false; new_format <= true; new_format++) {
        hid_t my_fapl;

        /* Set the FAPL for the type of format */
        if (new_format) {
            MESSAGE(5, ("Testing with new group format\n"));

            my_fapl = new_fapl;

            if (multi_vfd || split_vfd) {
                ret = set_multi_split(new_fapl, FSP_SIZE_DEF, split_vfd);
                CHECK(ret, FAIL, "set_multi_split");
            }

            ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, (hsize_t)1);
            CHECK(ret, FAIL, "H5P_set_file_space_strategy");

            expected_freespace = 4534;
            if (split_vfd)
                expected_freespace = 427;
            if (multi_vfd)
                expected_freespace = 248;
            expected_fs_del = 0;
        } /* end if */
        else {
            MESSAGE(5, ("Testing with old group format\n"));
            /* Default: non-paged aggregation, non-persistent free-space */
            my_fapl            = fapl;
            expected_freespace = 2464;
            if (split_vfd)
                expected_freespace = 264;
            if (multi_vfd)
                expected_freespace = 0;
            expected_fs_del = 4096;

        } /* end else */

        /* Create an "empty" file */
        file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, my_fapl);
        CHECK(file, FAIL, "H5Fcreate");

        /* Check if native VOL is being used */
        CHECK(h5_using_native_vol(my_fapl, file, &vol_is_native), FAIL, "h5_using_native_vol");

        ret = H5Fclose(file);
        CHECK_I(ret, "H5Fclose");

        if (!vol_is_native)
            continue;

        /* Get the "empty" file size */
        empty_filesize = h5_get_file_size(filename, H5P_DEFAULT);

        /* Re-open the file (with read-write permission) */
        file = H5Fopen(filename, H5F_ACC_RDWR, my_fapl);
        CHECK_I(file, "H5Fopen");

        /* Check that the free space is 0 */
        free_space = H5Fget_freespace(file);
        CHECK(free_space, FAIL, "H5Fget_freespace");
        VERIFY(free_space, 0, "H5Fget_freespace");

        /* Create dataspace for datasets */
        dspace = H5Screate(H5S_SCALAR);
        CHECK(dspace, FAIL, "H5Screate");

        /* Create a dataset creation property list */
        dcpl = H5Pcreate(H5P_DATASET_CREATE);
        CHECK(dcpl, FAIL, "H5Pcreate");

        /* Set the space allocation time to early */
        ret = H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY);
        CHECK(ret, FAIL, "H5Pset_alloc_time");

        /* Create datasets in file */
        for (u = 0; u < 10; u++) {
            snprintf(name, sizeof(name), "Dataset %u", u);
            dset = H5Dcreate2(file, name, H5T_STD_U32LE, dspace, H5P_DEFAULT, dcpl, H5P_DEFAULT);
            CHECK(dset, FAIL, "H5Dcreate2");

            ret = H5Dclose(dset);
            CHECK(ret, FAIL, "H5Dclose");
        } /* end for */

        /* Close dataspace */
        ret = H5Sclose(dspace);
        CHECK(ret, FAIL, "H5Sclose");

        /* Close dataset creation property list */
        ret = H5Pclose(dcpl);
        CHECK(ret, FAIL, "H5Pclose");

        /* Check that there is the right amount of free space in the file */
        free_space = H5Fget_freespace(file);
        CHECK(free_space, FAIL, "H5Fget_freespace");
        VERIFY(free_space, expected_freespace, "H5Fget_freespace");

        /* Delete datasets in file */
        for (k = 9; k >= 0; k--) {
            snprintf(name, sizeof(name), "Dataset %u", (unsigned)k);
            ret = H5Ldelete(file, name, H5P_DEFAULT);
            CHECK(ret, FAIL, "H5Ldelete");
        } /* end for */

        /* Check that there is the right amount of free space in the file */
        free_space = H5Fget_freespace(file);
        CHECK(free_space, FAIL, "H5Fget_freespace");
        VERIFY(free_space, expected_fs_del, "H5Fget_freespace");

        /* Close file */
        ret = H5Fclose(file);
        CHECK(ret, FAIL, "H5Fclose");

        /* Get the file size after modifications*/
        mod_filesize = h5_get_file_size(filename, H5P_DEFAULT);

        /* Check that the file reverted to empty size */
        VERIFY(mod_filesize, empty_filesize, "H5Fget_freespace");

        h5_delete_all_test_files(FILESPACE_NAME, my_fapl);
        H5Pclose(my_fapl);

    } /* end for */

} /* end test_file_freespace() */

/****************************************************************
**
**  test_sects_freespace():
**      This routine checks free-space section information for the
**    file as returned by the public routine H5Fget_free_sections().
**
*****************************************************************/
static void
test_sects_freespace(const char *driver_name, bool new_format)
{
    char            filename[FILENAME_LEN]; /* Filename to use */
    hid_t           file;                   /* File ID */
    hid_t           fcpl;                   /* File creation property list template */
    hid_t           fapl;                   /* File access property list template */
    hssize_t        free_space;             /* Amount of free-space in the file */
    hid_t           dspace;                 /* Dataspace ID */
    hid_t           dset;                   /* Dataset ID */
    hid_t           dcpl;                   /* Dataset creation property list */
    char            name[32];               /* Dataset name */
    hssize_t        nsects = 0;             /* # of free-space sections */
    hssize_t        nall;                   /* # of free-space sections for all types of data */
    hssize_t        nmeta = 0, nraw = 0;    /* # of free-space sections for meta/raw/generic data */
    H5F_sect_info_t sect_info[15];          /* Array to hold free-space information */
    H5F_sect_info_t all_sect_info[15];      /* Array to hold free-space information for all types of data */
    H5F_sect_info_t meta_sect_info[15];     /* Array to hold free-space information for metadata */
    H5F_sect_info_t raw_sect_info[15];      /* Array to hold free-space information for raw data */
    hsize_t         total   = 0;            /* sum of the free-space section sizes */
    hsize_t         tmp_tot = 0;            /* Sum of the free-space section sizes */
    hsize_t         last_size;              /* Size of last free-space section */
    hsize_t         dims[1];                /* Dimension sizes */
    unsigned        u;                      /* Local index variable */
    H5FD_mem_t      type;
    bool            split_vfd = false, multi_vfd = false;
    bool            vol_is_native;
    herr_t          ret; /* Return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing H5Fget_free_sections()--free-space section info in the file\n"));

    split_vfd = !strcmp(driver_name, "split");
    multi_vfd = !strcmp(driver_name, "multi");

    if (split_vfd || multi_vfd) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    fapl = h5_fileaccess();
    h5_fixname(FILESPACE_NAME[0], fapl, filename, sizeof filename);

    /* Create file-creation template */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, FAIL, "H5Pcreate");

    if (new_format) {
        ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
        CHECK(ret, FAIL, "H5Pset_libver_bounds");

        /* Set to paged aggregation and persistent free-space */
        ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, true, (hsize_t)1);
        CHECK(ret, FAIL, "H5Pget_file_space_strategy");

        /* Set up paged aligned address space for multi/split driver */
        if (multi_vfd || split_vfd) {
            ret = set_multi_split(fapl, FSP_SIZE_DEF, split_vfd);
            CHECK(ret, FAIL, "set_multi_split");
        }
    }
    else {
        ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, true, (hsize_t)1);
        CHECK(ret, FAIL, "H5Pget_file_space_strategy");
    }

    /* Create the file */
    file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl);
    CHECK(file, FAIL, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(fapl, file, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Fclose(file), FAIL, "H5Fclose");
        CHECK(H5Pclose(fcpl), FAIL, "H5Pclose");
        h5_delete_all_test_files(FILESPACE_NAME, fapl);
        H5Pclose(fapl);
        CHECK(H5Pclose(fapl), FAIL, "H5Pclose");
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Create a dataset creation property list */
    dcpl = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl, FAIL, "H5Pcreate");

    /* Set the space allocation time to early */
    ret = H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY);
    CHECK(ret, FAIL, "H5Pset_alloc_time");

    /* Create 1 large dataset */
    dims[0] = 1200;
    dspace  = H5Screate_simple(1, dims, NULL);
    dset    = H5Dcreate2(file, "Dataset_large", H5T_STD_U32LE, dspace, H5P_DEFAULT, dcpl, H5P_DEFAULT);
    CHECK(dset, FAIL, "H5Dcreate2");

    /* Close dataset */
    ret = H5Dclose(dset);
    CHECK(ret, FAIL, "H5Dclose");

    /* Close dataspace */
    ret = H5Sclose(dspace);
    CHECK(ret, FAIL, "H5Sclose");

    /* Create dataspace for datasets */
    dspace = H5Screate(H5S_SCALAR);
    CHECK(dspace, FAIL, "H5Screate");

    /* Create datasets in file */
    for (u = 0; u < 10; u++) {
        snprintf(name, sizeof(name), "Dataset %u", u);
        dset = H5Dcreate2(file, name, H5T_STD_U32LE, dspace, H5P_DEFAULT, dcpl, H5P_DEFAULT);
        CHECK(dset, FAIL, "H5Dcreate2");

        ret = H5Dclose(dset);
        CHECK(ret, FAIL, "H5Dclose");
    } /* end for */

    /* Close dataspace */
    ret = H5Sclose(dspace);
    CHECK(ret, FAIL, "H5Sclose");

    /* Close dataset creation property list */
    ret = H5Pclose(dcpl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Delete odd-numbered datasets in file */
    for (u = 0; u < 10; u++) {
        snprintf(name, sizeof(name), "Dataset %u", u);
        if (u % 2) {
            ret = H5Ldelete(file, name, H5P_DEFAULT);
            CHECK(ret, FAIL, "H5Ldelete");
        } /* end if */
    }     /* end for */

    /* Close file */
    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

    /* Re-open the file with read-only permission */
    file = H5Fopen(filename, H5F_ACC_RDONLY, fapl);
    CHECK_I(file, "H5Fopen");

    /* Get the amount of free space in the file */
    free_space = H5Fget_freespace(file);
    CHECK(free_space, FAIL, "H5Fget_freespace");

    /* Get the total # of free-space sections in the file */
    nall = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)0, NULL);
    CHECK(nall, FAIL, "H5Fget_free_sections");

    /* Should return failure when nsects is 0 with a nonnull sect_info */
    H5E_BEGIN_TRY
    {
        nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)0, all_sect_info);
    }
    H5E_END_TRY
    VERIFY(nsects, FAIL, "H5Fget_free_sections");

    /* Retrieve and verify free space info for all the sections */
    memset(all_sect_info, 0, sizeof(all_sect_info));
    nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)nall, all_sect_info);
    VERIFY(nsects, nall, "H5Fget_free_sections");

    /* Verify the amount of free-space is correct */
    for (u = 0; u < nall; u++)
        total += all_sect_info[u].size;
    VERIFY(free_space, total, "H5Fget_free_sections");

    /* Save the last section's size */
    last_size = all_sect_info[nall - 1].size;

    /* Retrieve and verify free space info for -1 sections */
    memset(sect_info, 0, sizeof(sect_info));
    nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)(nall - 1), sect_info);
    VERIFY(nsects, nall, "H5Fget_free_sections");

    /* Verify the amount of free-space is correct */
    total = 0;
    for (u = 0; u < (nall - 1); u++) {
        VERIFY(sect_info[u].addr, all_sect_info[u].addr, "H5Fget_free_sections");
        VERIFY(sect_info[u].size, all_sect_info[u].size, "H5Fget_free_sections");
        total += sect_info[u].size;
    }
    VERIFY(((hsize_t)free_space - last_size), total, "H5Fget_free_sections");

    /* Retrieve and verify free-space info for +1 sections */
    memset(sect_info, 0, sizeof(sect_info));
    nsects = H5Fget_free_sections(file, H5FD_MEM_DEFAULT, (size_t)(nall + 1), sect_info);
    VERIFY(nsects, nall, "H5Fget_free_sections");

    /* Verify amount of free-space is correct */
    total = 0;
    for (u = 0; u < nall; u++) {
        VERIFY(sect_info[u].addr, all_sect_info[u].addr, "H5Fget_free_sections");
        VERIFY(sect_info[u].size, all_sect_info[u].size, "H5Fget_free_sections");
        total += sect_info[u].size;
    }
    VERIFY(sect_info[nall].addr, 0, "H5Fget_free_sections");
    VERIFY(sect_info[nall].size, 0, "H5Fget_free_sections");
    VERIFY(free_space, total, "H5Fget_free_sections");

    memset(meta_sect_info, 0, sizeof(meta_sect_info));
    if (multi_vfd) {
        hssize_t ntmp;

        for (type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; type++) {
            if (type == H5FD_MEM_DRAW || type == H5FD_MEM_GHEAP)
                continue;
            /* Get the # of free-space sections in the file for metadata */
            ntmp = H5Fget_free_sections(file, type, (size_t)0, NULL);
            CHECK(ntmp, FAIL, "H5Fget_free_sections");

            if (ntmp > 0) {
                nsects = H5Fget_free_sections(file, type, (size_t)ntmp, &meta_sect_info[nmeta]);
                VERIFY(nsects, ntmp, "H5Fget_free_sections");
                nmeta += ntmp;
            }
        }
    }
    else {
        /* Get the # of free-space sections in the file for metadata */
        nmeta = H5Fget_free_sections(file, H5FD_MEM_SUPER, (size_t)0, NULL);
        CHECK(nmeta, FAIL, "H5Fget_free_sections");

        /* Retrieve and verify free-space sections for metadata */
        nsects = H5Fget_free_sections(file, H5FD_MEM_SUPER, (size_t)nmeta, meta_sect_info);
        VERIFY(nsects, nmeta, "H5Fget_free_sections");
    }

    /* Get the # of free-space sections in the file for raw data */
    nraw = H5Fget_free_sections(file, H5FD_MEM_DRAW, (size_t)0, NULL);
    CHECK(nraw, FAIL, "H5Fget_free_sections");

    /* Retrieve and verify free-space sections for raw data */
    memset(raw_sect_info, 0, sizeof(raw_sect_info));
    nsects = H5Fget_free_sections(file, H5FD_MEM_DRAW, (size_t)nraw, raw_sect_info);
    VERIFY(nsects, nraw, "H5Fget_free_sections");

    /* Sum all the free-space sections */
    for (u = 0; u < nmeta; u++)
        tmp_tot += meta_sect_info[u].size;

    for (u = 0; u < nraw; u++)
        tmp_tot += raw_sect_info[u].size;

    /* Verify free-space info */
    VERIFY(nmeta + nraw, nall, "H5Fget_free_sections");
    VERIFY(tmp_tot, total, "H5Fget_free_sections");

    /* Closing */
    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Pclose(fcpl);
    CHECK(fcpl, FAIL, "H5Pclose");

    h5_delete_all_test_files(FILESPACE_NAME, fapl);
    H5Pclose(fapl);

} /* end test_sects_freespace() */

/****************************************************************
**
**  test_filespace_compatible():
**    Verify that the trunk with the latest file space management
**    can open, read and modify 1.6 HDF5 file and 1.8 HDF5 file.
**    Also verify the correct file space handling information
**    and the amount of free space.
**
****************************************************************/
static void
test_filespace_compatible(void)
{
    int                   fd_old = (-1), fd_new = (-1); /* File descriptors for copying data */
    hid_t                 fid = H5I_INVALID_HID;        /* File id */
    hid_t                 did = H5I_INVALID_HID;        /* Dataset id */
    hid_t                 fcpl;                         /* File creation property list template */
    int                   check[100];                   /* Temporary buffer for verifying dataset data */
    int                   rdbuf[100];                   /* Temporary buffer for reading in dataset data */
    uint8_t               buf[READ_OLD_BUFSIZE];        /* temporary buffer for reading */
    ssize_t               nread;                        /* Number of bytes read in */
    unsigned              i, j;                         /* Local index variable */
    hssize_t              free_space;                   /* Amount of free-space in the file */
    bool                  persist;                      /* Persist free-space or not */
    hsize_t               threshold;                    /* Free-space section threshold */
    H5F_fspace_strategy_t strategy;                     /* File space handling strategy */
    bool                  vol_is_native;
    herr_t                ret; /* Return value */

    /* Output message about test being performed */
    MESSAGE(5, ("File space compatibility testing for 1.6 and 1.8 files\n"));

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, H5I_INVALID_HID, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    for (j = 0; j < NELMTS(OLD_FILENAME); j++) {
        const char *filename = H5_get_srcdir_filename(OLD_FILENAME[j]); /* Corrected test file name */

        /* Open and copy the test file into a temporary file */
        fd_old = HDopen(filename, O_RDONLY);
        CHECK(fd_old, FAIL, "HDopen");
        fd_new = HDopen(FILE5, O_RDWR | O_CREAT | O_TRUNC, H5_POSIX_CREATE_MODE_RW);
        CHECK(fd_new, FAIL, "HDopen");

        /* Copy data */
        while ((nread = HDread(fd_old, buf, (size_t)READ_OLD_BUFSIZE)) > 0) {
            ssize_t write_err = HDwrite(fd_new, buf, (size_t)nread);
            CHECK(write_err, -1, "HDwrite");
        } /* end while */

        /* Close the files */
        ret = HDclose(fd_old);
        CHECK(ret, FAIL, "HDclose");
        ret = HDclose(fd_new);
        CHECK(ret, FAIL, "HDclose");

        /* Open the temporary test file */
        fid = H5Fopen(FILE5, H5F_ACC_RDWR, H5P_DEFAULT);
        CHECK(fid, FAIL, "H5Fopen");

        /* There should not be any free space in the file */
        free_space = H5Fget_freespace(fid);
        CHECK(free_space, FAIL, "H5Fget_freespace");
        VERIFY(free_space, (hssize_t)0, "H5Fget_freespace");

        /* Get the file's file creation property list */
        fcpl = H5Fget_create_plist(fid);
        CHECK(fcpl, FAIL, "H5Fget_create_plist");

        /* Retrieve the file space info */
        ret = H5Pget_file_space_strategy(fcpl, &strategy, &persist, &threshold);
        CHECK(ret, FAIL, "H5Pget_file_space_strategy");

        /* File space handling strategy should be H5F_FSPACE_STRATEGY_FSM_AGGR */
        /* Persisting free-space should be false */
        /* Free-space section threshold should be 1 */
        VERIFY(strategy, H5F_FSPACE_STRATEGY_FSM_AGGR, "H5Pget_file_space_strategy");
        VERIFY(persist, false, "H5Pget_file_space_strategy");
        VERIFY(threshold, 1, "H5Pget_file_space_strategy");

        /* Generate raw data */
        for (i = 0; i < 100; i++)
            check[i] = (int)i;

        /* Open and read the dataset */
        did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT);
        CHECK(did, FAIL, "H5Dopen");
        ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdbuf);
        CHECK(ret, FAIL, "H5Dread");

        /* Verify the data read is correct */
        for (i = 0; i < 100; i++)
            VERIFY(rdbuf[i], check[i], "test_compatible");

        /* Close the dataset */
        ret = H5Dclose(did);
        CHECK(ret, FAIL, "H5Dclose");

        /* Remove the dataset */
        ret = H5Ldelete(fid, DSETNAME, H5P_DEFAULT);
        CHECK(ret, FAIL, "H5Ldelete");

        /* Close the plist */
        ret = H5Pclose(fcpl);
        CHECK(ret, FAIL, "H5Pclose");

        /* Close the file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");

        /* Re-Open the file */
        fid = H5Fopen(FILE5, H5F_ACC_RDONLY, H5P_DEFAULT);
        CHECK(fid, FAIL, "H5Fopen");

        /* The dataset should not be there */
        H5E_BEGIN_TRY
        {
            did = H5Dopen2(fid, DSETNAME, H5P_DEFAULT);
        }
        H5E_END_TRY
        VERIFY(did, FAIL, "H5Dopen");

        /* There should not be any free space in the file */
        free_space = H5Fget_freespace(fid);
        CHECK(free_space, FAIL, "H5Fget_freespace");
        VERIFY(free_space, (hssize_t)0, "H5Fget_freespace");

        /* Close the file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");
    } /* end for */
} /* test_filespace_compatible */

/****************************************************************
**
**  test_filespace_1.10.0_compatible():
**    Verify that the latest file space management can open, read and
**    modify 1.10.0 HDF5 files :
**    h5fc_ext1_i.h5:   H5F_FILE_SPACE_ALL, default threshold; has superblock extension but no fsinfo message
**    h5fc_ext1_f.h5:   H5F_FILE_SPACE_ALL_PERSIST, default threshold; has superblock extension with fsinfo
*message
**    h5fc_ext2_if.h5:  H5F_FILE_SPACE_ALL, non-default threshold; has superblock extension with fsinfo
*message
**    h5fc_ext2_sf.h5:  H5F_FILE_SPACE_VFD, default threshold; has superblock extension with fsinfo message
**    h5fc_ext3_isf.h5: H5F_FILE_SPACE_AGGR_VFD, default threshold; has superblock extension with fsinfo
*message
**    h5fc_ext_none.h5: H5F_FILE_SPACE_ALL, default threshold; without superblock extension
**  The above files are copied from release 1.10.0 tools/h5format_convert/testfiles.
**
****************************************************************/
static void
test_filespace_1_10_0_compatible(void)
{
    hid_t                 fid = H5I_INVALID_HID; /* File id */
    hid_t                 did = H5I_INVALID_HID; /* Dataset id */
    hid_t                 fcpl;                  /* File creation property list */
    bool                  persist;               /* Persist free-space or not */
    hsize_t               threshold;             /* Free-space section threshold */
    H5F_fspace_strategy_t strategy;              /* File space handling strategy */
    int                   wbuf[24];              /* Buffer for dataset data */
    int                   rdbuf[24];             /* Buffer for dataset data */
    int                   status;                /* Status from copying the existing file */
    unsigned              i, j;                  /* Local index variable */
    bool                  vol_is_native;
    herr_t                ret; /* Return value */

    /* Output message about test being performed */
    MESSAGE(5, ("File space compatibility testing for 1.10.0 files\n"));

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, H5I_INVALID_HID, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    for (j = 0; j < NELMTS(OLD_1_10_0_FILENAME); j++) {
        /* Make a copy of the test file */
        status = h5_make_local_copy(OLD_1_10_0_FILENAME[j], FILE5);
        CHECK(status, FAIL, "h5_make_local_copy");

        /* Open the temporary test file */
        fid = H5Fopen(FILE5, H5F_ACC_RDWR, H5P_DEFAULT);
        CHECK(fid, FAIL, "H5Fopen");

        /* Get the file's file creation property list */
        fcpl = H5Fget_create_plist(fid);
        CHECK(fcpl, FAIL, "H5Fget_create_plist");

        /* Retrieve the file space info */
        ret = H5Pget_file_space_strategy(fcpl, &strategy, &persist, &threshold);
        CHECK(ret, FAIL, "H5Pget_file_space_strategy");

        switch (j) {
            case 0:
                VERIFY(strategy, H5F_FILE_SPACE_STRATEGY_DEF, "H5Pget_file_space_strategy");
                VERIFY(persist, H5F_FREE_SPACE_PERSIST_DEF, "H5Pget_file_space_strategy");
                VERIFY(threshold, H5F_FREE_SPACE_THRESHOLD_DEF, "H5Pget_file_space_strategy");

                /* Open the dataset */
                did = H5Dopen2(fid, "/DSET_EA", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                for (i = 0; i < 24; i++)
                    wbuf[i] = (int)j + 1;

                /* Write to the dataset */
                ret = H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf);
                CHECK(ret, FAIL, "H5Dwrite");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            case 1:
                VERIFY(strategy, H5F_FSPACE_STRATEGY_FSM_AGGR, "H5Pget_file_space_strategy");
                VERIFY(persist, true, "H5Pget_file_space_strategy");
                VERIFY(threshold, H5F_FREE_SPACE_THRESHOLD_DEF, "H5Pget_file_space_strategy");

                /* Open the dataset */
                did = H5Dopen2(fid, "/DSET_NDATA_BT2", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                for (i = 0; i < 24; i++)
                    wbuf[i] = (int)j + 1;

                /* Write to the dataset */
                ret = H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf);
                CHECK(ret, FAIL, "H5Dwrite");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            case 2:
                VERIFY(strategy, H5F_FSPACE_STRATEGY_FSM_AGGR, "H5Pget_file_space_strategy");
                VERIFY(persist, H5F_FREE_SPACE_PERSIST_DEF, "H5Pget_file_space_strategy");
                VERIFY(threshold, 2, "H5Pget_file_space_strategy");

                /* Open the dataset */
                did = H5Dopen2(fid, "/DSET_NONE", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                for (i = 0; i < 24; i++)
                    wbuf[i] = (int)j + 1;

                /* Write to the dataset */
                ret = H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf);
                CHECK(ret, FAIL, "H5Dwrite");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            case 3:
                VERIFY(strategy, H5F_FSPACE_STRATEGY_NONE, "H5Pget_file_space_strategy");
                VERIFY(persist, H5F_FREE_SPACE_PERSIST_DEF, "H5Pget_file_space_strategy");
                VERIFY(threshold, H5F_FREE_SPACE_THRESHOLD_DEF, "H5Pget_file_space_strategy");

                /* Open the dataset */
                did = H5Dopen2(fid, "/GROUP/DSET_NDATA_EA", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                for (i = 0; i < 24; i++)
                    wbuf[i] = (int)j + 1;

                /* Write to the dataset */
                ret = H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf);
                CHECK(ret, FAIL, "H5Dwrite");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            case 4:
                VERIFY(strategy, H5F_FSPACE_STRATEGY_AGGR, "H5Pget_file_space_strategy");
                VERIFY(persist, H5F_FREE_SPACE_PERSIST_DEF, "H5Pget_file_space_strategy");
                VERIFY(threshold, H5F_FREE_SPACE_THRESHOLD_DEF, "H5Pget_file_space_strategy");

                /* Open the dataset */
                did = H5Dopen2(fid, "/GROUP/DSET_NDATA_FA", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                for (i = 0; i < 24; i++)
                    wbuf[i] = (int)j + 1;

                /* Write to the dataset */
                ret = H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf);
                CHECK(ret, FAIL, "H5Dwrite");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;
            case 5:
                VERIFY(strategy, H5F_FSPACE_STRATEGY_FSM_AGGR, "H5Pget_file_space_strategy");
                VERIFY(persist, H5F_FREE_SPACE_PERSIST_DEF, "H5Pget_file_space_strategy");
                VERIFY(threshold, H5F_FREE_SPACE_THRESHOLD_DEF, "H5Pget_file_space_strategy");

                /* Open the dataset */
                did = H5Dopen2(fid, "/GROUP/DSET_NDATA_NONE", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                for (i = 0; i < 24; i++)
                    wbuf[i] = (int)j + 1;

                /* Write to the dataset */
                ret = H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf);
                CHECK(ret, FAIL, "H5Dwrite");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            default:
                break;
        }

        /* Close the plist */
        ret = H5Pclose(fcpl);
        CHECK(ret, FAIL, "H5Pclose");

        /* Close the file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");

        /* Re-Open the file */
        fid = H5Fopen(FILE5, H5F_ACC_RDONLY, H5P_DEFAULT);
        CHECK(fid, FAIL, "H5Fopen");

        switch (j) {
            case 0:
                /* Open and read the dataset */
                did = H5Dopen2(fid, "/DSET_EA", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdbuf);
                CHECK(ret, FAIL, "H5Dread");

                /* Verify the data read is correct */
                for (i = 0; i < 24; i++)
                    VERIFY(rdbuf[i], j + 1, "test_compatible");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            case 1:
                /* Open and read the dataset */
                did = H5Dopen2(fid, "/DSET_NDATA_BT2", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdbuf);
                CHECK(ret, FAIL, "H5Dread");

                /* Verify the data read is correct */
                for (i = 0; i < 24; i++)
                    VERIFY(rdbuf[i], j + 1, "test_compatible");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            case 2:
                /* Open and read the dataset */
                did = H5Dopen2(fid, "/DSET_NONE", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdbuf);
                CHECK(ret, FAIL, "H5Dread");

                /* Verify the data read is correct */
                for (i = 0; i < 24; i++)
                    VERIFY(rdbuf[i], j + 1, "test_compatible");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            case 3:
                /* Open and read the dataset */
                did = H5Dopen2(fid, "/GROUP/DSET_NDATA_EA", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdbuf);
                CHECK(ret, FAIL, "H5Dread");

                /* Verify the data read is correct */
                for (i = 0; i < 24; i++)
                    VERIFY(rdbuf[i], j + 1, "test_compatible");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            case 4:

                /* Open and read the dataset */
                did = H5Dopen2(fid, "/GROUP/DSET_NDATA_FA", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdbuf);
                CHECK(ret, FAIL, "H5Dread");

                /* Verify the data read is correct */
                for (i = 0; i < 24; i++)
                    VERIFY(rdbuf[i], j + 1, "test_compatible");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            case 5:

                /* Open and read the dataset */
                did = H5Dopen2(fid, "/GROUP/DSET_NDATA_NONE", H5P_DEFAULT);
                CHECK(did, FAIL, "H5Dopen");

                ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdbuf);
                CHECK(ret, FAIL, "H5Dread");

                /* Verify the data read is correct */
                for (i = 0; i < 24; i++)
                    VERIFY(rdbuf[i], j + 1, "test_compatible");

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                break;

            default:
                break;
        }

        /* Close the file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");
    } /* end for */

} /* test_filespace_1_10_0_compatible */

/****************************************************************
**
**  test_filespace_round_compatible():
**    Verify that the trunk can open, read and modify these files--
**      1) They are initially created (via gen_filespace.c) in the trunk
**         with combinations of file space strategies, default/non-default
**         threshold, and file spacing paging enabled/disabled.
**         The library creates the file space info message with
**         "mark if unknown" in these files.
**      2) They are copied to the 1.8 branch, and are opened/read/modified
**         there via test_filespace_compatible() in test/tfile.c.
**         The 1.8 library marks the file space info message as "unknown"
**         in these files.
**      3) They are then copied back from the 1.8 branch to the trunk for
**         compatibility testing via this routine.
**      4) Upon encountering the file space info message which is marked
**         as "unknown", the library will use the default file space management
**         from then on: non-persistent free-space managers, default threshold,
**         and non-paging file space.
**
****************************************************************/
static void
test_filespace_round_compatible(void)
{
    hid_t                 fid  = H5I_INVALID_HID; /* File id */
    hid_t                 fcpl = H5I_INVALID_HID; /* File creation property list ID */
    unsigned              j;                      /* Local index variable */
    H5F_fspace_strategy_t strategy;               /* File space strategy */
    bool                  persist;                /* Persist free-space or not */
    hsize_t               threshold;              /* Free-space section threshold */
    hssize_t              free_space;             /* Amount of free space in the file */
    int                   status;                 /* Status from copying the existing file */
    bool                  vol_is_native;
    herr_t                ret; /* Return value */

    /* Output message about test being performed */
    MESSAGE(5, ("File space compatibility testing for files from trunk to 1_8 to trunk\n"));

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, H5I_INVALID_HID, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    for (j = 0; j < NELMTS(FSPACE_FILENAMES); j++) {
        /* Make a copy of the test file */
        status = h5_make_local_copy(FSPACE_FILENAMES[j], FILE5);
        CHECK(status, FAIL, "h5_make_local_copy");

        /* Open the temporary test file */
        fid = H5Fopen(FILE5, H5F_ACC_RDWR, H5P_DEFAULT);
        CHECK(fid, FAIL, "H5Fopen");

        /* Get the file's creation property list */
        fcpl = H5Fget_create_plist(fid);
        CHECK(fcpl, FAIL, "H5Fget_create_plist");

        ret = H5Pget_file_space_strategy(fcpl, &strategy, &persist, &threshold);
        CHECK(ret, FAIL, "H5Pget_file_space_strategy");
        VERIFY(strategy, H5F_FSPACE_STRATEGY_FSM_AGGR, "H5Pget_file_space_strategy");
        VERIFY(persist, false, "H5Pget_file_space_strategy");
        VERIFY(threshold, 1, "H5Pget_file_space_strategy");

        /* There should not be any free space in the file */
        free_space = H5Fget_freespace(fid);
        CHECK(free_space, FAIL, "H5Fget_freespace");
        VERIFY(free_space, (hssize_t)0, "H5Fget_freespace");

        /* Closing */
        ret = H5Fclose(fid);
        ret = H5Pclose(fcpl);
        CHECK(ret, FAIL, "H5Fclose");
    } /* end for */

} /* test_filespace_round_compatible */

/****************************************************************
**
**  test_libver_bounds_real():
**      Verify that a file created and modified with the
**      specified libver bounds has the specified object header
**      versions for the right objects.
**
****************************************************************/
static void
test_libver_bounds_real(H5F_libver_t libver_create, unsigned oh_vers_create, H5F_libver_t libver_mod,
                        unsigned oh_vers_mod)
{
    hid_t             file, group; /* Handles */
    hid_t             fapl;        /* File access property list */
    H5O_native_info_t ninfo;       /* Object info */
    bool              vol_is_native;
    herr_t            ret; /* Return value */

    /*
     * Create a new file using the creation properties.
     */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");

    ret = H5Pset_libver_bounds(fapl, libver_create, H5F_LIBVER_LATEST);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    file = H5Fcreate("tfile5.h5", H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(file, FAIL, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(fapl, file, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Pclose(fapl), FAIL, "H5Pclose");
        CHECK(H5Fclose(file), FAIL, "H5Fclose");
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /*
     * Make sure the root group has the correct object header version
     */
    ret = H5Oget_native_info_by_name(file, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Oget_native_info_by_name");
    VERIFY(ninfo.hdr.version, oh_vers_create, "H5Oget_native_info_by_name");

    /*
     * Reopen the file and make sure the root group still has the correct version
     */
    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

    ret = H5Pset_libver_bounds(fapl, libver_mod, H5F_LIBVER_LATEST);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    file = H5Fopen("tfile5.h5", H5F_ACC_RDWR, fapl);
    CHECK(file, FAIL, "H5Fopen");

    ret = H5Oget_native_info_by_name(file, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Oget_native_info_by_name");
    VERIFY(ninfo.hdr.version, oh_vers_create, "H5Oget_native_info_by_name");

    /*
     * Create a group named "G1" in the file, and make sure it has the correct
     * object header version
     */
    group = H5Gcreate2(file, "/G1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(group, FAIL, "H5Gcreate");

    //! [H5Oget_native_info_snip]

    ret = H5Oget_native_info(group, &ninfo, H5O_NATIVE_INFO_HDR);

    //! [H5Oget_native_info_snip]

    CHECK(ret, FAIL, "H5Oget_native)info");
    VERIFY(ninfo.hdr.version, oh_vers_mod, "H5Oget_native_info");

    ret = H5Gclose(group);
    CHECK(ret, FAIL, "H5Gclose");

    /*
     * Create a group named "/G1/G3" in the file, and make sure it has the
     * correct object header version
     */
    group = H5Gcreate2(file, "/G1/G3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(group, FAIL, "H5Gcreate");

    ret = H5Oget_native_info(group, &ninfo, H5O_NATIVE_INFO_HDR);
    CHECK(ret, FAIL, "H5Oget_native_info");
    VERIFY(ninfo.hdr.version, oh_vers_mod, "H5Oget_native_info");

    ret = H5Gclose(group);
    CHECK(ret, FAIL, "H5Gclose");

    //! [H5Oget_native_info_by_name_snip]

    /*
     * Make sure the root group still has the correct object header version
     */
    ret = H5Oget_native_info_by_name(file, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT);

    //! [H5Oget_native_info_by_name_snip]

    CHECK(ret, FAIL, "H5Oget_native_info_by_name");
    VERIFY(ninfo.hdr.version, oh_vers_create, "H5Oget_native_info_by_name");

    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");
} /* end test_libver_bounds_real() */

/*-------------------------------------------------------------------------
 * Function:    test_libver_bounds_open
 *
 * Purpose:     Tests opening latest file with various low/high bounds.
 *
 * Return:      Success:    0
 *              Failure:    number of errors
 *
 *-------------------------------------------------------------------------
 */
#define VFNAME      "verbounds.h5"
#define VERBDSNAME  "dataset 1"
#define SPACE1_DIM1 3
static void
test_libver_bounds_open(void)
{
    hid_t        file   = H5I_INVALID_HID;     /* File ID */
    hid_t        space  = H5I_INVALID_HID;     /* Dataspace ID */
    hid_t        dset   = H5I_INVALID_HID;     /* Dataset ID */
    hid_t        fapl   = H5I_INVALID_HID;     /* File access property list ID */
    hid_t        dcpl   = H5I_INVALID_HID;     /* Dataset creation property list ID */
    hsize_t      dim[1] = {SPACE1_DIM1};       /* Dataset dimensions */
    H5F_libver_t low, high;                    /* File format bounds */
    hsize_t      chunk_dim[1] = {SPACE1_DIM1}; /* Chunk dimensions */
    bool         vol_is_native;
    herr_t       ret; /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Opening File in Various Version Bounds\n"));

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, H5I_INVALID_HID, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Create a file access property list */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");

    /* Create dataspace */
    space = H5Screate_simple(1, dim, NULL);
    CHECK(space, FAIL, "H5Screate_simple");

    /* Create a dataset creation property list */
    dcpl = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl, FAIL, "H5Pcreate");

    /* Create and set chunk plist */
    ret = H5Pset_chunk(dcpl, 1, chunk_dim);
    CHECK(ret, FAIL, "H5Pset_chunk");
    ret = H5Pset_deflate(dcpl, 9);
    CHECK(ret, FAIL, "H5Pset_deflate");
    ret = H5Pset_chunk_opts(dcpl, H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS);
    CHECK(ret, FAIL, "H5Pset_chunk_opts");

    /* Create a file with (LATEST, LATEST) bounds, create a layout version 4
       dataset, then close the file */

    /* Set version bounds to (LATEST, LATEST) */
    low  = H5F_LIBVER_LATEST;
    high = H5F_LIBVER_LATEST;
    ret  = H5Pset_libver_bounds(fapl, low, high);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    /* Create the file */
    file = H5Fcreate(VFNAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(file, FAIL, "H5Fcreate");

    /* Create dataset */
    dset = H5Dcreate2(file, VERBDSNAME, H5T_NATIVE_INT, space, H5P_DEFAULT, dcpl, H5P_DEFAULT);
    CHECK(dset, FAIL, "H5Dcreate2");

    /* Close dataset and file */
    ret = H5Dclose(dset);
    CHECK(ret, FAIL, "H5Dclose");
    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

    /* Attempt to open latest file with (earliest, v18) should succeed */
    ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_EARLIEST, H5F_LIBVER_V18);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    if ((file = H5Fopen(VFNAME, H5F_ACC_RDONLY, fapl)) < 0)
        VERIFY((file >= 0), true, "Attempt to open latest file with earliest version should succeed");
    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

    /* Attempt to open latest file with (v18, v18), should fail */
    ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_V18, H5F_LIBVER_V18);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    file = H5Fopen(VFNAME, H5F_ACC_RDONLY, fapl);
    VERIFY((file >= 0), true, "Attempt to open latest file with v18 bounds should succeed");
    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

    /* Opening VERBFNAME in these combination should succeed */
    high = H5F_LIBVER_LATEST;
    for (low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) {

        /* Set version bounds for opening file */
        ret = H5Pset_libver_bounds(fapl, low, high);
        CHECK(ret, FAIL, "H5Pset_libver_bounds");

        /* Open the file */
        file = H5Fopen(VFNAME, H5F_ACC_RDONLY, fapl);
        VERIFY(file >= 0, true, "H5Fopen should succeed");

        ret = H5Fclose(file);
        CHECK(ret, FAIL, "H5Fclose");
    } /* for low */

    /* Close dataspace and property lists */
    ret = H5Sclose(space);
    CHECK(ret, FAIL, "H5Sclose");
    ret = H5Pclose(dcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");
} /* end test_libver_bounds_open() */

/*-------------------------------------------------------------------------
 * Function:    test_libver_bounds_copy
 *
 * Purpose:     Test to verify HDFFV-10800 is fixed:
 *              This test is copied from the user test program: copy10.c.
 *              (See attached programs in the jira issue.)
 *
 *              The source file used in the test is generated by the user test
 *              program "fill18.c" with the 1.8 library.  The file is created
 *              with the latest format and the dataset created in the file
 *              has version 3 fill value message (latest).
 *
 *              The test creates the destination file with (v18, v18) version bounds.
 *              H5Ocopy() should succeed in copying the dataset in the source file
 *              to the destination file.
 *
 * Return:      Success:    0
 *              Failure:    number of errors
 *
 *-------------------------------------------------------------------------
 */
static void
test_libver_bounds_copy(void)
{
    hid_t       src_fid = H5I_INVALID_HID; /* File ID */
    hid_t       dst_fid = H5I_INVALID_HID; /* File ID */
    hid_t       fapl    = H5I_INVALID_HID; /* File access property list ID */
    const char *src_fname;                 /* Source file name */
    herr_t      ret;                       /* Generic return value */
    bool        vol_is_native;
    bool        driver_is_default_compatible;

    /* Output message about the test being performed */
    MESSAGE(5, ("Testing H5Ocopy a dataset in a 1.8 library file to a 1.10 library file\n"));

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, H5I_INVALID_HID, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    ret = h5_driver_is_default_vfd_compatible(H5P_DEFAULT, &driver_is_default_compatible);
    CHECK_I(ret, "h5_driver_is_default_vfd_compatible");

    if (!driver_is_default_compatible) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Get the test file name */
    src_fname = H5_get_srcdir_filename(SRC_FILE);

    /* Open the source test file */
    src_fid = H5Fopen(src_fname, H5F_ACC_RDONLY, H5P_DEFAULT);
    CHECK(src_fid, FAIL, "H5Fopen");

    /* Create file access property list */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");

    /* Set library version bounds to (v18, v18) */
    ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_V18, H5F_LIBVER_V18);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    /* Create the destination file with the fapl */
    dst_fid = H5Fcreate(DST_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(dst_fid, FAIL, "H5Pcreate");

    /* Close the fapl */
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Copy the dataset in the source file to the destination file */
    ret = H5Ocopy(src_fid, DSET_DS1, dst_fid, DSET_DS1, H5P_DEFAULT, H5P_DEFAULT);
    VERIFY(ret, SUCCEED, "H5Ocopy");

    /* Close the source file */
    ret = H5Fclose(src_fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close the destination file */
    ret = H5Fclose(dst_fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Remove the destination file */
    H5E_BEGIN_TRY
    {
        H5Fdelete(DST_FILE, H5P_DEFAULT);
    }
    H5E_END_TRY

} /* end test_libver_bounds_copy() */

/****************************************************************
**
**  test_libver_bounds():
**      Verify that a file created and modified with various
**      libver bounds is handled correctly.  (Further testing
**      welcome)
**
****************************************************************/
static void
test_libver_bounds(void)
{
    /* Output message about test being performed */
    MESSAGE(5, ("Testing setting library version bounds\n"));

    /* Run the tests */
    test_libver_bounds_real(H5F_LIBVER_EARLIEST, 1, H5F_LIBVER_LATEST, 2);
    test_libver_bounds_real(H5F_LIBVER_LATEST, 2, H5F_LIBVER_EARLIEST, 1);
    test_libver_bounds_open();
    test_libver_bounds_copy();

} /* end test_libver_bounds() */

/**************************************************************************************
**
**  test_libver_bounds_low_high():
**      Tests to verify that format versions are correct with the following five
**      pairs of low/high version bounds set in fapl via H5Pset_libver_bounds():
**          (1) (earliest, v18)
**          (2) (earliest, v110)
**          (3) (v18, v18)
**          (4) (v18, v110)
**          (5) (v110, v110)
**
**      For each pair of setting in fapl, verify format versions with the following
**      six tests:
**          (1) test_libver_bounds_super(fapl): superblock versions
**          (2) test_libver_bounds_obj(fapl): object header versions
**          (3) test_libver_bounds_dataset(fapl): message versions associated with dataset
**          (4) test_libver_bounds_dataspace(fapl): dataspace message versions
**          (5) test_libver_bounds_datatype(fapl): datatype message versions
**          (6) test_libver_bounds_attributes(fapl): attribute message versions
**
**************************************************************************************/
static void
test_libver_bounds_low_high(const char *driver_name)
{
    hid_t        fapl = H5I_INVALID_HID; /* File access property list */
    H5F_libver_t low, high;              /* Low and high bounds */
    bool         vol_is_native;
    herr_t       ret; /* The return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing setting (low, high) format version bounds\n"));

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, H5I_INVALID_HID, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Create a file access property list */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, H5I_INVALID_HID, "H5Pcreate");

    /* Loop through all the combinations of low/high version bounds */
    for (low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++)
        for (high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) {

            H5E_BEGIN_TRY
            {
                /* Set the low/high version bounds */
                ret = H5Pset_libver_bounds(fapl, low, high);
            }
            H5E_END_TRY

            /* Should fail: invalid combinations */
            if (high == H5F_LIBVER_EARLIEST) {
                VERIFY(ret, FAIL, "H5Pset_libver_bounds");
                continue;
            }

            /* Should fail: invalid combinations */
            if (high < low) {
                VERIFY(ret, FAIL, "H5Pset_libver_bounds");
                continue;
            }

            /* All other combinations are valid and should succeed */
            VERIFY(ret, SUCCEED, "H5Pset_libver_bounds");

            /* Tests to verify version bounds */
            test_libver_bounds_super(fapl, driver_name);
            test_libver_bounds_obj(fapl);
            test_libver_bounds_dataset(fapl);
            test_libver_bounds_dataspace(fapl);
            test_libver_bounds_datatype(fapl);
            test_libver_bounds_attributes(fapl);
        }

    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

} /* end test_libver_bounds_low_high() */

/***********************************************************************
**
**  test_libver_bounds_super():
**      Verify superblock version with the following two tests:
**            (1) test_libver_bounds_super_create():
**              --when creating a file with the input fapl and the fcpl
**                that has the following feature enabled:
**                (A) default fcpl
**                (B) fcpl with v1-btee K value enabled
**                (C) fcpl with shared messages enabled
**                (D) fcpl with persistent free-space manager enabled
**
**            (2) test_libver_bounds_super_open():
**              --when opening a file which is created with the input fapl
**                and the fcpl setting as #A to #D above.
**
**     These two tests are run with or without SWMR file access.
**
*************************************************************************/
static void
test_libver_bounds_super(hid_t fapl, const char *driver_name)
{
    hid_t  fcpl = H5I_INVALID_HID; /* File creation property list */
    herr_t ret;                    /* The return value */

    /* Create a default fcpl: #A */
    /* This will result in superblock version 0 */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, H5I_INVALID_HID, "H5Pcreate");

    /* Verify superblock version when creating a file with input fapl,
       fcpl #A and with/without SWMR access */
    if (H5FD__supports_swmr_test(driver_name))
        test_libver_bounds_super_create(fapl, fcpl, true, false);
    test_libver_bounds_super_create(fapl, fcpl, false, false);

    /* Verify superblock version when opening a file which is created
       with input fapl, fcpl #A and with/without SWMR access */
    if (H5FD__supports_swmr_test(driver_name))
        test_libver_bounds_super_open(fapl, fcpl, true, false);
    test_libver_bounds_super_open(fapl, fcpl, false, false);

    /* Close the fcpl */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Create a fcpl with v1-btree K value enabled: #B */
    /* This will result in superblock version 1 */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, H5I_INVALID_HID, "H5Pcreate");
    ret = H5Pset_istore_k(fcpl, 64);
    CHECK(ret, FAIL, "H5Pset_istore_k");

    /* Verify superblock version when creating a file with input fapl,
       fcpl #B and with/without SWMR access */
    if (H5FD__supports_swmr_test(driver_name))
        test_libver_bounds_super_create(fapl, fcpl, true, false);
    test_libver_bounds_super_create(fapl, fcpl, false, false);

    /* Verify superblock version when opening a file which is created
       with input fapl, fcpl #B and with/without SWMR access */
    if (H5FD__supports_swmr_test(driver_name))
        test_libver_bounds_super_open(fapl, fcpl, true, false);
    test_libver_bounds_super_open(fapl, fcpl, false, false);

    /* Close the fcpl */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Create a fcpl with shared messages enabled: #C */
    /* This will result in superblock version 2 */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, H5I_INVALID_HID, "H5Pcreate");
    ret = H5Pset_shared_mesg_nindexes(fcpl, 1);
    CHECK(ret, FAIL, "H5Pset_shared_mesg_nindexes");
    ret = H5Pset_shared_mesg_index(fcpl, 0, H5O_SHMESG_ATTR_FLAG, 2);
    CHECK(ret, FAIL, "H5Pset_shared_mesg_index");

    /* Verify superblock version when creating a file with input fapl,
       fcpl #C and with/without SWMR access */
    if (H5FD__supports_swmr_test(driver_name))
        test_libver_bounds_super_create(fapl, fcpl, true, false);
    test_libver_bounds_super_create(fapl, fcpl, false, false);

    /* Verify superblock version when opening a file which is created
       with input fapl, fcpl #C and with/without SWMR access */
    if (H5FD__supports_swmr_test(driver_name))
        test_libver_bounds_super_open(fapl, fcpl, true, false);
    test_libver_bounds_super_open(fapl, fcpl, false, false);

    /* Close the fcpl */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");

    if (h5_using_default_driver(driver_name)) {
        /* Create a fcpl with persistent free-space manager enabled: #D */
        /* This will result in superblock version 2 */
        fcpl = H5Pcreate(H5P_FILE_CREATE);
        CHECK(fcpl, H5I_INVALID_HID, "H5Pcreate");
        ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, 1, (hsize_t)1);
        CHECK(ret, FAIL, "H5Pset_file_space");

        /* Verify superblock version when creating a file with input fapl,
           fcpl #D and with/without SWMR access */
        if (H5FD__supports_swmr_test(driver_name))
            test_libver_bounds_super_create(fapl, fcpl, true, true);
        test_libver_bounds_super_create(fapl, fcpl, false, true);

        /* Verify superblock version when opening a file which is created
           with input fapl, fcpl #D and with/without SWMR access */
        if (H5FD__supports_swmr_test(driver_name))
            test_libver_bounds_super_open(fapl, fcpl, true, true);
        test_libver_bounds_super_open(fapl, fcpl, false, true);

        /* Close the fcpl */
        ret = H5Pclose(fcpl);
        CHECK(ret, FAIL, "H5Pclose");
    }

} /* end test_libver_bounds_super() */

/**************************************************************************************************
**
**  test_libver_bounds_super_create():
**      Verify the following when the file is created with the input fapl, fcpl,
**      and with/without SWMR access:
**          (a) the superblock version #
**          (b) the file's low bound setting
**          (c) fail or succeed in creating the file
**
**      For file creation, the bounds setting in fapl, the feature enabled in fcpl,
**      and with/without SWMR file access will determine the results for #a to #c.
**
**      The first row for the following two tables is the 5 pairs of low/high bounds setting
**      in the input fapl. The next three rows list the expected results for #a to #c.
**      "-->" indicates "upgrade to"
**
**      The last table lists the expected results in creating the file when non-default
**      free-space info (fsinfo) is enabled in fcpl.
**
**                                  Creating a file with write access
**                    --------------------------------------------------------------------------------
**                    | (earliest, v18) | (earliest, v110) | (v18, v18) | (v18, v110) | (v110, v110) |
**                    |______________________________________________________________________________|
** Superblock version | vers 0, 1, 2    | vers 0, 1, 2     | vers 2     | vers 2      | vers 3       |
**                    |------------------------------------------------------------------------------|
** File's low bound   |                            no change                                         |
**                    |------------------------------------------------------------------------------|
** File creation      |                             succeed                                          |
**                    |______________________________________________________________________________|
**
**                                  Creating a file with SWMR-write access
**                    --------------------------------------------------------------------------------
**                    | (earliest, v18) | (earliest, v110) | (v18, v18) | (v18, v110) | (v110, v110) |
**                    |______________________________________________________________________________|
** Superblock version | --              | vers 3           | --         | vers  3     | vers 3       |
**                    |------------------------------------------------------------------------------|
** File's low bound   | --              | ->v110           | --         | ->v110      | no change    |
**                    |------------------------------------------------------------------------------|
** File creation      | fail            | succeed          | fail       | succeed     | succeed      |
**                    |______________________________________________________________________________|
**
**                                  Creating a file with write/SWMR-write access + non-default fsinfo
**                    --------------------------------------------------------------------------------
**                    | (earliest, v18) | (earliest, v110) | (v18, v18) | (v18, v110) | (v110, v110) |
**                    |______________________________________________________________________________|
** File creation      |  fail            | succeed         | fail       | succeed      | succeed     |
**                    |______________________________________________________________________________|
**
******************************************************************************************************/
static void
test_libver_bounds_super_create(hid_t fapl, hid_t fcpl, htri_t is_swmr, htri_t non_def_fsm)
{
    hid_t        fid = H5I_INVALID_HID; /* File ID */
    H5F_t       *f   = NULL;            /* Internal file pointer */
    H5F_libver_t low, high;             /* Low and high bounds */
    bool         ok;                    /* The result is ok or not */
    herr_t       ret;                   /* The return value */

    /* Try to create the file */
    H5E_BEGIN_TRY
    {
        fid = H5Fcreate(FILE8, H5F_ACC_TRUNC | (is_swmr ? H5F_ACC_SWMR_WRITE : 0), fcpl, fapl);
    }
    H5E_END_TRY

    /* Get the internal file pointer if the create succeeds */
    if (fid >= 0) {
        f = (H5F_t *)H5VL_object(fid);
        CHECK_PTR(f, "H5VL_object");
    }

    /* Retrieve the low/high bounds */
    ret = H5Pget_libver_bounds(fapl, &low, &high);
    CHECK(ret, FAIL, "H5Pget_libver_bounds");

    if (non_def_fsm && high < H5F_LIBVER_V110)
        VERIFY(fid, H5I_INVALID_HID, "H5Fcreate");

    else if (is_swmr) {                /* SWMR is enabled */
        if (high >= H5F_LIBVER_V110) { /* Should succeed */
            VERIFY(fid >= 0, true, "H5Fcreate");
            VERIFY(HDF5_SUPERBLOCK_VERSION_3, f->shared->sblock->super_vers, "HDF5_superblock_ver_bounds");
            VERIFY(f->shared->low_bound >= H5F_LIBVER_V110, true, "HDF5_superblock_ver_bounds");
        }
        else /* Should fail */
            VERIFY(fid >= 0, false, "H5Fcreate");
    }
    else { /* Should succeed */
        VERIFY(fid >= 0, true, "H5Fcreate");
        VERIFY(low, f->shared->low_bound, "HDF5_superblock_ver_bounds");

        switch (low) {
            case H5F_LIBVER_EARLIEST:
                ok = (f->shared->sblock->super_vers == HDF5_SUPERBLOCK_VERSION_DEF ||
                      f->shared->sblock->super_vers == HDF5_SUPERBLOCK_VERSION_1 ||
                      f->shared->sblock->super_vers == HDF5_SUPERBLOCK_VERSION_2);
                VERIFY(ok, true, "HDF5_superblock_ver_bounds");
                break;

            case H5F_LIBVER_V18:
                ok = (f->shared->sblock->super_vers == HDF5_SUPERBLOCK_VERSION_2);
                VERIFY(ok, true, "HDF5_superblock_ver_bounds");
                break;

            case H5F_LIBVER_V110:
            case H5F_LIBVER_V112:
            case H5F_LIBVER_V114:
            case H5F_LIBVER_V200:
                ok = (f->shared->sblock->super_vers == HDF5_SUPERBLOCK_VERSION_3);
                VERIFY(ok, true, "HDF5_superblock_ver_bounds");
                break;

            case H5F_LIBVER_ERROR:
            case H5F_LIBVER_NBOUNDS:
            default:
                ERROR("H5Pget_libver_bounds");

        } /* end switch */

    } /* end else */

    if (fid >= 0) { /* Close the file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");
    }

} /* end test_libver_bounds_super_create() */

/**************************************************************************************************
**
**  test_libver_bounds_super_open():
**      Verify the following when opening a file which is created with the input fapl, fcpl,
**      and with/without SWMR access:
**          (a) the file's low bound setting
**          (b) fail or succeed in opening the file
**
**      (1) Create a file with the input fapl, fcpl and with/without SWMR access
**      (2) Close the file
**      (3) Reopen the file with a new fapl that is set to the 5 pairs of low/high bounds
**          in a for loop. For each pair of setting in the new fapl:
**          --Verify the expected results for #a and #b above.
**          --Close the file.
**
**      For file open, the file's superblock version, the low/high bounds setting in fapl,
**      and with/without SWMR file access will determine the results for #a and #b.
**
**      The first row for the following tables (#A - #B) is the 5 pairs of low/high bounds setting
**      in the input fapl. The next two rows list the expected results for #a and #b.
**      "-->" indicates "upgrade to"
**
**      The last table (#C) lists the expected results in opening the file when non-default
**      free-space info (fsinfo) is enabled in fcpl.
**
**                      (A) Opening a file with write access
**
**                                              Superblock version 0, 1, 2, 3
**                  --------------------------------------------------------------------------------
**                  | (earliest, v18) | (earliest, v110) | (v18, v18) | (v18, v110) | (v110, v110) |
**                  |______________________________________________________________________________|
** File's low bound |                               no change                                      |
**                  |------------------------------------------------------------------------------|
** File open        |                               succeed                                        |
**                  |______________________________________________________________________________|
**
**
**                     (B) Opening a file with SWMR-write access
**
**                                              Superblock version 0, 1, 2
**                  -------------------------------------------------------------------------------
**                  | (earliest, v18) | (earliest, v10) | (v18, v18) | (v18, v110) | (v110, v110) |
**                  |_____________________________________________________________________________|
** File's low bound |                                   ----
**                  |-----------------------------------------------------------------------------|
** File open        |                                   fail
**                  |_____________________________________________________________________________|
**
**
**                                              Superblock version 3
**                  -------------------------------------------------------------------------------
**                  | (earliest, v18) | (earliest, v10) | (v18, v18) | (v18, v110) | (v110, v110) |
**                  |_____________________________________________________________________________|
** File's low bound | --              | -->v110         | --         | -->v110     | no change    |
**                  |-----------------------------------------------------------------------------|
** File open        | fail            | succeed         | fail       | succeed     | succeed      |
**                  |_____________________________________________________________________________|
**
**
**                      (C) Opening a file with write/SWMR-write access + non-default fsinfo
**                  -------------------------------------------------------------------------------
**                  | (earliest, v18) | (earliest, v10) | (v18, v18) | (v18, v110) | (v110, v110) |
**                  |_____________________________________________________________________________|
** File open        | fail            | succeed         | fail       | succeed     | succeed      |
**                  |_____________________________________________________________________________|
**
**
******************************************************************************************************/
static void
test_libver_bounds_super_open(hid_t fapl, hid_t fcpl, htri_t is_swmr, htri_t non_def_fsm)
{
    hid_t        fid      = H5I_INVALID_HID; /* File ID */
    hid_t        new_fapl = H5I_INVALID_HID; /* File access property list */
    H5F_libver_t low, high;                  /* Low and high bounds */
    herr_t       ret;                        /* Return value */

    /* Create the file with the input fcpl and fapl */
    H5E_BEGIN_TRY
    {
        fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, fcpl, fapl);
    }
    H5E_END_TRY

    /* Retrieve the low/high bounds */
    ret = H5Pget_libver_bounds(fapl, &low, &high);
    CHECK(ret, FAIL, "H5Pget_libver_bounds");

    if (non_def_fsm && high < H5F_LIBVER_V110) {
        VERIFY(fid, H5I_INVALID_HID, "H5Fcreate");
    }
    else {
        VERIFY(fid >= 0, true, "H5Fcreate");

        /* Close the file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");

        /* Create a default file access property list */
        new_fapl = H5Pcreate(H5P_FILE_ACCESS);
        CHECK(new_fapl, FAIL, "H5Pcreate");

        /* Loop through all the combinations of low/high bounds in new_fapl */
        for (low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) {
            for (high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) {
                H5E_BEGIN_TRY
                {
                    ret = H5Pset_libver_bounds(new_fapl, low, high);
                }
                H5E_END_TRY

                /* Invalid combinations */
                if (ret < 0)
                    continue;

                /* Open the file with or without SWMR access */
                H5E_BEGIN_TRY
                {
                    fid = H5Fopen(FILE8, H5F_ACC_RDWR | (is_swmr ? H5F_ACC_SWMR_WRITE : 0), new_fapl);
                }
                H5E_END_TRY

                /* Get the internal file pointer if the open succeeds */
                if (fid >= 0) {
                    ret = H5Fclose(fid);
                    CHECK(ret, FAIL, "H5Fclose");
                }
                else {

                    VERIFY((is_swmr || (non_def_fsm && (high < H5F_LIBVER_V110))), true, "H5Fopen");
                }

            } /* end for */
        }     /* end for */

        /* Close the file access property list */
        ret = H5Pclose(new_fapl);
        CHECK(ret, FAIL, "H5Pclose");
    } /* end else */

} /* end test_libver_bounds_super_open() */

/****************************************************************
**
**  test_libver_bounds_obj():
**      Verify object header versions:
**
**      (a) Create a file with:
**          --the input fapl
**          --a fcpl that has shared message enabled
**          Verify the root group's object header version.
**          Close the file.
**
**      (b) Create another file with:
**          --the input fapl
**          --a default fcpl
**          Verify the root group's object header version.
**          Close the file.
**
**      (c) Reopen the same file in (b) with a new fapl.
**          The new fapl is set to the 5 pairs of low/high
**          bounds in a "for" loop.  For each setting in fapl:
**          --Create a group in the file
**          --Verify the group's object header version
**          --Close and delete the group
**          --Close the file
**
****************************************************************/
static void
test_libver_bounds_obj(hid_t fapl)
{
    hid_t             fid      = H5I_INVALID_HID; /* File ID */
    hid_t             gid      = H5I_INVALID_HID; /* Group ID */
    hid_t             fcpl     = H5I_INVALID_HID; /* File creation property list */
    hid_t             new_fapl = H5I_INVALID_HID; /* File access property list */
    H5F_t            *f        = NULL;            /* Internal file pointer */
    H5F_libver_t      low, high;                  /* Low and high bounds */
    H5O_native_info_t ninfo;                      /* Object info */
    H5G_info_t        ginfo;                      /* Group info */
    herr_t            ret;                        /* Return value */

    /* Retrieve the low/high bounds from the input fapl */
    ret = H5Pget_libver_bounds(fapl, &low, &high);
    CHECK(ret, FAIL, "H5Pget_libver_bounds");

    /* Create a default file creation property list */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, H5I_INVALID_HID, "H5Pcreate");

    /* Enable shared message in the fcpl */
    /* This will result in a version 2 object header */
    ret = H5Pset_shared_mesg_nindexes(fcpl, 1);
    CHECK(ret, FAIL, "H5Pset_shared_mesg_nindexes");
    ret = H5Pset_shared_mesg_index(fcpl, 0, H5O_SHMESG_ATTR_FLAG, 2);
    CHECK(ret, FAIL, "H5Pset_shared_mesg_index");

    /* Create the file with the fcpl and the input fapl */
    fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, fcpl, fapl);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Get root group's object info */
    ret = H5Oget_native_info_by_name(fid, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Oget_native_info_by_name");

    /* Verify object header version is 2 because shared message is enabled */
    VERIFY(ninfo.hdr.version, H5O_VERSION_2, "H5O_obj_ver_bounds");

    /* Close the file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close the file creation property list */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Create a file with the default fcpl and input fapl */
    fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Get root group's object info */
    ret = H5Oget_native_info_by_name(fid, "/", &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Oget_native_info_by_name");

    /* Verify object header version is as indicated by low_bound */
    VERIFY(ninfo.hdr.version, H5O_obj_ver_bounds[low], "H5O_obj_ver_bounds");

    /* Close the file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Create a new default file access property list which
       is used to open the file in the "for" loop */
    new_fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(new_fapl, H5I_INVALID_HID, "H5Pcreate");

    /* Loop through all the combinations of low/high bounds in new_fapl */
    /* Open the file with the fapl; create a group and verify the
       object header version, then delete the group and close the file.*/
    for (low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) {
        for (high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) {
            H5E_BEGIN_TRY
            {
                ret = H5Pset_libver_bounds(new_fapl, low, high);
            }
            H5E_END_TRY

            if (ret < 0) /* Invalid combinations */
                continue;

            /* Open the file */
            H5E_BEGIN_TRY
            {
                fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl);
            }
            H5E_END_TRY
            VERIFY((fid >= 0), true, "File open should succeed");

            if (fid >= 0) { /* The file open succeeds */

                /* Get the internal file pointer */
                f = (H5F_t *)H5VL_object(fid);
                CHECK_PTR(f, "H5VL_object");

                /* Create a group in the file */
                gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
                CHECK(gid, FAIL, "H5Gcreate2");

                /* Get group information */
                ret = H5Gget_info(gid, &ginfo);
                CHECK(ret, FAIL, "H5Gget_info");

                /* Verify group storage type */
                if (f->shared->low_bound >= H5F_LIBVER_V18)
                    /* Links in group are stored in object header */
                    VERIFY(ginfo.storage_type, H5G_STORAGE_TYPE_COMPACT, "H5Gget_info");
                else
                    /* Links in group are stored with a "symbol table" */
                    VERIFY(ginfo.storage_type, H5G_STORAGE_TYPE_SYMBOL_TABLE, "H5Gget_info");

                /* Get object header information */
                ret = H5Oget_native_info_by_name(gid, GRP_NAME, &ninfo, H5O_NATIVE_INFO_HDR, H5P_DEFAULT);
                CHECK(ret, FAIL, "H5Oget_native_info_by_name");

                /* Verify object header version as indicated by low_bound */
                VERIFY(ninfo.hdr.version, H5O_obj_ver_bounds[f->shared->low_bound], "H5O_obj_ver_bounds");

                /* Close the group */
                ret = H5Gclose(gid);
                CHECK(ret, FAIL, "H5Gclose");

                /* Delete the group */
                ret = H5Ldelete(fid, GRP_NAME, H5P_DEFAULT);
                CHECK(ret, FAIL, "H5Ldelete");

                /* Close the file */
                ret = H5Fclose(fid);
                CHECK(ret, FAIL, "H5Fclose");

            } /* end if */
        }     /* end for */
    }         /* end for */

    /* Close the file access property list */
    ret = H5Pclose(new_fapl);
    CHECK(ret, FAIL, "H5Pclose");

} /* end test_libver_bounds_obj() */

/****************************************************************
**
**  test_libver_bounds_dataset():
**      Verify message versions associated with datasets:
**
**      (a) Create a file with default fcpl and the input fapl.
**          Create the following two datasets:
**              --A contiguous dataset
**              --A chunked dataset with "no filter edge chunks"
**          For both datasets, verify the versions for the layout,
**          fill value and filter pipeline messages.
**          Close the file.
**
**      (b) Create a new fapl that is set to the 5 pairs of low/high
**          bounds in a "for" loop.  For each pair of setting in the
**          new fapl:
**              --Open the same file in (a) with the fapl
**              --Create a chunked dataset with 2 unlimited
**                dimensions
**              --Verify the versions for the layout, fill value
**                and filter pipeline messages
**              --Close and delete the dataset
**              --Close the file
**
****************************************************************/
static void
test_libver_bounds_dataset(hid_t fapl)
{
    hid_t        fid      = H5I_INVALID_HID;                      /* File ID */
    hid_t        new_fapl = H5I_INVALID_HID;                      /* File access property list */
    hid_t        did      = H5I_INVALID_HID;                      /* Dataset ID */
    hid_t        sid      = H5I_INVALID_HID;                      /* Dataspace ID */
    hid_t        dcpl     = H5I_INVALID_HID;                      /* Dataset creation property list */
    H5D_t       *dset     = NULL;                                 /* Internal dataset pointer */
    H5F_t       *f        = NULL;                                 /* Internal file pointer */
    H5F_libver_t low, high;                                       /* Low and high bounds */
    herr_t       ret;                                             /* Return value */
    hsize_t      fix_dims2[2]   = {10, 4};                        /* Dimension sizes */
    hsize_t      fix_chunks2[2] = {4, 3};                         /* Chunk dimension sizes */
    hsize_t      dims2[2]       = {1, 4};                         /* Dimension sizes */
    hsize_t      max_dims2[2]   = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dimension sizes */
    hsize_t      chunks2[2]     = {4, 5};                         /* Chunk dimension sizes */

    /* Retrieve the low/high bounds from the input fapl */
    ret = H5Pget_libver_bounds(fapl, &low, &high);
    CHECK(ret, FAIL, "H5Pget_libver_bounds");

    /* Create the file with the input fapl */
    fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Create the dataspace */
    sid = H5Screate(H5S_SCALAR);
    CHECK(sid, H5I_INVALID_HID, "H5Screate");

    /* Create a contiguous dataset */
    did = H5Dcreate2(fid, DSETA, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(did, H5I_INVALID_HID, "H5Dcreate");

    /* Get the internal dataset pointer */
    dset = (H5D_t *)H5VL_object(did);
    CHECK_PTR(dset, "H5VL_object");

    /* Verify version for layout and fill value messages */
    if (low == H5F_LIBVER_EARLIEST) {
        /* For layout message: the earliest version the library will set is 3 */
        /* For fill value message: the earliest version the library will set is 2 */
        VERIFY(dset->shared->layout.version, H5O_LAYOUT_VERSION_DEFAULT, "H5O_layout_ver_bounds");
        VERIFY(dset->shared->dcpl_cache.fill.version, H5O_FILL_VERSION_2, "H5O_fill_ver_bounds");
    }
    else {
        VERIFY(dset->shared->layout.version, H5O_layout_ver_bounds[low], "H5O_layout_ver_bounds");
        VERIFY(dset->shared->dcpl_cache.fill.version, H5O_fill_ver_bounds[low], "H5O_fill_ver_bounds");
    }

    /* Verify filter pipeline message version */
    VERIFY(dset->shared->dcpl_cache.pline.version, H5O_pline_ver_bounds[low], "H5O_pline_ver_bounds");

    /* Close the dataset */
    ret = H5Dclose(did);
    CHECK(ret, FAIL, "H5Dclose");

    /* Close the dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");

    /* Set up dataspace and dcpl for creating a chunked dataset
       with "no filter edge chunks" enabled.
       This will result in a version 4 layout message */
    sid = H5Screate_simple(2, fix_dims2, NULL);
    CHECK(sid, H5I_INVALID_HID, "H5Screate_simple");
    dcpl = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl, H5I_INVALID_HID, "H5Pcreate");
    ret = H5Pset_chunk(dcpl, 2, fix_chunks2);
    CHECK(ret, FAIL, "H5Pset_chunk");
    ret = H5Pset_chunk_opts(dcpl, H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS);
    CHECK(ret, FAIL, "H5Pset_chunk_opts");

    /* Create the chunked dataset */
    H5E_BEGIN_TRY
    {
        did = H5Dcreate2(fid, DSETB, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
    }
    H5E_END_TRY

    if (did >= 0) {

        /* Get the internal dataset pointer */
        dset = (H5D_t *)H5VL_object(did);
        CHECK_PTR(dset, "H5VL_object");

        /* Verify layout message version and chunk indexing type */
        VERIFY(dset->shared->layout.version, H5O_LAYOUT_VERSION_4, "H5O_layout_ver_bounds");
        VERIFY(dset->shared->layout.u.chunk.idx_type, H5D_CHUNK_IDX_FARRAY, "chunk_index_type");

        /* Close the dataset */
        ret = H5Dclose(did);
        CHECK(ret, FAIL, "H5Dclose");
    }

    /* Close the file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close the dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");

    /* Close the dataset creation property list */
    ret = H5Pclose(dcpl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Create a default file access property list which is used
       to open the file in the 'for' loop */
    new_fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(new_fapl, H5I_INVALID_HID, "H5Pcreate");

    /* Set up dataspace and dcpl for creating a chunked dataset with
       2 unlimited dimensions in the 'for' loop */
    sid = H5Screate_simple(2, dims2, max_dims2);
    CHECK(sid, H5I_INVALID_HID, "H5Screate_simple");
    dcpl = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl, H5I_INVALID_HID, "H5Pcreate");
    ret = H5Pset_chunk(dcpl, 2, chunks2);
    CHECK(ret, FAIL, "H5Pset_chunk");

    /* Loop through all the combinations of low/high bounds in new_fapl */
    /* Open the file with the fapl and create the chunked dataset */
    /* Verify the dataset's layout, fill value and filter pipeline message versions */
    for (low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) {
        for (high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) {
            H5E_BEGIN_TRY
            {
                ret = H5Pset_libver_bounds(new_fapl, low, high);
            }
            H5E_END_TRY

            if (ret < 0) /* Invalid low/high combinations */
                continue;

            /* Open the file */
            H5E_BEGIN_TRY
            {
                fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl);
            }
            H5E_END_TRY
            VERIFY((fid >= 0), true, "File open should succeed");

            if (fid >= 0) { /* The file open succeeds */

                /* Get the internal file pointer */
                f = (H5F_t *)H5VL_object(fid);
                CHECK_PTR(f, "H5VL_object");

                /* Create the chunked dataset */
                did = H5Dcreate2(fid, DSETC, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
                CHECK(did, H5I_INVALID_HID, "H5Dcreate2");

                /* Get the internal file pointer */
                dset = (H5D_t *)H5VL_object(did);
                CHECK_PTR(dset, "H5VL_object");

                if (dset) {
                    /* Verify the dataset's layout, fill value and filter pipeline message versions */
                    /* Also verify the chunk indexing type */
                    if (f->shared->low_bound == H5F_LIBVER_EARLIEST) {
                        /* For layout message: the earliest version the library will set is 3 */
                        /* For fill value message: the earliest version the library will set is 2 */
                        VERIFY(dset->shared->layout.version, H5O_LAYOUT_VERSION_DEFAULT,
                               "H5O_layout_ver_bounds");
                        VERIFY(dset->shared->dcpl_cache.fill.version, H5O_FILL_VERSION_2,
                               "H5O_fill_ver_bounds");
                    }
                    else {
                        VERIFY(dset->shared->layout.version, H5O_layout_ver_bounds[f->shared->low_bound],
                               "H5O_layout_ver_bounds");
                        VERIFY(dset->shared->dcpl_cache.fill.version,
                               H5O_fill_ver_bounds[f->shared->low_bound], "H5O_fill_ver_bounds");
                    }

                    /* Verify the filter pipeline message version */
                    VERIFY(dset->shared->dcpl_cache.pline.version, H5O_pline_ver_bounds[f->shared->low_bound],
                           "H5O_pline_ver_bounds");

                    /* Verify the dataset's chunk indexing type */
                    if (dset->shared->layout.version == H5O_LAYOUT_VERSION_LATEST)
                        VERIFY(dset->shared->layout.u.chunk.idx_type, H5D_CHUNK_IDX_BT2, "chunk_index_type");
                    else
                        VERIFY(dset->shared->layout.u.chunk.idx_type, H5D_CHUNK_IDX_BTREE,
                               "chunk_index_type");
                }

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");

                /* Delete the dataset */
                ret = H5Ldelete(fid, DSETC, H5P_DEFAULT);
                CHECK(ret, FAIL, "H5Ldelete");

                /* Close the file */
                ret = H5Fclose(fid);
                CHECK(ret, FAIL, "H5Fclose");

            } /* end if */
        }     /* end for */
    }         /* end for */

    /* Close the file access property list */
    ret = H5Pclose(new_fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Close the dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");

    /* Close the dataset creation property list */
    ret = H5Pclose(dcpl);
    CHECK(ret, FAIL, "H5Pclose");

} /* end test_libver_bounds_dataset() */

/****************************************************************
**
**  test_libver_bounds_dataspace():
**      Verify dataspace message versions:
**
**      (a) Create a file with default fcpl and the input fapl.
**          Create the following two datasets:
**              --A dataset with scalar dataspace
**              --A dataset with null dataspace
**          For both datasets, verify the dataspace message versions.
**          Close the file.
**
**      (b) Create a new fapl that is set to the 5 pairs of low/high
**          bounds in a "for" loop.  For each pair of setting in the
**          new fapl:
**              --Open the same file in (a) with the fapl
**              --Create a chunked dataset, a compact dataset and
**                a contiguous dataset
**              --Verify the dataspace message version for these
**                three datasets
**              --Delete the three datasets and the dataspaces
**              --Close the file
**
****************************************************************/
static void
test_libver_bounds_dataspace(hid_t fapl)
{
    hid_t fid      = H5I_INVALID_HID;                                    /* File ID */
    hid_t new_fapl = H5I_INVALID_HID;                                    /* File access property list */
    hid_t did = H5I_INVALID_HID, did_null = H5I_INVALID_HID;             /* Dataset IDs */
    hid_t did_compact = H5I_INVALID_HID, did_contig = H5I_INVALID_HID;   /* Dataset IDs */
    hid_t sid = H5I_INVALID_HID, sid_null = H5I_INVALID_HID;             /* Dataspace IDs */
    hid_t sid_compact = H5I_INVALID_HID, sid_contig = H5I_INVALID_HID;   /* Dataspace IDs */
    hid_t dcpl         = H5I_INVALID_HID;                                /* Dataset creation property list */
    hid_t dcpl_compact = H5I_INVALID_HID, dcpl_contig = H5I_INVALID_HID; /* Dataset creation property lists */
    H5S_t       *space = NULL, *space_null = NULL;                       /* Internal dataspace pointers */
    H5F_t       *f = NULL;                                               /* Internal file pointer */
    H5F_libver_t low, high;                                              /* Low and high bounds */
    hsize_t      dims[1]     = {1};                                      /* Dimension sizes */
    hsize_t      dims2[2]    = {5, 4};                                   /* Dimension sizes */
    hsize_t      max_dims[1] = {H5S_UNLIMITED};                          /* Maximum dimension sizes */
    hsize_t      chunks[1]   = {4};                                      /* Chunk dimension sizes */
    herr_t       ret;                                                    /* Return value */

    /* Retrieve the low/high bounds from the input fapl */
    ret = H5Pget_libver_bounds(fapl, &low, &high);
    CHECK(ret, FAIL, "H5Pget_libver_bounds");

    /* Create the file with the input fapl */
    fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Create scalar dataspace */
    sid = H5Screate(H5S_SCALAR);
    CHECK(sid, H5I_INVALID_HID, "H5Screate");

    /* Create a dataset with the scalar dataspace */
    did = H5Dcreate2(fid, DSET, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(did, H5I_INVALID_HID, "H5Dcreate");

    /* Get the internal dataspace pointer */
    sid = H5Dget_space(did);
    CHECK(sid, H5I_INVALID_HID, "H5Dget_space");
    space = (H5S_t *)H5I_object(sid);
    CHECK_PTR(space, "H5I_object");

    /* Verify the dataspace version */
    VERIFY(space->extent.version, H5O_sdspace_ver_bounds[low], "H5O_sdspace_ver_bounds");

    /* Create null dataspace */
    sid_null = H5Screate(H5S_NULL);
    CHECK(sid_null, H5I_INVALID_HID, "H5Screate");

    /* Create a dataset with the null dataspace */
    did_null = H5Dcreate2(fid, DSET_NULL, H5T_NATIVE_INT, sid_null, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(did_null, H5I_INVALID_HID, "H5Dcreate");

    /* Get the internal dataspace pointer */
    sid_null = H5Dget_space(did_null);
    CHECK(sid_null, H5I_INVALID_HID, "H5Dget_space");
    space_null = (H5S_t *)H5I_object(sid_null);
    CHECK_PTR(space_null, "H5I_object");

    /* Verify the dataspace version */
    VERIFY(space_null->extent.version, H5O_SDSPACE_VERSION_2, "H5O_sdspace_ver_bounds");

    /* Close the datasets */
    ret = H5Dclose(did);
    CHECK(ret, FAIL, "H5Dclose");
    ret = H5Dclose(did_null);
    CHECK(ret, FAIL, "H5Dclose");

    /* Close the dataspaces */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");
    ret = H5Sclose(sid_null);
    CHECK(ret, FAIL, "H5Sclose");

    /* Close the file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Create a default file access property list which is used
       to open the file in the 'for' loop */
    new_fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(new_fapl, H5I_INVALID_HID, "H5Pcreate");

    /* Set up dataspace and dcpl for creating a chunked dataset */
    sid = H5Screate_simple(1, dims, max_dims);
    CHECK(sid, H5I_INVALID_HID, "H5Screate_simple");
    dcpl = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl, H5I_INVALID_HID, "H5Pcreate");
    ret = H5Pset_chunk(dcpl, 1, chunks);
    CHECK(ret, FAIL, "H5Pset_chunk");

    /* Set up dataspace and dcpl for creating a compact dataset */
    sid_compact = H5Screate_simple(1, dims, NULL);
    CHECK(sid_compact, H5I_INVALID_HID, "H5Screate_simple");
    dcpl_compact = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl_compact, H5I_INVALID_HID, "H5Pcreate");
    ret = H5Pset_layout(dcpl_compact, H5D_COMPACT);
    CHECK(ret, FAIL, "H5Pset_layout");

    /* Set up dataspace and dcpl for creating a contiguous dataset */
    sid_contig = H5Screate_simple(2, dims2, NULL);
    CHECK(sid_contig, H5I_INVALID_HID, "H5Screate_simple");
    dcpl_contig = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl_contig, H5I_INVALID_HID, "H5Pcreate");
    ret = H5Pset_layout(dcpl_contig, H5D_CONTIGUOUS);
    CHECK(ret, FAIL, "H5Pset_layout");

    /* Loop through all the combinations of low/high bounds in new_fapl */
    /* Open the file and create the chunked/compact/contiguous datasets */
    /* Verify the dataspace message version for the three datasets */
    for (low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) {
        for (high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) {
            hid_t  tmp_sid, tmp_sid_compact, tmp_sid_contig;         /* Dataspace IDs */
            H5S_t *tmp_space, *tmp_space_compact, *tmp_space_contig; /* Internal dataspace pointers */

            H5E_BEGIN_TRY
            {
                ret = H5Pset_libver_bounds(new_fapl, low, high);
            }
            H5E_END_TRY

            if (ret < 0) /* Invalid low/high combinations */
                continue;

            /* Open the file */
            H5E_BEGIN_TRY
            {
                fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl);
            }
            H5E_END_TRY
            VERIFY((fid >= 0), true, "File open should succeed");

            if (fid >= 0) { /* The file open succeeds */

                /* Get the internal file pointer */
                f = (H5F_t *)H5VL_object(fid);
                CHECK_PTR(f, "H5VL_object");

                /* Create the chunked dataset */
                did = H5Dcreate2(fid, DSETA, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
                CHECK(did, H5I_INVALID_HID, "H5Dcreate2");

                /* Get the internal dataspace pointer for the chunked dataset */
                tmp_sid = H5Dget_space(did);
                CHECK(tmp_sid, H5I_INVALID_HID, "H5Dget_space");
                tmp_space = (H5S_t *)H5I_object(tmp_sid);
                CHECK_PTR(tmp_space, "H5I_object");

                /* Create the compact dataset */
                did_compact = H5Dcreate2(fid, DSETB, H5T_NATIVE_INT, sid_compact, H5P_DEFAULT, dcpl_compact,
                                         H5P_DEFAULT);
                CHECK(did_compact, H5I_INVALID_HID, "H5Dcreate2");

                /* Get the internal dataspace pointer for the compact dataset */
                tmp_sid_compact = H5Dget_space(did_compact);
                CHECK(tmp_sid_compact, H5I_INVALID_HID, "H5Dget_space");
                tmp_space_compact = (H5S_t *)H5I_object(tmp_sid_compact);
                CHECK_PTR(tmp_space_compact, "H5I_object");

                /* Create the contiguous dataset */
                did_contig =
                    H5Dcreate2(fid, DSETC, H5T_NATIVE_INT, sid_contig, H5P_DEFAULT, dcpl_contig, H5P_DEFAULT);
                CHECK(did_contig, H5I_INVALID_HID, "H5Dcreate2");

                /* Get the internal dataspace pointer for the contiguous dataset */
                tmp_sid_contig = H5Dget_space(did_contig);
                CHECK(tmp_sid_contig, H5I_INVALID_HID, "H5Dget_space");
                tmp_space_contig = (H5S_t *)H5I_object(tmp_sid_contig);
                CHECK_PTR(tmp_space_contig, "H5I_object");

                if (tmp_space) {
                    /* Verify versions for the three dataspaces */
                    VERIFY(tmp_space->extent.version, H5O_sdspace_ver_bounds[f->shared->low_bound],
                           "H5O_sdspace_ver_bounds");
                }
                if (tmp_space_compact) {
                    VERIFY(tmp_space_compact->extent.version, H5O_sdspace_ver_bounds[f->shared->low_bound],
                           "H5O_sdspace_ver_bounds");
                }
                if (tmp_space_contig) {
                    VERIFY(tmp_space_contig->extent.version, H5O_sdspace_ver_bounds[f->shared->low_bound],
                           "H5O_sdspace_ver_bounds");
                }

                /* Close the three datasets */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");
                ret = H5Dclose(did_compact);
                CHECK(ret, FAIL, "H5Dclose");
                ret = H5Dclose(did_contig);
                CHECK(ret, FAIL, "H5Dclose");

                /* Close the three dataspaces */
                ret = H5Sclose(tmp_sid);
                CHECK(ret, FAIL, "H5Sclose");
                ret = H5Sclose(tmp_sid_compact);
                CHECK(ret, FAIL, "H5Sclose");
                ret = H5Sclose(tmp_sid_contig);
                CHECK(ret, FAIL, "H5Sclose");

                /* Delete the three datasets */
                ret = H5Ldelete(fid, DSETA, H5P_DEFAULT);
                CHECK(ret, FAIL, "H5Ldelete");
                ret = H5Ldelete(fid, DSETB, H5P_DEFAULT);
                CHECK(ret, FAIL, "H5Ldelete");
                ret = H5Ldelete(fid, DSETC, H5P_DEFAULT);
                CHECK(ret, FAIL, "H5Ldelete");

                /* Close the file */
                ret = H5Fclose(fid);
                CHECK(ret, FAIL, "H5Fclose");

            } /* end if */
        }     /* end for */
    }         /* end for */

    /* Close the file access property list */
    ret = H5Pclose(new_fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Close the three dataspaces */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");
    ret = H5Sclose(sid_compact);
    CHECK(ret, FAIL, "H5Sclose");
    ret = H5Sclose(sid_contig);
    CHECK(ret, FAIL, "H5Sclose");

    /* Close the three dataset creation property lists */
    ret = H5Pclose(dcpl);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(dcpl_compact);
    CHECK(ret, FAIL, "H5Pclose");
    ret = H5Pclose(dcpl_contig);
    CHECK(ret, FAIL, "H5Pclose");

} /* end test_libver_bounds_dataspace() */

/****************************************************************
**
**  test_libver_bounds_datatype():
**      Verify the datatype message version:
**
**      (a) Create the following datatypes:
**          1) integer
**          2) enum
**          3) array
**          4) compound
**          5) vlen
**      (b) Call test_libver_bounds_datatype_check() for each
**          datatype in (a) to verify the datatype message version.
**
****************************************************************/
static void
test_libver_bounds_datatype(hid_t fapl)
{
    hid_t tid = H5I_INVALID_HID, tid_enum = H5I_INVALID_HID, tid_array = H5I_INVALID_HID; /* Datatype IDs */
    hid_t tid_compound = H5I_INVALID_HID, tid_vlen = H5I_INVALID_HID;                     /* Datatype IDs */
    hid_t tid_complex = H5I_INVALID_HID;                                                  /* Datatype IDs */
    int   enum_value;   /* Value for enum datatype */
    typedef struct s1 { /* Data structure for compound datatype */
        char c;
        int  i;
    } s1;
    hsize_t dims[1] = {1}; /* Dimension sizes */
    herr_t  ret;           /* Return value */

    /* Create integer datatype */
    tid = H5Tcopy(H5T_NATIVE_INT);

    /* Verify datatype message version */
    test_libver_bounds_datatype_check(fapl, tid);

    /* Create enum datatype */
    tid_enum   = H5Tenum_create(tid);
    enum_value = 0;
    H5Tenum_insert(tid_enum, "val1", &enum_value);
    enum_value = 1;
    H5Tenum_insert(tid_enum, "val2", &enum_value);

    /* Verify datatype message version */
    test_libver_bounds_datatype_check(fapl, tid_enum);

    /* Create array datatype */
    tid_array = H5Tarray_create2(tid, 1, dims);

    /* Verify datatype message version */
    test_libver_bounds_datatype_check(fapl, tid_array);

    /* Create compound datatype */
    tid_compound = H5Tcreate(H5T_COMPOUND, sizeof(s1));
    H5Tinsert(tid_compound, "c", HOFFSET(s1, c), H5T_STD_U8LE);
    H5Tinsert(tid_compound, "i", HOFFSET(s1, i), H5T_NATIVE_INT);

    /* Verify datatype message version */
    test_libver_bounds_datatype_check(fapl, tid_compound);

    /* Create vlen datatype */
    tid_vlen = H5Tvlen_create(tid);

    /* Verify datatype message version */
    test_libver_bounds_datatype_check(fapl, tid_vlen);

    /* Create complex number datatype */
    tid_complex = H5Tcomplex_create(H5T_NATIVE_FLOAT);

    /* Verify datatype message version */
    test_libver_bounds_datatype_check(fapl, tid_complex);

    /* Close the datatypes */
    ret = H5Tclose(tid);
    CHECK(ret, FAIL, "H5Tclose");

    ret = H5Tclose(tid_enum);
    CHECK(ret, FAIL, "H5Tclose");

    ret = H5Tclose(tid_array);
    CHECK(ret, FAIL, "H5Tclose");

    ret = H5Tclose(tid_compound);
    CHECK(ret, FAIL, "H5Tclose");

    ret = H5Tclose(tid_vlen);
    CHECK(ret, FAIL, "H5Tclose");

    ret = H5Tclose(tid_complex);
    CHECK(ret, FAIL, "H5Tclose");

} /* end test_libver_bounds_datatype() */

/****************************************************************
**
**  test_libver_bounds_datatype_check():
**      Helper routine called by test_libver_bounds_datatype()
**      to verify the datatype message version for the input tid:
**
**      (a) Create a file with default fcpl and the input fapl.
**          Create a contiguous dataset with the input tid.
**          Verify the datatype message version.
**          Create a committed datatype of string to be
**          used later.
**          Close the file.
**
**      (b) Create a new fapl that is set to the 5 pairs of low/high
**          bounds in a "for" loop.  For each pair of setting in
**          the new fapl:
**              --Open the same file in (a) with the fapl
**              --Verify the message version for the committed
**                datatype created earlier
**              --Create a chunked dataset with the input tid
**              --Verify the datatype message version
**              --Close and delete the dataset
**              --Close the file
**
****************************************************************/
static void
test_libver_bounds_datatype_check(hid_t fapl, hid_t tid)
{
    hid_t        fid          = H5I_INVALID_HID;                /* File ID */
    hid_t        new_fapl     = H5I_INVALID_HID;                /* File access property list */
    hid_t        dcpl         = H5I_INVALID_HID;                /* Dataset creation property list */
    hid_t        dtid         = H5I_INVALID_HID;                /* Datatype ID for the dataset */
    hid_t        str_tid      = H5I_INVALID_HID;                /* String datatype ID */
    hid_t        did          = H5I_INVALID_HID;                /* Dataset ID */
    hid_t        sid          = H5I_INVALID_HID;                /* Dataspace ID */
    hsize_t      dims[1]      = {1};                            /* Dimension sizes */
    hsize_t      dims2[2]     = {5, 4};                         /* Dimension sizes */
    hsize_t      max_dims2[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dimension sizes */
    hsize_t      chunks[2]    = {2, 3};                         /* Chunk dimension sizes */
    H5T_t       *dtype        = NULL;                           /* Internal datatype pointer */
    H5T_t       *str_dtype    = NULL;  /* Internal datatype pointer for the string datatype */
    H5F_t       *f            = NULL;  /* Internal file pointer */
    bool         is_complex   = false; /* If datatype is a complex number type */
    H5F_libver_t low, high;            /* Low and high bounds */
    herr_t       ret;                  /* Return value */

    /* Retrieve the low/high version bounds from the input fapl */
    ret = H5Pget_libver_bounds(fapl, &low, &high);
    CHECK(ret, FAIL, "H5Pget_libver_bounds");

    /* Complex numbers can't be created with a high version bound < 2.0 */
    is_complex = (H5T_COMPLEX == H5Tget_class(tid));
    if (is_complex && high < H5F_LIBVER_V200)
        return;

    /* Create the file with the input fapl */
    fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Create a committed datatype of string which will be used
       later inside the 'for' loop */
    str_tid = H5Tcopy(H5T_C_S1);
    CHECK(str_tid, H5I_INVALID_HID, "H5Tcopy");
    ret = H5Tset_size(str_tid, (size_t)10);
    CHECK(ret, FAIL, "H5Tset_size");
    ret = H5Tcommit2(fid, "datatype", str_tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Tcommit2");
    ret = H5Tclose(str_tid);
    CHECK(ret, FAIL, "H5Tclose");

    /* Create dataspace */
    sid = H5Screate_simple(1, dims, NULL);
    CHECK(sid, H5I_INVALID_HID, "H5Screate_simple");

    /* Create a dataset with the input tid */
    did = H5Dcreate2(fid, DSET1, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(did, H5I_INVALID_HID, "H5Dcreate2");

    /* Get the dataset's datatype */
    dtid = H5Dget_type(did);
    CHECK(dtid, H5I_INVALID_HID, "H5Dget_type");

    /* Get the internal datatype pointer */
    dtype = (H5T_t *)H5I_object(dtid);
    CHECK_PTR(dtype, "H5I_object");

    /* Verify the datatype message version */
    /* H5T_COMPOUND, H5T_ENUM, H5T_ARRAY:
     *  --the library will set version according to low_bound
     *  --H5T_ARRAY: the earliest version the library will set is 2
     * H5T_COMPLEX:
     *  --the earliest version the library will set is 5
     * H5T_INTEGER, H5T_FLOAT, H5T_TIME, H5T_STRING, H5T_BITFIELD, H5T_OPAQUE,
     * H5T_REFERENCE:
     *  --the library will only use basic version
     */

    if (dtype->shared->type == H5T_COMPOUND || dtype->shared->type == H5T_ENUM ||
        dtype->shared->type == H5T_ARRAY) {
        if (dtype->shared->type == H5T_ARRAY && low == H5F_LIBVER_EARLIEST)
            VERIFY(dtype->shared->version, H5O_DTYPE_VERSION_2, "H5O_dtype_ver_bounds");
        else
            VERIFY(dtype->shared->version, H5O_dtype_ver_bounds[low], "H5O_dtype_ver_bounds");
    }
    else if (is_complex) {
        /* Complex number datatypes do not currently upgrade */
        VERIFY(dtype->shared->version, H5O_DTYPE_VERSION_5, "H5O_dtype_ver_bounds");
    }
    else
        VERIFY(dtype->shared->version, H5O_dtype_ver_bounds[H5F_LIBVER_EARLIEST], "H5O_dtype_ver_bounds");

    /* Close the dataset */
    ret = H5Dclose(did);
    CHECK(ret, FAIL, "H5Dclose");

    /* Close the dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Dclose");

    /* Close the datatype */
    ret = H5Tclose(dtid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Close the file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Create a default file access property list */
    new_fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(new_fapl, H5I_INVALID_HID, "H5Pcreate");

    /* Set up dataspace and dcpl for creating a chunked dataset */
    sid = H5Screate_simple(2, dims2, max_dims2);
    CHECK(sid, H5I_INVALID_HID, "H5Screate_simple");
    dcpl = H5Pcreate(H5P_DATASET_CREATE);
    CHECK(dcpl, H5I_INVALID_HID, "H5Pcreate");
    ret = H5Pset_chunk(dcpl, 2, chunks);
    CHECK(ret, FAIL, "H5Pset_chunk");

    /* Loop through all the combinations of low/high bounds */
    /* Open the file and create the chunked dataset with the input tid */
    /* Verify the dataset's datatype message version */
    /* Also verify the committed datatype message version */
    for (low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) {
        for (high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) {
            H5E_BEGIN_TRY
            {
                ret = H5Pset_libver_bounds(new_fapl, low, high);
            }
            H5E_END_TRY

            if (ret < 0) /* Invalid low/high combinations */
                continue;

            /* Complex numbers can't be created with a high version bound < 2.0 */
            if (is_complex && high < H5F_LIBVER_V200)
                continue;

            /* Open the file */
            H5E_BEGIN_TRY
            {
                fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl);
            }
            H5E_END_TRY
            VERIFY((fid >= 0), true, "File open should succeed");

            if (fid >= 0) { /* The file open succeeds */

                /* Get the internal file pointer */
                f = (H5F_t *)H5VL_object(fid);
                CHECK_PTR(f, "H5VL_object");

                /* Open the committed datatype */
                str_tid = H5Topen2(fid, "datatype", H5P_DEFAULT);
                CHECK(str_tid, FAIL, "H5Topen2");
                str_dtype = (H5T_t *)H5VL_object(str_tid);
                CHECK_PTR(str_dtype, "H5VL_object");

                /* Verify the committed datatype message version */
                VERIFY(str_dtype->shared->version, H5O_dtype_ver_bounds[H5F_LIBVER_EARLIEST],
                       "H5O_dtype_ver_bounds");

                /* Close the committed datatype */
                ret = H5Tclose(str_tid);
                CHECK(ret, FAIL, "H5Tclose");

                /* Create the chunked dataset */
                did = H5Dcreate2(fid, DSETNAME, tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
                CHECK(did, H5I_INVALID_HID, "H5Dcreate2");

                /* Get the dataset's datatype */
                dtid = H5Dget_type(did);
                CHECK(dtid, H5I_INVALID_HID, "H5Dget_type");

                /* Get the internal datatype pointer */
                dtype = (H5T_t *)H5I_object(dtid);
                CHECK_PTR(dtype, "H5I_object");

                if (dtype) {
                    /* Verify the dataset's datatype message version */
                    /* H5T_COMPOUND, H5T_ENUM, H5T_ARRAY:
                     *  --the library will set version according to low_bound
                     *  --H5T_ARRAY: the earliest version the library will set is 2
                     * H5T_COMPLEX:
                     *  --the earliest version the library will set is 5
                     * H5T_INTEGER, H5T_FLOAT, H5T_TIME, H5T_STRING, H5T_BITFIELD, H5T_OPAQUE,
                     * H5T_REFERENCE:
                     *  --the library will only use basic version
                     */
                    if (dtype->shared->type == H5T_COMPOUND || dtype->shared->type == H5T_ENUM ||
                        dtype->shared->type == H5T_ARRAY) {
                        if (dtype->shared->type == H5T_ARRAY && f->shared->low_bound == H5F_LIBVER_EARLIEST)
                            VERIFY(dtype->shared->version, H5O_DTYPE_VERSION_2, "H5O_dtype_ver_bounds");
                        else
                            VERIFY(dtype->shared->version, H5O_dtype_ver_bounds[f->shared->low_bound],
                                   "H5O_dtype_ver_bounds");
                    }
                    else if (is_complex) {
                        /* Complex number datatypes do not currently upgrade */
                        VERIFY(dtype->shared->version, H5O_DTYPE_VERSION_5, "H5O_dtype_ver_bounds");
                    }
                    else
                        VERIFY(dtype->shared->version, H5O_dtype_ver_bounds[H5F_LIBVER_EARLIEST],
                               "H5O_dtype_ver_bounds");
                }

                /* Close the dataset */
                ret = H5Dclose(did);
                CHECK(ret, FAIL, "H5Dclose");

                /* Close the dataset's datatype */
                ret = H5Tclose(dtid);
                CHECK(ret, FAIL, "H5Tclose");

                /* Delete the dataset */
                ret = H5Ldelete(fid, DSETNAME, H5P_DEFAULT);
                CHECK(ret, FAIL, "H5Ldelete");

                /* Close the file */
                ret = H5Fclose(fid);
                CHECK(ret, FAIL, "H5Fclose");

            } /* end if */
        }     /* end for */
    }         /* end for */

    /* Close the file access property list */
    ret = H5Pclose(new_fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Close the dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");

    /* Close the dataset creation property list */
    ret = H5Pclose(dcpl);
    CHECK(ret, FAIL, "H5Pclose");

} /* end test_libver_bounds_datatype_check() */

/****************************************************************
**
**  test_libver_bounds_attributes():
**      Verify the attribute message versions:
**
**      (a) Create a file with default fcpl and the input fapl.
**          Create a group and attach the following three attributes
**          to the group:
**          (1) Attribute with a committed datatype
**          (2) Attribute with integer type
**          (3) Attribute with character encoding set
**          Verify the three attributes' message versions.
**          Close the file.
**
**      (b) Create a fcpl that has shared datatype message enabled.
**          Create a file with the fcpl and the input fapl.
**          Create a group and attach an attribute with shared
**          integer type to the group.
**          Verify the attribute message version.
**          Close the file
**
**      (b) Create a new fapl that is set to the 5 pairs of low/high
**          bounds in a "for" loop.  For each pair of setting in
**          the new fapl:
**              --Open the same file in (b) with the fapl
**              --Open the group and attach an attribute with integer
**                type to the group
**              --Verify the attribute message version
**              --Delete the attribute
**              --Close the group and the file
**
****************************************************************/
static void
test_libver_bounds_attributes(hid_t fapl)
{
    hid_t        fid      = H5I_INVALID_HID; /* File ID */
    hid_t        fcpl     = H5I_INVALID_HID; /* File creation property list */
    hid_t        new_fapl = H5I_INVALID_HID; /* File access property list */
    hid_t        tid      = H5I_INVALID_HID; /* Datatype ID */
    hid_t        gid      = H5I_INVALID_HID; /* Group ID */
    hid_t        sid      = H5I_INVALID_HID; /* Dataspace ID */
    hid_t        aid      = H5I_INVALID_HID; /* Attribute ID */
    hid_t        attr_cpl = H5I_INVALID_HID; /* Attribute creation property list */
    H5A_t       *attr     = NULL;            /* Internal attribute pointer */
    H5F_t       *f        = NULL;            /* Internal file pointer */
    H5F_libver_t low, high;                  /* Low and high bounds */
    herr_t       ret;                        /* Return value */

    /* Retrieve the low/high bounds from the input fapl */
    ret = H5Pget_libver_bounds(fapl, &low, &high);
    CHECK(ret, FAIL, "H5Pget_libver_bounds");

    /* Create the file */
    fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Integer datatype */
    tid = H5Tcopy(H5T_NATIVE_INT);
    CHECK(tid, H5I_INVALID_HID, "H5Tcopy");

    /* Create a committed datatype */
    ret = H5Tcommit2(fid, "datatype", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Tcommit2");

    /* Create dataspace */
    sid = H5Screate(H5S_SCALAR);
    CHECK(sid, H5I_INVALID_HID, "H5Screate");

    /* Create a group */
    gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(gid, H5I_INVALID_HID, "H5Gcreate2");

    /* Attach an attribute to the group with the committed datatype */
    aid = H5Acreate2(gid, "attr1", tid, sid, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(aid, H5I_INVALID_HID, "H5Acreate2");

    /* Get the internal attribute pointer */
    attr = (H5A_t *)H5VL_object(aid);
    CHECK_PTR(attr, "H5VL_object");

    /* Verify the attribute version */
    if (low == H5F_LIBVER_EARLIEST)
        /* The earliest version the library can set for an attribute with committed datatype is 2 */
        VERIFY(attr->shared->version, H5O_ATTR_VERSION_2, "H5O_attr_ver_bounds");
    else
        VERIFY(attr->shared->version, H5O_attr_ver_bounds[low], "H5O_attr_ver_bounds");

    /* Close the attribute */
    ret = H5Aclose(aid);
    CHECK(ret, FAIL, "H5Aclose");

    /* Create an attribute to the group with integer type */
    aid = H5Acreate2(gid, "attr2", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(aid, FAIL, "H5Acreate2");

    /* Get the internal attribute pointer */
    attr = (H5A_t *)H5VL_object(aid);
    CHECK_PTR(attr, "H5VL_object");

    /* Verify attribute version */
    VERIFY(attr->shared->version, H5O_attr_ver_bounds[low], "H5O_attr_ver_bounds");

    /* Close the attribute */
    ret = H5Aclose(aid);
    CHECK(ret, FAIL, "H5Aclose");

    /* Enable character encoding in attribute creation property list */
    attr_cpl = H5Pcreate(H5P_ATTRIBUTE_CREATE);
    CHECK(attr_cpl, H5I_INVALID_HID, "H5Pcreate");
    ret = H5Pset_char_encoding(attr_cpl, H5T_CSET_UTF8);
    CHECK(ret, FAIL, "H5Pset_char_encoding");

    /* Attach an attribute to the group with character encoding set */
    aid = H5Acreate2(gid, "attr3", H5T_NATIVE_INT, sid, attr_cpl, H5P_DEFAULT);
    CHECK(aid, H5I_INVALID_HID, "H5Acreate2");

    /* Get internal attribute pointer */
    attr = (H5A_t *)H5VL_object(aid);
    CHECK_PTR(attr, "H5VL_object");

    /* Verify attribute version */
    if (low == H5F_LIBVER_EARLIEST)
        /* The earliest version the library can set for an attribute with character encoding is 3 */
        VERIFY(attr->shared->version, H5O_ATTR_VERSION_3, "H5O_attr_ver_bounds");
    else
        VERIFY(attr->shared->version, H5O_attr_ver_bounds[low], "H5O_attr_ver_bounds");

    /* Close the attribute */
    ret = H5Aclose(aid);
    CHECK(ret, FAIL, "H5Aclose");

    /* Close the attribute creation property list */
    ret = H5Pclose(attr_cpl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Close the group */
    ret = H5Gclose(gid);
    CHECK(ret, FAIL, "H5Gclose");

    /* Close the dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");

    /* Close the datatype */
    ret = H5Tclose(tid);
    CHECK(ret, FAIL, "H5Tclose");

    /* Close the file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Create a copy of the file creation property list */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    CHECK(fcpl, H5I_INVALID_HID, "H5Pcreate");

    /* Enable shared datatype message */
    ret = H5Pset_shared_mesg_nindexes(fcpl, 1);
    CHECK(ret, FAIL, "H5Pset_shared_mesg_nindexes");
    ret = H5Pset_shared_mesg_index(fcpl, 0, H5O_SHMESG_DTYPE_FLAG, 2);
    CHECK(ret, FAIL, "H5Pset_shared_mesg_index");

    /* Create the file with shared datatype message enabled */
    fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, fcpl, fapl);
    CHECK(fid, H5I_INVALID_HID, "H5Fcreate");

    /* Create an integer datatype */
    tid = H5Tcopy(H5T_NATIVE_INT);
    CHECK(tid, H5I_INVALID_HID, "H5Tcopy");

    /* Create dataspace */
    sid = H5Screate(H5S_SCALAR);
    CHECK(sid, H5I_INVALID_HID, "H5Screate");

    /* Create a group */
    gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(gid, H5I_INVALID_HID, "H5Gcreate2");

    /* Attach an attribute to the group with shared integer datatype */
    aid = H5Acreate2(gid, ATTR_NAME, tid, sid, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(aid, H5I_INVALID_HID, "H5Acreate2");

    /* Get the internal attribute pointer */
    attr = (H5A_t *)H5VL_object(aid);
    CHECK_PTR(attr, "H5VL_object");

    /* Verify the attribute version */
    if (low == H5F_LIBVER_EARLIEST)
        /* The earliest version the library can set for an attribute with shared datatype is 2 */
        VERIFY(attr->shared->version, H5O_ATTR_VERSION_2, "H5O_attr_ver_bounds");
    else
        VERIFY(attr->shared->version, H5O_attr_ver_bounds[low], "H5O_attr_ver_bounds");

    /* Close the attribute */
    ret = H5Aclose(aid);
    CHECK(ret, FAIL, "H5Aclose");

    /* Close the group */
    ret = H5Gclose(gid);
    CHECK(ret, FAIL, "H5Gclose");

    /* Close the dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");

    /* Close the datatype */
    ret = H5Tclose(tid);
    CHECK(ret, FAIL, "H5Tclose");

    /* Close the file */
    ret = H5Fclose(fid);
    CHECK(ret, FAIL, "H5Fclose");

    /* Create a default file access property list */
    new_fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(new_fapl, FAIL, "H5Pcreate");

    /* Create a scalar dataspace to be used later for the attribute */
    sid = H5Screate(H5S_SCALAR);
    CHECK(sid, H5I_INVALID_HID, "H5Screate");

    /* Loop through all the combinations of low/high bounds */
    /* Open the file and group and attach an attribute to the group */
    /* Verify the attribute version */
    for (low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) {
        for (high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) {
            H5E_BEGIN_TRY
            {
                ret = H5Pset_libver_bounds(new_fapl, low, high);
            }
            H5E_END_TRY

            if (ret < 0) /* Invalid low/high combinations */
                continue;

            /* Open the file */
            H5E_BEGIN_TRY
            {
                fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl);
            }
            H5E_END_TRY
            VERIFY((fid >= 0), true, "File open should succeed");

            if (fid >= 0) { /* The file open succeeds */

                /* Get the internal file pointer */
                f = (H5F_t *)H5VL_object(fid);
                CHECK_PTR(f, "H5VL_object");

                /* Open the group */
                gid = H5Gopen2(fid, GRP_NAME, H5P_DEFAULT);
                CHECK(gid, FAIL, "H5Gopen2");

                /* Attach an attribute to the group */
                aid = H5Acreate2(gid, "attr1", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT);
                CHECK(aid, FAIL, "H5Acreate2");

                /* Get the internal attribute pointer */
                attr = (H5A_t *)H5VL_object(aid);
                CHECK_PTR(attr, "H5VL_object");

                /* Verify the attribute message version */
                VERIFY(attr->shared->version >= H5O_attr_ver_bounds[f->shared->low_bound], true,
                       "H5O_attr_ver_bounds");

                /* Close the attribute */
                ret = H5Aclose(aid);
                CHECK(ret, FAIL, "H5Aclose");

                /* Delete the attribute */
                ret = H5Adelete(gid, "attr1");
                CHECK(ret, FAIL, "H5Adelete");

                /* Close the group */
                ret = H5Gclose(gid);
                CHECK(ret, FAIL, "H5Gclose");

                /* Close the file */
                ret = H5Fclose(fid);
                CHECK(ret, FAIL, "H5Fclose");

            } /* end if */
        }     /* end for */
    }         /* end for */

    /* Close the file access property list */
    ret = H5Pclose(new_fapl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Close the dataspace */
    ret = H5Sclose(sid);
    CHECK(ret, FAIL, "H5Sclose");

} /* end test_libver_bounds_attributes() */

/****************************************************************
**
**  test_libver_macros():
**    Verify that H5_VERSION_GE and H5_VERSION_LE work correactly.
**
****************************************************************/
static void
test_libver_macros(void)
{
    int major   = H5_VERS_MAJOR;
    int minor   = H5_VERS_MINOR;
    int release = H5_VERS_RELEASE;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing macros for library version comparison\n"));

    VERIFY(H5_VERSION_GE(major, minor, release), true, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major - 1, minor, release), true, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major - 1, minor + 1, release), true, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major - 1, minor, release + 1), true, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major, minor - 1, release), true, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major, minor - 1, release + 1), true, "H5_VERSION_GE");
    if (H5_VERS_RELEASE > 0)
        VERIFY(H5_VERSION_GE(major, minor, release - 1), true, "H5_VERSION_GE");

    VERIFY(H5_VERSION_GE(major + 1, minor, release), false, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major + 1, minor - 1, release), false, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major + 1, minor - 1, release - 1), false, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major, minor + 1, release), false, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major, minor + 1, release - 1), false, "H5_VERSION_GE");
    VERIFY(H5_VERSION_GE(major, minor, release + 1), false, "H5_VERSION_GE");

    VERIFY(H5_VERSION_LE(major, minor, release), true, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major + 1, minor, release), true, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major + 1, minor - 1, release), true, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major + 1, minor - 1, release - 1), true, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major, minor + 1, release), true, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major, minor + 1, release - 1), true, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major, minor, release + 1), true, "H5_VERSION_LE");

    VERIFY(H5_VERSION_LE(major - 1, minor, release), false, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major - 1, minor + 1, release), false, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major - 1, minor + 1, release + 1), false, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major, minor - 1, release), false, "H5_VERSION_LE");
    VERIFY(H5_VERSION_LE(major, minor - 1, release + 1), false, "H5_VERSION_LE");
    if (H5_VERS_RELEASE > 0)
        VERIFY(H5_VERSION_LE(major, minor, release - 1), false, "H5_VERSION_LE");
} /* test_libver_macros() */

/****************************************************************
**
**  test_libver_macros2():
**    Verify that H5_VERSION_GE works correactly and show how
**      to use it.
**
****************************************************************/
static void
test_libver_macros2(void)
{
    hid_t  file;
    hid_t  grp;
    htri_t status;
    herr_t ret; /* Return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing macros for library version comparison with a file\n"));

    /*
     * Create a file.
     */
    file = H5Fcreate(FILE6, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file, FAIL, "H5Fcreate");

    /*
     * Create a group in the file.
     */
    grp = H5Gcreate2(file, "Group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    CHECK(file, FAIL, "H5Gcreate");

    /*
     * Close the group
     */
    ret = H5Gclose(grp);
    CHECK(ret, FAIL, "H5Gclose");

    /*
     * Delete the group using different function based on the library version.
     *  And verify the action.
     */
#if H5_VERSION_GE(1, 8, 0)
    ret = H5Ldelete(file, "Group", H5P_DEFAULT);
    CHECK(ret, FAIL, "H5Lunlink");

    status = H5Lexists(file, "Group", H5P_DEFAULT);
    VERIFY(status, false, "H5Lexists");
#else
    ret = H5Gunlink(file, "Group");
    CHECK(ret, FAIL, "H5Gunlink");

    H5E_BEGIN_TRY
    {
        grp = H5Gopen(file, "Group");
    }
    H5E_END_TRY
    VERIFY(grp, FAIL, "H5Gopen");
#endif

    /*
     * Close the file.
     */
    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

} /* test_libver_macros2() */

/****************************************************************
**
**  test_filesize():
**    Verify H5Fincrement_filesize() and H5Fget_eoa() works as
**    indicated in the "RFC: Enhancement to the tool h5clear".
**
****************************************************************/
static void
test_incr_filesize(void)
{
    hid_t          fid;                            /* File opened with read-write permission */
    h5_stat_size_t filesize;                       /* Size of file when empty */
    hid_t          fcpl;                           /* File creation property list */
    hid_t          fapl;                           /* File access property list */
    hid_t          dspace;                         /* Dataspace ID */
    hid_t          dset;                           /* Dataset ID */
    hid_t          dcpl;                           /* Dataset creation property list */
    unsigned       u;                              /* Local index variable */
    char           filename[FILENAME_LEN];         /* Filename to use */
    char           name[32];                       /* Dataset name */
    haddr_t        stored_eoa;                     /* The stored EOA value */
    hid_t          driver_id    = H5I_INVALID_HID; /* ID for this VFD */
    unsigned long  driver_flags = 0;               /* VFD feature flags */
    bool           vol_is_native;
    herr_t         ret; /* Return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing H5Fincrement_filesize() and H5Fget_eoa())\n"));

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, H5I_INVALID_HID, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    fapl = h5_fileaccess();
    h5_fixname(FILE_INCR_FILESIZE, fapl, filename, sizeof filename);

    /* Get the VFD feature flags */
    driver_id = H5Pget_driver(fapl);
    CHECK(driver_id, FAIL, "H5Pget_driver");

    ret = H5FDdriver_query(driver_id, &driver_flags);
    CHECK(ret, FAIL, "H5PDdriver_query");

    /* Check whether the VFD feature flag supports these two public routines */
    if (driver_flags & H5FD_FEAT_SUPPORTS_SWMR_IO) {

        fcpl = H5Pcreate(H5P_FILE_CREATE);
        CHECK(fcpl, FAIL, "H5Pcreate");

        /* Set file space strategy */
        ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, false, (hsize_t)1);
        CHECK(ret, FAIL, "H5P_set_file_space_strategy");

        /* Create the test file */
        fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl);
        CHECK(fid, FAIL, "H5Fcreate");

        /* Create dataspace for datasets */
        dspace = H5Screate(H5S_SCALAR);
        CHECK(dspace, FAIL, "H5Screate");

        /* Create a dataset creation property list */
        dcpl = H5Pcreate(H5P_DATASET_CREATE);
        CHECK(dcpl, FAIL, "H5Pcreate");

        /* Set the space allocation time to early */
        ret = H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY);
        CHECK(ret, FAIL, "H5Pset_alloc_time");

        /* Create datasets in file */
        for (u = 0; u < 10; u++) {
            snprintf(name, sizeof(name), "Dataset %u", u);
            dset = H5Dcreate2(fid, name, H5T_STD_U32LE, dspace, H5P_DEFAULT, dcpl, H5P_DEFAULT);
            CHECK(dset, FAIL, "H5Dcreate2");

            ret = H5Dclose(dset);
            CHECK(ret, FAIL, "H5Dclose");
        } /* end for */

        /* Close dataspace */
        ret = H5Sclose(dspace);
        CHECK(ret, FAIL, "H5Sclose");

        /* Close dataset creation property list */
        ret = H5Pclose(dcpl);
        CHECK(ret, FAIL, "H5Pclose");

        /* Close file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");

        /* Get the file size */
        filesize = h5_get_file_size(filename, fapl);

        /* Open the file */
        fid = H5Fopen(filename, H5F_ACC_RDWR, fapl);
        CHECK(fid, FAIL, "H5Fopen");

        /* Get the stored EOA */
        ret = H5Fget_eoa(fid, &stored_eoa);
        CHECK(ret, FAIL, "H5Fget_eoa");

        /* Verify the stored EOA is the same as filesize */
        VERIFY(filesize, stored_eoa, "file size");

        /* Set the EOA to the MAX(EOA, EOF) + 512 */
        ret = H5Fincrement_filesize(fid, 512);
        CHECK(ret, FAIL, "H5Fincrement_filesize");

        /* Close file */
        ret = H5Fclose(fid);
        CHECK(ret, FAIL, "H5Fclose");

        /* Get the file size */
        filesize = h5_get_file_size(filename, fapl);

        /* Verify the filesize is the previous stored_eoa + 512 */
        VERIFY(filesize, stored_eoa + 512, "file size");

        /* Delete the test file */
        h5_delete_test_file(FILE_INCR_FILESIZE, fapl);

        /* Close the file access property list */
        ret = H5Pclose(fapl);
        CHECK(ret, FAIL, "H5Pclose");

        /* Close the file creation property list */
        ret = H5Pclose(fcpl);
        CHECK(ret, FAIL, "H5Pclose");
    }
} /* end test_incr_filesize() */

/****************************************************************
**
**  test_min_dset_ohdr():
**    Test API calls to toggle dataset object header minimization.
**
**  TODO (as separate function?):
**    + setting persists between close and (re)open?
**    + dataset header sizes created while changing value of toggle
**
****************************************************************/
static void
test_min_dset_ohdr(void)
{
    const char basename[]             = "min_dset_ohdr_testfile";
    char       filename[FILENAME_LEN] = "";
    hid_t      file_id                = H5I_INVALID_HID;
    hid_t      file2_id               = H5I_INVALID_HID;
    bool       minimize;
    bool       vol_is_native;
    herr_t     ret;

    MESSAGE(5, ("Testing dataset object header minimization\n"));

    /*********/
    /* SETUP */
    /*********/

    h5_fixname(basename, H5P_DEFAULT, filename, sizeof(filename));

    file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    CHECK_I(file_id, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, file_id, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Fclose(file_id), FAIL, "H5Fclose");
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /*********/
    /* TESTS */
    /*********/

    /*----------------------------------------
     * TEST default value
     */
    ret = H5Fget_dset_no_attrs_hint(file_id, &minimize);
    CHECK(ret, FAIL, "H5Fget_dset_no_attrs_hint");
    VERIFY(minimize, false, "minimize flag");

    /*----------------------------------------
     * TEST set to true
     */
    ret = H5Fset_dset_no_attrs_hint(file_id, true);
    CHECK(ret, FAIL, "H5Fset_dset_no_attrs_hint");

    ret = H5Fget_dset_no_attrs_hint(file_id, &minimize);
    CHECK(ret, FAIL, "H5Fget_dset_no_attrs_hint");
    VERIFY(minimize, true, "minimize flag");

    /*----------------------------------------
     * TEST second file open on same filename
     */
    file2_id = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT);
    CHECK_I(file2_id, "H5Fopen");

    /* verify true setting on second open
     */
    ret = H5Fget_dset_no_attrs_hint(file_id, &minimize);
    CHECK(ret, FAIL, "H5Fget_dset_no_attrs_hint");
    VERIFY(minimize, true, "minimize flag");

    /* re-set to false on first open
     */
    ret = H5Fset_dset_no_attrs_hint(file_id, false);
    CHECK(ret, FAIL, "H5Fset_dset_no_attrs_hint");

    /* verify false set on both opens
     */
    ret = H5Fget_dset_no_attrs_hint(file_id, &minimize);
    CHECK(ret, FAIL, "H5Fget_dset_no_attrs_hint");
    VERIFY(minimize, false, "minimize flag");

    ret = H5Fget_dset_no_attrs_hint(file2_id, &minimize);
    CHECK(ret, FAIL, "H5Fget_dset_no_attrs_hint");
    VERIFY(minimize, false, "minimize flag");

    /* re-set to true on second open
     */
    ret = H5Fset_dset_no_attrs_hint(file2_id, true);
    CHECK(ret, FAIL, "H5Fset_dset_no_attrs_hint");

    /* verify true set on both opens
     */
    ret = H5Fget_dset_no_attrs_hint(file_id, &minimize);
    CHECK(ret, FAIL, "H5Fget_dset_no_attrs_hint");
    VERIFY(minimize, true, "minimize flag");

    ret = H5Fget_dset_no_attrs_hint(file2_id, &minimize);
    CHECK(ret, FAIL, "H5Fget_dset_no_attrs_hint");
    VERIFY(minimize, true, "minimize flag");

    /*----------------------------------------
     * TEST error cases
     */

    /* trying to set with invalid file ID */
    H5E_BEGIN_TRY
    {
        ret = H5Fset_dset_no_attrs_hint(-1, true);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Fset_dset_no_attrs_hint");

    /* trying to get with invalid file ID */
    H5E_BEGIN_TRY
    {
        ret = H5Fget_dset_no_attrs_hint(-1, &minimize);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Fget_dset_no_attrs_hint");

    /* trying to get with invalid pointer */
    H5E_BEGIN_TRY
    {
        ret = H5Fget_dset_no_attrs_hint(file_id, NULL);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Fget_dset_no_attrs_hint");

    /************/
    /* TEARDOWN */
    /************/

    ret = H5Fclose(file_id);
    CHECK(ret, FAIL, "H5Fclose");
    ret = H5Fclose(file2_id);
    CHECK(ret, FAIL, "H5Fclose");
} /* end test_min_dset_ohdr() */

/****************************************************************
**
**  test_unseekable_file():
**    Test that attempting to create/open an unseekable file fails gracefully
**    without a segfault (see hdf5#1498)
****************************************************************/
static void
test_unseekable_file(void)
{
    /* Output message about test being performed */
    MESSAGE(5, ("Testing creating/opening an unseekable file\n"));

    /* Flush message in case this test segfaults */
    fflush(stdout);

    /* Creation */
#ifdef H5_HAVE_WIN32_API
    H5Fcreate("NUL", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
#else
    H5Fcreate("/dev/null", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
#endif

    /* Should fail without segfault */
    /* TODO - Does not properly fail on all systems */
    /* VERIFY(file_id, H5I_INVALID_HID, "H5Fcreate"); */

    /* Opening */
#ifdef H5_HAVE_WIN32_API
    H5Fopen("NUL", H5F_ACC_RDWR, H5P_DEFAULT);
#else
    H5Fopen("/dev/null", H5F_ACC_RDWR, H5P_DEFAULT);
#endif

    /* TODO - Does not properly fail on all systems */
    /* VERIFY(file_id, H5I_INVALID_HID, "H5Fopen"); */
}
/****************************************************************
**
**  test_deprec():
**    Test deprecated functionality.
**
****************************************************************/
#ifndef H5_NO_DEPRECATED_SYMBOLS
static void
test_deprec(const char *driver_name)
{
    hid_t       file; /* File IDs for old & new files */
    hid_t       fcpl; /* File creation property list */
    hid_t       fapl; /* File creation property list */
    hsize_t     align;
    unsigned    super;    /* Superblock version # */
    unsigned    freelist; /* Free list version # */
    unsigned    stab;     /* Symbol table entry version # */
    unsigned    shhdr;    /* Shared object header version # */
    H5F_info1_t finfo;    /* global information about file */
    bool        vol_is_native;
    herr_t      ret; /* Generic return value */

    /* Output message about test being performed */
    MESSAGE(5, ("Testing deprecated routines\n"));

    /* Creating a file with the default file creation property list no longer
     * creates a version 0 superblock.  Set up earliest file format on fapl.
     */
    fapl = H5Pcreate(H5P_FILE_ACCESS);
    CHECK(fapl, FAIL, "H5Pcreate");
    ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST);
    CHECK(ret, FAIL, "H5Pset_libver_bounds");

    /* Create file with default file creation property list */
    file = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
    CHECK(file, FAIL, "H5Fcreate");

    /* Check if native VOL is being used */
    CHECK(h5_using_native_vol(H5P_DEFAULT, file, &vol_is_native), FAIL, "h5_using_native_vol");
    if (!vol_is_native) {
        CHECK(H5Fclose(file), FAIL, "H5Fclose");
        MESSAGE(5, (" -- SKIPPED --\n"));
        return;
    }

    /* Get the file's version information */
    ret = H5Fget_info1(file, &finfo);
    CHECK(ret, FAIL, "H5Fget_info1");
    VERIFY(finfo.super_ext_size, 0, "H5Fget_info1");
    VERIFY(finfo.sohm.hdr_size, 0, "H5Fget_info1");
    VERIFY(finfo.sohm.msgs_info.index_size, 0, "H5Fget_info1");
    VERIFY(finfo.sohm.msgs_info.heap_size, 0, "H5Fget_info1");

    /* Get the file's dataset creation property list */
    fcpl = H5Fget_create_plist(file);
    CHECK(fcpl, FAIL, "H5Fget_create_plist");

    /* Test passing in an ID that is not a file ID, should fail */
    H5E_BEGIN_TRY
    {
        ret = H5Fset_latest_format(fcpl, true);
    }
    H5E_END_TRY
    VERIFY(ret, FAIL, "H5Fset_latest_format");

    /* Get the file's version information */
    ret = H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr);
    CHECK(ret, FAIL, "H5Pget_version");
    VERIFY(super, 0, "H5Pget_version");
    VERIFY(freelist, 0, "H5Pget_version");
    VERIFY(stab, 0, "H5Pget_version");
    VERIFY(shhdr, 0, "H5Pget_version");

    /* Close FCPL */
    ret = H5Pclose(fcpl);
    CHECK(ret, FAIL, "H5Pclose");

    /* Close file */
    ret = H5Fclose(file);
    CHECK(ret, FAIL, "H5Fclose");

    /* Only run this part of the test with the sec2/default driver */
    if (h5_using_default_driver(driver_name)) {
        hid_t tmp_fapl;
        hid_t new_fapl;

        /* Create a file creation property list */
        fcpl = H5Pcreate(H5P_FILE_CREATE);
        CHECK(fcpl, FAIL, "H5Pcreate");

        /* Set a property in the FCPL that will push the superblock version up */
        ret = H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, 1, (hsize_t)0);
        ret = H5Pset_file_space_page_size(fcpl, (hsize_t)512);
        CHECK(ret, FAIL, "H5Pset_file_space_strategy");

        tmp_fapl = H5Pcopy(fapl);
        ret      = H5Pset_alignment(tmp_fapl, (hsize_t)1, (hsize_t)1024);
        CHECK(ret, FAIL, "H5Pset_alignment");

        /* Creating a file with the non-default file creation property list should
         * create a version 2 superblock
         */

        /* Create file with custom file creation property list */
        file = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, tmp_fapl);
        CHECK(file, FAIL, "H5Fcreate");

        new_fapl = H5Fget_access_plist(file);
        H5Pget_alignment(new_fapl, NULL, &align);

        /* Close FCPL */
        ret = H5Pclose(fcpl);
        CHECK(ret, FAIL, "H5Pclose");

        /* Get the file's version information */
        ret = H5Fget_info1(file, &finfo);
        CHECK(ret, FAIL, "H5Fget_info1");
        VERIFY(finfo.super_ext_size, 152, "H5Fget_info1");
        VERIFY(finfo.sohm.hdr_size, 0, "H5Fget_info1");
        VERIFY(finfo.sohm.msgs_info.index_size, 0, "H5Fget_info1");
        VERIFY(finfo.sohm.msgs_info.heap_size, 0, "H5Fget_info1");

        /* Get the file's dataset creation property list */
        fcpl = H5Fget_create_plist(file);
        CHECK(fcpl, FAIL, "H5Fget_create_plist");

        /* Get the file's version information */
        ret = H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr);
        CHECK(ret, FAIL, "H5Pget_version");
        VERIFY(super, 2, "H5Pget_version");
        VERIFY(freelist, 0, "H5Pget_version");
        VERIFY(stab, 0, "H5Pget_version");
        VERIFY(shhdr, 0, "H5Pget_version");

        /* Close FCPL */
        ret = H5Pclose(fcpl);
        CHECK(ret, FAIL, "H5Pclose");

        /* Close file */
        ret = H5Fclose(file);
        CHECK(ret, FAIL, "H5Fclose");

        /* Re-open the file */
        file = H5Fopen(FILE1, H5F_ACC_RDONLY, fapl);
        CHECK(file, FAIL, "H5Fcreate");

        /* Get the file's version information */
        ret = H5Fget_info1(file, &finfo);
        CHECK(ret, FAIL, "H5Fget_info1");
        VERIFY(finfo.super_ext_size, 152, "H5Fget_info1");
        VERIFY(finfo.sohm.hdr_size, 0, "H5Fget_info1");
        VERIFY(finfo.sohm.msgs_info.index_size, 0, "H5Fget_info1");
        VERIFY(finfo.sohm.msgs_info.heap_size, 0, "H5Fget_info1");

        /* Get the file's creation property list */
        fcpl = H5Fget_create_plist(file);
        CHECK(fcpl, FAIL, "H5Fget_create_plist");

        /* Get the file's version information */
        ret = H5Pget_version(fcpl, &super, &freelist, &stab, &shhdr);
        CHECK(ret, FAIL, "H5Pget_version");
        VERIFY(super, 2, "H5Pget_version");
        VERIFY(freelist, 0, "H5Pget_version");
        VERIFY(stab, 0, "H5Pget_version");
        VERIFY(shhdr, 0, "H5Pget_version");

        /* Close FCPL */
        ret = H5Pclose(fcpl);
        CHECK(ret, FAIL, "H5Pclose");

        /* Close file */
        ret = H5Fclose(file);
        CHECK(ret, FAIL, "H5Fclose");

        /* Close temp FAPLs */
        ret = H5Pclose(tmp_fapl);
        CHECK(ret, FAIL, "H5Pclose");
        ret = H5Pclose(new_fapl);
        CHECK(ret, FAIL, "H5Pclose");

        { /* Test deprecated H5Pget/set_file_space() */

            H5F_file_space_type_t old_strategy;
            hsize_t               old_threshold;
            hid_t                 fid;
            hid_t                 ffcpl;

            fcpl = H5Pcreate(H5P_FILE_CREATE);
            CHECK(fcpl, FAIL, "H5Pcreate");

            ret = H5Pget_file_space(fcpl, &old_strategy, &old_threshold);
            CHECK(ret, FAIL, "H5Pget_file_space");
            VERIFY(old_strategy, H5F_FILE_SPACE_ALL, "H5Pget_file_space");
            VERIFY(old_threshold, H5F_FREE_SPACE_THRESHOLD_DEF, "H5Pget_file_space");

            /* Set file space strategy and free space section threshold */
            ret = H5Pset_file_space(fcpl, H5F_FILE_SPACE_ALL_PERSIST, (hsize_t)0);
            CHECK(ret, FAIL, "H5Pget_file_space");

            /* Get the file space info from the creation property */
            ret = H5Pget_file_space(fcpl, &old_strategy, &old_threshold);
            CHECK(ret, FAIL, "H5Pget_file_space");
            VERIFY(old_strategy, H5F_FILE_SPACE_ALL_PERSIST, "H5Pget_file_space");
            VERIFY(old_threshold, H5F_FREE_SPACE_THRESHOLD_DEF, "H5Pget_file_space");

            ret = H5Pset_file_space(fcpl, H5F_FILE_SPACE_DEFAULT, (hsize_t)3);
            CHECK(ret, FAIL, "H5Pget_file_space");

            ret = H5Pget_file_space(fcpl, &old_strategy, &old_threshold);
            CHECK(ret, FAIL, "H5Pget_file_space");
            VERIFY(old_strategy, H5F_FILE_SPACE_ALL_PERSIST, "H5Pget_file_space");
            VERIFY(old_threshold, 3, "H5Pget_file_space");

            /* Create a file */
            fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl);
            CHECK(file, FAIL, "H5Fcreate");

            old_strategy  = H5F_FILE_SPACE_DEFAULT;
            old_threshold = 0;
            ffcpl         = H5Fget_create_plist(fid);
            ret           = H5Pget_file_space(ffcpl, &old_strategy, &old_threshold);
            CHECK(ret, FAIL, "H5Pget_file_space");
            VERIFY(old_strategy, H5F_FILE_SPACE_ALL_PERSIST, "H5Pget_file_space");
            VERIFY(old_threshold, 3, "H5Pget_file_space");

            /* Close file */
            ret = H5Fclose(fid);
            CHECK(ret, FAIL, "H5Fclose");

            ret = H5Pclose(ffcpl);
            CHECK(ret, FAIL, "H5Pclose");

            ret = H5Pclose(fcpl);
            CHECK(ret, FAIL, "H5Pclose");

            /* Reopen the file */
            fid = H5Fopen(FILE1, H5F_ACC_RDONLY, fapl);
            CHECK(fid, FAIL, "H5Fcreate");

            old_strategy  = H5F_FILE_SPACE_DEFAULT;
            old_threshold = 0;
            ffcpl         = H5Fget_create_plist(fid);
            ret           = H5Pget_file_space(ffcpl, &old_strategy, &old_threshold);
            CHECK(ret, FAIL, "H5Pget_file_space");
            VERIFY(old_strategy, H5F_FILE_SPACE_ALL_PERSIST, "H5Pget_file_space");
            VERIFY(old_threshold, 3, "H5Pget_file_space");

            ret = H5Pclose(ffcpl);
            CHECK(ret, FAIL, "H5Pclose");

            ret = H5Fclose(fid);
            CHECK(ret, FAIL, "H5Fclose");
        }
    }

    /* Close FAPL */
    ret = H5Pclose(fapl);
    CHECK(ret, FAIL, "H5Pclose");

} /* test_deprec */
#endif /* H5_NO_DEPRECATED_SYMBOLS */

/****************************************************************
**
**  test_file(): Main low-level file I/O test routine.
**
****************************************************************/
void
test_file(void H5_ATTR_UNUSED *params)
{
    const char *driver_name;               /* File Driver value from environment */
    hid_t       fapl_id = H5I_INVALID_HID; /* VFD-dependent fapl ID */
    bool        driver_is_default_compatible;
    herr_t      ret;

    /* Output message about test being performed */
    MESSAGE(5, ("Testing Low-Level File I/O\n"));

    /* Get the VFD to use */
    driver_name = h5_get_test_driver_name();

    /* Improved version of VFD-dependent checks */
    fapl_id = h5_fileaccess();
    CHECK(fapl_id, H5I_INVALID_HID, "h5_fileaccess");

    ret = h5_driver_is_default_vfd_compatible(fapl_id, &driver_is_default_compatible);
    CHECK(ret, FAIL, "h5_driver_is_default_vfd_compatible");

    test_file_create();                   /* Test file creation(also creation templates)*/
    test_file_open(driver_name);          /* Test file opening */
    test_file_reopen();                   /* Test file reopening */
    test_file_close();                    /* Test file close behavior */
    test_get_file_id();                   /* Test H5Iget_file_id */
    test_get_obj_ids();                   /* Test H5Fget_obj_ids for Jira Issue 8528 */
    test_file_perm();                     /* Test file access permissions */
    test_file_perm2();                    /* Test file access permission again */
    test_file_is_accessible(driver_name); /* Test detecting HDF5 files correctly */
    test_file_delete(fapl_id);            /* Test H5Fdelete */
    test_file_open_dot();                 /* Test opening objects with "." for a name */
    test_file_open_overlap();             /* Test opening files in an overlapping manner */
    test_file_getname();                  /* Test basic H5Fget_name() functionality */
    test_file_double_root_open();         /* Test opening root group from two files works properly */
    test_file_double_group_open();        /* Test opening same group from two files works properly */
    test_file_double_dataset_open();      /* Test opening same dataset from two files works properly */
    test_file_double_datatype_open();     /* Test opening same named datatype from two files works properly */
    test_file_double_file_dataset_open(true);
    test_file_double_file_dataset_open(false);
    test_userblock_file_size(
        driver_name);        /* Tests that files created with a userblock have the correct size */
    test_cached_stab_info(); /* Tests that files are created with cached stab info in the superblock */

    if (driver_is_default_compatible) {
        test_rw_noupdate(); /* Test to ensure that RW permissions don't write the file unless dirtied */
    }

    test_userblock_alignment(
        driver_name); /* Tests that files created with a userblock and alignment interact properly */
    test_userblock_alignment_paged(driver_name); /* Tests files created with a userblock and alignment (via
                                                    paged aggregation) interact properly */
    test_filespace_info(driver_name);            /* Test file creation public routines: */
    /* H5Pget/set_file_space_strategy() & H5Pget/set_file_space_page_size() */
    /* Skipped testing for multi/split drivers */
    test_file_freespace(driver_name); /* Test file public routine H5Fget_freespace() */
                                      /* Skipped testing for multi/split drivers */
                                      /* Setup for multi/split drivers are there already */
    test_sects_freespace(driver_name,
                         true); /* Test file public routine H5Fget_free_sections() for new format */
                                /* Skipped testing for multi/split drivers */
                                /* Setup for multi/split drivers are there already */
    test_sects_freespace(driver_name, false); /* Test file public routine H5Fget_free_sections() */
                                              /* Skipped testing for multi/split drivers */

    if (driver_is_default_compatible) {
        test_filespace_compatible(); /* Test compatibility for file space management */

        test_filespace_round_compatible();  /* Testing file space compatibility for files from trunk to 1_8 to
                                               trunk */
        test_filespace_1_10_0_compatible(); /* Testing file space compatibility for files from release 1.10.0
                                             */
    }

    test_libver_bounds(); /* Test compatibility for file space management */
    test_libver_bounds_low_high(driver_name);
    test_libver_macros();   /* Test the macros for library version comparison */
    test_libver_macros2();  /* Test the macros for library version comparison */
    test_incr_filesize();   /* Test H5Fincrement_filesize() and H5Fget_eoa() */
    test_min_dset_ohdr();   /* Test dataset object header minimization */
    test_unseekable_file(); /* Test attempting to open/create an unseekable file */
#ifndef H5_NO_DEPRECATED_SYMBOLS
    test_file_ishdf5(driver_name); /* Test detecting HDF5 files correctly */
    test_deprec(driver_name);      /* Test deprecated routines */
#endif                             /* H5_NO_DEPRECATED_SYMBOLS */

    ret = H5Pclose(fapl_id);
    CHECK(ret, FAIL, "H5Pclose");

} /* test_file() */

/*-------------------------------------------------------------------------
 * Function:    cleanup_file
 *
 * Purpose:    Cleanup temporary test files
 *
 * Return:    none
 *
 *-------------------------------------------------------------------------
 */
void
cleanup_file(void H5_ATTR_UNUSED *params)
{
    if (GetTestCleanup()) {
        H5E_BEGIN_TRY
        {
            H5Fdelete(SFILE1, H5P_DEFAULT);
            H5Fdelete(FILE1, H5P_DEFAULT);
            H5Fdelete(FILE2, H5P_DEFAULT);
            H5Fdelete(FILE3, H5P_DEFAULT);
            H5Fdelete(FILE4, H5P_DEFAULT);
            H5Fdelete(FILE5, H5P_DEFAULT);
            H5Fdelete(FILE6, H5P_DEFAULT);
            H5Fdelete(FILE7, H5P_DEFAULT);
            H5Fdelete(FILE8, H5P_DEFAULT);
            H5Fdelete(DST_FILE, H5P_DEFAULT);
        }
        H5E_END_TRY
    }
}
