mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-12-03 02:32:04 +08:00
7863 lines
234 KiB
C
7863 lines
234 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* Copyright by The HDF Group. *
|
|
* All rights reserved. *
|
|
* *
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
* terms governing use, modification, and redistribution, is contained in *
|
|
* the COPYING file, which can be found at the root of the source code *
|
|
* distribution tree, or in https://www.hdfgroup.org/licenses. *
|
|
* If you do not have access to either file, you may request a copy from *
|
|
* help@hdfgroup.org. *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/***********************************************************
|
|
*
|
|
* Test program: swmr
|
|
*
|
|
* To test new public routines from SWMR project:
|
|
* H5Pget/set_metadata_read_attempts()
|
|
* H5Fget_metadata_read_retry_info()
|
|
* H5Fstart_swmr_write()
|
|
* H5Pget/set_object_flush_cb()
|
|
* H5Pget/set_append_flush()
|
|
*
|
|
*************************************************************/
|
|
|
|
#include "h5test.h"
|
|
#include "H5Iprivate.h"
|
|
#include "H5VLprivate.h" /* Virtual Object Layer */
|
|
|
|
/*
|
|
* This file needs to access private information from the H5F package.
|
|
* This file also needs to access the file, file driver, dataset,
|
|
* and object header testing code.
|
|
*/
|
|
#define H5F_FRIEND /*suppress error about including H5Fpkg */
|
|
#define H5F_TESTING
|
|
#include "H5Fpkg.h" /* File access */
|
|
|
|
#define H5D_FRIEND /*suppress error about including H5Dpkg */
|
|
#define H5D_TESTING
|
|
#include "H5Dpkg.h" /* Datasets */
|
|
|
|
#define H5FD_FRIEND /*suppress error about including H5FDpkg */
|
|
#define H5FD_TESTING
|
|
#include "H5FDpkg.h" /* File drivers */
|
|
|
|
#define H5O_FRIEND /*suppress error about including H5Opkg */
|
|
#define H5O_TESTING
|
|
#include "H5Opkg.h" /* Object headers */
|
|
|
|
static const char *FILENAME[] = {"swmr0", /* 0 */
|
|
"swmr1", /* 1 */
|
|
"swmr2", /* 2 */
|
|
NULL};
|
|
|
|
#define NAME_BUF_SIZE 1024 /* Length of file name */
|
|
|
|
/* Epsilon for floating-point comparisons */
|
|
#define FP_EPSILON 0.000001F
|
|
|
|
/* Tests for H5Pget/set_metadata_read_attempts(), H5Fget_metadata_read_retry_info */
|
|
static int test_metadata_read_attempts(hid_t in_fapl);
|
|
static int test_metadata_read_retry_info(hid_t in_fapl);
|
|
|
|
/* Tests for H5Fstart_swmr_write() */
|
|
static int test_start_swmr_write(hid_t in_fapl, bool new_format);
|
|
static int test_err_start_swmr_write(hid_t in_fapl, bool new_format);
|
|
static int test_start_swmr_write_concur(hid_t in_fapl, bool new_format);
|
|
static int test_start_swmr_write_stress_ohdr(hid_t in_fapl);
|
|
static int test_start_swmr_write_persist_dapl(hid_t in_fapl);
|
|
|
|
/* Tests for H5Pget/set_object_flush_cb() */
|
|
static herr_t flush_cb(hid_t obj_id, void *_udata);
|
|
static int test_object_flush_cb(hid_t in_fapl);
|
|
|
|
/* Tests for H5Pget/set_append_flush() */
|
|
static herr_t append_cb(hid_t dset_id, hsize_t *cur_dims, void *_udata);
|
|
static herr_t append_cb2(hid_t dset_id, hsize_t *cur_dims, void *_udata);
|
|
static int test_append_flush_generic(void);
|
|
static int test_append_flush_dataset_chunked(hid_t in_fapl);
|
|
static int test_append_flush_dataset_fixed(hid_t in_fapl);
|
|
static int test_append_flush_dataset_multiple(hid_t in_fapl);
|
|
|
|
/* Tests for file open flags/SWMR flags: single process access */
|
|
static int test_file_lock_same(hid_t fapl);
|
|
static int test_file_lock_swmr_same(hid_t fapl);
|
|
|
|
/* Tests for file open flags/SWMR flags: concurrent process access */
|
|
static int test_file_lock_concur(hid_t fapl);
|
|
static int test_file_lock_swmr_concur(hid_t fapl);
|
|
|
|
/* Test file lock environment variable */
|
|
static int test_file_locking(hid_t in_fapl, bool turn_locking_on, bool env_var_override);
|
|
|
|
/* Tests for SWMR VFD flag */
|
|
static int test_swmr_vfd_flag(void);
|
|
|
|
/* Tests for H5Drefresh: concurrent access */
|
|
static int test_refresh_concur(hid_t in_fapl, bool new_format);
|
|
|
|
/* Tests for multiple opens of files and datasets with H5Drefresh() & H5Fstart_swmr_write(): same process */
|
|
static int test_multiple_same(hid_t in_fapl, bool new_format);
|
|
|
|
/*
|
|
* Tests for H5Pget/set_metadata_read_attemps(), H5Fget_metadata_read_retry_info()
|
|
*/
|
|
|
|
/*
|
|
* test_metadata_read_attempts():
|
|
*
|
|
* Checks the following two public routines work as specified:
|
|
* H5Pset_metadata_read_attempts()
|
|
* H5Pget_metadata_read_attempts()
|
|
*/
|
|
static int
|
|
test_metadata_read_attempts(hid_t in_fapl)
|
|
{
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list */
|
|
hid_t file_fapl = H5I_INVALID_HID; /* The file's access property list */
|
|
hid_t fid = H5I_INVALID_HID, fid1 = H5I_INVALID_HID, fid2 = H5I_INVALID_HID; /* File IDs */
|
|
hid_t driver_id = H5I_INVALID_HID; /* ID for this VFD */
|
|
unsigned long driver_flags = 0; /* VFD feature flags */
|
|
bool compat_w_default_vfd; /* current VFD compat w/ H5P_DEFAULT? */
|
|
unsigned attempts; /* The # of read attempts */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
herr_t ret; /* Generic return value */
|
|
|
|
/* Output message about test being performed */
|
|
TESTING("H5Pget/set_metadata_read_attempts()");
|
|
|
|
/* Check if the driver is compatible with the default VFD.
|
|
* Most of the tests will attempt to create and open files with both the
|
|
* VFD specified in the passed-in fapl and the default VFD. Since this
|
|
* will clearly not work with VFDs that are not compatible with the default
|
|
* fapl (e.g.: split/multi), we just skip this entire test.
|
|
*/
|
|
if ((driver_id = H5Pget_driver(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5FDdriver_query(driver_id, &driver_flags) < 0)
|
|
FAIL_STACK_ERROR;
|
|
compat_w_default_vfd = (driver_flags & H5FD_FEAT_DEFAULT_VFD_COMPATIBLE) ? true : false;
|
|
|
|
if (!compat_w_default_vfd) {
|
|
SKIPPED();
|
|
puts(" The current VFD is not compatible with the default VFD.");
|
|
return 0;
|
|
}
|
|
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/*
|
|
* Set A:
|
|
* Tests on verifying the # of read attempts when:
|
|
* --setting/getting read attempts from a
|
|
* file access property list.
|
|
*/
|
|
/* Get # of read attempts -- should be the default: 1 */
|
|
if (H5Pget_metadata_read_attempts(fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != 1)
|
|
TEST_ERROR;
|
|
|
|
/* Set the # of read attempts to 0--should fail */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Pset_metadata_read_attempts(fapl, 0);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set the # of read attempts to a # > 0--should succeed */
|
|
if (H5Pset_metadata_read_attempts(fapl, 9) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve the # of read attempts -- should be 9 */
|
|
if (H5Pget_metadata_read_attempts(fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != 9)
|
|
TEST_ERROR;
|
|
|
|
/* Set the # of read attempts to the default for non-SWMR access: H5F_METADATA_READ_ATTEMPTS --should
|
|
* succeed */
|
|
if (H5Pset_metadata_read_attempts(fapl, H5F_METADATA_READ_ATTEMPTS) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve the # of read attempts -- should be H5F_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Set the # of read attempts to the default for SWMR access: H5F_SWMR_METADATA_READ_ATEMPTS --should
|
|
* succeed */
|
|
if (H5Pset_metadata_read_attempts(fapl, H5F_SWMR_METADATA_READ_ATTEMPTS) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve the # of read attempts -- should be H5F_SWMR_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_SWMR_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Set B:
|
|
* Tests on verifying read attempts when:
|
|
* --create a file with non-SWMR access
|
|
* --opening files with SWMR access
|
|
* --using default or non-default file access property list
|
|
*/
|
|
/* Test 1 */
|
|
/* Create a file with non-SWMR access and default fapl */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file's fapl -- should be H5F_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test 2 */
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with SWMR access and default read attempts */
|
|
if ((fid = H5Fopen(filename, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file's fapl -- should be H5F_SWMR_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_SWMR_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test 3 */
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the # of read attempts */
|
|
if (H5Pset_metadata_read_attempts(fapl, 9) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with SWMR access and fapl (non-default & set to 9) */
|
|
if ((fid = H5Fopen(filename, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file's fapl -- should be 9 */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != 9)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test 4 */
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the # of read attempts */
|
|
if (H5Pset_metadata_read_attempts(fapl, 1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with SWMR access and fapl (non-default & set to 1) */
|
|
if ((fid = H5Fopen(filename, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file fapl -- should be 1 */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != 1)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test 5 */
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with SWMR_READ and fapl (non-default read attempts but unset) */
|
|
if ((fid = H5Fopen(filename, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file's fapl -- should be H5F_SWMR_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_SWMR_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Set C:
|
|
* Tests on verifying read attempts when:
|
|
* --create a file with SWMR access
|
|
* --opening files with non-SWMR access
|
|
* --using default or non-default file access property list
|
|
*/
|
|
/* Test 1 */
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a file with non-SWMR access and default read attempts */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file's fapl -- should be H5F_SWMR_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_SWMR_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test 2 */
|
|
/* Open the file with non-SWMR access and default fapl */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file's fapl -- should be H5F_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test 3 */
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the # of read attempts */
|
|
if (H5Pset_metadata_read_attempts(fapl, 9) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with non-SWMR access and fapl (non-default & set to 9) */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file's fapl -- should be 9 */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != 9)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test 4 */
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the # of read attempts */
|
|
if (H5Pset_metadata_read_attempts(fapl, 1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with non-SWMR access and fapl (non-default & set to 1) */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file fapl -- should be 1 */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != 1)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Test 5 */
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with non-SWMR_READ and fapl (non-default but unset) */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file's fapl -- should be H5F_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the # of read attempts */
|
|
if (H5Pset_metadata_read_attempts(fapl, 9) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open file again with non-SWMR access and default fapl */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file fapl -- should be H5F_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open file again with SWMR access and default read attempts */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file fapl -- should be H5F_SWMR_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_SWMR_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Set D:
|
|
* Tests on verifying read attempts when:
|
|
* --create with non-SWMR access
|
|
* --opening files with SWMR access
|
|
* --H5reopen the files
|
|
*/
|
|
|
|
/* Create a file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open file again with SWMR access and default read attempts */
|
|
if ((fid1 = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the # of read attempts */
|
|
if (H5Pset_metadata_read_attempts(fapl, 9) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open file again with SWMR access and fapl (non-default & set to 9) */
|
|
if ((fid2 = H5Fopen(filename, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open fid1 */
|
|
if ((fid = H5Freopen(fid1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file fapl -- should be H5F_SWMR_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_SWMR_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open fid2 */
|
|
if ((fid = H5Freopen(fid2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file fapl -- should be H5F_SWMR_METADATA_READ_ATTEMPTS, not 9 */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_SWMR_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close all the files */
|
|
if (H5Fclose(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Set E:
|
|
* Tests on verifying read attempts when:
|
|
* --create with SWMR access
|
|
* --opening files with non-SWMR access
|
|
* --H5reopen the files
|
|
*/
|
|
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open file again with non-SWMR access and default fapl */
|
|
if ((fid1 = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a copy of the parameter fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the # of read attempts */
|
|
if (H5Pset_metadata_read_attempts(fapl, 9) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open file again with non-SWMR access and fapl (non-default & set to 9) */
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close fapl */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open fid1 */
|
|
if ((fid = H5Freopen(fid1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file fapl -- should be H5F_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open fid2 */
|
|
if ((fid = H5Freopen(fid2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get file's fapl */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from file fapl -- should be H5F_METADATA_READ_ATTEMPTS */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (attempts != H5F_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file's fapl */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close all the files */
|
|
if (H5Fclose(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
H5Pclose(file_fapl);
|
|
H5Fclose(fid);
|
|
H5Fclose(fid1);
|
|
H5Fclose(fid2);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
|
|
} /* test_metadata_read_attempts() */
|
|
|
|
/*
|
|
* test_metadata_read_retry_info():
|
|
*
|
|
* Checks whether the public routine H5Fget_metadata_read_retry_info
|
|
* works as specified.
|
|
*
|
|
*/
|
|
static int
|
|
test_metadata_read_retry_info(hid_t in_fapl)
|
|
{
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list */
|
|
hid_t new_fapl = H5I_INVALID_HID; /* File access property list */
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fid1 = H5I_INVALID_HID; /* File ID */
|
|
H5F_retry_info_t info, info1; /* The collection of metadata retries */
|
|
H5F_t *f = NULL, *f1 = NULL; /* Internal file object pointers */
|
|
unsigned i, j, n; /* Local index variables */
|
|
hid_t did1 = H5I_INVALID_HID; /* Dataset ID */
|
|
hid_t did2 = H5I_INVALID_HID; /* Dataset ID */
|
|
hid_t sid = H5I_INVALID_HID; /* Dataspace ID */
|
|
hid_t dcpl = H5I_INVALID_HID; /* Dataset creation property list */
|
|
hsize_t dims[2] = {6, 10}; /* Dataset dimensions */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
int buf[6][10], chkbuf1[6][10], chkbuf2[6][10]; /* Buffers for data */
|
|
hsize_t max_dims_1un[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Dataset maximum dimensions */
|
|
hsize_t max_dims_2un[2] = {500, H5S_UNLIMITED}; /* Dataset maximum dimensions */
|
|
hsize_t chunk_dims[2] = {2, 2}; /* Chunk dimensions */
|
|
|
|
/* Output message about test being performed */
|
|
TESTING("H5Fset_metadata_read_retry_info()");
|
|
|
|
/* Get a copy of the parameter in_fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a file without SWMR access */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a chunked dataset with 1 unlimited dimension: extensible array indexing will be used */
|
|
if ((sid = H5Screate_simple(2, dims, max_dims_1un)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 2, chunk_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did1 = H5Dcreate2(fid, "DSET_1UNLIM", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a chunked dataset with 2 unlimited dimension: v2 Btree indexing will be used */
|
|
if ((sid = H5Screate_simple(2, dims, max_dims_2un)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 2, chunk_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did2 = H5Dcreate2(fid, "DSET_2UNLIM", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Initialize buffer data */
|
|
for (i = n = 0; i < 6; i++)
|
|
for (j = 0; j < 10; j++)
|
|
buf[i][j] = (int)n++;
|
|
|
|
/* Write to the 2 datasets */
|
|
if (H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dwrite(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 1: tests on nbins
|
|
*/
|
|
/*
|
|
* Open a file without SWMR access, default # of read attempts--
|
|
* info.nbins should be 0
|
|
* info.retries should all be NULL
|
|
*/
|
|
/* Open the file without SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset */
|
|
if ((did1 = H5Dopen2(fid, "DSET_1UNLIM", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, chkbuf1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset */
|
|
if ((did2 = H5Dopen2(fid, "DSET_2UNLIM", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dread(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, chkbuf2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve retries information */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 0 */
|
|
if (info.nbins != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Should be all NULL */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++)
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Open a file with SWMR access, default # of read attempts--
|
|
* info.nbins should be 2
|
|
* info.retries should all be NULL
|
|
*/
|
|
/* Open the file with SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve retries information */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 2 */
|
|
if (info.nbins != 2)
|
|
TEST_ERROR;
|
|
|
|
/* Should be all NULL */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++)
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Open a file with SWMR access, # of read_attempts is 10:
|
|
* info.nbins should be 1
|
|
* info.retries should all be NULL
|
|
*/
|
|
if ((new_fapl = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Pset_metadata_read_attempts(new_fapl, 10) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve retry information */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 1 */
|
|
if (info.nbins != 1)
|
|
TEST_ERROR;
|
|
|
|
/* Should be all NULL */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++)
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(new_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Open a file with SWMR access, # of read attempts is 101:
|
|
* info.nbins should be 3
|
|
* info.retries should all be NULL
|
|
*/
|
|
if ((new_fapl = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_metadata_read_attempts(new_fapl, 101) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve retry information */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 3 */
|
|
if (info.nbins != 3)
|
|
TEST_ERROR;
|
|
|
|
/* Should be all NULL */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++)
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(new_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Open a file with SWMR access, # of read_attempts is 10000:
|
|
* info.nbins should be 4
|
|
* info.retries should all be NULL
|
|
*/
|
|
if ((new_fapl = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Pset_metadata_read_attempts(new_fapl, 10000) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve retry information */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 4 */
|
|
if (info.nbins != 4)
|
|
TEST_ERROR;
|
|
|
|
/* Should be all NULL */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++)
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(new_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Open a file with SWMR access, # of read_attempts is 1:
|
|
* info.nbins should be 0
|
|
* info.retries should all be NULL
|
|
*/
|
|
if ((new_fapl = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Pset_metadata_read_attempts(new_fapl, 1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve retry information */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 0 */
|
|
if (info.nbins != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Should be all NULL */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++)
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(new_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 2: tests on retries info
|
|
*/
|
|
|
|
/* Open the file with SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset */
|
|
if ((did1 = H5Dopen2(fid, "DSET_1UNLIM", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read data from the dataset */
|
|
if (H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, chkbuf1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset */
|
|
if ((did2 = H5Dopen2(fid, "DSET_2UNLIM", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read data from the dataset */
|
|
if (H5Dread(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, chkbuf2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve retry information */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 2 */
|
|
if (info.nbins != 2)
|
|
TEST_ERROR;
|
|
|
|
/* Should be all NULL */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++)
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if ((f = (H5F_t *)H5VL_object(fid)) == NULL)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Increment 1st set of retries for metadata items:
|
|
* a) v2 B-tree leaf node--retries[4][1]
|
|
* b) Extensive array data block--retries[15][1]
|
|
* c) File's superblock--retries[20][0]
|
|
*/
|
|
|
|
/* v2 B-tree leaf node: log retry 99 for 500 times */
|
|
for (i = 0; i < 500; i++) {
|
|
if (H5F_track_metadata_read_retries(f, H5AC_BT2_LEAF_ID, 99) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
|
|
/* Extensive array data block: log retry 10 for 1000 times */
|
|
for (i = 0; i < 1000; i++)
|
|
if (H5F_track_metadata_read_retries(f, H5AC_EARRAY_DBLOCK_ID, 10) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* File's superblock: log retry 1 for 1 time */
|
|
if (H5F_track_metadata_read_retries(f, H5AC_SUPERBLOCK_ID, 1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the collection of metadata read retries */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify retries for v2 B-tree leaf node */
|
|
if (info.retries[4][0] != 0)
|
|
TEST_ERROR;
|
|
if (info.retries[4][1] != 500)
|
|
TEST_ERROR;
|
|
|
|
/* Verify retries for extensive array data block */
|
|
if (info.retries[15][0] != 0)
|
|
TEST_ERROR;
|
|
if (info.retries[15][1] != 1000)
|
|
TEST_ERROR;
|
|
|
|
/* Verify retries for file's superblock */
|
|
if (info.retries[20][0] != 1)
|
|
TEST_ERROR;
|
|
if (info.retries[20][1] != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Free memory for info.retries */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++) {
|
|
if (info.retries[i] != NULL)
|
|
H5free_memory(info.retries[i]);
|
|
}
|
|
|
|
/*
|
|
* Increment 2nd set of retries for metadata items:
|
|
* a) Object header--retries[0][0]
|
|
* b) Extensive array datablock--retries[15][0]
|
|
* c) Fixed array header--retries[17][1]
|
|
* d) File's superblock--retries[20][0]
|
|
*/
|
|
|
|
/* Object header: log retry 5 for 5 times */
|
|
for (i = 0; i < 5; i++) {
|
|
if (H5F_track_metadata_read_retries(f, H5AC_OHDR_ID, 5) < 0)
|
|
TEST_ERROR;
|
|
}
|
|
|
|
/* Extensive array data block: log retry 4 for 1 time */
|
|
if (H5F_track_metadata_read_retries(f, H5AC_EARRAY_DBLOCK_ID, 4) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Fixed array header : log retry 50 for 10000 times */
|
|
for (i = 0; i < 10000; i++) {
|
|
if (H5F_track_metadata_read_retries(f, H5AC_FARRAY_HDR_ID, 50) < 0)
|
|
TEST_ERROR;
|
|
}
|
|
|
|
/* File's superblock: log retry 1 for 1 more time */
|
|
if (H5F_track_metadata_read_retries(f, H5AC_SUPERBLOCK_ID, 1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the collection of metadata read retries */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Verify info has both previous + current retries information:
|
|
*/
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++) {
|
|
switch (i) {
|
|
case 0: /* Object header */
|
|
if (info.retries[i][0] != 5)
|
|
TEST_ERROR;
|
|
if (info.retries[i][1] != 0)
|
|
TEST_ERROR;
|
|
break;
|
|
|
|
case 4: /* v2 B-tree leaf node */
|
|
if (info.retries[i][0] != 0)
|
|
TEST_ERROR;
|
|
if (info.retries[i][1] != 500)
|
|
TEST_ERROR;
|
|
break;
|
|
|
|
case 15: /* Extensive array data block */
|
|
if (info.retries[i][0] != 1)
|
|
TEST_ERROR;
|
|
if (info.retries[i][1] != 1000)
|
|
TEST_ERROR;
|
|
break;
|
|
|
|
case 17: /* Fixed array header */
|
|
if (info.retries[i][0] != 0)
|
|
TEST_ERROR;
|
|
if (info.retries[i][1] != 10000)
|
|
TEST_ERROR;
|
|
break;
|
|
|
|
case 20: /* File's superblock */
|
|
if (info.retries[i][0] != 2)
|
|
TEST_ERROR;
|
|
if (info.retries[i][1] != 0)
|
|
TEST_ERROR;
|
|
break;
|
|
|
|
default:
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Free memory for info.retries */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++)
|
|
if (info.retries[i] != NULL)
|
|
H5free_memory(info.retries[i]);
|
|
|
|
/* Closing */
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a copy of the file access property list */
|
|
if ((new_fapl = H5Pcopy(fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the number of metadata read attempts to 101 */
|
|
if (H5Pset_metadata_read_attempts(new_fapl, 101) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if ((f = (H5F_t *)H5VL_object(fid)) == NULL)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* File's superblock: log retry 1 for 1 time */
|
|
if (H5F_track_metadata_read_retries(f, H5AC_SUPERBLOCK_ID, 1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the collection of metadata read retries */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 3 */
|
|
if (info.nbins != 3)
|
|
TEST_ERROR;
|
|
|
|
/* Verify retries info */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++) {
|
|
switch (i) {
|
|
case 20: /* File's superblock */
|
|
if (info.retries[i][0] != 1)
|
|
TEST_ERROR;
|
|
if (info.retries[i][1] != 0)
|
|
TEST_ERROR;
|
|
if (info.retries[i][2] != 0)
|
|
TEST_ERROR;
|
|
break;
|
|
|
|
default:
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Free memory */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++)
|
|
if (info.retries[i] != NULL)
|
|
H5free_memory(info.retries[i]);
|
|
|
|
/* Closing */
|
|
if (H5Pclose(new_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 3: Tests on retrieving the collection of retries
|
|
* when H5Fopen and H5Freopen the same file.
|
|
*/
|
|
|
|
/*
|
|
* Open a file without SWMR access, default # of read attempts--
|
|
* H5Freopen the same file--
|
|
* Both files should:
|
|
* nbins should be 0
|
|
* retries should all be NULL
|
|
*/
|
|
/* Open the file without SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open fid */
|
|
if ((fid1 = H5Freopen(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve retries information for fid */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve retries information for fid1*/
|
|
if (H5Fget_metadata_read_retry_info(fid1, &info1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 0 */
|
|
if (info.nbins != 0)
|
|
TEST_ERROR;
|
|
if (info1.nbins != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Should be all NULL */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++) {
|
|
if (info.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
if (info1.retries[i] != NULL)
|
|
TEST_ERROR;
|
|
}
|
|
|
|
/* Closing */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Open a file with SWMR access, default # of read attempts:
|
|
* --increment retries for metadata item: fixed array data block page (retries[19][0])
|
|
* H5Freopen the same file:
|
|
* --increment retries for metadata item: free-space sections (retries[9][1])--
|
|
*/
|
|
/* Open the file with SWMR access */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object for fid */
|
|
if ((f = (H5F_t *)H5VL_object(fid)) == NULL)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Re-open fid */
|
|
if ((fid1 = H5Freopen(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object for fid1 */
|
|
if ((f1 = (H5F_t *)H5VL_object(fid1)) == NULL)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* For fid: fixed array data block page--log retry 9 for 500 times */
|
|
for (i = 0; i < 500; i++) {
|
|
if (H5F_track_metadata_read_retries(f, H5AC_FARRAY_DBLK_PAGE_ID, 9) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
|
|
/* For fid1: free-space sections--log retry 99 for 1000 times */
|
|
for (i = 0; i < 1000; i++) {
|
|
if (H5F_track_metadata_read_retries(f1, H5AC_FSPACE_SINFO_ID, 99) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
|
|
/* Retrieve the collection of metadata read retries for fid */
|
|
if (H5Fget_metadata_read_retry_info(fid, &info) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the collection of metadata read retries for fid1 */
|
|
if (H5Fget_metadata_read_retry_info(fid1, &info1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify nbins for fid & fid1: should be 2 */
|
|
if (info.nbins != 2)
|
|
TEST_ERROR;
|
|
if (info1.nbins != 2)
|
|
TEST_ERROR;
|
|
|
|
/* Verify retries for fid: fixed array data block page */
|
|
if (info.retries[19][0] != 500)
|
|
TEST_ERROR;
|
|
if (info.retries[19][1] != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify retries for fid: free-space sections */
|
|
/* (Since file was re-opened) */
|
|
if (info.retries[9][0] != 0)
|
|
TEST_ERROR;
|
|
if (info.retries[9][1] != 1000)
|
|
TEST_ERROR;
|
|
|
|
/* Verify retries for fid1: free-space sections */
|
|
if (info1.retries[9][0] != 0)
|
|
TEST_ERROR;
|
|
if (info1.retries[9][1] != 1000)
|
|
TEST_ERROR;
|
|
|
|
/* Verify retries for fid1: fixed array data block page */
|
|
/* (Since file was re-opened) */
|
|
if (info1.retries[19][0] != 500)
|
|
TEST_ERROR;
|
|
if (info1.retries[19][1] != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Free memory for info.retries and info1.retries */
|
|
for (i = 0; i < H5F_NUM_METADATA_READ_RETRY_TYPES; i++) {
|
|
if (info.retries[i] != NULL)
|
|
H5free_memory(info.retries[i]);
|
|
if (info1.retries[i] != NULL)
|
|
H5free_memory(info1.retries[i]);
|
|
} /* end for */
|
|
|
|
/* Closing */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
H5Pclose(new_fapl);
|
|
H5Dclose(did1);
|
|
H5Dclose(did2);
|
|
H5Sclose(sid);
|
|
H5Pclose(dcpl);
|
|
H5Fclose(fid);
|
|
H5Fclose(fid1);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
|
|
} /* test_metadata_read_retry_info() */
|
|
|
|
/*
|
|
* Tests for H5Fstart_swmr_write()
|
|
*/
|
|
|
|
/*
|
|
* test_start_swmr_write():
|
|
*
|
|
* Verify SWMR writing is enabled via H5Fstart_swmr_write():
|
|
* Mainly test for file created with SWMR_WRITE + with/without latest format:
|
|
* --file will have v3 superblock and all latest version support enabled
|
|
*
|
|
* (A) Creating a file
|
|
* Create a file with SWMR_WRITE + non-latest-format
|
|
* Create a chunked dataset "dataset1" in the file -- should be using latest chunk indexing
|
|
* Should fail to enable SWMR as the file is already in SWMR writing mode
|
|
* Close the file
|
|
*
|
|
* (B) Opening a file
|
|
* Open the file with write + non-latest-format
|
|
* --file has v3 superblock and all latest version support enabled
|
|
* Open dataset "dataset1" 3 times--keep it open
|
|
* Write to "dataset1"
|
|
* Create a group in the file
|
|
* Create a chunked dataset "dataset2" in the group--should be using latest chunk indexing--keep it open
|
|
* Should succeed in enabling SWMR
|
|
* Should succeed in reading from multiple opens of "dataset1"
|
|
* Close multiple opens of "dataset1"
|
|
* Close "dataset2"
|
|
* Create "dataset3"--should be using latest chunk indexing
|
|
* Close "dataset3"
|
|
* Close the group and file
|
|
*/
|
|
static int
|
|
test_start_swmr_write(hid_t in_fapl, bool new_format)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property */
|
|
hid_t gid = H5I_INVALID_HID; /* Group ID */
|
|
hid_t dcpl = H5I_INVALID_HID; /* Dataset creation property */
|
|
hid_t file_fapl = H5I_INVALID_HID; /* File access property for the file */
|
|
hid_t did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID, did3 = H5I_INVALID_HID; /* Dataset IDs */
|
|
hid_t did1_a = H5I_INVALID_HID, did1_b = H5I_INVALID_HID;
|
|
hid_t sid1 = H5I_INVALID_HID, sid2 = H5I_INVALID_HID, sid3 = H5I_INVALID_HID; /* Dataspace IDs */
|
|
hsize_t dim[1] = {1}; /* Dimension sizes */
|
|
hsize_t max_dim[1] = {H5S_UNLIMITED}; /* Maximum dimension sizes */
|
|
hsize_t chunk_dim[1] = {2}; /* Chunk dimension sizes */
|
|
hsize_t dim2[2] = {5, 10}; /* Dimension sizes */
|
|
hsize_t max_dim2[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dimension sizes */
|
|
hsize_t chunk_dim2[2] = {2, 7}; /* Chunk dimension sizes */
|
|
H5D_chunk_index_t idx_type; /* Dataset chunk index type */
|
|
int wdata = 99; /* Data to write */
|
|
int rdata; /* Data read */
|
|
unsigned attempts; /* The retrieved # of read attempts */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
herr_t ret; /* Return value */
|
|
|
|
/* Get a copy of the parameter fapl (non-latest-format) */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (new_format) {
|
|
TESTING("H5Fstart_swmr_write() when creating/opening a file with latest format");
|
|
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
else {
|
|
TESTING("H5Fstart_swmr_write() when creating/opening a file without latest format");
|
|
} /* end if */
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/*
|
|
* Case A: when creating a file
|
|
*/
|
|
|
|
/* Create the file with SWMR write + non-latest-format */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC | (new_format ? 0 : H5F_ACC_SWMR_WRITE), H5P_DEFAULT,
|
|
fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the file's access_property list */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts from the file's fapl */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 100 */
|
|
if (attempts != (unsigned int)(new_format ? H5F_METADATA_READ_ATTEMPTS : H5F_SWMR_METADATA_READ_ATTEMPTS))
|
|
TEST_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create "dataset1" */
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 1, chunk_dim) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((sid1 = H5Screate_simple(1, dim, max_dim)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did1 = H5Dcreate2(fid, "dataset1", H5T_NATIVE_INT, sid1, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the chunk index type */
|
|
if (H5D__layout_idx_type_test(did1, &idx_type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (idx_type != H5D_CHUNK_IDX_EARRAY)
|
|
FAIL_PUTS_ERROR("should be using extensible array as index");
|
|
|
|
/* Write to the dataset */
|
|
if (H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to enable SWMR for non-latest-format */
|
|
/* Should succeed in enabling SWMR for latest format */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (new_format) {
|
|
if (ret < 0)
|
|
TEST_ERROR;
|
|
}
|
|
else if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Read from the dataset */
|
|
if (H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify the data is correct */
|
|
if (wdata != rdata)
|
|
TEST_ERROR;
|
|
|
|
/* Close "dataset1", dataspace, dataset creation property list */
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the file's access_property list */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 100 */
|
|
if (attempts != H5F_SWMR_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file access property list */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case B: when opening a file
|
|
*/
|
|
|
|
/* Open the file again with write + non-latest-format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the file's access_property list */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 1 */
|
|
if (attempts != H5F_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* open "dataset1", keep it open */
|
|
if ((did1 = H5Dopen2(fid, "dataset1", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* open "dataset1" second time */
|
|
if ((did1_a = H5Dopen2(fid, "dataset1", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* open "dataset1" third time */
|
|
if ((did1_b = H5Dopen2(fid, "dataset1", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to "dataset1" */
|
|
wdata = 88;
|
|
if (H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a group */
|
|
if ((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create "dataset2" in the group, keep it open */
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 2, chunk_dim2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((sid2 = H5Screate_simple(2, dim2, max_dim2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did2 = H5Dcreate2(gid, "dataset2", H5T_NATIVE_INT, sid2, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the chunk index type for "dataset2" */
|
|
if (H5D__layout_idx_type_test(did2, &idx_type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (idx_type != H5D_CHUNK_IDX_BT2)
|
|
FAIL_PUTS_ERROR("should be using v2 B-tree chunk indexing");
|
|
|
|
/* Should succeed in enabling SWMR writing */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the file's access_property list */
|
|
if ((file_fapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the # of read attempts */
|
|
if (H5Pget_metadata_read_attempts(file_fapl, &attempts) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should be 100 */
|
|
if (attempts != H5F_SWMR_METADATA_READ_ATTEMPTS)
|
|
TEST_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(file_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
rdata = 0;
|
|
/* Read from "dataset1" via did1_b (multiple opens) */
|
|
if (H5Dread(did1_b, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (wdata != rdata)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did1_b) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read from "dataset1" */
|
|
rdata = 0;
|
|
if (H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (wdata != rdata)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
rdata = 0;
|
|
/* Read from "dataset1" via did1_a (multiple opens) */
|
|
if (H5Dread(did1_a, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (wdata != rdata)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did1_a) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close "dataset2", dataspace, dataset creation property list */
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create "dataset3" */
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 2, chunk_dim2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((sid3 = H5Screate_simple(2, dim2, max_dim2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did3 = H5Dcreate2(fid, "dataset3", H5T_NATIVE_INT, sid3, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the chunk index type for "dataset3" */
|
|
if (H5D__layout_idx_type_test(did3, &idx_type) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (idx_type != H5D_CHUNK_IDX_BT2)
|
|
FAIL_PUTS_ERROR("should be using v2 B-tree as index");
|
|
|
|
/* Close "dataset3", dataspace, dataset creation property list */
|
|
if (H5Dclose(did3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the group */
|
|
if (H5Gclose(gid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file access property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(fid);
|
|
H5Pclose(fapl);
|
|
H5Pclose(file_fapl);
|
|
H5Gclose(gid);
|
|
H5Pclose(dcpl);
|
|
H5Dclose(did1);
|
|
H5Dclose(did1_a);
|
|
H5Dclose(did1_b);
|
|
H5Dclose(did2);
|
|
H5Dclose(did3);
|
|
H5Sclose(sid1);
|
|
H5Sclose(sid2);
|
|
H5Sclose(sid3);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_start_swmr_write() */
|
|
|
|
/*
|
|
* test_err_start_swmr_write():
|
|
*
|
|
* Verify failure conditions in enabling SWMR writing mode via H5Fstart_swmr_write():
|
|
* (A) When creating a file:
|
|
* (1) Create a file with SWMR write + with/without latest format
|
|
* --fail to enable SWMR because the file is already in SWMR writing mode
|
|
* If (latest-format):
|
|
* (2a) Create a file with write + latest format and with opened named datatype
|
|
* --fail to enable SWMR because there are opened datatype
|
|
* If !(latest-format):
|
|
* (2b) Create a file with write + non-latest-format
|
|
* --fail to enable SWMR because superblock version is not at least 3
|
|
*
|
|
* (B) When opening a file which is created with write + latest format:
|
|
* (1) Open the file with SWMR write + with/without latest format
|
|
* --fail to enable SWMR because the file is already in SWMR writing mode
|
|
* (2) Open the file with read only + with/without latest format
|
|
* --fail to enable SWMR because the file is not opened with write
|
|
* (3) Open the file with SWMR read only + with/without latest format
|
|
* --fail to enable SWMR because the file is not opened with write
|
|
* (4) Open the file with write + with/without latest format and with opened named datatype/attribute
|
|
* --fail to enable SWMR because there are opened datatype/attribute
|
|
*
|
|
* (C) When doing multiple opens for a file:
|
|
* Create a file with (a) write + latest format or (b) SMWR write + non-latest-format
|
|
* Close the file
|
|
* (1) --Open the file with write + with/without latest format
|
|
* --Enable SWMR writing mode twice
|
|
* --First time succeed, second time fail
|
|
* --Close the file
|
|
(2) --Open the file with write + with/without latest format
|
|
* --Succeed to enable SWMR writing mode
|
|
* --Reopen the same file
|
|
* --fail to enable SWMR writing mode for the reopened file
|
|
* --Close the file
|
|
(3) --Open the file with write + with/without latest format
|
|
* --Open the same file again
|
|
* --succeed to enable SWMR for the first opened file
|
|
* --fail to enable SWMR for the second opened file
|
|
* --Close the file
|
|
*
|
|
* (D) (!new_format): When opening a file which is created with write + non-latest-format:
|
|
* (1) Open the file with SWMR write+latest format
|
|
* --fail to open due to superblock version not 3
|
|
* (2) Open the file with SWMR write+non-latest-format
|
|
* --fail to open due to superblock version not 3
|
|
|
|
* (3) Open the file with write+latest format
|
|
* --fail to enable SWMR due to superblock version not 3
|
|
* (4) Open the file with write+non-latest-format
|
|
* --fail to enable SWMR due to superblock version not 3
|
|
*/
|
|
static int
|
|
test_err_start_swmr_write(hid_t in_fapl, bool new_format)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fid2 = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* A copy of file access property */
|
|
hid_t new_fapl = H5I_INVALID_HID; /* A copy of file access property */
|
|
hid_t gid = H5I_INVALID_HID; /* Group ID */
|
|
hid_t did = H5I_INVALID_HID; /* Dataset ID */
|
|
hid_t sid = H5I_INVALID_HID; /* Dataspace ID */
|
|
hid_t aid = H5I_INVALID_HID; /* Attribute ID */
|
|
hid_t tid = H5I_INVALID_HID; /* Datatype ID */
|
|
hid_t bad_fid = H5I_INVALID_HID; /* Test fid (should never represent a real ID) */
|
|
herr_t ret; /* Return value */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
|
|
/* Create a copy of the input parameter in_fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if ((new_fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(new_fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (new_format) {
|
|
TESTING("H5Fstart_swmr_write() on failure conditions for latest format");
|
|
|
|
if ((fapl = H5Pcopy(new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
else {
|
|
TESTING("H5Fstart_swmr_write() on failure conditions for without latest format");
|
|
}
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/*
|
|
* (A) When creating a file:
|
|
*/
|
|
|
|
/* Case 1 */
|
|
|
|
/* Create the file with SWMR_WRITE + with/without latest format */
|
|
fid = H5Fcreate(filename, H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl);
|
|
|
|
/* Should fail to enable SWMR writing when the file is already in SWMR writing mode */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 2 */
|
|
|
|
if (new_format) {
|
|
|
|
/* Create the file with write + latest format */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create and commit a named datatype */
|
|
if ((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Tcommit2(fid, "TID", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing when there is an opened named datatype */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the datatype */
|
|
if (H5Tclose(tid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should succeed in enabling SWMR writing */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
else {
|
|
|
|
/* Create a file with write + non-latest-format */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing because the file's superblock version is not at least 3 */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
} /* end if */
|
|
|
|
/*
|
|
* (B) When opening a file which is created with the latest format
|
|
*/
|
|
|
|
/* Create a file with write + latest format */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 1 */
|
|
|
|
/* Open the file with SWMR write + with/without latest format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing when the file is already in SWMR writing mode */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 2 */
|
|
|
|
/* Open the file with read only access + with/without latest format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing when the file is opened with read only access */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 3 */
|
|
|
|
/* Open the file file with SWMR read access + with/without latest format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing when the file is opened with SWMR read access only */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 4 */
|
|
|
|
/* Open the file with write + with/without latest format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create and commit a named datatype */
|
|
if ((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Tcommit2(fid, "TID", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create dataspace */
|
|
if ((sid = H5Screate(H5S_SCALAR)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Attach an attribute to the named datatype */
|
|
if ((aid = H5Acreate2(tid, "attr", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing when there are opened named datatype and attribute */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the datatype */
|
|
if (H5Tclose(tid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Still fail to enable SWMR writing when the attribute is still opened */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the attribute */
|
|
if (H5Aclose(aid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should succeed in enabling SWMR writing */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the dataspace */
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* (C) Failure cases for multiple opens
|
|
*/
|
|
|
|
/* Case 1 */
|
|
|
|
/* Create a file with write + with/without latest format */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC | (new_format ? 0 : H5F_ACC_SWMR_WRITE), H5P_DEFAULT,
|
|
fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the file with write + with/without latest format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should succeed in enabling SWMR writing mode */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Should fail for a second call to enable SWMR writing mode */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 2 */
|
|
|
|
/* Open the file with write + with/without latest format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should succeed in enabling SWMR writing mode */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Re-open the same file */
|
|
if ((fid2 = H5Freopen(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing mode for fid2 */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid2);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the files */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 3 */
|
|
|
|
/* Open the file with write + with/without latest format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the same file */
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should succeed in enabling SWMR writing for fid */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing for fid2 */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid2);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the files */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (!new_format) {
|
|
|
|
/*
|
|
* (D) When opening a file which is created without the latest format:
|
|
*/
|
|
|
|
/* Create a file with write + without latest format */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 1 */
|
|
|
|
/* Should fail to open the file with SWMR write + latest format due to superblock version not at least
|
|
* 3 */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
bad_fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, new_fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (bad_fid >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Case 2 */
|
|
|
|
/* Should fail to open the file with SWMR write + non-latest-format due to superblock version not at
|
|
* least 3 */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
bad_fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (bad_fid >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Case 3 */
|
|
|
|
/* Open the file with write + latest format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, new_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing due to superblock version not at least 3 */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 4 */
|
|
|
|
/* Open the file with write + non-latest-format */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to enable SWMR writing because the file's superblock version is not at least 3 */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Fstart_swmr_write(fid);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
} /* not new */
|
|
|
|
/* Close the file access property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(new_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Sclose(sid);
|
|
H5Gclose(gid);
|
|
H5Dclose(did);
|
|
H5Fclose(fid);
|
|
H5Fclose(fid2);
|
|
H5Pclose(fapl);
|
|
H5Pclose(new_fapl);
|
|
/* bad_fid should only represent a read ID in the error case.
|
|
* It never needs to be closed in the normal case.
|
|
*/
|
|
H5Fclose(bad_fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_err_start_swmr_write() */
|
|
|
|
/*
|
|
* test_start_swmr_write_concur():
|
|
*
|
|
* The "new_format" parameter indicates whether to create the file with latest format or not.
|
|
* To have SWMR support, can use either one of the following in creating a file:
|
|
* (a) Create the file with write + latest format:
|
|
* --result in v3 superblock with latest chunk indexing types
|
|
* (b) Create the file with SWMR write + non-latest-format:
|
|
* --result in v3 superblock with latest chunk indexing types
|
|
* Create a chunked dataset with 1 extendible dimension in the file
|
|
*
|
|
* Verify concurrent access for H5Fstart_swmr_write()--
|
|
* (1) Parent: open a file with write access
|
|
* Child: concurrent open of the file with read & SWMR read (fail)
|
|
* (2) Parent: open a file with write access; enable SWMR writing mode
|
|
* Child: open the file 2 times with read & SWMR read (succeed)
|
|
* open the dataset 2 times with the 2 file opens
|
|
* verify data read from multiple opens of the dataset is correct
|
|
* (3) Parent: open a file with write access; enable SWMR writing mode
|
|
* Child: Concurrent open of the file with read only (fail)
|
|
* (4) Parent: open a file with write access; enable SWMR writing mode
|
|
* Child: concurrent open of the file with write access (fail)
|
|
* (5) Parent: open a file with write access; enable SWMR writing mode
|
|
* Child: concurrent open of the file with write and SWMR write access (fail)
|
|
*/
|
|
#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID))
|
|
|
|
static int
|
|
test_start_swmr_write_concur(hid_t H5_ATTR_UNUSED in_fapl, bool new_format)
|
|
{
|
|
if (new_format) {
|
|
TESTING("H5Fstart_swmr_write()--concurrent access for latest format");
|
|
}
|
|
else {
|
|
TESTING("H5Fstart_swmr_write()--concurrent access for non-latest-format");
|
|
}
|
|
|
|
SKIPPED();
|
|
puts(" Test skipped due to fork or waitpid not defined.");
|
|
return 0;
|
|
} /* test_start_swmr_write_concur() */
|
|
|
|
#else /* !defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */
|
|
|
|
static int
|
|
test_start_swmr_write_concur(hid_t in_fapl, bool new_format)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID, fid1 = H5I_INVALID_HID, fid2 = H5I_INVALID_HID; /* File IDs */
|
|
hid_t fapl; /* File access property list */
|
|
pid_t childpid = 0; /* Child process ID */
|
|
pid_t tmppid; /* Child process ID returned by waitpid */
|
|
int child_status; /* Status passed to waitpid */
|
|
int child_wait_option = 0; /* Options passed to waitpid */
|
|
int child_exit_val; /* Exit status of the child */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
|
|
hid_t did = H5I_INVALID_HID, did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID, did3 = H5I_INVALID_HID;
|
|
hid_t sid = H5I_INVALID_HID;
|
|
hid_t dcpl = H5I_INVALID_HID;
|
|
hsize_t chunk_dims[1] = {1};
|
|
hsize_t maxdims[1] = {H5S_UNLIMITED};
|
|
hsize_t dims[1] = {1};
|
|
int wdata = 0;
|
|
|
|
int out_pdf[2];
|
|
int in_pdf[2];
|
|
int notify = 0;
|
|
|
|
/* Output message about test being performed */
|
|
if (new_format) {
|
|
TESTING("H5Fstart_swmr_write()--concurrent access for latest format");
|
|
}
|
|
else {
|
|
TESTING("H5Fstart_swmr_write()--concurrent access for non-latest-format");
|
|
}
|
|
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if (new_format) {
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the test file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
else {
|
|
/* Create the test file without latest format but with SWMR write */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
} /* end if */
|
|
|
|
/* Create a chunked dataset with 1 extendible dimension */
|
|
if ((sid = H5Screate_simple(1, dims, maxdims)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 1, chunk_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the dataset */
|
|
if (H5Dclose(did) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case (1):
|
|
* Verify concurrent file open with H5F_ACC_RDONLY|H5F_ACC_SWMR_READ
|
|
* will fail without H5Fstart_swmr_write()
|
|
*/
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Should fail */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
/* Open the test file */
|
|
fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid >= 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if ((tmppid = waitpid(childpid, &child_status, child_wait_option)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check exit status of child process */
|
|
if (WIFEXITED(child_status)) {
|
|
if ((child_exit_val = WEXITSTATUS(child_status)) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else /* child process terminated abnormally */
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case (2):
|
|
* Verify concurrent file open with H5F_ACC_RDONLY|H5F_ACC_SWMR_READ
|
|
* will succeed with H5Fstart_swmr_write()
|
|
*/
|
|
|
|
/* Create 2 pipes */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (pipe(in_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid1 = H5I_INVALID_HID, child_fid2; /* File IDs */
|
|
hid_t child_did1 = H5I_INVALID_HID, child_did2 = H5I_INVALID_HID; /* Dataset IDs */
|
|
int child_notify = 0;
|
|
int rdata = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
/* close unused read end for in_pdf */
|
|
if (HDclose(in_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Should succeed in opening the test file 2 times */
|
|
if ((child_fid1 = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if ((child_fid2 = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* open "dataset" 2 times */
|
|
if ((child_did1 = H5Dopen2(child_fid1, "dataset", H5P_DEFAULT)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if ((child_did2 = H5Dopen2(child_fid2, "dataset", H5P_DEFAULT)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Read from "dataset" via child_did1 */
|
|
rdata = 0;
|
|
if (H5Dread(child_did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (rdata != 88)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Notify parent process */
|
|
child_notify = 2;
|
|
if (HDwrite(in_pdf[1], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 3) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Refresh "dataset" via child_did2 */
|
|
if (H5Drefresh(child_did2) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Read from "dataset" child_did2 */
|
|
rdata = 0;
|
|
if (H5Dread(child_did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (rdata != 99)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Read from "dataset" child_did1 */
|
|
rdata = 0;
|
|
if (H5Dread(child_did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rdata) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (rdata != 99)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the dataset */
|
|
if (H5Dclose(child_did1))
|
|
exit(EXIT_FAILURE);
|
|
if (H5Dclose(child_did2))
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(child_fid1) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (H5Fclose(child_fid2) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (HDclose(in_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Close unused write end for in_pdf */
|
|
if (HDclose(in_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* open "dataset", keep it open */
|
|
if ((did1 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did2 = H5Dopen2(fid2, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did3 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to "dataset" */
|
|
wdata = 88;
|
|
if (H5Dwrite(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Flush to disk */
|
|
if (H5Fflush(fid1, H5F_SCOPE_LOCAL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Enable SWMR writing mode */
|
|
if (H5Fstart_swmr_write(fid1) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for notification from child process */
|
|
while (notify != 2) {
|
|
if (HDread(in_pdf[0], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
|
|
/* Write to "dataset" */
|
|
wdata = 99;
|
|
if (H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wdata) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Flush to disk */
|
|
if (H5Fflush(fid1, H5F_SCOPE_LOCAL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 3;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the dataset */
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipes */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (HDclose(in_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if ((tmppid = waitpid(childpid, &child_status, child_wait_option)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check exit status of child process */
|
|
if (WIFEXITED(child_status)) {
|
|
if ((child_exit_val = WEXITSTATUS(child_status)) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else /* Child process terminated abnormally */
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case (3):
|
|
* Verify concurrent file open with H5F_ACC_RDONLY
|
|
* will fail with H5Fstart_swmr_write()
|
|
*/
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Should fail in opening the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid >= 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
} /* end if */
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Enable SWMR writing mode */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if ((tmppid = waitpid(childpid, &child_status, child_wait_option)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check exit status of child process */
|
|
if (WIFEXITED(child_status)) {
|
|
if ((child_exit_val = WEXITSTATUS(child_status)) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else /* Child process terminated abnormally */
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case (4):
|
|
* Verify concurrent file open with H5F_ACC_RDWR
|
|
* will fail with H5Fstart_swmr_write()
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Should fail in opening the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid = H5Fopen(filename, H5F_ACC_RDWR, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid >= 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
} /* end if */
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Enable SWMR writing mode */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if ((tmppid = waitpid(childpid, &child_status, child_wait_option)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check exit status of child process */
|
|
if (WIFEXITED(child_status)) {
|
|
if ((child_exit_val = WEXITSTATUS(child_status)) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else /* Child process terminated abnormally */
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case (5):
|
|
* Verify concurrent file open with H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE
|
|
* will fail with H5Fstart_swmr_write()
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Should fail in opening the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid >= 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Enable SWMR writing mode */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if ((tmppid = waitpid(childpid, &child_status, child_wait_option)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check exit status of child process */
|
|
if (WIFEXITED(child_status)) {
|
|
if ((child_exit_val = WEXITSTATUS(child_status)) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else /* Child process terminated abnormally */
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Sclose(sid);
|
|
H5Pclose(dcpl);
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
|
|
} /* test_start_swmr_write_concur() */
|
|
#endif /* !defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */
|
|
|
|
/*
|
|
* test_start_swmr_write_stress_ohdr():
|
|
*
|
|
* Verify that H5Fswmr_start_write() works correctly when the dataspace header
|
|
* message is not located in chunk #0 of the object header.
|
|
*
|
|
*/
|
|
static int
|
|
test_start_swmr_write_stress_ohdr(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File IDs */
|
|
hid_t fapl; /* File access property list */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
hid_t did = H5I_INVALID_HID, did2 = H5I_INVALID_HID; /* Dataset IDs */
|
|
hid_t sid = H5I_INVALID_HID; /* Dataspace ID */
|
|
hid_t tid = H5I_INVALID_HID; /* Datatype ID */
|
|
hid_t dcpl = H5I_INVALID_HID; /* Dataset creation property list ID */
|
|
hid_t aid = H5I_INVALID_HID; /* Attribute ID */
|
|
hsize_t chunk_dims[2] = {10, 10};
|
|
hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED};
|
|
char fill[256]; /* Fill value for dataset */
|
|
char attr_data[32]; /* Data value for attribute */
|
|
hsize_t dims[2] = {1, 1};
|
|
unsigned chunk_num; /* Object header chunk # for dataspace message */
|
|
|
|
/* Output message about test being performed */
|
|
TESTING("H5Fstart_swmr_write()--stress object header messages");
|
|
|
|
/* Initialize buffers */
|
|
memset(fill, 0, sizeof(fill));
|
|
memset(attr_data, 0, sizeof(attr_data));
|
|
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the test file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a chunked dataset with 2 extendible dimensions */
|
|
if ((sid = H5Screate_simple(1, dims, maxdims)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((tid = H5Tcopy(H5T_C_S1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Tset_size(tid, 256) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 1, chunk_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_fill_value(dcpl, tid, &fill) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did = H5Dcreate2(fid, "dataset", tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the chunk # for the dataspace message */
|
|
chunk_num = UINT_MAX;
|
|
if (H5O__msg_get_chunkno_test(did, H5O_SDSPACE_ID, &chunk_num) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Should be in chunk #0 for now */
|
|
if (0 != chunk_num)
|
|
TEST_ERROR;
|
|
|
|
/* Create a second chunked dataset with 2 extendible dimensions */
|
|
/* (So that the original dataset's object header can't be extended) */
|
|
if ((sid = H5Screate_simple(1, dims, maxdims)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((tid = H5Tcopy(H5T_C_S1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Tset_size(tid, 256) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 1, chunk_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_fill_value(dcpl, tid, &fill) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did2 = H5Dcreate2(fid, "dataset2", tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the second dataset */
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the objects for the dataset creation */
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Tclose(tid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create attribute on original dataset, to push dataspace header message out of header chunk #0 */
|
|
if ((sid = H5Screate(H5S_SCALAR)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((tid = H5Tcopy(H5T_C_S1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Tset_size(tid, 32) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Tset_strpad(tid, H5T_STR_NULLTERM) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((aid = H5Acreate2(did, "attr", tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Awrite(aid, tid, attr_data) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Tclose(tid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Aclose(aid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the chunk # for the dataspace message */
|
|
chunk_num = UINT_MAX;
|
|
if (H5O__msg_get_chunkno_test(did, H5O_SDSPACE_ID, &chunk_num) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Should be in chunk #0 for now */
|
|
if (1 != chunk_num)
|
|
TEST_ERROR;
|
|
|
|
/* Enable SWMR write */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the dataset */
|
|
if (H5Dclose(did) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the FAPL */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Sclose(aid);
|
|
H5Sclose(tid);
|
|
H5Sclose(sid);
|
|
H5Sclose(did);
|
|
H5Sclose(did2);
|
|
H5Pclose(dcpl);
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_start_swmr_write_stress_ohdr() */
|
|
|
|
/*
|
|
* test_start_swmr_write_persist_dapl():
|
|
*
|
|
* Verify H5Fstart_swmr_write() doesn't wipe out dataset access properties for
|
|
* open datasets.
|
|
*
|
|
*/
|
|
static herr_t
|
|
dummy_append_flush_cb(hid_t H5_ATTR_UNUSED dataset_id, hsize_t H5_ATTR_UNUSED *cur_dims,
|
|
void H5_ATTR_UNUSED *user_data)
|
|
{
|
|
return SUCCEED;
|
|
}
|
|
|
|
static herr_t
|
|
tssw_persist_dapl_verify(hid_t did, hid_t vdsid1, hid_t vdsid2, hsize_t boundary, H5D_append_cb_t append_func,
|
|
void *append_func_ud, size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0,
|
|
const char *efile_prefix, const char *virtual_prefix, hsize_t gap_size,
|
|
H5D_vds_view_t virtual_view)
|
|
{
|
|
hid_t dapl = H5I_INVALID_HID;
|
|
hid_t vds_dapl1 = H5I_INVALID_HID;
|
|
hid_t vds_dapl2 = H5I_INVALID_HID;
|
|
hsize_t boundary_out = 0;
|
|
H5D_append_cb_t append_func_out = NULL;
|
|
void *append_func_ud_out = NULL;
|
|
size_t rdcc_nslots_out = 0;
|
|
size_t rdcc_nbytes_out = 0;
|
|
double rdcc_w0_out = 0.;
|
|
char efile_prefix_out[64];
|
|
char virtual_prefix_out[64];
|
|
hsize_t gap_size_out = 0;
|
|
H5D_vds_view_t virtual_view_out = H5D_VDS_LAST_AVAILABLE;
|
|
|
|
/* Get dataset access property lists */
|
|
if ((dapl = H5Dget_access_plist(did)) < 0)
|
|
TEST_ERROR;
|
|
if ((vds_dapl1 = H5Dget_access_plist(vdsid1)) < 0)
|
|
TEST_ERROR;
|
|
if ((vds_dapl2 = H5Dget_access_plist(vdsid2)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get append flush property and verify */
|
|
if (H5Pget_append_flush(dapl, 1, &boundary_out, &append_func_out, &append_func_ud_out) < 0)
|
|
TEST_ERROR;
|
|
if (boundary != boundary_out)
|
|
TEST_ERROR;
|
|
if (append_func != append_func_out)
|
|
TEST_ERROR;
|
|
if (append_func_ud != append_func_ud_out)
|
|
TEST_ERROR;
|
|
|
|
/* Get chunk cache property and verify */
|
|
if (H5Pget_chunk_cache(dapl, &rdcc_nslots_out, &rdcc_nbytes_out, &rdcc_w0_out) < 0)
|
|
TEST_ERROR;
|
|
if (rdcc_nslots != rdcc_nslots_out)
|
|
TEST_ERROR;
|
|
if (rdcc_nbytes != rdcc_nbytes_out)
|
|
TEST_ERROR;
|
|
if (fabs(rdcc_w0 - rdcc_w0_out) > (double)FP_EPSILON)
|
|
TEST_ERROR;
|
|
|
|
/* Get efile prefix property and verify */
|
|
if (H5Pget_efile_prefix(dapl, efile_prefix_out, sizeof(efile_prefix_out)) < 0)
|
|
TEST_ERROR;
|
|
if (strncmp(efile_prefix, efile_prefix_out, sizeof(efile_prefix_out)))
|
|
TEST_ERROR;
|
|
|
|
/* Get virtual prefix property and verify */
|
|
if (H5Pget_virtual_prefix(vds_dapl1, virtual_prefix_out, sizeof(virtual_prefix_out)) < 0)
|
|
TEST_ERROR;
|
|
if (strncmp(virtual_prefix, virtual_prefix_out, sizeof(virtual_prefix_out)))
|
|
TEST_ERROR;
|
|
|
|
/* Get virtual printf gap property and verify */
|
|
if (H5Pget_virtual_printf_gap(vds_dapl1, &gap_size_out) < 0)
|
|
TEST_ERROR;
|
|
if (gap_size != gap_size_out)
|
|
TEST_ERROR;
|
|
|
|
/* Get virtual view property and verify. Use vds_dapl2 since a VDS can't
|
|
* have both LAST_AVAILABLE and a printf gap set. vds1 has a printf gap and
|
|
* vds2 has LAST_AVAILABLE. */
|
|
if (H5Pget_virtual_view(vds_dapl2, &virtual_view_out) < 0)
|
|
TEST_ERROR;
|
|
if (virtual_view != virtual_view_out)
|
|
TEST_ERROR;
|
|
|
|
/* Close DAPLs */
|
|
if (H5Pclose(dapl) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pclose(vds_dapl1) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pclose(vds_dapl2) < 0)
|
|
TEST_ERROR;
|
|
|
|
return SUCCEED;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(dapl);
|
|
H5Pclose(vds_dapl1);
|
|
H5Pclose(vds_dapl2);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return FAIL;
|
|
} /* tssw_persist_dapl_verify() */
|
|
|
|
static int
|
|
test_start_swmr_write_persist_dapl(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property */
|
|
hid_t dcpl = H5I_INVALID_HID; /* Dataset creation property */
|
|
hid_t vds_dcpl = H5I_INVALID_HID; /* Virtual dataset creation property */
|
|
hid_t dapl1 = H5I_INVALID_HID; /* Dataset access property */
|
|
hid_t dapl2 = H5I_INVALID_HID; /* Dataset access property */
|
|
hid_t did = H5I_INVALID_HID; /* Dataset ID */
|
|
hid_t vdsid1 = H5I_INVALID_HID; /* Virtual Dataset ID */
|
|
hid_t vdsid2 = H5I_INVALID_HID; /* Virtual Dataset ID */
|
|
hid_t sid = H5I_INVALID_HID; /* Dataspace IDs*/
|
|
hsize_t dim[1] = {1}; /* Dimension sizes */
|
|
hsize_t max_dim[1] = {H5S_UNLIMITED}; /* Maximum dimension sizes */
|
|
hsize_t chunk_dim[1] = {2}; /* Chunk dimension sizes */
|
|
hsize_t boundary = 23;
|
|
H5D_append_cb_t append_func = dummy_append_flush_cb;
|
|
void *append_func_ud = &boundary;
|
|
size_t rdcc_nslots = 125;
|
|
size_t rdcc_nbytes = 23434;
|
|
double rdcc_w0 = 0.68419;
|
|
const char *efile_prefix = "dummy_efile_prefix";
|
|
const char *virtual_prefix = "dummy_virtual_prefix";
|
|
hsize_t gap_size = 421;
|
|
H5D_vds_view_t virtual_view = H5D_VDS_FIRST_MISSING;
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
|
|
/* Get a copy of the parameter fapl (non-latest-format) */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
TESTING("H5Fstart_swmr_write() persists DAPL settings");
|
|
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Create the file with SWMR write + non-latest-format */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create dapl with custom properties */
|
|
if ((dapl1 = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set append flush property */
|
|
boundary = 23;
|
|
if (H5Pset_append_flush(dapl1, 1, &boundary, dummy_append_flush_cb, append_func_ud) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set chunk cache property */
|
|
if (H5Pset_chunk_cache(dapl1, rdcc_nslots, rdcc_nbytes, rdcc_w0) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set efile prefix property */
|
|
if (H5Pset_efile_prefix(dapl1, efile_prefix) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set virtual prefix property */
|
|
if (H5Pset_virtual_prefix(dapl1, virtual_prefix) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set virtual printf gap property */
|
|
if (H5Pset_virtual_printf_gap(dapl1, gap_size) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Must create separate dapl2 for a different view, since the non-default
|
|
* view of FIRST_MISSING wipes out the printf gap setting */
|
|
if ((dapl2 = H5Pcopy(dapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set virtual view property */
|
|
if (H5Pset_virtual_view(dapl2, virtual_view) < 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case A: create file, create dataset
|
|
*/
|
|
|
|
/* Create "dataset1" */
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pset_chunk(dcpl, 1, chunk_dim) < 0)
|
|
TEST_ERROR;
|
|
if ((sid = H5Screate_simple(1, dim, max_dim)) < 0)
|
|
TEST_ERROR;
|
|
if ((did = H5Dcreate2(fid, "dataset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create "vds1" */
|
|
if ((vds_dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pset_layout(vds_dcpl, H5D_VIRTUAL) < 0)
|
|
TEST_ERROR;
|
|
if ((vdsid1 = H5Dcreate2(fid, "vds1", H5T_NATIVE_INT, sid, H5P_DEFAULT, vds_dcpl, dapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create "vds2" */
|
|
if ((vdsid2 = H5Dcreate2(fid, "vds2", H5T_NATIVE_INT, sid, H5P_DEFAULT, vds_dcpl, dapl2)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Enable swmr write */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify dataset still has correct access properties */
|
|
if (tssw_persist_dapl_verify(did, vdsid1, vdsid2, boundary, append_func, append_func_ud, rdcc_nslots,
|
|
rdcc_nbytes, rdcc_w0, efile_prefix, virtual_prefix, gap_size,
|
|
virtual_view) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close "dataset1" */
|
|
if (H5Dclose(did) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close "vds1" */
|
|
if (H5Dclose(vdsid1) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close "vds2" */
|
|
if (H5Dclose(vdsid2) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case B: opened file, open dataset
|
|
*/
|
|
|
|
/* Open the file again with write */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Open "dataset1", keep it open */
|
|
if ((did = H5Dopen2(fid, "dataset1", dapl1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open "vds1", keep it open */
|
|
if ((vdsid1 = H5Dopen2(fid, "vds1", dapl1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open "vds1", keep it open */
|
|
if ((vdsid2 = H5Dopen2(fid, "vds2", dapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Enable swmr write */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify dataset still has correct access properties */
|
|
if (tssw_persist_dapl_verify(did, vdsid1, vdsid2, boundary, append_func, append_func_ud, rdcc_nslots,
|
|
rdcc_nbytes, rdcc_w0, efile_prefix, virtual_prefix, gap_size,
|
|
virtual_view) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close "dataset1" */
|
|
if (H5Dclose(did) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close "vds1" */
|
|
if (H5Dclose(vdsid1) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close "vds2" */
|
|
if (H5Dclose(vdsid2) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case C: opened file, create dataset
|
|
*/
|
|
|
|
/* Open the file again with write */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create "dataset2" */
|
|
if ((did = H5Dcreate2(fid, "dataset2", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create "vds3" */
|
|
if ((vdsid1 = H5Dcreate2(fid, "vds3", H5T_NATIVE_INT, sid, H5P_DEFAULT, vds_dcpl, dapl1)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create "vds4" */
|
|
if ((vdsid2 = H5Dcreate2(fid, "vds4", H5T_NATIVE_INT, sid, H5P_DEFAULT, vds_dcpl, dapl2)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Enable swmr write */
|
|
if (H5Fstart_swmr_write(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify dataset still has correct access properties */
|
|
if (tssw_persist_dapl_verify(did, vdsid1, vdsid2, boundary, append_func, append_func_ud, rdcc_nslots,
|
|
rdcc_nbytes, rdcc_w0, efile_prefix, virtual_prefix, gap_size,
|
|
virtual_view) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close "dataset1" */
|
|
if (H5Dclose(did) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close "vds1" */
|
|
if (H5Dclose(vdsid1) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close "vds2" */
|
|
if (H5Dclose(vdsid2) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close dataspace, dapl, dcpl*/
|
|
if (H5Sclose(sid) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pclose(vds_dcpl) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pclose(dapl1) < 0)
|
|
TEST_ERROR;
|
|
if (H5Pclose(dapl2) < 0)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Fclose(fid);
|
|
H5Pclose(fapl);
|
|
H5Pclose(dcpl);
|
|
H5Pclose(vds_dcpl);
|
|
H5Pclose(dapl1);
|
|
H5Pclose(dapl2);
|
|
H5Dclose(did);
|
|
H5Dclose(vdsid1);
|
|
H5Dclose(vdsid2);
|
|
H5Sclose(sid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_start_swmr_write_persist_dapl() */
|
|
|
|
/*
|
|
* Tests for H5Pset/get_object_flush_cb()
|
|
*/
|
|
|
|
/* The callback function for object flush property */
|
|
static herr_t
|
|
flush_cb(hid_t H5_ATTR_UNUSED obj_id, void *_udata)
|
|
{
|
|
unsigned *flush_ct = (unsigned *)_udata;
|
|
++(*flush_ct);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* test_object_flush_cb()
|
|
*
|
|
* Verify the public routines H5Pget/set_object_flush_cb() work as specified:
|
|
* 1) To verify the failure condition in setting object flush property
|
|
* 2) To verify the object flush property values retrieved from a default
|
|
* file access property list.
|
|
* 3) To verify the object flush property values retrieved from a non-default
|
|
* file access property list.
|
|
* 4) To verify the object flush property values retrieved from a default
|
|
* file access property list of a file
|
|
* 5) To verify the object flush property values retrieved from a non-default
|
|
* file access property list of a file
|
|
* To verify the object flush callback is invoked when doing H5Oflush(),
|
|
* H5Dflush(), H5Gflush() and H5Tflush().
|
|
*/
|
|
static int
|
|
test_object_flush_cb(hid_t in_fapl)
|
|
{
|
|
hid_t fapl = H5I_INVALID_HID; /* A copy of file access property list */
|
|
hid_t ffapl = H5I_INVALID_HID; /* A file's file access property list */
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t gid = H5I_INVALID_HID; /* Group ID */
|
|
hid_t did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID; /* Dataset IDs */
|
|
hid_t sid = H5I_INVALID_HID; /* Dataspace ID */
|
|
hsize_t dims[2] = {5, 10}; /* Dataset dimension sizes */
|
|
int buf[50]; /* Data buffer */
|
|
H5F_flush_cb_t ret_cb; /* The callback function set in object flush property */
|
|
void *ret_ct; /* The user data set in object flush property */
|
|
unsigned flush_ct = 0; /* The user data for object flush property */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
int i; /* Local index variable */
|
|
herr_t ret; /* Generic return value */
|
|
|
|
TESTING("H5Pget/set_obj_flush_cb()");
|
|
|
|
/*
|
|
* Case (1)
|
|
* To verify the failure condition in setting object flush property
|
|
*/
|
|
/* Should fail if the callback function is not defined but user data is defined */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Pset_object_flush_cb(fapl, NULL, &flush_ct);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case (2)
|
|
* To verify the object flush property values retrieved from a
|
|
* default file access property list.
|
|
*/
|
|
|
|
/* Create a copy of file access property list */
|
|
if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve object flush property values for the default file access property list */
|
|
if (H5Pget_object_flush_cb(fapl, &ret_cb, &ret_ct) < 0)
|
|
TEST_ERROR;
|
|
/* Should be null */
|
|
if (ret_cb != NULL || ret_ct != NULL)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case (3)
|
|
* To verify the object flush property values retrieved from a
|
|
* non-default file access property list.
|
|
*/
|
|
/* Set the object flush property */
|
|
if (H5Pset_object_flush_cb(fapl, flush_cb, &flush_ct) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Increment the counter */
|
|
++flush_ct;
|
|
|
|
/* Retrieve object flush property values for the non-default file access property list */
|
|
if (H5Pget_object_flush_cb(fapl, &ret_cb, &ret_ct) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_cb != flush_cb || *(unsigned *)ret_ct != 1)
|
|
TEST_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case (4)
|
|
* To verify the object flush property values retrieved from a
|
|
* default file access property list of a file
|
|
*/
|
|
|
|
/* Reset values */
|
|
flush_ct = 0;
|
|
ret_cb = NULL;
|
|
ret_ct = NULL;
|
|
|
|
/* Make a copy of the input parameter in_fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Create the test file: without setting object flush property in fapl */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the file's file access property list */
|
|
if ((ffapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the object flush property values */
|
|
if (H5Pget_object_flush_cb(ffapl, &ret_cb, &ret_ct) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_cb != NULL || ret_ct != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(ffapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Cases (5)
|
|
* To verify the object flush property values retrieved from a non-default
|
|
* file access property list of a file.
|
|
* To verify the object flush callback is invoked when doing H5Oflush(),
|
|
* H5Dflush(), H5Gflush() and H5Tflush().
|
|
*/
|
|
/* Reset values */
|
|
flush_ct = 0;
|
|
ret_cb = NULL;
|
|
ret_ct = NULL;
|
|
|
|
/* Set the object flush property */
|
|
if (H5Pset_object_flush_cb(fapl, flush_cb, &flush_ct) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file: with object flush property setting in fapl */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a dataset */
|
|
if ((sid = H5Screate_simple(2, dims, dims)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a dataset */
|
|
if ((did1 = H5Dcreate2(fid, "dataset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Initialize data buffer */
|
|
for (i = 0; i < 50; i++)
|
|
buf[i] = i + 1;
|
|
|
|
/* Write to the dataset */
|
|
if (H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Flush the dataset object */
|
|
if (H5Oflush(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the file's file access property list */
|
|
if ((ffapl = H5Fget_access_plist(fid)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the object flush property values */
|
|
if (H5Pget_object_flush_cb(ffapl, &ret_cb, &ret_ct) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_cb != flush_cb || *(unsigned *)ret_ct != 1)
|
|
TEST_ERROR;
|
|
|
|
/* Create a group */
|
|
if ((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Flush the group */
|
|
if (H5Gflush(gid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Retrieve the object flush property values */
|
|
if (H5Pget_object_flush_cb(ffapl, &ret_cb, &ret_ct) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_cb != flush_cb || *(unsigned *)ret_ct != 2)
|
|
TEST_ERROR;
|
|
|
|
/* Create a dataset */
|
|
if ((did2 = H5Dcreate2(gid, "dataset2", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Flush the dataset */
|
|
if (H5Dflush(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the object flush property values */
|
|
if (H5Pget_object_flush_cb(ffapl, &ret_cb, &ret_ct) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_cb != flush_cb || *(unsigned *)ret_ct != 3)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Gclose(gid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(ffapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
H5Pclose(ffapl);
|
|
H5Sclose(sid);
|
|
H5Dclose(did1);
|
|
H5Dclose(did2);
|
|
H5Gclose(gid);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_object_flush_cb() */
|
|
|
|
/*
|
|
* Tests for H5Pset/get_append_flush()
|
|
*/
|
|
|
|
/* The callback function for append flush property */
|
|
static herr_t
|
|
append_cb(hid_t H5_ATTR_UNUSED dset_id, hsize_t H5_ATTR_UNUSED *cur_dims, void *_udata)
|
|
{
|
|
unsigned *count = (unsigned *)_udata;
|
|
++(*count++);
|
|
return 0;
|
|
} /* append_cb() */
|
|
|
|
/* The callback function for append flush property */
|
|
static herr_t
|
|
append_cb2(hid_t H5_ATTR_UNUSED dset_id, hsize_t H5_ATTR_UNUSED *cur_dims, void *_udata)
|
|
{
|
|
unsigned *count = (unsigned *)_udata;
|
|
++(*count++);
|
|
return 0;
|
|
} /* append_cb2() */
|
|
|
|
/*
|
|
* test_append_flush_generic()
|
|
*
|
|
* Verify H5Pget/set_append_flush() work as specified for a generic dataset
|
|
* access property list:
|
|
* 1) To verify the append flush property values retrieved from a default
|
|
* access property list.
|
|
* -- zero boundary, null callback function, null user data
|
|
* 2) To verify the failure conditions in setting append flush property:
|
|
* -- an invalid dataset rank: <= 0, > H5S_MAX_RANK
|
|
* -- undefined callback but defined user data
|
|
* -- no boundary specified
|
|
* -- invalid boundary size: H5S_UNLIMITED, negative value
|
|
* 3) To verify the append flush property values retrieved from a non-default
|
|
* access property list.
|
|
* -- the set callback function, the set user data
|
|
* -- the # of boundary sizes retrieved does not exceed MIN(input ndims, the ndims set)
|
|
*/
|
|
static int
|
|
test_append_flush_generic(void)
|
|
{
|
|
hid_t dapl = H5I_INVALID_HID; /* A copy of dataset access property */
|
|
hsize_t boundary[3]; /* The boundary for append flush property */
|
|
unsigned count = 0; /* The user data for append flush property */
|
|
hsize_t ret_boundary[3]; /* The boundary set in append flush property */
|
|
H5D_append_cb_t ret_cb; /* The callback function set in append flush property */
|
|
unsigned *ret_count; /* The user data set in append flush property */
|
|
herr_t ret; /* The return value */
|
|
|
|
TESTING("H5Fget/set_append_flush() for a generic dataset access property list");
|
|
|
|
/*
|
|
* Case (1)
|
|
* To verify the retrieved append flush property values:
|
|
* -- zero boundary, null callback function, null user data
|
|
*/
|
|
|
|
/* Create a copy of dataset access property list */
|
|
if ((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(dapl, 2, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 0)
|
|
TEST_ERROR;
|
|
if (ret_cb != NULL || ret_count != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(dapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case (2)
|
|
* To verify the failure conditions in setting append flush property:
|
|
* -- an invalid dataset rank: <= 0, > H5S_MAX_RANK
|
|
* -- no boundary specified
|
|
* -- undefined callback but defined user data
|
|
* -- invalid boundary size: H5S_UNLIMITED, negative value
|
|
*/
|
|
|
|
/* Create a copy of dataset access property list */
|
|
if ((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Invalid dataset rank: zero value */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Pset_append_flush(dapl, 0, NULL, NULL, &count);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Invalid dataset rank: > H5S_MAX_RANK */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Pset_append_flush(dapl, H5S_MAX_RANK + 1, NULL, NULL, &count);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* No boundary specified */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Pset_append_flush(dapl, 2, NULL, NULL, &count);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set up a valid boundary */
|
|
boundary[0] = 1;
|
|
boundary[1] = 1;
|
|
|
|
/* Undefined callback function but defined user data */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Pset_append_flush(dapl, 2, boundary, NULL, &count);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Invalid boundary size: negative value */
|
|
boundary[0] = (hsize_t)-1;
|
|
boundary[1] = 1;
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Pset_append_flush(dapl, 2, boundary, append_cb, &count);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Invalid boundary size: H5S_UNLIMITED */
|
|
boundary[0] = 1;
|
|
boundary[1] = H5S_UNLIMITED;
|
|
H5E_BEGIN_TRY
|
|
{
|
|
ret = H5Pset_append_flush(dapl, 2, boundary, append_cb, &count);
|
|
}
|
|
H5E_END_TRY
|
|
if (ret >= 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case (3)
|
|
* To verify the append flush property values retrieved from a non-default
|
|
* access property list:
|
|
* -- the set callback function, the set user data
|
|
* -- the # of boundary sizes retrieved does not exceed MIN(input ndims, the ndims set)
|
|
*/
|
|
boundary[0] = boundary[1] = 1;
|
|
boundary[2] = 0;
|
|
count = 1;
|
|
if (H5Pset_append_flush(dapl, 2, boundary, append_cb, &count) < 0)
|
|
FAIL_STACK_ERROR;
|
|
++count;
|
|
|
|
/* Verify expected values: with boundary rank > set boundary rank */
|
|
if (H5Pget_append_flush(dapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
if (ret_boundary[0] != 1 || ret_boundary[1] != 1 || boundary[2] != 0)
|
|
TEST_ERROR;
|
|
if (ret_cb == NULL || ret_count == NULL || *ret_count != 2)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values: with boundary rank < set boundary rank */
|
|
memset(ret_boundary, 0, sizeof(ret_boundary));
|
|
if (H5Pget_append_flush(dapl, 1, ret_boundary, NULL, NULL) < 0)
|
|
TEST_ERROR;
|
|
if (ret_boundary[0] != 1 || ret_boundary[1] != 0 || boundary[2] != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(dapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(dapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_append_flush_generic() */
|
|
|
|
/*
|
|
* test_append_flush_dataset_chunked()
|
|
*
|
|
* Verify H5Pget/set_append_flush() work as specified for a chunked dataset's
|
|
* access property list:
|
|
* 1) To verify the append flush property values retrieved from a default
|
|
* access property list:
|
|
* -- zero boundary, null callback function, null user data
|
|
* 2) To verify failure in creating dataset when:
|
|
* -- the rank set in append flush property is not the same as the dataset's rank
|
|
* -- boundary (non-zero) is set for a non-extendible dimension
|
|
* 3) To verify the append flush property values retrieved from a non-default
|
|
* access property list:
|
|
* -- the set callback function, the set user data
|
|
* -- the # of boundary sizes retrieved does not exceed MIN(input ndims, the ndims set)
|
|
*/
|
|
static int
|
|
test_append_flush_dataset_chunked(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* file ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* A copy of file access property */
|
|
hid_t did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID; /* The dataset ID */
|
|
hid_t sid = H5I_INVALID_HID; /* The dataspace ID */
|
|
hid_t dcpl = H5I_INVALID_HID; /* A copy of dataset creation property */
|
|
hid_t dapl = H5I_INVALID_HID; /* A copy of dataset access property */
|
|
hid_t ddapl = H5I_INVALID_HID; /* The dataset access property of the opened dataset */
|
|
|
|
hsize_t boundary[3]; /* Boundary size */
|
|
unsigned count = 0; /* User data */
|
|
|
|
hsize_t ret_boundary[3]; /* Boundary size set in the append flush property */
|
|
H5D_append_cb_t ret_cb; /* The callback function set in the append flush property */
|
|
unsigned *ret_count; /* The user data set in the append flush property */
|
|
|
|
char filename[NAME_BUF_SIZE]; /* file name */
|
|
|
|
hsize_t dims[2] = {100, 0}; /* The dataset dimension sizes */
|
|
hsize_t maxdims[2] = {100, H5S_UNLIMITED}; /* The dataset maximum dimension sizes */
|
|
hsize_t chunk_dims[2] = {5, 2}; /* The chunk dimension sizes */
|
|
|
|
TESTING("H5Fget/set_append_flush() for a chunked dataset's access property list");
|
|
|
|
/*
|
|
* Case (1)--
|
|
* For a chunked dataset's access property list:
|
|
* --to verify the append flush property values retrieved from a default access
|
|
* a default access property list is:
|
|
* zero rank, zero boundary, null callback function, null user data
|
|
*/
|
|
|
|
/* Get a copy of the input parameter in_fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Create the test file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a chunked dataset with 1 extendible dimension */
|
|
if ((sid = H5Screate_simple(2, dims, maxdims)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 2, chunk_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did1 = H5Dcreate2(fid, "dataset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get the dataset's access property list */
|
|
if ((ddapl = H5Dget_access_plist(did1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 0 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
if (ret_cb != NULL || ret_count != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Close the dataset's access property list */
|
|
if (H5Pclose(ddapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case (2)--
|
|
* For a chunked dataset's access property list:
|
|
* --to verify failure in creating the dataset when:
|
|
* --the rank set in append flush property is not the same as the dataset's rank
|
|
* -- boundary (non-zero) is set for a non-extendible dimension
|
|
* --to verify failure in opening the dataset
|
|
* -- boundary (non-zero) is set for a non-extendible dimension
|
|
*/
|
|
/* Create a copy of dataset access property list */
|
|
if ((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set boundary dimension rank > the rank of dataset to be created */
|
|
memset(boundary, 0, sizeof(boundary));
|
|
if (H5Pset_append_flush(dapl, 3, boundary, NULL, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to Create the dataset */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
did2 = H5Dcreate2(fid, "dataset2", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (did2 >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set boundary for a non-extendible dimension */
|
|
boundary[0] = boundary[1] = 1;
|
|
if (H5Pset_append_flush(dapl, 2, boundary, NULL, NULL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to create the dataset */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
did2 = H5Dcreate2(fid, "dataset2", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (did2 >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Create and close the dataset */
|
|
if ((did2 = H5Dcreate2(fid, "dataset2", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should fail to open the dataset */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
did2 = H5Dopen2(fid, "dataset2", dapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (did2 >= 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case (3)--
|
|
* For a chunked dataset's access property list:
|
|
* --To verify the append flush property values retrieved from a non-default
|
|
* access property list:
|
|
* -- the set callback function, the set user data
|
|
* -- the # of boundary sizes retrieved does not exceed MIN(input ndims, the ndims set)
|
|
*/
|
|
|
|
boundary[0] = 0;
|
|
boundary[1] = 1;
|
|
if (H5Pset_append_flush(dapl, 2, boundary, append_cb, &count) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did2 = H5Dopen2(fid, "dataset2", dapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the dataset's access property list */
|
|
if ((ddapl = H5Dget_access_plist(did2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
memset(ret_boundary, 0, sizeof(ret_boundary));
|
|
ret_cb = NULL;
|
|
ret_count = NULL;
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_cb != append_cb || ret_count != &count)
|
|
TEST_ERROR;
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 1 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
|
|
memset(ret_boundary, 0, sizeof(ret_boundary));
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 1, ret_boundary, NULL, NULL) < 0)
|
|
TEST_ERROR;
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 0 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(ddapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(dcpl);
|
|
H5Pclose(dapl);
|
|
H5Pclose(ddapl);
|
|
H5Dclose(did1);
|
|
H5Dclose(did2);
|
|
H5Pclose(fapl);
|
|
H5Sclose(sid);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_append_flush_dataset_chunked() */
|
|
|
|
/*
|
|
* test_append_flush_dataset_fixed():
|
|
*
|
|
* Verify H5Pget/set_append_flush() work as specified for a
|
|
* non-chunked (fixed size) dataset's access property list:
|
|
* (1) To verify success in creating the dataset--whatever is set for the append flush property setting
|
|
* (2) To verify that default append flush property values are retrieved for both
|
|
* default or non-default access property list:
|
|
* -- zero boundary, null callback function, null user data
|
|
*/
|
|
static int
|
|
test_append_flush_dataset_fixed(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* file ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* A copy of file access property */
|
|
hid_t did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID; /* The dataset ID */
|
|
hid_t sid = H5I_INVALID_HID; /* The dataspace ID */
|
|
hid_t dapl = H5I_INVALID_HID; /* A copy of dataset access property */
|
|
hid_t ddapl = H5I_INVALID_HID; /* The dataset access property of the opened dataset */
|
|
|
|
hsize_t boundary[3]; /* Boundary size */
|
|
unsigned count = 0; /* User data */
|
|
|
|
hsize_t ret_boundary[3]; /* Boundary size set in the append flush property */
|
|
H5D_append_cb_t ret_cb; /* The callback function set in the append flush property */
|
|
unsigned *ret_count; /* The user data set in the append flush property */
|
|
|
|
char filename[NAME_BUF_SIZE]; /* file name */
|
|
|
|
hsize_t dims[1] = {100};
|
|
|
|
TESTING("H5Fget/set_append_flush() for a non-chunked dataset's access property list");
|
|
|
|
/*
|
|
* Case (1)--
|
|
* For a non-chunked dataset's access property list:
|
|
* --to verify the append flush property values retrieved from
|
|
* a default access property list is:
|
|
* zero boundary, null callback function, null user data
|
|
*/
|
|
|
|
/* Get a copy of the input parameter in_fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Create the test file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a dataset */
|
|
if ((sid = H5Screate_simple(1, dims, dims)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did1 = H5Dcreate2(fid, "dataset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get the dataset's access property list */
|
|
if ((ddapl = H5Dget_access_plist(did1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 0 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
if (ret_cb != NULL || ret_count != NULL)
|
|
TEST_ERROR;
|
|
|
|
/* Close the dataset's access property list */
|
|
if (H5Pclose(ddapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case (2)--
|
|
* For a non-chunked dataset's access property list:
|
|
* --to verify success in creating and opening the dataset even when append flush property
|
|
* is setup with error conditions:
|
|
* --the rank set in append flush property is not the same as the dataset's rank
|
|
* --boundary is set
|
|
* --to verify the append flush property values are:
|
|
* zero boundary, null callback function, null user data
|
|
*/
|
|
/* Create a copy of dataset access property list */
|
|
if ((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
boundary[0] = 1;
|
|
boundary[1] = boundary[2] = 0;
|
|
if (H5Pset_append_flush(dapl, 3, boundary, append_cb, &count) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should succeed to create the dataset: append flush property has no effect */
|
|
if ((did2 = H5Dcreate2(fid, "dataset2", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, dapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get the dataset's access property list */
|
|
if ((ddapl = H5Dget_access_plist(did2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_cb != NULL || ret_count != NULL)
|
|
TEST_ERROR;
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 0 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(ddapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should succeed in opening the dataset: append flush property has no effect */
|
|
if ((did2 = H5Dopen2(fid, "dataset2", dapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Get the dataset's access property list */
|
|
if ((ddapl = H5Dget_access_plist(did2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_cb != NULL || ret_count != NULL)
|
|
TEST_ERROR;
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 0 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/*
|
|
* Case (3)--
|
|
* For a non-chunked dataset's access property list:
|
|
* --To verify the append flush property values retrieved from a non-default
|
|
* access property list:
|
|
* zero boundary, null callback function, null user data
|
|
*/
|
|
|
|
memset(boundary, 0, sizeof(boundary));
|
|
if (H5Pset_append_flush(dapl, 1, boundary, append_cb, &count) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did2 = H5Dopen2(fid, "dataset2", dapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the dataset's access property list */
|
|
if ((ddapl = H5Dget_access_plist(did2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 1, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values */
|
|
if (ret_cb != NULL || ret_count != NULL)
|
|
TEST_ERROR;
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 0 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(ddapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(dapl);
|
|
H5Pclose(ddapl);
|
|
H5Dclose(did1);
|
|
H5Dclose(did2);
|
|
H5Pclose(fapl);
|
|
H5Sclose(sid);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_append_flush_dataset_fixed() */
|
|
|
|
/*
|
|
* test_append_flush_multiple()
|
|
*
|
|
* Verify H5Pget/set_append_flush() work as specified for multiple opens
|
|
* of a dataset:
|
|
* (1) did1 = H5Dcreate(...dapl1...)
|
|
* did2 = H5Dopen2(...dapl2)
|
|
* H5Pget_append_flush(did1...)
|
|
* H5Pget_append_flush(did2...)
|
|
* -- should return append flush property values set in dapl1
|
|
* (2) H5Dcreate(...H5P_DEFAULT...)
|
|
* H5Dclose()
|
|
* did1 = H5Dopen2(...dapl1)
|
|
* did2 = H5Dopen2(..dapl2)
|
|
* H5Pget_append_flush(did1, ...)
|
|
* H5Pget_append_flush(did2, ...)
|
|
* -- should return append flush property values set in dapl1
|
|
* NOTE:
|
|
* FOR NOW: return the append flush property values of the create or the very first open
|
|
* LATER ON: should REJECT subsequent dataset open if append flush property values differ
|
|
*/
|
|
static int
|
|
test_append_flush_dataset_multiple(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* file ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* A copy of file access property */
|
|
hid_t did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID; /* The dataset ID */
|
|
hid_t sid = H5I_INVALID_HID; /* The dataspace ID */
|
|
hid_t dcpl = H5I_INVALID_HID; /* A copy of dataset creation property */
|
|
hid_t dapl1 = H5I_INVALID_HID; /* A copy of dataset access property */
|
|
hid_t dapl2 = H5I_INVALID_HID; /* A copy of dataset access property */
|
|
hid_t ddapl = H5I_INVALID_HID; /* The dataset access property of the opened dataset */
|
|
|
|
hsize_t boundary1[3]; /* Boundary size */
|
|
hsize_t boundary2[3]; /* Boundary size */
|
|
unsigned count1 = 0; /* User data */
|
|
unsigned count2 = 0; /* User data */
|
|
|
|
hsize_t ret_boundary[3]; /* Boundary size set in the append flush property */
|
|
H5D_append_cb_t ret_cb; /* The callback function set in the append flush property */
|
|
unsigned *ret_count; /* The user data set in the append flush property */
|
|
|
|
char filename[NAME_BUF_SIZE]; /* file name */
|
|
|
|
hsize_t dims[2] = {0, 0}; /* The dataset dimension sizes */
|
|
hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* The dataset maximum dimension sizes */
|
|
hsize_t chunk_dims[2] = {5, 2}; /* The chunk dimension sizes */
|
|
|
|
TESTING("H5Fget/set_append_flush() for multiple opens of a chunked dataset");
|
|
|
|
/*
|
|
* Case (1)
|
|
* For a chunked dataset's access property list:
|
|
* did1 = H5Dcreate(...dapl1...)
|
|
* did2 = H5Dopen2(...dapl2)
|
|
* H5Pget_append_flush(did1...)
|
|
* H5Pget_append_flush(did2...)
|
|
* -- should return append flush property values set in dapl1
|
|
*/
|
|
|
|
/* Create a copy of dataset access property list */
|
|
if ((dapl1 = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dapl2 = H5Pcreate(H5P_DATASET_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
boundary1[0] = 0;
|
|
boundary1[1] = 1;
|
|
count1 = 0;
|
|
if (H5Pset_append_flush(dapl1, 2, boundary1, append_cb, &count1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
boundary2[0] = 1;
|
|
boundary2[1] = 0;
|
|
count2 = 0;
|
|
if (H5Pset_append_flush(dapl2, 2, boundary2, append_cb2, &count2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a copy of the input parameter in_fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
/* Create the test file to work on */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a chunked dataset with 2 extendible dimensions */
|
|
if ((sid = H5Screate_simple(2, dims, maxdims)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 2, chunk_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did1 = H5Dcreate2(fid, "dataset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset */
|
|
if ((did2 = H5Dopen2(fid, "dataset1", dapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the dataset's access property list for did1 */
|
|
if ((ddapl = H5Dget_access_plist(did1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values: should be the setting in dapl1 */
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 1 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
if (ret_cb != append_cb || ret_count != &count1)
|
|
TEST_ERROR;
|
|
|
|
/* Close the dataset's access property list */
|
|
if (H5Pclose(ddapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the dataset's access property list for did2 */
|
|
if ((ddapl = H5Dget_access_plist(did2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values: should be the setting in dapl1 */
|
|
if (ret_boundary[0] != 0 || ret_boundary[1] != 1 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
if (ret_cb != append_cb || ret_count != &count1)
|
|
TEST_ERROR;
|
|
|
|
/* Close the dataset's access property list */
|
|
if (H5Pclose(ddapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
H5Dclose(did1);
|
|
H5Dclose(did2);
|
|
|
|
/*
|
|
* Case (2)
|
|
* For a chunked dataset's access property list:
|
|
* H5Dcreate(...H5P_DEFAULT...)
|
|
* H5Dclose()
|
|
* did1 = H5Dopen2(...dapl1)
|
|
* did2 = H5Dopen2(..dapl2)
|
|
* H5Pget_append_flush(did1, ...)
|
|
* H5Pget_append_flush(did2, ...)
|
|
* -- should return append flush property values set in dapl1
|
|
*/
|
|
if ((did1 = H5Dcreate2(fid, "dataset2", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset with append flush setting in dapl2 */
|
|
if ((did1 = H5Dopen2(fid, "dataset2", dapl2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset with append flush setting in dapl1 */
|
|
if ((did2 = H5Dopen2(fid, "dataset2", dapl1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the dataset's access property list for did1 */
|
|
if ((ddapl = H5Dget_access_plist(did1)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values: should be the setting in dapl2 */
|
|
if (ret_boundary[0] != 1 || ret_boundary[1] != 0 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
if (ret_cb != append_cb2 || ret_count != &count2)
|
|
TEST_ERROR;
|
|
|
|
/* Close the access property list */
|
|
if (H5Pclose(ddapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get the dataset's access property list for did2 */
|
|
if ((ddapl = H5Dget_access_plist(did2)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Retrieve the append flush property values */
|
|
if (H5Pget_append_flush(ddapl, 3, ret_boundary, &ret_cb, (void **)&ret_count) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Verify expected values: should be the setting in dapl2 */
|
|
if (ret_boundary[0] != 1 || ret_boundary[1] != 0 || ret_boundary[2] != 0)
|
|
TEST_ERROR;
|
|
if (ret_cb != append_cb2 || ret_count != &count2)
|
|
TEST_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Pclose(ddapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dapl2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dapl1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(dcpl);
|
|
H5Pclose(dapl1);
|
|
H5Pclose(dapl2);
|
|
H5Pclose(ddapl);
|
|
H5Dclose(did1);
|
|
H5Dclose(did2);
|
|
H5Pclose(fapl);
|
|
H5Sclose(sid);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_append_flush_dataset_multiple() */
|
|
|
|
/****************************************************************
|
|
**
|
|
** test_file_lock_same():
|
|
** With the implementation of file locking, this test checks file
|
|
** open with different combinations of flags.
|
|
** This is for single process access.
|
|
**
|
|
*****************************************************************/
|
|
static int
|
|
test_file_lock_same(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID, fid2 = H5I_INVALID_HID; /* File IDs */
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list */
|
|
unsigned intent; /* File access flags */
|
|
char filename[NAME_BUF_SIZE]; /* file name */
|
|
|
|
/* Output message about test being performed */
|
|
TESTING("File open with different combinations of flags--single process access");
|
|
|
|
/* Set locking in the fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_file_locking(fapl, true, true) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[1], fapl, filename, sizeof(filename));
|
|
|
|
/*
|
|
* Case 1: 1) RDWR 2) RDWR : should succeed
|
|
*/
|
|
/* Create file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get and check file intent */
|
|
if (H5Fget_intent(fid, &intent) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (intent != H5F_ACC_RDWR)
|
|
TEST_ERROR;
|
|
|
|
/* Open the same file with RDWR */
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get and check the intent */
|
|
if (H5Fget_intent(fid2, &intent) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (intent != H5F_ACC_RDWR)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 2: 1) RDWR 2) RDONLY : should succeed
|
|
*/
|
|
/* Open file with RDWR */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get and check the intent */
|
|
if (H5Fget_intent(fid, &intent) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (intent != H5F_ACC_RDWR)
|
|
TEST_ERROR;
|
|
|
|
/* Open file with RDONLY */
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get and check the intent: should get intent from 1st open */
|
|
if (H5Fget_intent(fid2, &intent) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (intent != H5F_ACC_RDWR)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 3: 1) RDONLY 2) RDWR : should fail
|
|
*/
|
|
/* Open file with RDONLY */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get and check the intent */
|
|
if (H5Fget_intent(fid, &intent) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (intent != H5F_ACC_RDONLY)
|
|
TEST_ERROR;
|
|
|
|
/* Open file with RDWR should fail */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid2 >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close first file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 4: 1) RDONLY 2) RDONLY : should succeed
|
|
*/
|
|
/* Open file with RDONLY */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get and check the intent */
|
|
if (H5Fget_intent(fid, &intent) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (intent != H5F_ACC_RDONLY)
|
|
TEST_ERROR;
|
|
|
|
/* Open file with RDONLY */
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get and check the intent */
|
|
if (H5Fget_intent(fid2, &intent) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (intent != H5F_ACC_RDONLY)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
H5Fclose(fid2);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* end test_file_lock_same() */
|
|
|
|
/****************************************************************
|
|
**
|
|
** test_file_lock_swmr_same():
|
|
** With the implementation of file locking, this test checks file
|
|
** open with different combinations of flags + SWMR flags.
|
|
** This is for single process access.
|
|
**
|
|
*****************************************************************/
|
|
static int
|
|
test_file_lock_swmr_same(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File IDs */
|
|
hid_t fid2 = H5I_INVALID_HID;
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list */
|
|
char filename[NAME_BUF_SIZE]; /* file name */
|
|
|
|
/* Output message about test being performed */
|
|
TESTING("File open with different combinations of flags + SWMR flags--single process access");
|
|
|
|
/* Set locking in the fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[1], fapl, filename, sizeof(filename));
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create a file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Cases a, b, c, d: H5Fopen failure cases
|
|
*/
|
|
|
|
/*
|
|
* Case a: RDWR|SWRM_READ : should fail
|
|
*/
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_READ, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid >= 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case b: RDWR|SWMM_WRTE|SWMR_READ : should fail
|
|
*/
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid >= 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case c: RDONLY|SWMM_WRITE : should fail
|
|
*/
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid >= 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Case d: RDONLY|SWMM_WRITE|SWMR_READ : should fail
|
|
*/
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid >= 0)
|
|
TEST_ERROR;
|
|
|
|
/*
|
|
* Cases 1 - 12: combinations of different flags for 1st and 2nd opens
|
|
*/
|
|
|
|
/*
|
|
* Case 1: 1) RDWR 2) RDWR|SWMR_WRITE : should fail
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid2 = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid2 >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 2: 1) RDWR 2) RDONLY|SWMR_READ : should succeed
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
|
|
TEST_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 3: 1) RDWR|SWMR_WRITE 2)RDWR : should succeed
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 4: 1) RDWR|SWMR_WRITE 2) RDWR|SWMR_WRITE : should succeed
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 5: 1) RDWR|SWMR_WRITE 2) RDONLY|SWMR_READ : should succeed
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 6: 1) RDWR|SWMR_WRITE 2) RDONLY : should succeed
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 7: 1) RDONLY|SWMR_READ 2)RDWR : should fail
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid2 = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid2 >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 8: 1) RDONLY|SWMR_READ 2) RDWR|SWMR_WRITE : should fail
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid2 = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid2 >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 9: 1) RDONLY|SWMR_READ 2) RDONLY|SWMR_READ : should succeed
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 10: 1) RDONLY|SWMR_READ 2) RDONLY : should succeed
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
TEST_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 11: 1) RDONLY 2) RDWR|SWMR_WRITE: should fail
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid2 = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid2 >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 12: 1) RDONLY 2) RDONLY|SWMR_READ : should fail
|
|
*/
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid2 = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid2 >= 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
H5Fclose(fid2);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* end test_file_lock_swmr_same() */
|
|
|
|
/****************************************************************
|
|
**
|
|
** test_file_lock_concur():
|
|
** With the implementation of file locking, this test checks file
|
|
** open with different combinations of flags.
|
|
** This is for concurrent access.
|
|
**
|
|
*****************************************************************/
|
|
#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID) && defined(H5_HAVE_FLOCK))
|
|
|
|
static int
|
|
test_file_lock_concur(hid_t H5_ATTR_UNUSED in_fapl)
|
|
{
|
|
/* Output message about test being performed */
|
|
TESTING("File open with different combinations of flags--concurrent access");
|
|
SKIPPED();
|
|
puts(" Test skipped due to fork or waitpid not defined.");
|
|
return 0;
|
|
|
|
} /* end test_file_lock_concur() */
|
|
|
|
#else /* !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID) && defined(H5_HAVE_FLOCK)) */
|
|
|
|
static int
|
|
test_file_lock_concur(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list */
|
|
char filename[NAME_BUF_SIZE]; /* file name */
|
|
pid_t childpid = 0; /* Child process ID */
|
|
int child_status; /* Status passed to waitpid */
|
|
int child_wait_option = 0; /* Options passed to waitpid */
|
|
int out_pdf[2];
|
|
int notify = 0;
|
|
|
|
/* Output message about test being performed */
|
|
TESTING("File open with different combinations of flags--concurrent access");
|
|
|
|
/* Set locking in the fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_file_locking(fapl, true, true) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[1], fapl, filename, sizeof(filename));
|
|
|
|
/* Create the test file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 1: 1) RDWR 2) RDWR : should fail
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDWR, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 2: 1) RDWR 2) RDONLY : should fail
|
|
*/
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Opens the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Opens the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 3: 1) RDONLY 2) RDWR : should fail
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Opens the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDWR, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
} /* end if */
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Opens the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 4: 1) RDONLY 2) RDONLY : should succeed
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Opens the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should succeed */
|
|
if (child_fid >= 0) {
|
|
/* Close the file */
|
|
if (H5Fclose(child_fid) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
} /* end if */
|
|
|
|
exit(EXIT_FAILURE);
|
|
} /* end if */
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
|
|
} /* end test_file_lock_concur() */
|
|
|
|
#endif /* #if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID) && defined(H5_HAVE_FLOCK)) */
|
|
|
|
/****************************************************************
|
|
**
|
|
** test_file_lock_swmr_concur(): low-level file test routine.
|
|
** With the implementation of file locking, this test checks file
|
|
** open with different combinations of flags + SWMR flags.
|
|
** This is for concurrent access.
|
|
**
|
|
*****************************************************************/
|
|
#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID))
|
|
|
|
static int
|
|
test_file_lock_swmr_concur(hid_t H5_ATTR_UNUSED in_fapl)
|
|
{
|
|
/* Output message about test being performed */
|
|
TESTING("File open with different combintations of flags + SWMR flags--concurrent access");
|
|
SKIPPED();
|
|
puts(" Test skipped due to fork or waitpid not defined.");
|
|
return 0;
|
|
|
|
} /* end test_file_lock_swmr_concur() */
|
|
|
|
#else /* !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) */
|
|
|
|
static int
|
|
test_file_lock_swmr_concur(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl; /* File access property list */
|
|
char filename[NAME_BUF_SIZE]; /* file name */
|
|
pid_t childpid = 0; /* Child process ID */
|
|
int child_status; /* Status passed to waitpid */
|
|
int child_wait_option = 0; /* Options passed to waitpid */
|
|
int out_pdf[2];
|
|
int notify = 0;
|
|
|
|
/* Output message about test being performed */
|
|
TESTING("File open with different combintations of flags + SWMR flags--concurrent access");
|
|
|
|
/* Set locking in the fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_file_locking(fapl, true, true) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[2], fapl, filename, sizeof(filename));
|
|
|
|
/* Set to use latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the test file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 1: 1) RDWR 2) RDWR|SWMR_WRITE : should fail
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 2: 1) RDWR 2) RDONLY|SWMR_READ: should fail
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 3: 1) RDWR|SWMR_WRITE 2) RDWR : should fail
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 4: 1) RDWR|SWMR_WRITE 2) RDWR|SWMR_WRITE : should fail
|
|
*/
|
|
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 5: 1) RDWR|SWMR_WRITE 2) RDONLY|SWMR_READ : should succeed
|
|
*/
|
|
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should succeed */
|
|
if (child_fid >= 0) {
|
|
if (H5Fclose(child_fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 6: 1) RDWR|SWMR_WRITE 2) RDONLY : should fail
|
|
*/
|
|
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 7: 1) RDONLY|SWMR_READ 2) RDWR : should fail
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDWR, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 8: 1) RDONLY|SWMR_READ 2) RDWR|SWMR_WRITE : should fail
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 9: 1) RDONLY|SWMR_READ 2) RDONLY|SWMR_READ : should succeed
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should succeed */
|
|
if (child_fid >= 0) {
|
|
if (H5Fclose(child_fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 10: 1) RDONLY|SWMR_READ 2) RDONLY : should succeed
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
if ((child_fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Should succeed */
|
|
if (child_fid >= 0) {
|
|
if (H5Fclose(child_fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 11: 1) RDONLY 2) RDWR|SWMR_WRITE : should fail
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should fail */
|
|
if (child_fid == FAIL)
|
|
exit(EXIT_SUCCESS);
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/*
|
|
* Case 12: 1) RDONLY 2) RDONLY|SWMR_READ : should succeed
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Should succeed */
|
|
if (child_fid >= 0) {
|
|
if (H5Fclose(child_fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check if child terminated normally */
|
|
if (WIFEXITED(child_status)) {
|
|
/* Check exit status of the child */
|
|
if (WEXITSTATUS(child_status) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
|
|
} /* end test_file_lock_swmr_concur() */
|
|
|
|
#endif /* !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) */
|
|
|
|
/****************************************************************
|
|
**
|
|
** test_file_locking():
|
|
** Tests various combinations of file locking flags and
|
|
** and environment variables.
|
|
**
|
|
*****************************************************************/
|
|
static int
|
|
test_file_locking(hid_t in_fapl, bool turn_locking_on, bool env_var_override)
|
|
{
|
|
#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID))
|
|
if (turn_locking_on && env_var_override)
|
|
TESTING("File locking: ON w/ env var override");
|
|
else if (turn_locking_on && !env_var_override)
|
|
TESTING("File locking: ON");
|
|
else if (!turn_locking_on && env_var_override)
|
|
TESTING("File locking: OFF w/ env var override");
|
|
else
|
|
TESTING("File locking: OFF");
|
|
SKIPPED();
|
|
puts(" Test skipped due to fork or waitpid not defined.");
|
|
return 0;
|
|
#else /* !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) */
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list */
|
|
char filename[NAME_BUF_SIZE]; /* file name */
|
|
pid_t childpid = 0; /* Child process ID */
|
|
int child_status; /* Status passed to waitpid */
|
|
int child_wait_option = 0; /* Options passed to waitpid */
|
|
int out_pdf[2];
|
|
int notify = 0;
|
|
int exit_status = 0;
|
|
herr_t ret;
|
|
|
|
if (turn_locking_on && env_var_override)
|
|
TESTING("File locking: ON w/ env var override");
|
|
else if (turn_locking_on && !env_var_override)
|
|
TESTING("File locking: ON");
|
|
else if (!turn_locking_on && env_var_override)
|
|
TESTING("File locking: OFF w/ env var override");
|
|
else
|
|
TESTING("File locking: OFF");
|
|
|
|
/* Copy the incoming fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set locking in the fapl */
|
|
if (H5Pset_file_locking(fapl, turn_locking_on ? true : false, true) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* If requested, set the environment variable */
|
|
if (env_var_override) {
|
|
if (HDsetenv(HDF5_USE_FILE_LOCKING, turn_locking_on ? "FALSE" : "TRUE", true) < 0)
|
|
TEST_ERROR;
|
|
if (H5F__reparse_file_lock_variable_test() < 0)
|
|
TEST_ERROR;
|
|
}
|
|
else {
|
|
if (HDsetenv(HDF5_USE_FILE_LOCKING, "", true) < 0)
|
|
TEST_ERROR;
|
|
if (H5F__reparse_file_lock_variable_test() < 0)
|
|
TEST_ERROR;
|
|
}
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[1], fapl, filename, sizeof(filename));
|
|
|
|
/* Create the test file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Open a file for read-only and then read-write. This will fail
|
|
* when the locking scheme is turned on.
|
|
*/
|
|
|
|
/* Create 1 pipe */
|
|
if (pipe(out_pdf) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (childpid == 0) {
|
|
|
|
/* Child process */
|
|
|
|
hid_t child_fid = H5I_INVALID_HID; /* File ID */
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1) {
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Open and close the test file */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
child_fid = H5Fopen(filename, H5F_ACC_RDWR, fapl);
|
|
ret = H5Fclose(child_fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
if (H5I_INVALID_HID == child_fid || FAIL == ret)
|
|
exit(EXIT_FAILURE);
|
|
else
|
|
exit(EXIT_SUCCESS);
|
|
} /* end child process work */
|
|
|
|
/* close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the pipe */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if (waitpid(childpid, &child_status, child_wait_option) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Check exit status of the child */
|
|
if (WIFEXITED(child_status))
|
|
exit_status = WEXITSTATUS(child_status);
|
|
else
|
|
TEST_ERROR;
|
|
|
|
/* The child process should have passed or failed as follows:
|
|
*
|
|
* locks on: FAIL
|
|
* locks off: PASS
|
|
* locks on, env var override: PASS
|
|
* locks off, env var override: FAIL
|
|
*/
|
|
if (turn_locking_on && !env_var_override && (0 == exit_status))
|
|
TEST_ERROR;
|
|
else if (!turn_locking_on && !env_var_override && (0 != exit_status))
|
|
TEST_ERROR;
|
|
else if (turn_locking_on && env_var_override && (0 != exit_status))
|
|
TEST_ERROR;
|
|
else if (!turn_locking_on && env_var_override && (0 == exit_status))
|
|
TEST_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the copied property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
|
|
#endif /* !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) */
|
|
|
|
} /* end test_file_locking() */
|
|
|
|
/****************************************************************
|
|
**
|
|
** test_different_lock_flags():
|
|
** Tests opening a file multiple times with different lock
|
|
** flags.
|
|
**
|
|
*****************************************************************/
|
|
static int
|
|
test_different_lock_flags(hid_t in_fapl)
|
|
{
|
|
hid_t fid1 = H5I_INVALID_HID; /* File ID */
|
|
hid_t fid2 = H5I_INVALID_HID; /* File ID */
|
|
hid_t fid3 = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl_id = H5I_INVALID_HID; /* File access property list */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
|
|
TESTING("Using different lock flags");
|
|
|
|
/* Copy the incoming fapl */
|
|
if ((fapl_id = H5Pcopy(in_fapl)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set locking in the fapl */
|
|
if (H5Pset_file_locking(fapl_id, true, true) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[1], fapl_id, filename, sizeof(filename));
|
|
|
|
/* Create the test file */
|
|
if ((fid1 = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Open the test file with the same flags (should pass) */
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Unset locking in the fapl */
|
|
if (H5Pset_file_locking(fapl_id, false, false) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Open the test file with different flags (should FAIL) */
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid3 = H5Fopen(filename, H5F_ACC_RDWR, fapl_id);
|
|
}
|
|
H5E_END_TRY
|
|
if (H5I_INVALID_HID != fid3)
|
|
FAIL_PUTS_ERROR("Should not have been able to open a file with different locking flags");
|
|
|
|
/* Close the files */
|
|
if (H5Fclose(fid1) < 0)
|
|
TEST_ERROR;
|
|
if (H5Fclose(fid2) < 0)
|
|
TEST_ERROR;
|
|
|
|
/* Close the copied property list */
|
|
if (H5Pclose(fapl_id) < 0)
|
|
TEST_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(fapl_id);
|
|
H5Fclose(fid1);
|
|
H5Fclose(fid2);
|
|
H5Fclose(fid3);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* end test_different_lock_flags() */
|
|
|
|
static int
|
|
test_swmr_vfd_flag(void)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* file ID */
|
|
hid_t sec2_fapl = H5I_INVALID_HID; /* fapl ID of a VFD that supports SWMR writes (sec2) */
|
|
hid_t bad_fapl = H5I_INVALID_HID; /* fapl ID of a VFD that does not support SWMR writes (stdio) */
|
|
char filename[NAME_BUF_SIZE]; /* file name */
|
|
|
|
TESTING("SWMR-enabled VFD flag functionality");
|
|
|
|
/* Attempt to open a file using a SWMR-compatible VFD. */
|
|
|
|
if ((sec2_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_fapl_sec2(sec2_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_libver_bounds(sec2_fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
h5_fixname(FILENAME[0], sec2_fapl, filename, sizeof(filename));
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE, H5P_DEFAULT, sec2_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Attempt to open a file using a non-SWMR-compatible VFD. */
|
|
|
|
if ((bad_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_fapl_stdio(bad_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_libver_bounds(bad_fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
fid = -1;
|
|
h5_fixname(FILENAME[0], bad_fapl, filename, sizeof(filename));
|
|
H5E_BEGIN_TRY
|
|
{
|
|
fid = H5Fcreate(filename, H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE, H5P_DEFAULT, bad_fapl);
|
|
}
|
|
H5E_END_TRY
|
|
if (fid >= 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Pclose(sec2_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(bad_fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Pclose(sec2_fapl);
|
|
H5Pclose(bad_fapl);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_swmr_vfd_flag() */
|
|
|
|
#ifdef OUT
|
|
/*
|
|
* This exposes a bug for H5Orefresh while handling opened objects for H5Fstart_swmr_write().
|
|
* The boolean to skip file truncation test when reading in superblock will fix the problem.
|
|
* Will work to move that to test/flushrefresh.c later.
|
|
*/
|
|
static int
|
|
test_bug_refresh(hid_t in_fapl)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID;
|
|
hid_t fapl = H5I_INVALID_HID;
|
|
H5F_t *f;
|
|
hid_t gid1 = H5I_INVALID_HID;
|
|
hid_t gid2 = H5I_INVALID_HID;
|
|
hid_t gid3 = H5I_INVALID_HID;
|
|
hid_t gid4 = H5I_INVALID_HID;
|
|
hid_t gid5 = H5I_INVALID_HID;
|
|
hid_t gid6 = H5I_INVALID_HID;
|
|
hid_t gid7 = H5I_INVALID_HID;
|
|
hid_t gid8 = H5I_INVALID_HID;
|
|
hid_t gid9 = H5I_INVALID_HID;
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
|
|
/* Create a copy of the input parameter in_fapl */
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
TESTING("H5Orefresh failure conditions");
|
|
|
|
/* Create a file with the latest format */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Get a pointer to the internal file object */
|
|
if (NULL == (f = (H5F_t *)H5VL_object(fid)))
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create groups: compact to dense storage */
|
|
if ((gid1 = H5Gcreate2(fid, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((gid2 = H5Gcreate2(fid, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((gid3 = H5Gcreate2(fid, "group3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((gid4 = H5Gcreate2(fid, "group4", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((gid5 = H5Gcreate2(fid, "group5", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((gid6 = H5Gcreate2(fid, "group6", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((gid7 = H5Gcreate2(fid, "group7", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((gid8 = H5Gcreate2(fid, "group8", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((gid9 = H5Gcreate2(fid, "group9", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (H5Fflush(fid, H5F_SCOPE_GLOBAL) < 0)
|
|
TEST_ERROR;
|
|
|
|
if (H5Grefresh(gid1) < 0)
|
|
TEST_ERROR;
|
|
if (H5Grefresh(gid2) < 0)
|
|
TEST_ERROR;
|
|
if (H5Grefresh(gid3) < 0)
|
|
TEST_ERROR;
|
|
if (H5Grefresh(gid4) < 0)
|
|
TEST_ERROR;
|
|
if (H5Grefresh(gid5) < 0)
|
|
TEST_ERROR;
|
|
if (H5Grefresh(gid6) < 0)
|
|
TEST_ERROR;
|
|
if (H5Grefresh(gid7) < 0)
|
|
TEST_ERROR;
|
|
if (H5Grefresh(gid8) < 0)
|
|
TEST_ERROR;
|
|
if (H5Grefresh(gid9) < 0)
|
|
TEST_ERROR;
|
|
|
|
H5Gclose(gid1);
|
|
H5Gclose(gid2);
|
|
H5Gclose(gid3);
|
|
H5Gclose(gid4);
|
|
H5Gclose(gid5);
|
|
H5Gclose(gid6);
|
|
H5Gclose(gid7);
|
|
H5Gclose(gid8);
|
|
H5Gclose(gid9);
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
PASSED();
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Gclose(gid1);
|
|
H5Gclose(gid2);
|
|
H5Gclose(gid3);
|
|
H5Gclose(gid4);
|
|
H5Gclose(gid5);
|
|
H5Gclose(gid6);
|
|
H5Gclose(gid7);
|
|
H5Gclose(gid8);
|
|
H5Gclose(gid9);
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
} /* test_bug_refresh() */
|
|
#endif /* OUT */
|
|
|
|
/*
|
|
* test_refresh_concur():
|
|
*
|
|
* The "new_format" parameter indicates whether to create the file with latest format or not.
|
|
* To have SWMR support, can use either one of the following in creating a file:
|
|
* (a) Create the file with write + latest format:
|
|
* --result in v3 superblock with latest chunk indexing types
|
|
* (b) Create the file with SWMR write + non-latest-format:
|
|
* --result in v3 superblock with latest chunk indexing types
|
|
*
|
|
* Verify H5Drefresh() works correctly with concurrent access:
|
|
* Parent process:
|
|
* (1) Open the test file, write to the dataset
|
|
* (2) Notify child process #A
|
|
* (3) Wait for notification from child process #B
|
|
* (4) Extend the dataset, write to the dataset, flush the file
|
|
* (5) Notify child process #C
|
|
* Child process:
|
|
* (1) Wait for notification from parent process #A
|
|
* (2) Open the file 2 times
|
|
* (3) Open the dataset 2 times with the 2 files
|
|
* (4) Verify the dataset's dimension and data read are correct
|
|
* (5) Notify parent process #B
|
|
* (6) Wait for notification from parent process #C
|
|
* (7) Refresh the dataset
|
|
* (8) Verify the dataset's dimension and data are correct
|
|
*/
|
|
#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID))
|
|
|
|
static int
|
|
test_refresh_concur(hid_t H5_ATTR_UNUSED in_fapl, bool new_format)
|
|
{
|
|
if (new_format) {
|
|
TESTING("H5Drefresh()--concurrent access for latest format");
|
|
}
|
|
else {
|
|
TESTING("H5Drefresh()--concurrent access for non-latest-format");
|
|
}
|
|
|
|
SKIPPED();
|
|
puts(" Test skipped due to fork or waitpid not defined.");
|
|
return 0;
|
|
} /* test_refresh_concur() */
|
|
|
|
#else /* !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) */
|
|
|
|
static int
|
|
test_refresh_concur(hid_t in_fapl, bool new_format)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID; /* File ID */
|
|
hid_t fapl; /* File access property list */
|
|
pid_t childpid = 0; /* Child process ID */
|
|
pid_t tmppid; /* Child process ID returned by waitpid */
|
|
int child_status; /* Status passed to waitpid */
|
|
int child_wait_option = 0; /* Options passed to waitpid */
|
|
int child_exit_val; /* Exit status of the child */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
|
|
hid_t did = H5I_INVALID_HID;
|
|
hid_t sid = H5I_INVALID_HID;
|
|
hid_t dcpl = H5I_INVALID_HID;
|
|
hsize_t chunk_dims[1] = {1};
|
|
hsize_t maxdims[1] = {H5S_UNLIMITED};
|
|
hsize_t dims[1] = {1};
|
|
hsize_t new_dims[1] = {2};
|
|
|
|
int out_pdf[2];
|
|
int in_pdf[2];
|
|
int notify = 0;
|
|
int wbuf[2];
|
|
|
|
/* Output message about test being performed */
|
|
if (new_format) {
|
|
TESTING("H5Drefresh()--concurrent access for latest format");
|
|
}
|
|
else {
|
|
TESTING("H5Drefresh()--concurrent access for non-latest-format");
|
|
} /* end if */
|
|
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if (new_format) {
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the test file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
else {
|
|
/* Create the test file without latest format but with SWMR write */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
} /* end if */
|
|
|
|
/* Create a chunked dataset with 1 extendible dimension */
|
|
if ((sid = H5Screate_simple(1, dims, maxdims)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 1, chunk_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Dclose(did) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create 2 pipes */
|
|
if (pipe(out_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (pipe(in_pdf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Fork child process */
|
|
if ((childpid = fork()) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
if (childpid == 0) { /* Child process */
|
|
hid_t child_fid1 = H5I_INVALID_HID; /* File ID */
|
|
hid_t child_fid2 = H5I_INVALID_HID; /* File ID */
|
|
hid_t child_did1 = H5I_INVALID_HID, child_did2 = H5I_INVALID_HID;
|
|
hid_t child_sid = H5I_INVALID_HID;
|
|
hsize_t tdims[1];
|
|
int rbuf[2] = {0, 0};
|
|
int child_notify = 0;
|
|
|
|
/* Close unused write end for out_pdf */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* close unused read end for in_pdf */
|
|
if (HDclose(in_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 1)
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Open the file 2 times */
|
|
if ((child_fid1 = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
if ((child_fid2 = H5Fopen(filename, H5F_ACC_RDONLY | H5F_ACC_SWMR_READ, fapl)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Open the dataset 2 times */
|
|
if ((child_did1 = H5Dopen2(child_fid1, "dataset", H5P_DEFAULT)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if ((child_did2 = H5Dopen2(child_fid2, "dataset", H5P_DEFAULT)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Get the dataset's dataspace via did1 */
|
|
if ((child_sid = H5Dget_space(child_did1)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (H5Sget_simple_extent_dims(child_sid, tdims, NULL) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (tdims[0] != 1)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Read from the dataset via did2 */
|
|
if (H5Dread(child_did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Verify the data is correct */
|
|
if (rbuf[0] != 99)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Notify parent process */
|
|
child_notify = 2;
|
|
if (HDwrite(in_pdf[1], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Wait for notification from parent process */
|
|
while (child_notify != 3)
|
|
if (HDread(out_pdf[0], &child_notify, sizeof(int)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Refresh dataset via did1 */
|
|
if (H5Drefresh(child_did1) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Get the dataset's dataspace and verify */
|
|
if ((child_sid = H5Dget_space(child_did1)) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (H5Sget_simple_extent_dims(child_sid, tdims, NULL) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
if (tdims[0] != 2)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Read from the dataset */
|
|
if (H5Dread(child_did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Verify the data is correct */
|
|
if (rbuf[0] != 100 || rbuf[1] != 100)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the 2 datasets */
|
|
if (H5Dclose(child_did1) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (H5Dclose(child_did2) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the 2 files */
|
|
if (H5Fclose(child_fid1) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (H5Fclose(child_fid2) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
/* Close the pipes */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
if (HDclose(in_pdf[1]) < 0)
|
|
exit(EXIT_FAILURE);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/* Close unused read end for out_pdf */
|
|
if (HDclose(out_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Close unused write end for in_pdf */
|
|
if (HDclose(in_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the test file */
|
|
if ((fid = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset */
|
|
if ((did = H5Dopen2(fid, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to the dataset */
|
|
wbuf[0] = wbuf[1] = 99;
|
|
if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Flush to disk */
|
|
if (H5Fflush(fid, H5F_SCOPE_LOCAL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 1;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for notification from child process */
|
|
while (notify != 2) {
|
|
if (HDread(in_pdf[0], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
|
|
/* Cork the metadata cache, to prevent the object header from being
|
|
* flushed before the data has been written */
|
|
if (H5Odisable_mdc_flushes(did) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Extend the dataset */
|
|
if (H5Dset_extent(did, new_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to the dataset */
|
|
wbuf[0] = wbuf[1] = 100;
|
|
if (H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Uncork the metadata cache */
|
|
if (H5Oenable_mdc_flushes(did) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Flush to disk */
|
|
if (H5Fflush(fid, H5F_SCOPE_LOCAL) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Notify child process */
|
|
notify = 3;
|
|
if (HDwrite(out_pdf[1], ¬ify, sizeof(int)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the pipes */
|
|
if (HDclose(out_pdf[1]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (HDclose(in_pdf[0]) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Wait for child process to complete */
|
|
if ((tmppid = waitpid(childpid, &child_status, child_wait_option)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Check exit status of child process */
|
|
if (WIFEXITED(child_status)) {
|
|
if ((child_exit_val = WEXITSTATUS(child_status)) != 0)
|
|
TEST_ERROR;
|
|
}
|
|
else /* Child process terminated abnormally */
|
|
TEST_ERROR;
|
|
|
|
/* Close the dataset */
|
|
if (H5Dclose(did) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Dclose(did);
|
|
H5Sclose(sid);
|
|
H5Pclose(dcpl);
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return -1;
|
|
|
|
} /* test_refresh_concur() */
|
|
#endif /* !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)) */
|
|
|
|
/*
|
|
* test_multiple_same():
|
|
*
|
|
* The "new_format" parameter indicates whether to create the file with latest format or not.
|
|
* To have SWMR support, can use either one of the following in creating a file:
|
|
* (a) Create the file with write + latest format:
|
|
* --result in v3 superblock with latest chunk indexing types
|
|
* (b) Create the file with SWMR write + non-latest-format:
|
|
* --result in v3 superblock with latest chunk indexing types
|
|
*
|
|
* Verify that H5Drefresh() and H5Fstart_swmr_write() work properly with multiple
|
|
* opens of files and datasets.
|
|
*/
|
|
static int
|
|
test_multiple_same(hid_t in_fapl, bool new_format)
|
|
{
|
|
hid_t fid = H5I_INVALID_HID, fid1 = H5I_INVALID_HID, fid2 = H5I_INVALID_HID,
|
|
fid3 = H5I_INVALID_HID; /* File IDs */
|
|
hid_t fapl; /* File access property list */
|
|
char filename[NAME_BUF_SIZE]; /* File name */
|
|
hid_t did = H5I_INVALID_HID, did1 = H5I_INVALID_HID, did2 = H5I_INVALID_HID, did3 = H5I_INVALID_HID;
|
|
hid_t sid = H5I_INVALID_HID;
|
|
hid_t dcpl = H5I_INVALID_HID;
|
|
hsize_t chunk_dims[2] = {1, 2};
|
|
hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED};
|
|
hsize_t dims[2] = {1, 1};
|
|
int rbuf = 0;
|
|
int wbuf = 0;
|
|
|
|
/* Output message about test being performed */
|
|
if (new_format) {
|
|
TESTING("multiple--single process access for latest format");
|
|
}
|
|
else {
|
|
TESTING("multiple--single process access for non-latest-format");
|
|
} /* end if */
|
|
|
|
if ((fapl = H5Pcopy(in_fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Set the filename to use for this test (dependent on fapl) */
|
|
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
|
|
|
|
if (new_format) {
|
|
/* Set to use the latest library format */
|
|
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Create the test file */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
}
|
|
else {
|
|
/* Create the test file without latest format but with SWMR write */
|
|
if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
} /* end if */
|
|
|
|
/* Create a chunked dataset with 1 extendible dimension */
|
|
if ((sid = H5Screate_simple(2, dims, maxdims)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pset_chunk(dcpl, 2, chunk_dims) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Closing */
|
|
if (H5Dclose(did) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Sclose(sid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Pclose(dcpl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the file */
|
|
if (H5Fclose(fid) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 1 */
|
|
|
|
/* Open the file 3 times: SWMR-write, read-write, read-only */
|
|
if ((fid1 = H5Fopen(filename, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid3 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset 3 times with fid1, fid2, fid3 */
|
|
if ((did1 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did2 = H5Dopen2(fid2, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did3 = H5Dopen2(fid3, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to the dataset via did1 */
|
|
wbuf = 88;
|
|
if (H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Refresh via did2 */
|
|
if (H5Drefresh(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read from the dataset via did2 */
|
|
rbuf = 0;
|
|
if (H5Dread(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Verify the data is correct */
|
|
if (rbuf != 88)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to the dataset via did3 */
|
|
wbuf = 99;
|
|
if (H5Dwrite(did3, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Refresh via did1 */
|
|
if (H5Drefresh(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read from the dataset via did1 */
|
|
rbuf = 0;
|
|
if (H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
/* Verify the data is correct */
|
|
if (rbuf != 99)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close datasets */
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close files */
|
|
if (H5Fclose(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 2 */
|
|
|
|
/* Open the file 3 times: read-write, read-only, read-write */
|
|
if ((fid1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid3 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset 3 times with fid1, fid2, fid3 */
|
|
if ((did1 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did2 = H5Dopen2(fid2, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did3 = H5Dopen2(fid3, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to the dataset via did1 */
|
|
wbuf = 88;
|
|
if (H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Refresh via did2 */
|
|
if (H5Drefresh(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read from dataset via did2 */
|
|
rbuf = 0;
|
|
if (H5Dread(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (rbuf != wbuf)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to dataset via did3 */
|
|
wbuf = 99;
|
|
if (H5Dwrite(did3, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Enable SWMR write */
|
|
if (H5Fstart_swmr_write(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read from dataset via did1 and verify data is correct */
|
|
rbuf = 0;
|
|
if (H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (rbuf != wbuf)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to dataset via did2 */
|
|
wbuf = 100;
|
|
if (H5Dwrite(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Refresh dataset via did3 */
|
|
if (H5Drefresh(did3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read from dataset via did3 and verify data is correct */
|
|
rbuf = 0;
|
|
if (H5Dread(did3, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (rbuf != wbuf)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close datasets */
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Dclose(did3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close files */
|
|
if (H5Fclose(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (H5Fclose(fid3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Case 3 */
|
|
|
|
/* Open the file 3 times: read-write, read-only, read-only */
|
|
if ((fid1 = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid2 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((fid3 = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Open the dataset 3 times with fid1, fid2, fid3 */
|
|
if ((did1 = H5Dopen2(fid1, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did2 = H5Dopen2(fid2, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if ((did3 = H5Dopen2(fid3, "dataset", H5P_DEFAULT)) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to the dataset via did1 */
|
|
wbuf = 88;
|
|
if (H5Dwrite(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Refresh dataset via did2 */
|
|
if (H5Drefresh(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read from dataset via did2 and verify data is correct */
|
|
rbuf = 0;
|
|
if (H5Dread(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (rbuf != wbuf)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close dataset via did2 */
|
|
if (H5Dclose(did2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file via fid2 */
|
|
if (H5Fclose(fid2) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Write to dataset via did3 */
|
|
wbuf = 99;
|
|
if (H5Dwrite(did3, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close dataset via did3 */
|
|
if (H5Dclose(did3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file via fid3 */
|
|
if (H5Fclose(fid3) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Enable SWMR writing */
|
|
if (H5Fstart_swmr_write(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Read from dataset via did1 and verify data is correct */
|
|
rbuf = 0;
|
|
if (H5Dread(did1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf) < 0)
|
|
FAIL_STACK_ERROR;
|
|
if (rbuf != wbuf)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close dataset via did1 */
|
|
if (H5Dclose(did1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close file via fid1 */
|
|
if (H5Fclose(fid1) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
/* Close the property list */
|
|
if (H5Pclose(fapl) < 0)
|
|
FAIL_STACK_ERROR;
|
|
|
|
PASSED();
|
|
return 0;
|
|
|
|
error:
|
|
H5E_BEGIN_TRY
|
|
{
|
|
H5Dclose(did);
|
|
H5Dclose(did1);
|
|
H5Dclose(did2);
|
|
H5Dclose(did3);
|
|
H5Sclose(sid);
|
|
H5Pclose(dcpl);
|
|
H5Pclose(fapl);
|
|
H5Fclose(fid);
|
|
H5Fclose(fid1);
|
|
H5Fclose(fid2);
|
|
H5Fclose(fid3);
|
|
}
|
|
H5E_END_TRY
|
|
|
|
return 1;
|
|
|
|
} /* test_multiple_same() */
|
|
|
|
/****************************************************************
|
|
**
|
|
** Tests for new public routines introduced from the SWMR project.
|
|
**
|
|
****************************************************************/
|
|
int
|
|
main(void)
|
|
{
|
|
int nerrors = 0; /* The # of errors */
|
|
hid_t fapl = H5I_INVALID_HID; /* File access property list ID */
|
|
char *driver = NULL; /* VFD string (from env variable) */
|
|
char *lock_env_var = NULL; /* file locking env var pointer */
|
|
bool use_file_locking; /* read from env var */
|
|
bool file_locking_enabled = false; /* Checks if the file system supports locks */
|
|
|
|
/* Testing setup */
|
|
h5_reset();
|
|
|
|
/* Skip this test if SWMR I/O is not supported for the VFD specified
|
|
* by the environment variable.
|
|
*/
|
|
driver = getenv(HDF5_DRIVER);
|
|
if (!H5FD__supports_swmr_test(driver)) {
|
|
printf("This VFD does not support SWMR I/O\n");
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
/* Check the environment variable that determines if we care
|
|
* about file locking. File locking should be used unless explicitly
|
|
* disabled.
|
|
*/
|
|
lock_env_var = getenv(HDF5_USE_FILE_LOCKING);
|
|
if (lock_env_var && !strcmp(lock_env_var, "FALSE"))
|
|
use_file_locking = false;
|
|
else
|
|
use_file_locking = true;
|
|
|
|
/* Check if file locking is enabled on this file system */
|
|
if (use_file_locking)
|
|
if (h5_check_if_file_locking_enabled(&file_locking_enabled) < 0) {
|
|
printf("Error when determining if file locks are enabled\n");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
/* Get file access property list */
|
|
fapl = h5_fileaccess();
|
|
|
|
#ifdef OUT
|
|
nerrors += test_bug_refresh(fapl);
|
|
#endif
|
|
nerrors += test_refresh_concur(fapl, true);
|
|
nerrors += test_refresh_concur(fapl, false);
|
|
nerrors += test_multiple_same(fapl, true);
|
|
nerrors += test_multiple_same(fapl, false);
|
|
|
|
/* Tests on H5Pget/set_metadata_read_attempts() and H5Fget_metadata_read_retry_info() */
|
|
nerrors += test_metadata_read_attempts(fapl);
|
|
nerrors += test_metadata_read_retry_info(fapl);
|
|
|
|
/* Tests on H5Fstart_swmr_write() */
|
|
/*
|
|
* Modify the following routines to test for files:
|
|
* H5Fcreate(write, latest format) or H5Fcreate(SWMR write, non-latest-format)
|
|
* --both result in v3 superblock and latest version support
|
|
*/
|
|
nerrors += test_start_swmr_write(fapl, true);
|
|
nerrors += test_start_swmr_write(fapl, false);
|
|
nerrors += test_err_start_swmr_write(fapl, true);
|
|
nerrors += test_err_start_swmr_write(fapl, false);
|
|
nerrors += test_start_swmr_write_concur(fapl, true);
|
|
nerrors += test_start_swmr_write_concur(fapl, false);
|
|
nerrors += test_start_swmr_write_stress_ohdr(fapl);
|
|
nerrors += test_start_swmr_write_persist_dapl(fapl);
|
|
|
|
/* Tests for H5Pget/set_object_flush_cb() */
|
|
nerrors += test_object_flush_cb(fapl);
|
|
|
|
/* Tests on H5Pget/set_append_flush() */
|
|
nerrors += test_append_flush_generic();
|
|
nerrors += test_append_flush_dataset_chunked(fapl);
|
|
nerrors += test_append_flush_dataset_fixed(fapl);
|
|
nerrors += test_append_flush_dataset_multiple(fapl);
|
|
|
|
if (use_file_locking && file_locking_enabled) {
|
|
/*
|
|
* Tests for:
|
|
* file open flags--single process access
|
|
* file open flags--concurrent access
|
|
*/
|
|
nerrors += test_file_lock_same(fapl);
|
|
nerrors += test_file_lock_concur(fapl);
|
|
/*
|
|
* Tests for:
|
|
* file open flags+SWMR flags--single process access
|
|
* file open flags+SWMR flags--concurrent access
|
|
*
|
|
* Modify the following 2 routines to test for files:
|
|
* H5Fcreate(write, latest format) or H5Fcreate(SWMR write, non-latest-format)
|
|
* --both result in v3 superblock and latest version support
|
|
*/
|
|
nerrors += test_file_lock_swmr_same(fapl);
|
|
nerrors += test_file_lock_swmr_concur(fapl);
|
|
}
|
|
|
|
/* Tests SWMR VFD compatibility flag.
|
|
* Only needs to run when the VFD is the default (sec2).
|
|
*/
|
|
if (NULL == driver || !strcmp(driver, "") || !strcmp(driver, "sec2"))
|
|
nerrors += test_swmr_vfd_flag();
|
|
|
|
/* Test multiple opens via different locking flags */
|
|
if (use_file_locking && file_locking_enabled)
|
|
nerrors += test_different_lock_flags(fapl);
|
|
|
|
/* These tests change the HDF5_USE_FILE_LOCKING environment variable
|
|
* so they should be run last.
|
|
*/
|
|
if (use_file_locking && file_locking_enabled) {
|
|
nerrors += test_file_locking(fapl, true, true);
|
|
nerrors += test_file_locking(fapl, true, false);
|
|
nerrors += test_file_locking(fapl, false, true);
|
|
nerrors += test_file_locking(fapl, false, false);
|
|
}
|
|
|
|
if (nerrors)
|
|
goto error;
|
|
|
|
printf("All tests passed.\n");
|
|
|
|
h5_cleanup(FILENAME, fapl);
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
error:
|
|
nerrors = MAX(1, nerrors);
|
|
printf("***** %d SWMR TEST%s FAILED! *****\n", nerrors, 1 == nerrors ? "" : "S");
|
|
return EXIT_FAILURE;
|
|
|
|
} /* end main() */
|