summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/CMakeTests.cmake2
-rw-r--r--test/Makefile.am2
-rw-r--r--test/chunk_info.c6
-rw-r--r--test/direct_chunk.c94
-rw-r--r--test/dsets.c369
-rw-r--r--test/event_set.c66
-rw-r--r--test/filter_plugin1_dsets.c2
-rw-r--r--test/filter_plugin2_dsets.c2
-rw-r--r--test/filter_plugin3_dsets.c2
-rw-r--r--test/filter_plugin4_groups.c2
-rw-r--r--test/h5test.h3
-rw-r--r--test/links.c8
-rw-r--r--test/null_vol_connector.c2
-rw-r--r--test/tfile.c1
-rw-r--r--test/trefstr.c2
-rw-r--r--test/vol.c926
16 files changed, 1428 insertions, 61 deletions
diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake
index 17931cf..e840559 100644
--- a/test/CMakeTests.cmake
+++ b/test/CMakeTests.cmake
@@ -402,6 +402,8 @@ set (test_CLEANFILES
mirror_rw/*
mirror_wo/*
event_set_*.h5
+ h5s_block.h5
+ h5s_plist.h5
)
# Remove any output file left over from previous test run
diff --git a/test/Makefile.am b/test/Makefile.am
index 4bf9620..d465664 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -175,7 +175,7 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse
zero_chunk.h5 chunk_single.h5 swmr_non_latest.h5 \
earray_hdr_fd.h5 farray_hdr_fd.h5 bt2_hdr_fd.h5 \
storage_size.h5 dls_01_strings.h5 power2up.h5 version_bounds.h5 \
- alloc_0sized.h5 \
+ alloc_0sized.h5 h5s_block.h5 h5s_plist.h5 \
extend.h5 istore.h5 extlinks*.h5 frspace.h5 links*.h5 \
sys_file1 tfile[1-7].h5 th5s[1-4].h5 lheap.h5 fheap.h5 ohdr.h5 \
stab.h5 extern_[1-5].h5 extern_[1-4][rw].raw gheap[0-4].h5 \
diff --git a/test/chunk_info.c b/test/chunk_info.c
index 7104941..7c6dcc1 100644
--- a/test/chunk_info.c
+++ b/test/chunk_info.c
@@ -1676,7 +1676,7 @@ test_basic_query(hid_t fapl)
/* iterate over all chunks */
cptr = &(chunk_infos[0]);
- if (H5Dchunk_iter(dset, &iter_cb, &cptr) < 0)
+ if (H5Dchunk_iter(dset, H5P_DEFAULT, &iter_cb, &cptr) < 0)
TEST_ERROR;
VERIFY(cptr, &(chunk_infos[2]), "Iterator did not iterate all chunks");
@@ -1690,7 +1690,7 @@ test_basic_query(hid_t fapl)
/* iterate and stop after one iteration */
cptr = &(chunk_infos[0]);
- if (H5Dchunk_iter(dset, &iter_cb_stop, &cptr) < 0)
+ if (H5Dchunk_iter(dset, H5P_DEFAULT, &iter_cb_stop, &cptr) < 0)
TEST_ERROR;
VERIFY(cptr, &(chunk_infos[1]), "Verification of halted iterator failed\n");
@@ -1698,7 +1698,7 @@ test_basic_query(hid_t fapl)
cptr = &(chunk_infos[0]);
H5E_BEGIN_TRY
{
- ret = H5Dchunk_iter(dset, &iter_cb_fail, &cptr);
+ ret = H5Dchunk_iter(dset, H5P_DEFAULT, &iter_cb_fail, &cptr);
}
H5E_END_TRY;
if (ret >= 0)
diff --git a/test/direct_chunk.c b/test/direct_chunk.c
index 61e3df9..0d270bd 100644
--- a/test/direct_chunk.c
+++ b/test/direct_chunk.c
@@ -1990,23 +1990,23 @@ test_read_unallocated_chunk(hid_t file)
/* Create the data space with unlimited dimensions. */
if ((dataspace = H5Screate_simple(RANK, dims, maxdims)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if ((mem_space = H5Screate_simple(RANK, chunk_dims, NULL)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Modify dataset creation properties, i.e. enable chunking, no compression */
if ((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if ((status = H5Pset_chunk(cparms, RANK, chunk_dims)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Create a new dataset within the file using cparms creation properties. */
if ((dataset = H5Dcreate2(file, DATASETNAME11, H5T_NATIVE_INT, dataspace, H5P_DEFAULT, cparms,
H5P_DEFAULT)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Write a single chunk to intialize the chunk storage */
HDmemset(direct_buf, 0, CHUNK_NX * CHUNK_NY * sizeof(int));
@@ -2014,7 +2014,7 @@ test_read_unallocated_chunk(hid_t file)
offset[1] = 0;
if (H5Dwrite_chunk(dataset, dxpl, filter_mask, offset, chunk_nbytes, direct_buf) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Attempt to read each chunk in the dataset. Chunks are not allocated,
* therefore we expect the result of H5Dread_chunk to fail. Chunk idx starts
@@ -2034,7 +2034,7 @@ test_read_unallocated_chunk(hid_t file)
/* Check that the chunk read call does not succeed. */
if (status != -1)
- goto error;
+ TEST_ERROR
/* Query the size of the non-existant chunk */
direct_chunk_nbytes = ULONG_MAX;
@@ -2046,18 +2046,23 @@ test_read_unallocated_chunk(hid_t file)
/* Check that the chunk storage size call does not succeed. */
if (status != -1)
- goto error;
- if (direct_chunk_nbytes != 0)
- goto error;
+ TEST_ERROR
+ if (direct_chunk_nbytes != ULONG_MAX)
+ TEST_ERROR
}
}
/* Close/release resources. */
- H5Dclose(dataset);
- H5Sclose(mem_space);
- H5Sclose(dataspace);
- H5Pclose(cparms);
- H5Pclose(dxpl);
+ if (H5Dclose(dataset) < 0)
+ FAIL_STACK_ERROR;
+ if (H5Sclose(mem_space) < 0)
+ FAIL_STACK_ERROR;
+ if (H5Sclose(dataspace) < 0)
+ FAIL_STACK_ERROR;
+ if (H5Pclose(cparms) < 0)
+ FAIL_STACK_ERROR;
+ if (H5Pclose(dxpl) < 0)
+ FAIL_STACK_ERROR;
PASSED();
return 0;
@@ -2121,103 +2126,100 @@ test_single_chunk(unsigned config)
TESTING("Single chunk I/O");
/* Initialize data */
- for (i = 0; i < DIM0; i++) {
+ for (i = 0; i < DIM0; i++)
for (j = 0; j < DIM1; j++)
wdata[i][j] = j / CHUNK0;
- }
/* Create a new file with the latest format */
if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (config & CONFIG_LATEST)
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if ((fid = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Create dataspace */
if ((sid = H5Screate_simple(2, dims, NULL)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Create the dataset creation property list and set the chunk size */
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (H5Pset_chunk(dcpl, 2, chunk) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Create the dataset */
if ((did = H5Dcreate2(fid, DATASET, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (config & CONFIG_DIRECT_WRITE) {
/* Write the data directly to the dataset */
if (H5Dwrite_chunk(did, H5P_DEFAULT, 0, offset, CHUNK0 * CHUNK1 * 4, (void *)wdata) < 0)
- goto error;
+ FAIL_STACK_ERROR;
} /* end if */
else
/* Write the data to the dataset */
if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)wdata) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/*
* Close and release resources.
*/
if (H5Pclose(dcpl) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (config & CONFIG_REOPEN_DSET)
if (H5Dclose(did) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (H5Sclose(sid) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (H5Pclose(fapl) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (config & CONFIG_REOPEN_FILE)
if (H5Fclose(fid) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Open the file and dataset with default properties */
if (config & CONFIG_REOPEN_FILE)
if ((fid = H5Fopen(FILE, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (config & CONFIG_REOPEN_DSET)
if ((did = H5Dopen2(fid, DATASET, H5P_DEFAULT)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Retrieve dataset creation property list */
if ((dcpl = H5Dget_create_plist(did)) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (config & CONFIG_DIRECT_READ) {
/* Read the data directly */
if (H5Dread_chunk(did, H5P_DEFAULT, offset, &filters, rdata) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Verify returned filter mask */
if (filters != 0)
- goto error;
+ TEST_ERROR
} /* end if */
else
/* Read the data */
if (H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata) < 0)
- goto error;
+ FAIL_STACK_ERROR;
/* Verify that the data read was correct. */
- for (i = 0; i < DIM0; i++) {
- for (j = 0; j < DIM1; j++) {
+ for (i = 0; i < DIM0; i++)
+ for (j = 0; j < DIM1; j++)
if (rdata[i][j] != wdata[i][j])
- goto error;
- }
- }
+ TEST_ERROR
/*
* Close and release resources
*/
if (H5Pclose(dcpl) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (H5Dclose(did) < 0)
- goto error;
+ FAIL_STACK_ERROR;
if (H5Fclose(fid) < 0)
- goto error;
+ FAIL_STACK_ERROR;
PASSED();
return 0;
diff --git a/test/dsets.c b/test/dsets.c
index 96f8b81..cc35fe3 100644
--- a/test/dsets.c
+++ b/test/dsets.c
@@ -83,6 +83,8 @@ const char *FILENAME[] = {"dataset", /* 0 */
"power2up", /* 24 */
"version_bounds", /* 25 */
"alloc_0sized", /* 26 */
+ "h5s_block", /* 27 */
+ "h5s_plist", /* 28 */
NULL};
#define OHMIN_FILENAME_A "ohdr_min_a"
@@ -14963,6 +14965,370 @@ error:
} /* end test_object_header_minimization_dcpl() */
/*-----------------------------------------------------------------------------
+ * Function: test_h5s_block
+ *
+ * Purpose: Test the H5S_BLOCK feature.
+ *
+ * Return: Success/pass: 0
+ * Failure/error: -1
+ *
+ * Programmer: Quincey Koziol
+ * 3 November 2020
+ *
+ *-----------------------------------------------------------------------------
+ */
+static herr_t
+test_h5s_block(void)
+{
+ hid_t file_id = H5I_INVALID_HID; /* File ID */
+ char filename[FILENAME_BUF_SIZE] = "";
+ hid_t dset_id = H5I_INVALID_HID; /* Dataset ID */
+ hsize_t dims[1] = {20}; /* Dataset's dataspace size */
+ hsize_t start = 2; /* Starting offset of hyperslab selection */
+ hsize_t count = 10; /* Count of hyperslab selection */
+ hid_t file_space_id = H5I_INVALID_HID; /* File dataspace ID */
+ int buf[20]; /* Memory buffer for I/O */
+ unsigned u; /* Local index variable */
+ herr_t ret;
+
+ TESTING("contiguous memory buffers with H5S_BLOCK");
+
+ /*********/
+ /* SETUP */
+ /*********/
+ if (NULL == h5_fixname(FILENAME[27], H5P_DEFAULT, filename, sizeof(filename)))
+ TEST_ERROR
+ if (H5I_INVALID_HID == (file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)))
+ FAIL_STACK_ERROR
+ if ((file_space_id = H5Screate_simple(1, dims, NULL)) < 0)
+ FAIL_STACK_ERROR
+ if ((dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_INT, file_space_id, H5P_DEFAULT, H5P_DEFAULT,
+ H5P_DEFAULT)) < 0)
+ FAIL_STACK_ERROR
+
+ for (u = 0; u < 20; u++)
+ buf[u] = (int)u;
+
+ /*********/
+ /* TESTS */
+ /*********/
+
+ /* Check error cases */
+ H5E_BEGIN_TRY
+ {
+ ret = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_BLOCK, H5P_DEFAULT, buf);
+ }
+ H5E_END_TRY;
+ if (ret == SUCCEED)
+ TEST_ERROR
+
+ /* Write the entire dataset */
+ if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Reset the memory buffer */
+ HDmemset(buf, 0, sizeof(buf));
+
+ /* Read the entire dataset */
+ if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify the data read in */
+ for (u = 0; u < 20; u++)
+ if (buf[u] != (int)u)
+ TEST_ERROR
+
+ /* Read a hyperslab from the file to the first 10 elements of the buffer */
+ if (H5Sselect_hyperslab(file_space_id, H5S_SELECT_SET, &start, NULL, &count, NULL) < 0)
+ FAIL_STACK_ERROR
+ if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, file_space_id, H5P_DEFAULT, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify the data read in */
+ for (u = 0; u < count; u++)
+ if (buf[u] != (int)(u + start))
+ TEST_ERROR
+
+ /* Verify that reading 0 elements is handled correctly and doesn't modify buffer */
+ if (H5Sselect_none(file_space_id) < 0)
+ FAIL_STACK_ERROR
+ if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, file_space_id, H5P_DEFAULT, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify the data read in */
+ for (u = 0; u < count; u++)
+ if (buf[u] != (int)(u + start))
+ TEST_ERROR
+
+ /************/
+ /* TEARDOWN */
+ /************/
+ if (FAIL == H5Sclose(file_space_id))
+ FAIL_STACK_ERROR
+ if (FAIL == H5Dclose(dset_id))
+ FAIL_STACK_ERROR
+ if (FAIL == H5Fclose(file_id))
+ FAIL_STACK_ERROR
+
+ PASSED();
+
+ return SUCCEED;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Sclose(file_space_id);
+ H5Dclose(dset_id);
+ H5Fclose(file_id);
+ }
+ H5E_END_TRY;
+
+ return FAIL;
+} /* end test_h5s_block() */
+
+/*-----------------------------------------------------------------------------
+ * Function: test_h5s_plist
+ *
+ * Purpose: Test the H5S_PLIST feature.
+ *
+ * Return: Success/pass: 0
+ * Failure/error: -1
+ *
+ * Programmer: Quincey Koziol
+ * 28 January 2021
+ *
+ *-----------------------------------------------------------------------------
+ */
+static herr_t
+test_h5s_plist(void)
+{
+ hid_t file_id = H5I_INVALID_HID; /* File ID */
+ char filename[FILENAME_BUF_SIZE] = "";
+ hid_t dset_id = H5I_INVALID_HID; /* Dataset ID */
+ hsize_t dims[1] = {20}; /* Dataset's dataspace size */
+ hid_t dxpl_id = H5I_INVALID_HID; /* Dataset xfer property list ID */
+ hid_t dxpl_id_copy = H5I_INVALID_HID; /* Copy of dataset xfer property list ID */
+ hsize_t start = 2; /* Starting offset of hyperslab selection */
+ hsize_t stride = 1; /* Stride of hyperslab selection */
+ hsize_t count = 10; /* Count of hyperslab selection */
+ hsize_t start2 = 14; /* Starting offset of hyperslab selection */
+ hsize_t count2 = 4; /* Count of hyperslab selection */
+ hsize_t block = 1; /* Block size of hyperslab selection */
+ hid_t file_space_id = H5I_INVALID_HID; /* File dataspace ID */
+ int buf[20]; /* Memory buffer for I/O */
+ unsigned u; /* Local index variable */
+ herr_t ret;
+
+ TESTING("dataset's dataspace selection for I/O in DXPL with H5S_PLIST");
+
+ /*********/
+ /* SETUP */
+ /*********/
+ if (NULL == h5_fixname(FILENAME[28], H5P_DEFAULT, filename, sizeof(filename)))
+ TEST_ERROR
+ if (H5I_INVALID_HID == (file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)))
+ FAIL_STACK_ERROR
+ if ((file_space_id = H5Screate_simple(1, dims, NULL)) < 0)
+ FAIL_STACK_ERROR
+ if ((dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_INT, file_space_id, H5P_DEFAULT, H5P_DEFAULT,
+ H5P_DEFAULT)) < 0)
+ FAIL_STACK_ERROR
+ if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
+ FAIL_STACK_ERROR
+
+ for (u = 0; u < 20; u++)
+ buf[u] = (int)u;
+
+ /*********/
+ /* TESTS */
+ /*********/
+
+ /* Check error cases */
+ H5E_BEGIN_TRY
+ {
+ /* Bad rank */
+ ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id, 0, H5S_SELECT_SET, &start, &stride, &count,
+ &block);
+ }
+ H5E_END_TRY;
+ if (ret == SUCCEED)
+ TEST_ERROR
+ H5E_BEGIN_TRY
+ {
+ /* Bad selection operator */
+ ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_NOOP, &start, &stride, &count,
+ &block);
+ }
+ H5E_END_TRY;
+ if (ret == SUCCEED)
+ TEST_ERROR
+ H5E_BEGIN_TRY
+ {
+ /* Bad start pointer */
+ ret =
+ H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, NULL, &stride, &count, &block);
+ }
+ H5E_END_TRY;
+ if (ret == SUCCEED)
+ TEST_ERROR
+ H5E_BEGIN_TRY
+ {
+ /* Bad stride value (stride of NULL is OK) */
+ stride = 0;
+ ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, &start, &stride, &count,
+ &block);
+ stride = 1;
+ }
+ H5E_END_TRY;
+ if (ret == SUCCEED)
+ TEST_ERROR
+ H5E_BEGIN_TRY
+ {
+ /* Bad count pointer */
+ ret =
+ H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, &start, &stride, NULL, &block);
+ }
+ H5E_END_TRY;
+ if (ret == SUCCEED)
+ TEST_ERROR
+
+ /* Block pointer is allowed to be NULL */
+
+ H5E_BEGIN_TRY
+ {
+ /* H5S_PLIST for memory dataspace */
+ ret = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_PLIST, H5S_ALL, H5P_DEFAULT, buf);
+ }
+ H5E_END_TRY;
+ if (ret == SUCCEED)
+ TEST_ERROR
+
+ /* Write the entire dataset */
+ if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Reset the memory buffer */
+ HDmemset(buf, 0, sizeof(buf));
+
+ /* Read the entire dataset */
+ if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify the data read in */
+ for (u = 0; u < 20; u++)
+ if (buf[u] != (int)u)
+ TEST_ERROR
+
+ /* Reset the memory buffer */
+ HDmemset(buf, 0, sizeof(buf));
+
+ /* Set valid selection in DXPL */
+ if (H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, &start, &stride, &count, &block) <
+ 0)
+ FAIL_STACK_ERROR
+
+ /* Read a hyperslab from the file to the first 10 elements of the buffer */
+ if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify the data read in */
+ for (u = 0; u < count; u++)
+ if (buf[u] != (int)(u + start))
+ TEST_ERROR
+
+ /* Reset the memory buffer */
+ HDmemset(buf, 0, sizeof(buf));
+
+ /* Check for copying property list w/selection */
+ if ((dxpl_id_copy = H5Pcopy(dxpl_id)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Read a hyperslab from the file to the first 10 elements of the buffer */
+ if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id_copy, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify the data read in */
+ for (u = 0; u < count; u++)
+ if (buf[u] != (int)(u + start))
+ TEST_ERROR
+
+ /* Attempt to 'OR' block with invalid dimensions into the selection */
+ H5E_BEGIN_TRY
+ {
+ ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id_copy, 2, H5S_SELECT_OR, &start, &stride, &count,
+ &block);
+ }
+ H5E_END_TRY;
+ if (ret == SUCCEED)
+ TEST_ERROR
+
+ /* Set new valid selection in DXPL */
+ if (H5Pset_dataset_io_hyperslab_selection(dxpl_id_copy, 1, H5S_SELECT_SET, &start, &stride, &count,
+ &block) < 0)
+ FAIL_STACK_ERROR
+
+ /* Read a hyperslab from the file to the first 10 elements of the buffer */
+ if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id_copy, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify the data read in */
+ for (u = 0; u < count; u++)
+ if (buf[u] != (int)(u + start))
+ TEST_ERROR
+
+ /* Close the copy */
+ if (FAIL == H5Pclose(dxpl_id_copy))
+ FAIL_STACK_ERROR
+ dxpl_id_copy = H5I_INVALID_HID;
+
+ /* 'OR' valid block into the existing selection in original DXPL */
+ if (H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_OR, &start2, &stride, &count2, &block) <
+ 0)
+ FAIL_STACK_ERROR
+
+ /* Read a disjoint hyperslab from the file to the first 10 elements of the buffer */
+ if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id, buf) < 0)
+ FAIL_STACK_ERROR
+
+ /* Verify the data read in */
+ for (u = 0; u < count; u++)
+ if (buf[u] != (int)(u + start))
+ TEST_ERROR
+ for (u = 0; u < count2; u++)
+ if (buf[u + count] != (int)(u + start2))
+ TEST_ERROR
+
+ /************/
+ /* TEARDOWN */
+ /************/
+ if (FAIL == H5Pclose(dxpl_id))
+ FAIL_STACK_ERROR
+ if (FAIL == H5Sclose(file_space_id))
+ FAIL_STACK_ERROR
+ if (FAIL == H5Dclose(dset_id))
+ FAIL_STACK_ERROR
+ if (FAIL == H5Fclose(file_id))
+ FAIL_STACK_ERROR
+
+ PASSED();
+
+ return SUCCEED;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Pclose(dxpl_id_copy);
+ H5Pclose(dxpl_id);
+ H5Sclose(file_space_id);
+ H5Dclose(dset_id);
+ H5Fclose(file_id);
+ }
+ H5E_END_TRY;
+
+ return FAIL;
+} /* end test_h5s_plist() */
+
+/*-----------------------------------------------------------------------------
* Function: test_0sized_dset_metadata_alloc
*
* Purpose: Tests the metadata allocation for 0-sized datasets.
@@ -15407,7 +15773,10 @@ main(void)
/* Tests version bounds using its own file */
nerrors += (test_versionbounds() < 0 ? 1 : 0);
+ /* Tests that use their own file */
nerrors += (test_object_header_minimization_dcpl() < 0 ? 1 : 0);
+ nerrors += (test_h5s_block() < 0 ? 1 : 0);
+ nerrors += (test_h5s_plist() < 0 ? 1 : 0);
/* Run misc tests */
nerrors += (dls_01_main() < 0 ? 1 : 0);
diff --git a/test/event_set.c b/test/event_set.c
index 6568663..5df49e9 100644
--- a/test/event_set.c
+++ b/test/event_set.c
@@ -94,6 +94,71 @@ error:
}
/*-------------------------------------------------------------------------
+ * Function: test_es_none
+ *
+ * Purpose: Tests for passing H5ES_NONE to H5ES routines
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Quincey Koziol
+ * Friday, February 26, 2021
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_es_none(void)
+{
+ TESTING("event set H5ES_NONE");
+
+ /* Wait */
+ if (H5ESwait(H5ES_NONE, 0, NULL, NULL) < 0)
+ TEST_ERROR;
+
+ /* Cancel */
+ if (H5EScancel(H5ES_NONE, NULL, NULL) < 0)
+ TEST_ERROR;
+
+ /* Get count */
+ if (H5ESget_count(H5ES_NONE, NULL) < 0)
+ TEST_ERROR;
+
+ /* Get op counter */
+ if (H5ESget_op_counter(H5ES_NONE, NULL) < 0)
+ TEST_ERROR;
+
+ /* Get error status */
+ if (H5ESget_err_status(H5ES_NONE, NULL) < 0)
+ TEST_ERROR;
+
+ /* Get error count */
+ if (H5ESget_err_count(H5ES_NONE, NULL) < 0)
+ TEST_ERROR;
+
+ /* Get error info */
+ if (H5ESget_err_info(H5ES_NONE, 0, NULL, NULL) < 0)
+ TEST_ERROR;
+
+ /* Register insert function */
+ if (H5ESregister_insert_func(H5ES_NONE, NULL, NULL) < 0)
+ TEST_ERROR;
+
+ /* Register complete function */
+ if (H5ESregister_complete_func(H5ES_NONE, NULL, NULL) < 0)
+ TEST_ERROR;
+
+ /* Close */
+ if (H5ESclose(H5ES_NONE) < 0)
+ TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ return 1;
+}
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Tests event sets
@@ -118,6 +183,7 @@ main(void)
/* Tests */
nerrors += test_es_create();
+ nerrors += test_es_none();
/* Cleanup */
h5_cleanup(FILENAME, fapl_id);
diff --git a/test/filter_plugin1_dsets.c b/test/filter_plugin1_dsets.c
index 5d6c1ef..2b1e4d2 100644
--- a/test/filter_plugin1_dsets.c
+++ b/test/filter_plugin1_dsets.c
@@ -17,7 +17,7 @@
#include <stdlib.h>
#include <stdio.h>
-#include "H5PLextern.h"
+#include "hdf5dev.h"
#define FILTER1_ID 257
diff --git a/test/filter_plugin2_dsets.c b/test/filter_plugin2_dsets.c
index d2011d4..0bef1a0 100644
--- a/test/filter_plugin2_dsets.c
+++ b/test/filter_plugin2_dsets.c
@@ -17,7 +17,7 @@
#include <stdlib.h>
#include <stdio.h>
-#include "H5PLextern.h"
+#include "hdf5dev.h"
#define FILTER2_ID 258
#define MULTIPLIER 3
diff --git a/test/filter_plugin3_dsets.c b/test/filter_plugin3_dsets.c
index 618ce06..b9b3b82 100644
--- a/test/filter_plugin3_dsets.c
+++ b/test/filter_plugin3_dsets.c
@@ -18,7 +18,7 @@
#include <stdlib.h>
#include <stdio.h>
-#include "H5PLextern.h"
+#include "hdf5dev.h"
#define FILTER3_ID 259
diff --git a/test/filter_plugin4_groups.c b/test/filter_plugin4_groups.c
index 630dcd6..589347c 100644
--- a/test/filter_plugin4_groups.c
+++ b/test/filter_plugin4_groups.c
@@ -18,7 +18,7 @@
#include <stdio.h>
#include <string.h>
-#include "H5PLextern.h"
+#include "hdf5dev.h"
#define FILTER4_ID 260
#define SUFFIX_LEN 8
diff --git a/test/h5test.h b/test/h5test.h
index 0d7dade..f5c9608 100644
--- a/test/h5test.h
+++ b/test/h5test.h
@@ -22,9 +22,10 @@
/*
* Include required headers. This file tests internal library functions,
- * so we include the private headers here.
+ * so we include the private headers here, along with developer routines.
*/
#include "hdf5.h"
+#include "hdf5dev.h"
#include "H5private.h"
#include "H5Eprivate.h"
diff --git a/test/links.c b/test/links.c
index b2d0d9a..f022783 100644
--- a/test/links.c
+++ b/test/links.c
@@ -3507,6 +3507,7 @@ done:
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
return FAIL;
@@ -3597,6 +3598,7 @@ done:
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
return FAIL;
@@ -13785,6 +13787,7 @@ done:
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
return FAIL;
@@ -13876,6 +13879,7 @@ done:
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
return FAIL;
@@ -16683,7 +16687,7 @@ obj_exists(hid_t fapl, hbool_t new_format)
FAIL_STACK_ERROR
/* Hard links */
- /* Verify that H5Oexists_by_name() fails for non-existent link in root group */
+ /* Verify that H5Oexists_by_name() returns false for non-existent link in root group */
H5E_BEGIN_TRY
{
status = H5Oexists_by_name(fid, "foo", H5P_DEFAULT);
@@ -16702,7 +16706,7 @@ obj_exists(hid_t fapl, hbool_t new_format)
if (TRUE != H5Oexists_by_name(fid, "group", H5P_DEFAULT))
TEST_ERROR
- /* Verify that H5Oexists_by_name() fails for non-existent link in non-root group */
+ /* Verify that H5Oexists_by_name() returns false for non-existent object in non-root group */
H5E_BEGIN_TRY
{
status = H5Oexists_by_name(fid, "group/foo", H5P_DEFAULT);
diff --git a/test/null_vol_connector.c b/test/null_vol_connector.c
index b574a8e..7a1de6c 100644
--- a/test/null_vol_connector.c
+++ b/test/null_vol_connector.c
@@ -19,7 +19,7 @@
#include "hdf5.h"
/* For HDF5 plugin functionality */
-#include "H5PLextern.h"
+#include "hdf5dev.h"
/* This connector's header */
#include "null_vol_connector.h"
diff --git a/test/tfile.c b/test/tfile.c
index 6a52392..62f3c73 100644
--- a/test/tfile.c
+++ b/test/tfile.c
@@ -1452,6 +1452,7 @@ test_obj_count_and_id(hid_t fid1, hid_t fid2, hid_t did, hid_t gid1, hid_t gid2,
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
ERROR("H5Fget_obj_ids");
diff --git a/test/trefstr.c b/test/trefstr.c
index a3f568a..d0575ab 100644
--- a/test/trefstr.c
+++ b/test/trefstr.c
@@ -186,7 +186,7 @@ test_refstr_cmp(void)
H5RS_str_t *rs1; /* Ref-counted string created */
H5RS_str_t *rs2; /* Ref-counted string created */
int cmp; /* Comparison value */
- ssize_t len; /* Length of string */
+ size_t len; /* Length of string */
herr_t ret; /* Generic return value */
/* Output message about test being performed */
diff --git a/test/vol.c b/test/vol.c
index d975243..c7586d5 100644
--- a/test/vol.c
+++ b/test/vol.c
@@ -20,6 +20,12 @@
/* Headers needed */
#include "h5test.h"
+#include "H5Iprivate.h" /* IDs */
+#define H5T_FRIEND /* Suppress error about including H5Tpkg */
+#include "H5Tpkg.h" /* Datatypes */
+#define H5VL_FRIEND /* Suppress error about including H5VLpkg */
+#define H5VL_TESTING
+#include "H5VLpkg.h" /* Virtual Object Layer */
/* Filename */
const char *FILENAME[] = {"native_vol_test", NULL};
@@ -35,6 +41,136 @@ const char *FILENAME[] = {"native_vol_test", NULL};
#define N_ELEMENTS 10
+/* A VOL class struct to verify registering optional operations */
+static int reg_opt_curr_op_val;
+static herr_t reg_opt_op_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req);
+static herr_t reg_opt_link_optional(void *obj, const H5VL_loc_params_t *loc_params,
+ H5VL_optional_args_t *args, hid_t dxpl_id, void **req);
+static herr_t reg_opt_datatype_get(void *obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req);
+#define REG_OPT_VOL_NAME "reg_opt"
+#define REG_OPT_VOL_VALUE ((H5VL_class_value_t)502)
+static const H5VL_class_t reg_opt_vol_g = {
+ H5VL_VERSION, /* VOL class struct version */
+ REG_OPT_VOL_VALUE, /* value */
+ REG_OPT_VOL_NAME, /* name */
+ 0, /* version */
+ 0, /* capability flags */
+ NULL, /* initialize */
+ NULL, /* terminate */
+ {
+ /* info_cls */
+ (size_t)0, /* size */
+ NULL, /* copy */
+ NULL, /* compare */
+ NULL, /* free */
+ NULL, /* to_str */
+ NULL, /* from_str */
+ },
+ {
+ /* wrap_cls */
+ NULL, /* get_object */
+ NULL, /* get_wrap_ctx */
+ NULL, /* wrap_object */
+ NULL, /* unwrap_object */
+ NULL, /* free_wrap_ctx */
+ },
+ {
+ /* attribute_cls */
+ NULL, /* create */
+ NULL, /* open */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* get */
+ NULL, /* specific */
+ reg_opt_op_optional, /* optional */
+ NULL /* close */
+ },
+ {
+ /* dataset_cls */
+ NULL, /* create */
+ NULL, /* open */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* get */
+ NULL, /* specific */
+ reg_opt_op_optional, /* optional */
+ NULL /* close */
+ },
+ {
+ /* datatype_cls */
+ NULL, /* commit */
+ NULL, /* open */
+ reg_opt_datatype_get, /* get */
+ NULL, /* specific */
+ reg_opt_op_optional, /* optional */
+ NULL /* close */
+ },
+ {
+ /* file_cls */
+ NULL, /* create */
+ NULL, /* open */
+ NULL, /* get */
+ NULL, /* specific */
+ reg_opt_op_optional, /* optional */
+ NULL /* close */
+ },
+ {
+ /* group_cls */
+ NULL, /* create */
+ NULL, /* open */
+ NULL, /* get */
+ NULL, /* specific */
+ reg_opt_op_optional, /* optional */
+ NULL /* close */
+ },
+ {
+ /* link_cls */
+ NULL, /* create */
+ NULL, /* copy */
+ NULL, /* move */
+ NULL, /* get */
+ NULL, /* specific */
+ reg_opt_link_optional /* optional */
+ },
+ {
+ /* object_cls */
+ NULL, /* open */
+ NULL, /* copy */
+ NULL, /* get */
+ NULL, /* specific */
+ reg_opt_link_optional /* optional */
+ },
+ {
+ /* introspect_cls */
+ NULL, /* get_conn_cls */
+ NULL, /* get_cap_flags */
+ NULL, /* opt_query */
+ },
+ {
+ /* request_cls */
+ NULL, /* wait */
+ NULL, /* notify */
+ NULL, /* cancel */
+ NULL, /* specific */
+ NULL, /* optional */
+ NULL /* free */
+ },
+ {
+ /* blob_cls */
+ NULL, /* put */
+ NULL, /* get */
+ NULL, /* specific */
+ NULL /* optional */
+ },
+ {
+ /* token_cls */
+ NULL, /* cmp */
+ NULL, /* to_str */
+ NULL /* from_str */
+ },
+ NULL /* optional */
+};
+
#define FAKE_VOL_NAME "fake"
#define FAKE_VOL_VALUE ((H5VL_class_value_t)501)
@@ -90,6 +226,136 @@ static const H5VL_class_t fake_vol_g = {
},
{
/* datatype_cls */
+ NULL, /* commit */
+ NULL, /* open */
+ reg_opt_datatype_get, /* get */
+ NULL, /* specific */
+ NULL, /* optional */
+ NULL /* close */
+ },
+ {
+ /* file_cls */
+ NULL, /* create */
+ NULL, /* open */
+ NULL, /* get */
+ NULL, /* specific */
+ NULL, /* optional */
+ NULL /* close */
+ },
+ {
+ /* group_cls */
+ NULL, /* create */
+ NULL, /* open */
+ NULL, /* get */
+ NULL, /* specific */
+ NULL, /* optional */
+ NULL /* close */
+ },
+ {
+ /* link_cls */
+ NULL, /* create */
+ NULL, /* copy */
+ NULL, /* move */
+ NULL, /* get */
+ NULL, /* specific */
+ NULL /* optional */
+ },
+ {
+ /* object_cls */
+ NULL, /* open */
+ NULL, /* copy */
+ NULL, /* get */
+ NULL, /* specific */
+ NULL /* optional */
+ },
+ {
+ /* introspect_cls */
+ NULL, /* get_conn_cls */
+ NULL, /* get_cap_flags */
+ NULL, /* opt_query */
+ },
+ {
+ /* request_cls */
+ NULL, /* wait */
+ NULL, /* notify */
+ NULL, /* cancel */
+ NULL, /* specific */
+ NULL, /* optional */
+ NULL /* free */
+ },
+ {
+ /* blob_cls */
+ NULL, /* put */
+ NULL, /* get */
+ NULL, /* specific */
+ NULL /* optional */
+ },
+ {
+ /* token_cls */
+ NULL, /* cmp */
+ NULL, /* to_str */
+ NULL /* from_str */
+ },
+ NULL /* optional */
+};
+
+static herr_t fake_async_get_cap_flags(const void *info, unsigned *cap_flags);
+
+#define FAKE_ASYNC_VOL_NAME "fake_async"
+#define FAKE_ASYNC_VOL_VALUE ((H5VL_class_value_t)503)
+
+/* A VOL class struct that describes a VOL class with no
+ * functionality except to set the async capability flag.
+ */
+static const H5VL_class_t fake_async_vol_g = {
+ H5VL_VERSION, /* VOL class struct version */
+ FAKE_ASYNC_VOL_VALUE, /* value */
+ FAKE_ASYNC_VOL_NAME, /* name */
+ 0, /* connector version */
+ H5VL_CAP_FLAG_ASYNC, /* capability flags */
+ NULL, /* initialize */
+ NULL, /* terminate */
+ {
+ /* info_cls */
+ (size_t)0, /* size */
+ NULL, /* copy */
+ NULL, /* compare */
+ NULL, /* free */
+ NULL, /* to_str */
+ NULL, /* from_str */
+ },
+ {
+ /* wrap_cls */
+ NULL, /* get_object */
+ NULL, /* get_wrap_ctx */
+ NULL, /* wrap_object */
+ NULL, /* unwrap_object */
+ NULL, /* free_wrap_ctx */
+ },
+ {
+ /* attribute_cls */
+ NULL, /* create */
+ NULL, /* open */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* get */
+ NULL, /* specific */
+ NULL, /* optional */
+ NULL /* close */
+ },
+ {
+ /* dataset_cls */
+ NULL, /* create */
+ NULL, /* open */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* get */
+ NULL, /* specific */
+ NULL, /* optional */
+ NULL /* close */
+ },
+ {
+ /* datatype_cls */
NULL, /* commit */
NULL, /* open */
NULL, /* get */
@@ -134,8 +400,9 @@ static const H5VL_class_t fake_vol_g = {
},
{
/* introspect_cls */
- NULL, /* get_conn_cls */
- NULL, /* opt_query */
+ NULL, /* get_conn_cls */
+ fake_async_get_cap_flags, /* get_cap_flags */
+ NULL, /* opt_query */
},
{
/* request_cls */
@@ -163,6 +430,146 @@ static const H5VL_class_t fake_vol_g = {
};
/*-------------------------------------------------------------------------
+ * Function: reg_opt_op_optional_verify
+ *
+ * Purpose: Common verification routine for dynamic optional operations
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+reg_opt_op_optional_verify(void *obj, H5VL_optional_args_t *args)
+{
+ int *o = (int *)obj;
+ int *op_args;
+
+ /* Check for receiving correct operation value */
+ if (args->op_type != reg_opt_curr_op_val)
+ return -1;
+
+ /* Check that the object is correct */
+ if ((-1) != *o)
+ return -1;
+
+ /* Update the object, with the operation value */
+ *o = args->op_type;
+
+ /* Check that the argument is correct */
+ op_args = args->args;
+ if (NULL == op_args)
+ return -1;
+ if ((-1) != *op_args)
+ return -1;
+
+ /* Update the argument return parameter */
+ *op_args = args->op_type;
+
+ return 0;
+} /* end reg_opt_op_optional_verify() */
+
+/*-------------------------------------------------------------------------
+ * Function: reg_opt_op_optional
+ *
+ * Purpose: Common callback to perform a connector-specific operation
+ * on an object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+reg_opt_op_optional(void *obj, H5VL_optional_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id,
+ void H5_ATTR_UNUSED **req)
+{
+ /* Invoke the common value verification routine */
+ return reg_opt_op_optional_verify(obj, args);
+} /* end reg_opt_op_optional() */
+
+/*-------------------------------------------------------------------------
+ * Function: reg_opt_link_optional
+ *
+ * Purpose: Callback to perform a connector-specific operation
+ * on a link
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+reg_opt_link_optional(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args,
+ hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req)
+{
+ /* Check for receiving correct loc_params info */
+ if (loc_params->type != H5VL_OBJECT_BY_NAME)
+ return -1;
+ if (loc_params->obj_type != H5I_GROUP)
+ return -1;
+ if (HDstrcmp(loc_params->loc_data.loc_by_name.name, ".") != 0)
+ return -1;
+ if (loc_params->loc_data.loc_by_name.lapl_id != H5P_LINK_ACCESS_DEFAULT)
+ return -1;
+
+ /* Invoke the common value verification routine */
+ return reg_opt_op_optional_verify(obj, args);
+} /* end reg_opt_link_optional() */
+
+/*-------------------------------------------------------------------------
+ * Function: reg_opt_datatype_get
+ *
+ * Purpose: Handles the datatype get callback
+ *
+ * Note: This is _strictly_ a testing fixture to support the
+ * exercise_reg_opt_oper() testing routine. It fakes just
+ * enough of the named datatype VOL callback for the
+ * H5VL_register_using_vol_id() call in that test routine to
+ * succeed.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+reg_opt_datatype_get(void H5_ATTR_UNUSED *obj, H5VL_datatype_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id,
+ void H5_ATTR_UNUSED **req)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ if (H5VL_DATATYPE_GET_BINARY_SIZE == args->op_type) {
+ if (H5Tencode(H5T_NATIVE_INT, NULL, args->args.get_binary_size.size) < 0)
+ ret_value = FAIL;
+ } /* end if */
+ else if (H5VL_DATATYPE_GET_BINARY == args->op_type) {
+ if (H5Tencode(H5T_NATIVE_INT, args->args.get_binary.buf, &args->args.get_binary.buf_size) < 0)
+ ret_value = FAIL;
+ } /* end if */
+ else
+ ret_value = FAIL;
+
+ return ret_value;
+} /* end reg_opt_datatype_get() */
+
+/*-------------------------------------------------------------------------
+ * Function: fake_async_get_cap_flags
+ *
+ * Purpose: Return the capability flags for the 'fake async' connector
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+fake_async_get_cap_flags(const void H5_ATTR_UNUSED *info, unsigned *cap_flags)
+{
+ *cap_flags = fake_async_vol_g.cap_flags;
+
+ return SUCCEED;
+} /* end fake_async_get_cap_flags() */
+
+/*-------------------------------------------------------------------------
* Function: test_vol_registration()
*
* Purpose: Tests if we can load, register, and close a simple
@@ -1176,6 +1583,519 @@ error:
} /* end test_basic_datatype_operation() */
+typedef herr_t (*reg_opt_obj_oper_t)(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t obj_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id);
+typedef herr_t (*reg_opt_link_oper_t)(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t obj_id, const char *name, hid_t lapl_id,
+ H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id);
+typedef union {
+ reg_opt_obj_oper_t obj_op;
+ reg_opt_link_oper_t link_op;
+} reg_opt_oper_t;
+
+/*-------------------------------------------------------------------------
+ * Function: exercise_reg_opt_oper()
+ *
+ * Purpose: Exercise a particular optional operation for a type.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+exercise_reg_opt_oper(hid_t fake_vol_id, hid_t reg_opt_vol_id, H5VL_subclass_t subcls,
+ const char *subcls_name, H5I_type_t id_type, reg_opt_oper_t reg_opt_op)
+{
+ char op_name[256]; /* Operation name to register */
+ hid_t obj_id = H5I_INVALID_HID;
+ H5VL_object_t * vol_obj;
+ H5VL_optional_args_t vol_cb_args;
+ int fake_obj, fake_arg;
+ int op_val = -1, op_val2 = -1;
+ int find_op_val;
+ herr_t ret = SUCCEED;
+
+ /* Test registering optional operation */
+ HDsnprintf(op_name, sizeof(op_name), "%s-op1", subcls_name);
+ if (H5VLregister_opt_operation(subcls, op_name, &op_val) < 0)
+ TEST_ERROR;
+
+ /* Verify that the reserved amount of optional operations is obeyed */
+ /* (The first optional operation registered should be at the lower limit) */
+ if (op_val != H5VL_RESERVED_NATIVE_OPTIONAL)
+ TEST_ERROR;
+
+ /* Look up 1st registered optional operation */
+ find_op_val = 0;
+ if (H5VLfind_opt_operation(subcls, op_name, &find_op_val) < 0)
+ TEST_ERROR;
+
+ /* Verify that the operation was looked up successfully */
+ if (op_val != find_op_val)
+ TEST_ERROR;
+
+ /* Test registering second optional operation */
+ HDsnprintf(op_name, sizeof(op_name), "%s-op2", subcls_name);
+ if (H5VLregister_opt_operation(subcls, op_name, &op_val2) < 0)
+ TEST_ERROR;
+
+ /* Verify that the reserved amount of optional operations is obeyed */
+ /* (The 2nd optional operation registered should be at the lower limit + 1) */
+ if (op_val2 != (H5VL_RESERVED_NATIVE_OPTIONAL + 1))
+ TEST_ERROR;
+
+ /* Look up 2nd registered optional operation */
+ find_op_val = 0;
+ if (H5VLfind_opt_operation(subcls, op_name, &find_op_val) < 0)
+ TEST_ERROR;
+
+ /* Verify that the operation was looked up successfully */
+ if (op_val2 != find_op_val)
+ TEST_ERROR;
+
+ /* Push a new API context on the stack */
+ /* (Necessary for the named datatype construction routines) */
+ if (H5VL_SUBCLS_DATATYPE == subcls)
+ H5CX_push();
+
+ /* Create fake object on fake VOL connector */
+ if (H5I_INVALID_HID == (obj_id = H5VL_register_using_vol_id(id_type, &fake_obj, fake_vol_id, TRUE)))
+ TEST_ERROR;
+
+ /* Pop the API context off the stack */
+ if (H5VL_SUBCLS_DATATYPE == subcls)
+ H5CX_pop(FALSE);
+
+ /* Attempt to issue operation on fake VOL connector */
+ fake_obj = -1;
+ fake_arg = -1;
+ vol_cb_args.op_type = op_val;
+ vol_cb_args.args = &fake_arg;
+ H5E_BEGIN_TRY
+ {
+ if (H5VL_SUBCLS_LINK == subcls || H5VL_SUBCLS_OBJECT == subcls)
+ ret = (*reg_opt_op.link_op)(__FILE__, __func__, __LINE__, obj_id, ".", H5P_DEFAULT, &vol_cb_args,
+ H5P_DEFAULT, H5ES_NONE);
+ else
+ ret = (*reg_opt_op.obj_op)(__FILE__, __func__, __LINE__, obj_id, &vol_cb_args, H5P_DEFAULT,
+ H5ES_NONE);
+ }
+ H5E_END_TRY;
+ if (FAIL != ret)
+ FAIL_PUTS_ERROR("should not be able to perform an optional operation with a NULL callback");
+ if ((-1) != fake_obj)
+ FAIL_PUTS_ERROR("'fake_obj' changed during failed operation?");
+ if ((-1) != fake_arg)
+ FAIL_PUTS_ERROR("'fake_arg' changed during failed operation?");
+
+ /* Named datatypes must be destroyed differently */
+ if (H5VL_SUBCLS_DATATYPE == subcls) {
+ H5T_t *dt;
+
+ /* Destroy fake datatype object */
+ if (NULL == (dt = H5I_remove(obj_id)))
+ TEST_ERROR;
+ if (H5VL_free_object(dt->vol_obj) < 0)
+ TEST_ERROR;
+ dt->vol_obj = NULL;
+ if (H5T_close(dt) < 0)
+ TEST_ERROR;
+ } /* end if */
+ else {
+ /* Destroy fake object */
+ if (NULL == (vol_obj = H5I_remove(obj_id)))
+ TEST_ERROR;
+ if (H5VL_free_object(vol_obj) < 0)
+ TEST_ERROR;
+ } /* end else */
+
+ /* Push a new API context on the stack */
+ /* (Necessary for the named datatype construction routines) */
+ if (H5VL_SUBCLS_DATATYPE == subcls)
+ H5CX_push();
+
+ /* Create fake object on reg_opt VOL connector */
+ if (H5I_INVALID_HID == (obj_id = H5VL_register_using_vol_id(id_type, &fake_obj, reg_opt_vol_id, TRUE)))
+ TEST_ERROR;
+
+ /* Pop the API context off the stack */
+ if (H5VL_SUBCLS_DATATYPE == subcls)
+ H5CX_pop(FALSE);
+
+ /* Issue first operation */
+ fake_obj = -1;
+ fake_arg = -1;
+ reg_opt_curr_op_val = op_val;
+ vol_cb_args.op_type = op_val;
+ vol_cb_args.args = &fake_arg;
+ if (H5VL_SUBCLS_LINK == subcls || H5VL_SUBCLS_OBJECT == subcls)
+ ret = (*reg_opt_op.link_op)(__FILE__, __func__, __LINE__, obj_id, ".", H5P_DEFAULT, &vol_cb_args,
+ H5P_DEFAULT, H5ES_NONE);
+ else
+ ret =
+ (*reg_opt_op.obj_op)(__FILE__, __func__, __LINE__, obj_id, &vol_cb_args, H5P_DEFAULT, H5ES_NONE);
+ if (ret < 0)
+ TEST_ERROR;
+
+ /* Verify that fake object & argument were modified correctly */
+ if (op_val != fake_obj)
+ FAIL_PUTS_ERROR("'fake_obj' not updated");
+ if (op_val != fake_arg)
+ FAIL_PUTS_ERROR("'fake_arg' not updated");
+
+ /* Issue second operation */
+ fake_obj = -1;
+ fake_arg = -1;
+ reg_opt_curr_op_val = op_val2;
+ vol_cb_args.op_type = op_val2;
+ vol_cb_args.args = &fake_arg;
+ if (H5VL_SUBCLS_LINK == subcls || H5VL_SUBCLS_OBJECT == subcls)
+ ret = (*reg_opt_op.link_op)(__FILE__, __func__, __LINE__, obj_id, ".", H5P_DEFAULT, &vol_cb_args,
+ H5P_DEFAULT, H5ES_NONE);
+ else
+ ret =
+ (*reg_opt_op.obj_op)(__FILE__, __func__, __LINE__, obj_id, &vol_cb_args, H5P_DEFAULT, H5ES_NONE);
+ if (ret < 0)
+ TEST_ERROR;
+
+ /* Verify that fake object & argument were modified correctly */
+ if (op_val2 != fake_obj)
+ FAIL_PUTS_ERROR("'fake_obj' not updated");
+ if (op_val2 != fake_arg)
+ FAIL_PUTS_ERROR("'fake_arg' not updated");
+
+ /* Named datatypes must be destroyed differently */
+ if (H5VL_SUBCLS_DATATYPE == subcls) {
+ H5T_t *dt;
+
+ /* Destroy fake datatype object */
+ if (NULL == (dt = H5I_remove(obj_id)))
+ TEST_ERROR;
+ if (H5VL_free_object(dt->vol_obj) < 0)
+ TEST_ERROR;
+ dt->vol_obj = NULL;
+ if (H5T_close(dt) < 0)
+ TEST_ERROR;
+ } /* end if */
+ else {
+ /* Destroy fake object */
+ if (NULL == (vol_obj = H5I_remove(obj_id)))
+ TEST_ERROR;
+ if (H5VL_free_object(vol_obj) < 0)
+ TEST_ERROR;
+ } /* end else */
+
+ /* Unregister 2nd registered optional operation */
+ if (H5VLunregister_opt_operation(subcls, op_name) < 0)
+ TEST_ERROR;
+
+ return SUCCEED;
+
+error:
+ return FAIL;
+} /* end exercise_reg_opt_oper() */
+
+/*-------------------------------------------------------------------------
+ * Function: test_register_opt_operation()
+ *
+ * Purpose: Tests if we can load, register, and close a simple
+ * VOL connector.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_register_opt_operation(void)
+{
+ hid_t fake_vol_id = H5I_INVALID_HID;
+ hid_t reg_opt_vol_id = H5I_INVALID_HID;
+ struct {
+ H5VL_subclass_t subcls;
+ const char * subcls_name;
+ H5I_type_t id_type;
+ reg_opt_oper_t reg_opt_op;
+ } test_params[] = {{H5VL_SUBCLS_ATTR, "attr", H5I_ATTR, {.obj_op = H5VLattr_optional_op}},
+ {H5VL_SUBCLS_DATASET, "dataset", H5I_DATASET, {.obj_op = H5VLdataset_optional_op}},
+ {H5VL_SUBCLS_DATATYPE, "datatype", H5I_DATATYPE, {.obj_op = H5VLdatatype_optional_op}},
+ {H5VL_SUBCLS_FILE, "file", H5I_FILE, {.obj_op = H5VLfile_optional_op}},
+ {H5VL_SUBCLS_GROUP, "group", H5I_GROUP, {.obj_op = H5VLgroup_optional_op}},
+ {H5VL_SUBCLS_LINK, "link", H5I_GROUP, {.link_op = H5VLlink_optional_op}},
+ {H5VL_SUBCLS_OBJECT, "object", H5I_GROUP, {.link_op = H5VLobject_optional_op}}};
+ int op_val = -1;
+ unsigned u;
+ herr_t ret = SUCCEED;
+
+ TESTING("dynamically registering optional operations");
+
+ /* Register the VOL connectors for testing */
+ if ((fake_vol_id = H5VLregister_connector(&fake_vol_g, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+ if ((reg_opt_vol_id = H5VLregister_connector(&reg_opt_vol_g, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ /* Test registering invalid optional VOL subclass operations */
+ H5E_BEGIN_TRY
+ {
+ ret = H5VLregister_opt_operation(H5VL_SUBCLS_NONE, "fail", &op_val);
+ }
+ H5E_END_TRY;
+ if (FAIL != ret)
+ FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'NONE' VOL subclass");
+ if ((-1) != op_val)
+ FAIL_PUTS_ERROR("'op_val' changed during failed operation?");
+ H5E_BEGIN_TRY
+ {
+ ret = H5VLregister_opt_operation(H5VL_SUBCLS_INFO, "fail2", &op_val);
+ }
+ H5E_END_TRY;
+ if (FAIL != ret)
+ FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'INFO' VOL subclass");
+ if ((-1) != op_val)
+ FAIL_PUTS_ERROR("'op_val' changed during failed operation?");
+ H5E_BEGIN_TRY
+ {
+ ret = H5VLregister_opt_operation(H5VL_SUBCLS_WRAP, "fail3", &op_val);
+ }
+ H5E_END_TRY;
+ if (FAIL != ret)
+ FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'WRAP' VOL subclass");
+ if ((-1) != op_val)
+ FAIL_PUTS_ERROR("'op_val' changed during failed operation?");
+ H5E_BEGIN_TRY
+ {
+ ret = H5VLregister_opt_operation(H5VL_SUBCLS_BLOB, "fail4", &op_val);
+ }
+ H5E_END_TRY;
+ if (FAIL != ret)
+ FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'BLOB' VOL subclass");
+ if ((-1) != op_val)
+ FAIL_PUTS_ERROR("'op_val' changed during failed operation?");
+ H5E_BEGIN_TRY
+ {
+ ret = H5VLregister_opt_operation(H5VL_SUBCLS_TOKEN, "fail5", &op_val);
+ }
+ H5E_END_TRY;
+ if (FAIL != ret)
+ FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'TOKEN' VOL subclass");
+ if ((-1) != op_val)
+ FAIL_PUTS_ERROR("'op_val' changed during failed operation?");
+
+ /* Test registering valid optional VOL subclass operation with NULL op_val ptr*/
+ H5E_BEGIN_TRY
+ {
+ ret = H5VLregister_opt_operation(H5VL_SUBCLS_FILE, "fail6", NULL);
+ }
+ H5E_END_TRY;
+ if (FAIL != ret)
+ FAIL_PUTS_ERROR("should not be able to register an optional operation with a NULL 'op_val'");
+
+ /* Try finding a non-existent optional VOL subclass operation */
+ H5E_BEGIN_TRY
+ {
+ ret = H5VLfind_opt_operation(H5VL_SUBCLS_DATASET, "fail", &op_val);
+ }
+ H5E_END_TRY;
+ if (FAIL != ret)
+ FAIL_PUTS_ERROR("should not be able to find a non-existent optional operation");
+
+ /* Try unregistering a non-existent optional VOL subclass operation */
+ H5E_BEGIN_TRY
+ {
+ ret = H5VLunregister_opt_operation(H5VL_SUBCLS_DATASET, "fail");
+ }
+ H5E_END_TRY;
+ if (FAIL != ret)
+ FAIL_PUTS_ERROR("should not be able to unregister a non-existent optional operation");
+
+ /* Optional operations on requests are supported (but difficult to test further) */
+ if (H5VLregister_opt_operation(H5VL_SUBCLS_REQUEST, "req_op", &op_val) < 0)
+ TEST_ERROR;
+
+ /* Register & test calling optional operations for each valid VOL subclass */
+ /* (Table-driven, with test_params array) */
+ for (u = 0; u < NELMTS(test_params); u++)
+ /* Exercise appropriate callback, for each VOL subclass */
+ if (exercise_reg_opt_oper(fake_vol_id, reg_opt_vol_id, test_params[u].subcls,
+ test_params[u].subcls_name, test_params[u].id_type,
+ test_params[u].reg_opt_op) < 0)
+ TEST_ERROR;
+
+ /* Unregister the VOL connectors */
+ if (H5VLunregister_connector(fake_vol_id) < 0)
+ TEST_ERROR;
+ if (H5VLunregister_connector(reg_opt_vol_id) < 0)
+ TEST_ERROR;
+
+ PASSED();
+
+ return SUCCEED;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5VLunregister_connector(fake_vol_id);
+ H5VLunregister_connector(reg_opt_vol_id);
+ }
+ H5E_END_TRY;
+
+ return FAIL;
+} /* end test_register_opt_operation() */
+
+/*-------------------------------------------------------------------------
+ * Function: test_async_vol_props()
+ *
+ * Purpose: Test properties related to asynchronous VOL connector operation
+ *
+ * Note: Overrides the HDF5_VOL_CONNECTOR environment variable, to
+ * provide stable testing environment.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_async_vol_props(void)
+{
+ hid_t fapl_id = H5I_INVALID_HID;
+ hid_t vol_id = H5I_INVALID_HID;
+ H5VL_pass_through_info_t passthru_info;
+ unsigned cap_flags = 0;
+ char * conn_env_str = NULL;
+
+ TESTING("Async VOL props");
+
+ /* Retrieve the file access property for testing */
+ fapl_id = h5_fileaccess();
+
+ /* Test 'capability flags' property */
+
+ /* Test query w/NULL for cap_flags parameter */
+ if (H5Pget_vol_cap_flags(fapl_id, NULL) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Override possible environment variable & re-initialize default VOL connector */
+ conn_env_str = HDgetenv("HDF5_VOL_CONNECTOR");
+ if (conn_env_str) {
+ if (NULL == (conn_env_str = HDstrdup(conn_env_str)))
+ TEST_ERROR
+ if (HDunsetenv("HDF5_VOL_CONNECTOR") < 0)
+ TEST_ERROR
+ if (H5VL__reparse_def_vol_conn_variable_test() < 0)
+ TEST_ERROR
+ } /* end if */
+
+ /* Test query w/default VOL, which should indicate no async, since native connector
+ * doesn't support async.
+ */
+ if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0)
+ FAIL_STACK_ERROR;
+ if ((cap_flags & H5VL_CAP_FLAG_ASYNC) > 0)
+ TEST_ERROR
+ if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) == 0)
+ TEST_ERROR
+
+ /* Close FAPL */
+ if (H5Pclose(fapl_id) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Register a fake VOL connector that sets the async capability flag */
+ if ((vol_id = H5VLregister_connector(&fake_async_vol_g, H5P_DEFAULT)) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Set environment variable to use 'fake async' connector & re-init default connector */
+ if (HDsetenv("HDF5_VOL_CONNECTOR", "fake_async", TRUE) < 0)
+ TEST_ERROR
+ if (H5VL__reparse_def_vol_conn_variable_test() < 0)
+ TEST_ERROR
+
+ /* Retrieve the file access property again */
+ fapl_id = h5_fileaccess();
+
+ /* Test query w/fake async VOL, which should succeed */
+ cap_flags = 0;
+ if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0)
+ FAIL_STACK_ERROR;
+ if ((cap_flags & H5VL_CAP_FLAG_ASYNC) == 0)
+ TEST_ERROR
+ if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) > 0)
+ TEST_ERROR
+
+ /* Reset environment variable & re-init default connector */
+ if (HDunsetenv("HDF5_VOL_CONNECTOR") < 0)
+ TEST_ERROR
+ if (H5VL__reparse_def_vol_conn_variable_test() < 0)
+ TEST_ERROR
+
+ /* Close FAPL */
+ if (H5Pclose(fapl_id) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Retrieve the file access property again */
+ fapl_id = h5_fileaccess();
+
+ /* Set the VOL connector for the FAPL to the fake async connector */
+ if (H5Pset_vol(fapl_id, vol_id, NULL) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Test query w/fake async VOL, which should succeed */
+ cap_flags = 0;
+ if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0)
+ FAIL_STACK_ERROR;
+ if ((cap_flags & H5VL_CAP_FLAG_ASYNC) == 0)
+ TEST_ERROR
+ if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) > 0)
+ TEST_ERROR
+
+ /* Stack the [internal] passthrough VOL connector on top of the fake async connector */
+ passthru_info.under_vol_id = vol_id;
+ passthru_info.under_vol_info = NULL;
+ if (H5Pset_vol(fapl_id, H5VL_PASSTHRU, &passthru_info) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Test query w/passthru -> fake async VOL, which should succeed */
+ cap_flags = 0;
+ if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0)
+ FAIL_STACK_ERROR;
+ if ((cap_flags & H5VL_CAP_FLAG_ASYNC) == 0)
+ TEST_ERROR
+ if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) > 0)
+ TEST_ERROR
+
+ /* Unregister the fake async VOL ID */
+ if (H5VLunregister_connector(vol_id) < 0)
+ TEST_ERROR;
+
+ /* Close FAPL */
+ if (H5Pclose(fapl_id) < 0)
+ FAIL_STACK_ERROR;
+
+ /* Restore environment variable, if there was one */
+ if (conn_env_str) {
+ if (HDsetenv("HDF5_VOL_CONNECTOR", conn_env_str, TRUE) < 0)
+ TEST_ERROR
+ HDfree(conn_env_str);
+
+ if (H5VL__reparse_def_vol_conn_variable_test() < 0)
+ TEST_ERROR
+ } /* end if */
+
+ PASSED();
+
+ return SUCCEED;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Pclose(fapl_id);
+ H5VLunregister_connector(vol_id);
+ }
+ H5E_END_TRY;
+ HDfree(conn_env_str);
+
+ return FAIL;
+} /* end test_async_vol_props() */
+
/*-------------------------------------------------------------------------
* Function: main
*
@@ -1201,6 +2121,7 @@ main(void)
HDputs("Testing basic Virtual Object Layer (VOL) functionality.");
nerrors += test_vol_registration() < 0 ? 1 : 0;
+ nerrors += test_register_opt_operation() < 0 ? 1 : 0;
nerrors += test_native_vol_init() < 0 ? 1 : 0;
nerrors += test_basic_file_operation(env_h5_drvr) < 0 ? 1 : 0;
nerrors += test_basic_group_operation() < 0 ? 1 : 0;
@@ -1209,6 +2130,7 @@ main(void)
nerrors += test_basic_object_operation() < 0 ? 1 : 0;
nerrors += test_basic_link_operation() < 0 ? 1 : 0;
nerrors += test_basic_datatype_operation() < 0 ? 1 : 0;
+ nerrors += test_async_vol_props() < 0 ? 1 : 0;
if (nerrors) {
HDprintf("***** %d Virtual Object Layer TEST%s FAILED! *****\n", nerrors, nerrors > 1 ? "S" : "");