diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/CMakeTests.cmake | 2 | ||||
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | test/chunk_info.c | 6 | ||||
-rw-r--r-- | test/direct_chunk.c | 94 | ||||
-rw-r--r-- | test/dsets.c | 369 | ||||
-rw-r--r-- | test/event_set.c | 66 | ||||
-rw-r--r-- | test/filter_plugin1_dsets.c | 2 | ||||
-rw-r--r-- | test/filter_plugin2_dsets.c | 2 | ||||
-rw-r--r-- | test/filter_plugin3_dsets.c | 2 | ||||
-rw-r--r-- | test/filter_plugin4_groups.c | 2 | ||||
-rw-r--r-- | test/h5test.h | 3 | ||||
-rw-r--r-- | test/links.c | 8 | ||||
-rw-r--r-- | test/null_vol_connector.c | 2 | ||||
-rw-r--r-- | test/tfile.c | 1 | ||||
-rw-r--r-- | test/trefstr.c | 2 | ||||
-rw-r--r-- | test/vol.c | 926 |
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 */ @@ -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(®_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" : ""); |