summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.am3
-rw-r--r--test/h5test.c1
-rw-r--r--test/testvfdswmr.sh.in215
-rw-r--r--test/vfd_swmr.c30
-rw-r--r--test/vfd_swmr_addrem_writer.c2
-rw-r--r--test/vfd_swmr_attrdset_writer.c395
-rw-r--r--test/vfd_swmr_bigset_writer.c5
-rw-r--r--test/vfd_swmr_dsetchks_writer.c606
-rw-r--r--test/vfd_swmr_dsetops_writer.c609
-rw-r--r--test/vfd_swmr_generator.c2
-rw-r--r--test/vfd_swmr_gperf_writer.c2979
-rw-r--r--test/vfd_swmr_group_writer.c22
-rw-r--r--test/vfd_swmr_reader.c2
-rw-r--r--test/vfd_swmr_remove_reader.c2
-rw-r--r--test/vfd_swmr_remove_writer.c2
-rw-r--r--test/vfd_swmr_sparse_reader.c2
-rw-r--r--test/vfd_swmr_sparse_writer.c2
-rw-r--r--test/vfd_swmr_vlstr_reader.c9
-rw-r--r--test/vfd_swmr_vlstr_writer.c2
-rw-r--r--test/vfd_swmr_writer.c2
-rw-r--r--test/vfd_swmr_zoo_writer.c2
21 files changed, 4172 insertions, 722 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index ee35664..3ae26bd 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -54,6 +54,7 @@ SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) links_env$(EXEEXT) \
vfd_swmr_group_reader$(EXEEXT) vfd_swmr_group_writer$(EXEEXT) \
vfd_swmr_vlstr_reader$(EXEEXT) vfd_swmr_vlstr_writer$(EXEEXT) \
vfd_swmr_zoo_reader$(EXEEXT) vfd_swmr_zoo_writer$(EXEEXT) \
+ vfd_swmr_gperf_reader$(EXEEXT) vfd_swmr_gperf_writer$(EXEEXT) \
vds_env$(EXEEXT) \
vds_swmr_gen$(EXEEXT) vds_swmr_reader$(EXEEXT) vds_swmr_writer$(EXEEXT)
if HAVE_SHARED_CONDITIONAL
@@ -111,6 +112,7 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version \
vfd_swmr_vlstr_reader vfd_swmr_vlstr_writer \
vfd_swmr_zoo_reader vfd_swmr_zoo_writer \
vfd_swmr_attrdset_reader vfd_swmr_attrdset_writer \
+ vfd_swmr_gperf_reader vfd_swmr_gperf_writer \
vfd_swmr_check_compat \
vfd_swmr_dsetchks_reader vfd_swmr_dsetchks_writer \
swmr_check_compat_vfd vds_env vds_swmr_gen vds_swmr_reader vds_swmr_writer \
@@ -178,6 +180,7 @@ vfd_swmr_zoo_reader_SOURCES=vfd_swmr_zoo_writer.c genall5.c
vfd_swmr_bigset_reader_SOURCES=vfd_swmr_bigset_writer.c
vfd_swmr_group_reader_SOURCES=vfd_swmr_group_writer.c
+vfd_swmr_gperf_reader_SOURCES=vfd_swmr_gperf_writer.c
vfd_swmr_dsetops_reader_SOURCES=vfd_swmr_dsetops_writer.c
vfd_swmr_attrdset_writer_SOURCES=vfd_swmr_attrdset_writer.c
diff --git a/test/h5test.c b/test/h5test.c
index 9ec29ed..755ae93 100644
--- a/test/h5test.c
+++ b/test/h5test.c
@@ -1925,7 +1925,6 @@ static const H5FD_class_t H5FD_dummy_g = {
NULL, /* lock */
NULL, /* unlock */
NULL, /* del */
- NULL, /* dedup */
H5FD_FLMAP_DICHOTOMY /* fl_map */
};
diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in
index 6095c03..ac54968 100644
--- a/test/testvfdswmr.sh.in
+++ b/test/testvfdswmr.sh.in
@@ -145,9 +145,9 @@ all_tests="generator expand shrink expand_shrink sparse vlstr_null vlstr_oob zoo
all_tests="${all_tests} groups groups_attrs groups_ops few_big many_small attrdset"
tests=${all_tests}
-# For exhaustive run, add: os_groups_attrs, os_groups_ops, dsetops, dsetchks
+# For exhaustive run, add: os_groups_attrs, os_groups_ops, os_groups_seg, dsetops, dsetchks
if [[ "$HDF5TestExpress" -eq 0 ]] ; then # exhaustive run
- all_tests="${all_tests} os_groups_attrs os_groups_ops dsetops dsetchks"
+ all_tests="${all_tests} os_groups_attrs os_groups_ops os_groups_seg dsetops dsetchks"
fi
if [ $# -gt 0 ]; then
@@ -1008,6 +1008,36 @@ done
###############################################################################
#
+# Setting for "os_groups_seg" test
+#
+# Only for exhaustive run
+#
+# Verify the segmentation fault is fixed when running with:
+# --1,000,000 groups
+# --as writer only
+#
+###############################################################################
+#
+#
+GROUP_seg_n=1000000 # Number of groups when segmentation fault occurs
+#
+if [ ${do_os_groups_seg:-no} != no ]; then
+ echo launch vfd_swmr_group operations with old-style group: $GROUP_seg_n groups ......may take some time......
+ catch_out_err_and_rc vfd_swmr_group_writer \
+ ../vfd_swmr_group_writer -q -N -G -n $GROUP_seg_n -a $GROUP_seg_n
+
+ # Collect exit code of the writer
+ if [ $(cat vfd_swmr_group_writer.rc) -ne 0 ]; then
+ echo writer had error
+ nerrors=$((nerrors + 1))
+ fi
+
+ # Clean up output files
+ rm -f vfd_swmr_group_writer.{out,rc}
+fi
+
+###############################################################################
+#
# Setting for bigset (few_big and many_small) tests
#
###############################################################################
@@ -1209,51 +1239,55 @@ done
###############################################################################
#
#
-for options in "-p -e 20 -t -q" "-g -m 5 -n 2 -s 10 -w 7 -q" "-k -m 10 -n 5 -r 5 -l 10 -q"; do
- #
- #
- if [ ${do_dsetops:-no} = no ]; then
- continue
- fi
- # Clean up any existing fifo files from previous runs
- if [ -e ./$DSETOPS_FIFO_WRITER_TO_READER ]; then # If writer fifo file is found
- rm -f ./$DSETOPS_FIFO_WRITER_TO_READER
- fi
- if [ -e ./$DSETOPS_FIFO_READER_TO_WRITER ]; then # If reader fifo file is found
- rm -f ./$DSETOPS_FIFO_READER_TO_WRITER
- fi
- #
- echo launch vfd_swmr_dsetops_writer dsetops, options $options ......may take some time......
- catch_out_err_and_rc vfd_swmr_dsetops_writer \
- ../vfd_swmr_dsetops_writer $options &
- pid_writer=$!
-
- catch_out_err_and_rc vfd_swmr_dsetops_reader \
- ../vfd_swmr_dsetops_reader $options &
- pid_reader=$!
-
- # Wait for the reader to finish before signaling the
- # writer to quit: the writer holds the file open so that the
- # reader will find the shadow file when it opens
- # the .h5 file.
- wait $pid_reader
- wait $pid_writer
-
- # Collect exit code of the reader
- if [ $(cat vfd_swmr_dsetops_reader.rc) -ne 0 ]; then
- echo reader had error
- nerrors=$((nerrors + 1))
- fi
+# Loop with flushing of raw data and then without
+for flush in "" "-U"; do
+ # Loop with different operations
+ for options in "-p -e 20 -t -q" "-g -m 5 -n 2 -s 10 -w 7 -q" "-k -m 10 -n 5 -r 5 -l 10 -q"; do
+ #
+ #
+ if [ ${do_dsetops:-no} = no ]; then
+ continue
+ fi
+ # Clean up any existing fifo files from previous runs
+ if [ -e ./$DSETOPS_FIFO_WRITER_TO_READER ]; then # If writer fifo file is found
+ rm -f ./$DSETOPS_FIFO_WRITER_TO_READER
+ fi
+ if [ -e ./$DSETOPS_FIFO_READER_TO_WRITER ]; then # If reader fifo file is found
+ rm -f ./$DSETOPS_FIFO_READER_TO_WRITER
+ fi
+ #
+ echo launch vfd_swmr_dsetops_writer dsetops, options $options $flush......may take some time......
+ catch_out_err_and_rc vfd_swmr_dsetops_writer \
+ ../vfd_swmr_dsetops_writer $options $flush &
+ pid_writer=$!
+
+ catch_out_err_and_rc vfd_swmr_dsetops_reader \
+ ../vfd_swmr_dsetops_reader $options $flush &
+ pid_reader=$!
+
+ # Wait for the reader to finish before signaling the
+ # writer to quit: the writer holds the file open so that the
+ # reader will find the shadow file when it opens
+ # the .h5 file.
+ wait $pid_reader
+ wait $pid_writer
+
+ # Collect exit code of the reader
+ if [ $(cat vfd_swmr_dsetops_reader.rc) -ne 0 ]; then
+ echo reader had error
+ nerrors=$((nerrors + 1))
+ fi
- # Collect exit code of the writer
- if [ $(cat vfd_swmr_dsetops_writer.rc) -ne 0 ]; then
- echo writer had error
- nerrors=$((nerrors + 1))
- fi
+ # Collect exit code of the writer
+ if [ $(cat vfd_swmr_dsetops_writer.rc) -ne 0 ]; then
+ echo writer had error
+ nerrors=$((nerrors + 1))
+ fi
- # Clean up output files
- rm -f vfd_swmr_dsetops_writer.{out,rc}
- rm -f vfd_swmr_dsetops_reader.*.{out,rc}
+ # Clean up output files
+ rm -f vfd_swmr_dsetops_writer.{out,rc}
+ rm -f vfd_swmr_dsetops_reader.*.{out,rc}
+ done
done
###############################################################################
@@ -1273,51 +1307,56 @@ dsetchks_list=(
"-r -m 11 -n 5 -l 7 -q"
"-f -x 5 -y 2 -q"
)
-for options in "${dsetchks_list[@]}"; do
- #
- #
- if [ ${do_dsetchks:-no} = no ]; then
- continue
- fi
- # Clean up any existing fifo files from previous runs
- if [ -e ./$DSETCHKS_FIFO_WRITER_TO_READER ]; then # If writer fifo file is found
- rm -f ./$DSETCHKS_FIFO_WRITER_TO_READER
- fi
- if [ -e ./$DSETCHKS_FIFO_READER_TO_WRITER ]; then # If reader fifo file is found
- rm -f ./$DSETCHKS_FIFO_READER_TO_WRITER
- fi
- #
- echo launch vfd_swmr_dsetchks_writer dsetchks, options $options ......may take some time......
- catch_out_err_and_rc vfd_swmr_dsetchks_writer \
- ../vfd_swmr_dsetchks_writer $options &
- pid_writer=$!
-
- catch_out_err_and_rc vfd_swmr_dsetchks_reader \
- ../vfd_swmr_dsetchks_reader $options &
- pid_reader=$!
-
- # Wait for the reader to finish before signaling the
- # writer to quit: the writer holds the file open so that the
- # reader will find the shadow file when it opens
- # the .h5 file.
- wait $pid_reader
- wait $pid_writer
-
- # Collect exit code of the reader
- if [ $(cat vfd_swmr_dsetchks_reader.rc) -ne 0 ]; then
- echo reader had error
- nerrors=$((nerrors + 1))
- fi
+#
+#
+# Loop with flushing of raw data and then without
+for flush in "" "-U"; do
+ for options in "${dsetchks_list[@]}"; do
+ #
+ #
+ if [ ${do_dsetchks:-no} = no ]; then
+ continue
+ fi
+ # Clean up any existing fifo files from previous runs
+ if [ -e ./$DSETCHKS_FIFO_WRITER_TO_READER ]; then # If writer fifo file is found
+ rm -f ./$DSETCHKS_FIFO_WRITER_TO_READER
+ fi
+ if [ -e ./$DSETCHKS_FIFO_READER_TO_WRITER ]; then # If reader fifo file is found
+ rm -f ./$DSETCHKS_FIFO_READER_TO_WRITER
+ fi
+ #
+ echo launch vfd_swmr_dsetchks_writer dsetchks, options $options $flush ......may take some time......
+ catch_out_err_and_rc vfd_swmr_dsetchks_writer \
+ ../vfd_swmr_dsetchks_writer $options $flush &
+ pid_writer=$!
+
+ catch_out_err_and_rc vfd_swmr_dsetchks_reader \
+ ../vfd_swmr_dsetchks_reader $options $flush &
+ pid_reader=$!
+
+ # Wait for the reader to finish before signaling the
+ # writer to quit: the writer holds the file open so that the
+ # reader will find the shadow file when it opens
+ # the .h5 file.
+ wait $pid_reader
+ wait $pid_writer
+
+ # Collect exit code of the reader
+ if [ $(cat vfd_swmr_dsetchks_reader.rc) -ne 0 ]; then
+ echo reader had error
+ nerrors=$((nerrors + 1))
+ fi
- # Collect exit code of the writer
- if [ $(cat vfd_swmr_dsetchks_writer.rc) -ne 0 ]; then
- echo writer had error
- nerrors=$((nerrors + 1))
- fi
+ # Collect exit code of the writer
+ if [ $(cat vfd_swmr_dsetchks_writer.rc) -ne 0 ]; then
+ echo writer had error
+ nerrors=$((nerrors + 1))
+ fi
- # Clean up output files
- rm -f vfd_swmr_dsetchks_writer.{out,rc}
- rm -f vfd_swmr_dsetchks_reader.*.{out,rc}
+ # Clean up output files
+ rm -f vfd_swmr_dsetchks_writer.{out,rc}
+ rm -f vfd_swmr_dsetchks_reader.*.{out,rc}
+ done
done
###############################################################################
diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c
index 09dee38..3ed73c1 100644
--- a/test/vfd_swmr.c
+++ b/test/vfd_swmr.c
@@ -884,7 +884,7 @@ test_writer_md(void)
hid_t sid = -1; /* Dataspace ID */
hid_t did = -1; /* Dataset ID */
int * rwbuf = NULL; /* Data buffer for writing */
- H5O_info_t oinfo; /* Object metadata information */
+ H5O_info2_t oinfo; /* Object metadata information */
char dname[100]; /* Name of dataset */
hsize_t dims[2] = {50, 20}; /* Dataset dimension sizes */
hsize_t max_dims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Dataset maximum dimension sizes */
@@ -961,7 +961,7 @@ test_writer_md(void)
FAIL_STACK_ERROR
/* Get dataset object header address */
- if (H5Oget_info(did, &oinfo, H5O_INFO_BASIC) < 0)
+ if (H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0)
FAIL_STACK_ERROR
/* Close the dataset */
@@ -998,7 +998,7 @@ test_writer_md(void)
FAIL_STACK_ERROR
/* Get dataset object info */
- if (H5Oget_info(did, &oinfo, H5O_INFO_BASIC) < 0)
+ if (H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0)
FAIL_STACK_ERROR
/* Close the dataset */
@@ -1032,7 +1032,7 @@ test_writer_md(void)
FAIL_STACK_ERROR
/* Get dataset object info */
- if (H5Oget_info(did, &oinfo, H5O_INFO_BASIC) < 0)
+ if (H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0)
FAIL_STACK_ERROR
/* Close the dataset */
@@ -1166,16 +1166,16 @@ test_file_end_tick_concur(void)
static unsigned
test_reader_md_concur(void)
{
- unsigned i = 0; /* Local index variables */
- uint8_t * buf = NULL; /* Data page from the page buffer */
- hid_t dcpl = -1; /* Dataset creation property list */
- hid_t sid = -1; /* Dataspace ID */
- hid_t did = -1; /* Dataset ID */
- int * rwbuf = NULL; /* Data buffer for writing */
- H5O_info_t oinfo; /* Object metadata information */
- char dname[100]; /* Name of dataset */
- hsize_t dims[2] = {50, 20}; /* Dataset dimension sizes */
- hsize_t max_dims[2] = /* Dataset maximum dimension sizes */
+ unsigned i = 0; /* Local index variables */
+ uint8_t * buf = NULL; /* Data page from the page buffer */
+ hid_t dcpl = -1; /* Dataset creation property list */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ int * rwbuf = NULL; /* Data buffer for writing */
+ H5O_info2_t oinfo; /* Object metadata information */
+ char dname[100]; /* Name of dataset */
+ hsize_t dims[2] = {50, 20}; /* Dataset dimension sizes */
+ hsize_t max_dims[2] = /* Dataset maximum dimension sizes */
{H5S_UNLIMITED, H5S_UNLIMITED};
hsize_t chunk_dims[2] = {2, 5}; /* Dataset chunked dimension sizes */
unsigned num_entries = 0; /* Number of entries in the index */
@@ -1519,7 +1519,7 @@ test_reader_md_concur(void)
FAIL_STACK_ERROR
/* Get dataset object header address */
- if (H5Oget_info(did, &oinfo, H5O_INFO_BASIC) < 0)
+ if (H5Oget_info3(did, &oinfo, H5O_INFO_BASIC) < 0)
FAIL_STACK_ERROR
/* Close the dataset */
diff --git a/test/vfd_swmr_addrem_writer.c b/test/vfd_swmr_addrem_writer.c
index 7f13cec..f115d2e 100644
--- a/test/vfd_swmr_addrem_writer.c
+++ b/test/vfd_swmr_addrem_writer.c
@@ -95,7 +95,7 @@ open_skeleton(const char *filename, unsigned verbose)
goto error;
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(config, 4, 5, TRUE, FALSE, 128, "./rw-shadow");
+ init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, 128, "./rw-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, config)) < 0)
diff --git a/test/vfd_swmr_attrdset_writer.c b/test/vfd_swmr_attrdset_writer.c
index 27a23e6..f445321 100644
--- a/test/vfd_swmr_attrdset_writer.c
+++ b/test/vfd_swmr_attrdset_writer.c
@@ -150,12 +150,16 @@ static bool open_dset_real(hid_t fid, hid_t *did, const char *name, unsigned *ma
unsigned *min_dense);
static bool close_dsets(const dsets_state_t *ds);
+static bool perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config,
+ np_state_t *np);
static bool attr_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which);
static bool attr_action(unsigned action, const state_t *s, hid_t did, unsigned which);
static bool add_attr(const state_t *s, hid_t did, unsigned int which);
static bool modify_attr(const state_t *s, hid_t did, unsigned int which);
static bool delete_attr(hid_t did, unsigned int which);
+static bool verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config,
+ np_state_t *np);
static bool verify_attr_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds,
unsigned which);
static bool verify_attr_action(unsigned action, hid_t did, unsigned which);
@@ -222,13 +226,23 @@ state_init(state_t *s, int argc, char **argv)
{
unsigned long tmp;
int ch;
- const hsize_t dims = 1;
- char tfile[PATH_MAX];
+ const hsize_t dims = 1;
+ char * tfile = NULL;
char * end;
*s = ALL_HID_INITIALIZER;
- esnprintf(tfile, sizeof(tfile), "%s", argv[0]);
- esnprintf(s->progname, sizeof(s->progname), "%s", basename(tfile));
+
+ if (H5_basename(argv[0], &tfile) < 0) {
+ HDprintf("H5_basename failed\n");
+ TEST_ERROR;
+ }
+
+ esnprintf(s->progname, sizeof(s->progname), "%s", tfile);
+
+ if (tfile) {
+ HDfree(tfile);
+ tfile = NULL;
+ }
while ((ch = getopt(argc, argv, "pgkvmbqSNa:d:u:c:")) != -1) {
switch (ch) {
@@ -340,6 +354,9 @@ state_init(state_t *s, int argc, char **argv)
return true;
error:
+ if (tfile)
+ HDfree(tfile);
+
return false;
} /* state_init() */
@@ -892,16 +909,89 @@ error:
} /* close_dsets() */
/*
- * Attribute handling by the writer
+ * Writer
*/
/*
- * Perform the "action" for each of the datasets specified on the command line.
+ * Perform the attribute operations specified on the command line.
* ADD_ATTR : -a <nattrs> option
* MODIFY_ATTR : -m option
* DELETE_ATTR : -d <dattrs> option
*/
static bool
+perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np)
+{
+ unsigned step;
+ bool result;
+ unsigned dd;
+
+ for (step = 0; step < s->asteps; step++) {
+ dbgf(2, "Adding attribute %d\n", step);
+
+ result = attr_dsets_action(ADD_ATTR, s, ds, step);
+
+ if (s->use_np && !np_writer(result, step, s, np, config)) {
+ HDprintf("np_writer() for addition failed\n");
+ TEST_ERROR;
+ }
+ }
+
+ if (s->mod_attr) {
+
+ /* Need to sync up writer/reader before moving onto the next phase */
+ if (s->use_np && !np_writer(true, 0, s, np, config)) {
+ HDprintf("np_writer() for modification failed\n");
+ TEST_ERROR;
+ }
+
+ /* Start modification */
+ for (step = 0; step < s->asteps; step++) {
+ dbgf(2, "Modifying attribute %d\n", step);
+
+ result = attr_dsets_action(MODIFY_ATTR, s, ds, step);
+
+ if (s->use_np && !np_writer(result, step, s, np, config)) {
+ HDprintf("np_writer() for modification failed\n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ if (s->dattrs) {
+
+ /* Need to sync up writer/reader before moving onto the next phase */
+ if (s->use_np && !np_writer(true, 0, s, np, config)) {
+ HDprintf("np_writer() for deletion failed\n");
+ TEST_ERROR;
+ }
+
+ /* Start deletion */
+ for (dd = 0, step = s->asteps - 1; dd < s->dattrs; dd++, --step) {
+ dbgf(2, "Deleting attribute %d\n", step);
+
+ result = attr_dsets_action(DELETE_ATTR, s, ds, step);
+
+ if (s->use_np && !np_writer(result, step, s, np, config)) {
+ HDprintf("np_writer() for deletion failed\n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ return true;
+
+error:
+ return false;
+
+} /* perform_dsets_operations() */
+
+/*
+ * Perform the "action" for each of the datasets specified on the command line.
+ * -p: compact dataset
+ * -g: contiguous dataset
+ * -k: 5 chunked datasets with 5 indexing types
+ */
+static bool
attr_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which)
{
int nerrors = 0;
@@ -1181,14 +1271,111 @@ error:
*/
/*
- * Verify the action on each of the datasets specified:
+ * Verify the attribute operations specified on the command line:
* ADD_ATTR : -a <nattrs> option
* MODIFY_ATTR : -m option
* DELETE_ATTR : -d <dattrs> option
*
* Also verify continuation block and compact<->dense storage if:
* --[-c <csteps>] is 1
- * --not -m option
+ * --not appliable for -m option
+ */
+static bool
+verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np)
+{
+ unsigned step;
+ bool result;
+ unsigned dd;
+
+ /* Start verifying addition */
+ for (step = 0; step < s->asteps; step++) {
+ dbgf(2, "Verifying...attribute %d\n", step);
+
+ if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ TEST_ERROR;
+ }
+
+ /* Wait for a few ticks for the update to happen */
+ decisleep(config->tick_len * s->update_interval);
+
+ result = verify_attr_dsets_action(ADD_ATTR, s, ds, step);
+
+ if (s->use_np && !np_reader(result, step, s, np)) {
+ HDprintf("np_reader() for verifying addition failed\n");
+ TEST_ERROR;
+ }
+ }
+
+ if (s->mod_attr) {
+ /* Need to sync up writer/reader before moving onto the next phase */
+ if (!np_reader_no_verification(s, np, config)) {
+ HDprintf("np_reader_no_verification() for verifying modification failed\n");
+ TEST_ERROR;
+ }
+
+ /* Start verifying modification */
+ for (step = 0; step < s->asteps; step++) {
+ dbgf(2, "Verifying...modify attribute %d\n", step);
+
+ if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ TEST_ERROR;
+ }
+
+ /* Wait for a few ticks for the update to happen */
+ decisleep(config->tick_len * s->update_interval);
+
+ result = verify_attr_dsets_action(MODIFY_ATTR, s, ds, step);
+
+ if (s->use_np && !np_reader(result, step, s, np)) {
+ HDprintf("np_reader() for verifying modification failed\n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ if (s->dattrs) {
+
+ /* Need to sync up writer/reader before moving onto the next phase */
+ if (!np_reader_no_verification(s, np, config)) {
+ HDprintf("np_reader_no_verification() for verifying modification failed\n");
+ TEST_ERROR;
+ }
+
+ /* Start verifying deletion */
+ for (dd = 0, step = s->asteps - 1; dd < s->dattrs; dd++, --step) {
+ dbgf(2, "Verifying...delete attribute %d\n", step);
+
+ if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ TEST_ERROR;
+ }
+
+ /* Wait for a few ticks for the update to happen */
+ decisleep(config->tick_len * s->update_interval);
+
+ result = verify_attr_dsets_action(DELETE_ATTR, s, ds, step);
+
+ if (s->use_np && !np_reader(result, step, s, np)) {
+ HDprintf("np_reader() for verifying deletion failed\n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ return true;
+
+error:
+
+ return false;
+} /* verify_dsets_operations() */
+
+/*
+ * Verify the "action" for each of the datasets specified on the command line.
+ * -p: compact dataset
+ * -g: contiguous dataset
+ * -k: 5 chunked datasets with 5 indexing types
*/
static bool
verify_attr_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which)
@@ -1317,12 +1504,13 @@ static bool
verify_add_or_modify_attr(unsigned action, hid_t did, char *attr_name, unsigned int which)
{
unsigned int read_which;
- char vl_which[sizeof("attr-9999999999")];
- char * read_vl_which = NULL;
- bool is_vl = false;
- hid_t aid = H5I_INVALID_HID;
- hid_t atid = H5I_INVALID_HID;
- bool ret = FALSE;
+ unsigned int tmp_val;
+ char tmp_vl_val[sizeof("attr-9999999999")];
+ char * read_vl_which;
+ bool is_vl = false;
+ hid_t aid = H5I_INVALID_HID;
+ hid_t atid = H5I_INVALID_HID;
+ bool ret = FALSE;
HDassert(did != badhid);
HDassert(action == ADD_ATTR || action == MODIFY_ATTR);
@@ -1339,17 +1527,18 @@ verify_add_or_modify_attr(unsigned action, hid_t did, char *attr_name, unsigned
if ((is_vl = H5Tis_variable_str(atid))) {
if (action == ADD_ATTR)
- HDsprintf(vl_which, "%u", which);
+ HDsprintf(tmp_vl_val, "%u", which);
else
- HDsprintf(vl_which, "%u %c", which, 'M');
-
- if ((read_vl_which = HDmalloc(sizeof("9999999999"))) == NULL) {
- HDprintf("HDmalloc failed\n");
- TEST_ERROR;
- }
+ HDsprintf(tmp_vl_val, "%u %c", which, 'M');
+ }
+ else {
+ if (action == MODIFY_ATTR)
+ tmp_val = which + 1;
+ else
+ tmp_val = which;
}
- if (H5Aread(aid, atid, is_vl ? (void *)&read_vl_which : (void *)&read_which) < 0) {
+ if (H5Aread(aid, atid, is_vl ? &read_vl_which : (void *)&read_which) < 0) {
HDprintf("H5Aread failed\n");
TEST_ERROR;
}
@@ -1365,14 +1554,17 @@ verify_add_or_modify_attr(unsigned action, hid_t did, char *attr_name, unsigned
}
if (is_vl) {
- if (!HDstrcmp(vl_which, read_vl_which))
+ dbgf(2, "read_vl_which = %s, tmp_vl_val= %s\n", read_vl_which, tmp_vl_val);
+ if (!HDstrcmp(read_vl_which, tmp_vl_val))
ret = true;
}
- else
- ret = (read_which == which);
+ else {
+ dbgf(2, "read_which = %u, tmp_val = %u\n", read_which, tmp_val);
+ ret = (read_which == tmp_val);
+ }
- if (read_vl_which)
- HDfree(read_vl_which);
+ if (is_vl)
+ H5free_memory(read_vl_which);
return ret;
@@ -1384,8 +1576,8 @@ error:
}
H5E_END_TRY;
- if (read_vl_which)
- HDfree(read_vl_which);
+ if (is_vl)
+ H5free_memory(read_vl_which);
return false;
@@ -1452,9 +1644,8 @@ verify_storage_cont(unsigned action, hid_t did, unsigned int which, unsigned max
/* Verify dense storage & no cont */
else if (which == max_compact)
ret = verify_storage_cont_real(did, which, max_compact);
-
- /* For deletion */
}
+ /* For deletion */
else if (action == DELETE_ATTR) {
/* Verify compact storage & cont */
@@ -1763,17 +1954,14 @@ error:
int
main(int argc, char **argv)
{
- hid_t fapl = H5I_INVALID_HID;
- hid_t fcpl = H5I_INVALID_HID;
- unsigned step;
+ hid_t fapl = H5I_INVALID_HID;
+ hid_t fcpl = H5I_INVALID_HID;
bool writer = FALSE;
state_t s;
const char * personality;
H5F_vfd_swmr_config_t config;
np_state_t np;
dsets_state_t ds;
- unsigned dd;
- bool result;
if (!state_init(&s, argc, argv)) {
HDprintf("state_init() failed\n");
@@ -1792,7 +1980,7 @@ main(int argc, char **argv)
}
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(&config, 4, 7, writer, FALSE, 128, "./attrdset-shadow");
+ init_vfd_swmr_config(&config, 4, 7, writer, true, 128, "./attrdset-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, 4096, &config)) < 0) {
@@ -1835,136 +2023,15 @@ main(int argc, char **argv)
}
if (writer) {
- for (step = 0; step < s.asteps; step++) {
- dbgf(2, "Adding attribute %d\n", step);
-
- result = attr_dsets_action(ADD_ATTR, &s, &ds, step);
-
- if (s.use_np && !np_writer(result, step, &s, &np, &config)) {
- HDprintf("np_writer() for addition failed\n");
- TEST_ERROR;
- }
- }
-
- if (s.mod_attr) {
-
- /* Need to sync up writer/reader before moving onto the next phase */
- if (s.use_np && !np_writer(true, 0, &s, &np, &config)) {
- HDprintf("np_writer() for modification failed\n");
- TEST_ERROR;
- }
-
- /* Start modification */
- for (step = 0; step < s.asteps; step++) {
- dbgf(2, "Modifying attribute %d\n", step);
-
- result = attr_dsets_action(MODIFY_ATTR, &s, &ds, step);
-
- if (s.use_np && !np_writer(result, step, &s, &np, &config)) {
- HDprintf("np_writer() for modification failed\n");
- TEST_ERROR;
- }
- }
- }
-
- if (s.dattrs) {
-
- /* Need to sync up writer/reader before moving onto the next phase */
- if (s.use_np && !np_writer(true, 0, &s, &np, &config)) {
- HDprintf("np_writer() for deletion failed\n");
- TEST_ERROR;
- }
-
- /* Start deletion */
- for (dd = 0, step = s.asteps - 1; dd < s.dattrs; dd++, --step) {
- dbgf(2, "Deleting attribute %d\n", step);
-
- result = attr_dsets_action(DELETE_ATTR, &s, &ds, step);
-
- if (s.use_np && !np_writer(result, step, &s, &np, &config)) {
- HDprintf("np_writer() for deletion failed\n");
- TEST_ERROR;
- }
- }
+ if (!perform_dsets_operations(&s, &ds, &config, &np)) {
+ HDprintf("perform_dsets_operations() failed\n");
+ TEST_ERROR;
}
}
else {
-
- /* Start verifying addition */
- for (step = 0; step < s.asteps; step++) {
- dbgf(2, "Verifying...attribute %d\n", step);
-
- if (s.use_np && !np_confirm_verify_notify(np.fd_writer_to_reader, step, &s, &np)) {
- HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
- TEST_ERROR;
- }
-
- /* Wait for a few ticks for the update to happen */
- decisleep(config.tick_len * s.update_interval);
-
- result = verify_attr_dsets_action(ADD_ATTR, &s, &ds, step);
-
- if (s.use_np && !np_reader(result, step, &s, &np)) {
- HDprintf("np_reader() for verifying addition failed\n");
- TEST_ERROR;
- }
- }
-
- if (s.mod_attr) {
- /* Need to sync up writer/reader before moving onto the next phase */
- if (!np_reader_no_verification(&s, &np, &config)) {
- HDprintf("np_reader_no_verification() for verifying modification failed\n");
- TEST_ERROR;
- }
-
- /* Start verifying modification */
- for (step = 0; step < s.asteps; step++) {
- dbgf(2, "Verifying...modify attribute %d\n", step);
-
- if (s.use_np && !np_confirm_verify_notify(np.fd_writer_to_reader, step, &s, &np)) {
- HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
- TEST_ERROR;
- }
-
- /* Wait for a few ticks for the update to happen */
- decisleep(config.tick_len * s.update_interval);
-
- result = verify_attr_dsets_action(MODIFY_ATTR, &s, &ds, step);
-
- if (s.use_np && !np_reader(result, step, &s, &np)) {
- HDprintf("np_reader() for verifying modification failed\n");
- TEST_ERROR;
- }
- }
- }
-
- if (s.dattrs) {
-
- /* Need to sync up writer/reader before moving onto the next phase */
- if (!np_reader_no_verification(&s, &np, &config)) {
- HDprintf("np_reader_no_verification() for verifying modification failed\n");
- TEST_ERROR;
- }
-
- /* Start verifying deletion */
- for (dd = 0, step = s.asteps - 1; dd < s.dattrs; dd++, --step) {
- dbgf(2, "Verifying...delete attribute %d\n", step);
-
- if (s.use_np && !np_confirm_verify_notify(np.fd_writer_to_reader, step, &s, &np)) {
- HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
- TEST_ERROR;
- }
-
- /* Wait for a few ticks for the update to happen */
- decisleep(config.tick_len * s.update_interval);
-
- result = verify_attr_dsets_action(DELETE_ATTR, &s, &ds, step);
-
- if (s.use_np && !np_reader(result, step, &s, &np)) {
- HDprintf("np_reader() for verifying deletion failed\n");
- TEST_ERROR;
- }
- }
+ if (!verify_dsets_operations(&s, &ds, &config, &np)) {
+ HDprintf("verify_dsets_operations() failed\n");
+ TEST_ERROR;
}
}
diff --git a/test/vfd_swmr_bigset_writer.c b/test/vfd_swmr_bigset_writer.c
index 9c05fa6..61d552e 100644
--- a/test/vfd_swmr_bigset_writer.c
+++ b/test/vfd_swmr_bigset_writer.c
@@ -2259,6 +2259,11 @@ main(int argc, char **argv)
HDfree(mat);
+ if (s.dataset)
+ HDfree(s.dataset);
+ if (s.sources)
+ HDfree(s.sources);
+
return EXIT_SUCCESS;
error:
diff --git a/test/vfd_swmr_dsetchks_writer.c b/test/vfd_swmr_dsetchks_writer.c
index 1d9bc4c..d264ca9 100644
--- a/test/vfd_swmr_dsetchks_writer.c
+++ b/test/vfd_swmr_dsetchks_writer.c
@@ -74,6 +74,7 @@ typedef struct {
bool use_np; /* For -N option */
bool use_vfd_swmr; /* For -S option */
bool use_filter; /* For -o option */
+ bool flush_raw_data; /* For -U option */
bool single_index; /* -s option: create a chunked dataset with single chunk index */
bool implicit_index; /* -i option: create a chunked datasets with implicit chunk index */
@@ -99,9 +100,9 @@ typedef struct {
{ \
.filename = "", .file = H5I_INVALID_HID, .filetype = H5T_NATIVE_UINT32, \
.update_interval = READER_WAIT_TICKS, .csteps = 1, .use_np = true, .use_vfd_swmr = true, \
- .use_filter = false, .single_index = false, .implicit_index = false, .fa_index = false, \
- .ea_index = false, .bt2_index = false, .rows = 10, .cols = 5, .gwrites = 0, .pwrites = 0, \
- .twrites = 0, .lwrites = 0, .xincrs = 0, .ydecrs = 0 \
+ .use_filter = false, .flush_raw_data = true, .single_index = false, .implicit_index = false, \
+ .fa_index = false, .ea_index = false, .bt2_index = false, .rows = 10, .cols = 5, .gwrites = 0, \
+ .pwrites = 0, .twrites = 0, .lwrites = 0, .xincrs = 0, .ydecrs = 0 \
}
/* Structure to hold info for different dataset types */
@@ -166,20 +167,21 @@ static void setup_selection(unsigned action, unsigned which, const state_t *s, c
static void check_set_edge_block(const state_t *s, const dsets_state_t *ds, unsigned i, unsigned j,
hsize_t *block);
static void check_set_partial_block(unsigned action, const hsize_t *dims, hsize_t *block, hsize_t *start);
-static bool write_dset(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *stride, hsize_t *count,
- hsize_t *block);
+static bool write_chunks(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *stride,
+ hsize_t *count, hsize_t *block);
static bool write_dset_single(unsigned action, const state_t *s, const dsets_state_t *ds);
static bool dsets_extent(unsigned action, const state_t *s, const dsets_state_t *ds);
static bool dset_extent_real(unsigned action, hid_t did, const hsize_t *chunk_dims);
static bool verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config,
- np_state_t *np);
+ np_state_t *np, bool fileclosed);
-static bool verify_dsets_chunks(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which);
-static bool verify_read_dset(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *stride,
- hsize_t *count, hsize_t *block);
-static bool verify_read_dset_single(unsigned action, const state_t *s, const dsets_state_t *ds);
+static bool verify_dsets_chunks(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which,
+ bool fileclosed);
+static bool verify_chunks(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *stride,
+ hsize_t *count, hsize_t *block, bool fileclosed, bool flush_raw_data);
+static bool verify_dset_single(unsigned action, const state_t *s, const dsets_state_t *ds, bool fileclosed);
static bool verify_dsets_extent(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which);
static bool verify_dset_extent_real(unsigned action, hid_t did, unsigned rows, unsigned cols, unsigned which);
@@ -189,16 +191,16 @@ static const hid_t badhid = H5I_INVALID_HID;
static void
usage(const char *progname)
{
- fprintf(stderr,
- "usage: %s \n"
- " [-s] [-i] [-f] [-e] [-r]\n"
- " [-m rows] [-n cols]\n"
- " [-g gwrites] [-p pwrites] [-t twrites] [-l lwrites]\n"
- " [-x xincrs] [-y decrs]\n"
- " [-u nticks] [-c csteps] [-S] [-N] [-q] [-b] [-o]\n",
- progname);
-
- fprintf(
+ HDfprintf(stderr,
+ "usage: %s \n"
+ " [-s] [-i] [-f] [-e] [-r]\n"
+ " [-m rows] [-n cols]\n"
+ " [-g gwrites] [-p pwrites] [-t twrites] [-l lwrites]\n"
+ " [-x xincrs] [-y decrs]\n"
+ " [-u nticks] [-c csteps] [-U] [-S] [-N] [-q] [-b] [-o]\n",
+ progname);
+
+ HDfprintf(
stderr,
"\n"
"-s: create a 2-d chunked dataset with single index\n"
@@ -218,6 +220,7 @@ usage(const char *progname)
" (default is 4)\n"
"-c csteps: `csteps` steps communication interval between reader and writer\n"
" (default is 1)\n"
+ "-U: disable flush of raw data (default is flushing raw data)\n"
"-S: do not use VFD SWMR\n"
"-N: do not use named pipes for test synchronization\n"
"-q: silence printouts, few messages\n"
@@ -225,7 +228,7 @@ usage(const char *progname)
" (default is H5T_NATIVE_UINT32)\n\n"
"-o: enable compression (deflate filter) for the datasets\n");
- fprintf(
+ HDfprintf(
stderr,
"\n"
"Note:\n"
@@ -263,14 +266,24 @@ state_init(state_t *s, int argc, char **argv)
{
unsigned long tmp;
int ch;
- char tfile[PATH_MAX];
+ char * tfile = NULL;
char * end;
*s = ALL_HID_INITIALIZER;
- esnprintf(tfile, sizeof(tfile), "%s", argv[0]);
- esnprintf(s->progname, sizeof(s->progname), "%s", basename(tfile));
- while ((ch = getopt(argc, argv, "siferom:n:x:y:g:p:t:l:bqSNu:c:")) != -1) {
+ if (H5_basename(argv[0], &tfile) < 0) {
+ HDprintf("H5_basename failed\n");
+ TEST_ERROR
+ }
+
+ esnprintf(s->progname, sizeof(s->progname), "%s", tfile);
+
+ if (tfile) {
+ HDfree(tfile);
+ tfile = NULL;
+ }
+
+ while ((ch = getopt(argc, argv, "siferom:n:x:y:g:p:t:l:bqSNUu:c:")) != -1) {
switch (ch) {
case 's': /* A chunked dataset with single index */
@@ -309,6 +322,10 @@ state_init(state_t *s, int argc, char **argv)
s->use_vfd_swmr = false;
break;
+ case 'U': /* Disable flush of raw data */
+ s->flush_raw_data = false;
+ break;
+
case 'N': /* Disable named pipes synchronization */
s->use_np = false;
break;
@@ -326,15 +343,15 @@ state_init(state_t *s, int argc, char **argv)
errno = 0;
tmp = strtoul(optarg, &end, 0);
if (end == optarg || *end != '\0') {
- printf("couldn't parse `-%c` argument `%s`\n", ch, optarg);
+ HDprintf("couldn't parse `-%c` argument `%s`\n", ch, optarg);
TEST_ERROR;
}
else if (errno != 0) {
- printf("couldn't parse `-%c` argument `%s`\n", ch, optarg);
+ HDprintf("couldn't parse `-%c` argument `%s`\n", ch, optarg);
TEST_ERROR;
}
else if (tmp > UINT_MAX) {
- printf("`-%c` argument `%lu` too large\n", ch, tmp);
+ HDprintf("`-%c` argument `%lu` too large\n", ch, tmp);
TEST_ERROR;
}
@@ -372,63 +389,63 @@ state_init(state_t *s, int argc, char **argv)
/* Require to specify at least -s or -i or -f or -e or -r option */
if (!s->single_index && !s->implicit_index && !s->fa_index && !s->ea_index && !s->bt2_index) {
- printf("Require to specify at least -s or -i or -f or -e or -r option\n");
+ HDprintf("Require to specify at least -s or -i or -f or -e or -r option\n");
usage(s->progname);
goto error;
}
/* -x or -y option only apply to dataset with fixed/extensible array/v2 btree index */
if ((s->single_index || s->implicit_index) && (s->xincrs || s->ydecrs)) {
- printf("-x or -y option not applicable to dataset with single or implicit index\n");
+ HDprintf("-x or -y option not applicable to dataset with single or implicit index\n");
usage(s->progname);
goto error;
}
/* rows and cols cannot be zero */
if (s->rows == 0 || s->cols == 0) {
- printf("-m <rows> or -n <cols> cannot be zero\n");
+ HDprintf("-m <rows> or -n <cols> cannot be zero\n");
TEST_ERROR;
}
/* -c <csteps> cannot be zero */
if (!s->csteps) {
- printf("communication interval cannot be zero\n");
+ HDprintf("communication interval cannot be zero\n");
TEST_ERROR;
}
/* -c <csteps> and -g <gwrites> options */
if (s->gwrites && s->csteps > s->gwrites) {
- printf("communication interval with -g <gwrites> is out of bounds\n");
+ HDprintf("communication interval with -g <gwrites> is out of bounds\n");
TEST_ERROR;
}
/* -c <csteps> and -p <pwrites> options */
if (s->pwrites && s->csteps > s->pwrites) {
- printf("communication interval with -p <pwrites> is out of bounds\n");
+ HDprintf("communication interval with -p <pwrites> is out of bounds\n");
TEST_ERROR;
}
/* -c <csteps> and -t <twrites> options */
if (s->twrites && s->csteps > s->twrites) {
- printf("communication interval with -t <twrites> is out of bounds\n");
+ HDprintf("communication interval with -t <twrites> is out of bounds\n");
TEST_ERROR;
}
/* -c <csteps> and -l <lwrites> options */
if (s->lwrites && s->csteps > s->lwrites) {
- printf("communication interval with -l <lwrites> is out of bounds\n");
+ HDprintf("communication interval with -l <lwrites> is out of bounds\n");
TEST_ERROR;
}
/* -c <csteps> and -x <xincrs> options */
if (s->xincrs && s->csteps > s->xincrs) {
- printf("communication interval with -x <xincrs> is out of bounds\n");
+ HDprintf("communication interval with -x <xincrs> is out of bounds\n");
TEST_ERROR;
}
/* -c <csteps> and -y <ydecrs> options */
if (s->ydecrs && s->csteps > s->ydecrs) {
- printf("communication interval with -y <ydecrs> is out of bounds\n");
+ HDprintf("communication interval with -y <ydecrs> is out of bounds\n");
TEST_ERROR;
}
@@ -438,6 +455,8 @@ state_init(state_t *s, int argc, char **argv)
return true;
error:
+ if (tfile)
+ HDfree(tfile);
return false;
} /* state_init() */
@@ -472,26 +491,26 @@ create_dsets(const state_t *s, dsets_state_t *ds)
/* Create dataset creation property list */
/* Set properties in dcpl that are common for all the datasets */
if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) {
- printf("H5Pcreate failed\n");
+ HDprintf("H5Pcreate failed\n");
TEST_ERROR;
}
/* Set to chunked layout */
if (H5Pset_layout(dcpl, H5D_CHUNKED) < 0) {
- printf("H5Pset_layout failed\n");
+ HDprintf("H5Pset_layout failed\n");
TEST_ERROR;
}
/* Set fill value to FILL_INIT */
if (H5Pset_fill_value(dcpl, s->filetype, &fillval) < 0) {
- printf("H5Pset_fill_value failed\n");
+ HDprintf("H5Pset_fill_value failed\n");
goto error;
}
/* Set to use filter as specified */
if (s->use_filter) {
if (H5Pset_deflate(dcpl, 5) < 0) {
- printf("H5Pset_deflate failed\n");
+ HDprintf("H5Pset_deflate failed\n");
goto error;
}
}
@@ -501,41 +520,41 @@ create_dsets(const state_t *s, dsets_state_t *ds)
if (s->single_index) {
if ((dcpl2 = H5Pcopy(dcpl)) < 0) {
- printf("H5Tcopy failed\n");
+ HDprintf("H5Tcopy failed\n");
TEST_ERROR;
}
if (H5Pset_chunk(dcpl2, 2, dims) < 0) {
- printf("H5Pset_chunk failed\n");
+ HDprintf("H5Pset_chunk failed\n");
TEST_ERROR;
}
if ((sid = H5Screate_simple(2, dims, dims)) < 0) {
- printf("H5Screate_simple failed\n");
+ HDprintf("H5Screate_simple failed\n");
TEST_ERROR;
}
/* Create the chunked dataset: single index */
if ((ds->single_did = H5Dcreate2(s->file, DSET_SINGLE_NAME, s->filetype, sid, H5P_DEFAULT, dcpl2,
H5P_DEFAULT)) < 0) {
- printf("H5Dcreate2 chunked dataset:single index failed\n");
+ HDprintf("H5Dcreate2 chunked dataset:single index failed\n");
TEST_ERROR;
}
if (H5Pclose(dcpl2) < 0) {
- printf("H5Pclose failed\n");
+ HDprintf("H5Pclose failed\n");
TEST_ERROR;
}
if (H5Sclose(sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
}
/* Chunk size is common for datasets with implicit/fa/ea/bt2 index */
if (H5Pset_chunk(dcpl, 2, ds->chunk_dims) < 0) {
- printf("H5Pset_chunk failed\n");
+ HDprintf("H5Pset_chunk failed\n");
TEST_ERROR;
}
@@ -544,34 +563,34 @@ create_dsets(const state_t *s, dsets_state_t *ds)
if (s->implicit_index) {
if ((dcpl2 = H5Pcopy(dcpl)) < 0) {
- printf("H5Pcopy failed\n");
+ HDprintf("H5Pcopy failed\n");
TEST_ERROR;
}
if (H5Pset_alloc_time(dcpl2, H5D_ALLOC_TIME_EARLY) < 0) {
- printf("H5Pset_alloc_time\n");
+ HDprintf("H5Pset_alloc_time\n");
TEST_ERROR;
}
if ((sid = H5Screate_simple(2, dims, dims)) < 0) {
- printf("H5Screate_simple failed\n");
+ HDprintf("H5Screate_simple failed\n");
TEST_ERROR;
}
/* Create the chunked dataset: implicit index */
if ((ds->implicit_did = H5Dcreate2(s->file, DSET_IMPLICIT_NAME, s->filetype, sid, H5P_DEFAULT, dcpl2,
H5P_DEFAULT)) < 0) {
- printf("H5Dcreate2 chunked dataset:implicit index failed\n");
+ HDprintf("H5Dcreate2 chunked dataset:implicit index failed\n");
TEST_ERROR;
}
if (H5Pclose(dcpl2) < 0) {
- printf("H5Pclose failed\n");
+ HDprintf("H5Pclose failed\n");
TEST_ERROR;
}
if (H5Sclose(sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
}
@@ -585,19 +604,19 @@ create_dsets(const state_t *s, dsets_state_t *ds)
max_dims[1] = dims[1] * 2;
if ((sid = H5Screate_simple(2, dims, max_dims)) < 0) {
- printf("H5Screate_simple failed\n");
+ HDprintf("H5Screate_simple failed\n");
TEST_ERROR;
}
/* Create the chunked dataset (fixed array index) with the named datatype */
if ((ds->fa_did =
H5Dcreate2(s->file, DSET_FA_NAME, s->filetype, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) {
- printf("H5Dcreate2 chunked dataset: fa index failed\n");
+ HDprintf("H5Dcreate2 chunked dataset: fa index failed\n");
TEST_ERROR;
}
if (H5Sclose(sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
}
@@ -611,19 +630,19 @@ create_dsets(const state_t *s, dsets_state_t *ds)
max_dims[1] = H5S_UNLIMITED;
if ((sid = H5Screate_simple(2, dims, max_dims)) < 0) {
- printf("H5Screate_simple failed\n");
+ HDprintf("H5Screate_simple failed\n");
TEST_ERROR;
}
/* Create the chunked dataset (extensible array index) with the named datatype */
if ((ds->ea_did =
H5Dcreate2(s->file, DSET_EA_NAME, s->filetype, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) {
- printf("H5Dcreate2 chunked dataset: ea index failed\n");
+ HDprintf("H5Dcreate2 chunked dataset: ea index failed\n");
TEST_ERROR;
}
if (H5Sclose(sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
}
@@ -636,25 +655,25 @@ create_dsets(const state_t *s, dsets_state_t *ds)
max_dims[0] = max_dims[1] = H5S_UNLIMITED;
if ((sid = H5Screate_simple(2, dims, max_dims)) < 0) {
- printf("H5Screate_simple failed\n");
+ HDprintf("H5Screate_simple failed\n");
TEST_ERROR;
}
/* Create the chunked dataset (btree2 index) with the named datatype */
if ((ds->bt2_did =
H5Dcreate2(s->file, DSET_BT2_NAME, s->filetype, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) {
- printf("H5Dcreate2 chunked dataset: bt2 index failed\n");
+ HDprintf("H5Dcreate2 chunked dataset: bt2 index failed\n");
TEST_ERROR;
}
if (H5Sclose(sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
}
if (H5Pclose(dcpl) < 0) {
- printf("H5Pclose failed\n");
+ HDprintf("H5Pclose failed\n");
TEST_ERROR;
}
@@ -690,7 +709,7 @@ open_dsets(const state_t *s, dsets_state_t *ds)
/* Dataset with single index */
if (s->single_index) {
if ((ds->single_did = H5Dopen2(s->file, DSET_SINGLE_NAME, H5P_DEFAULT)) < 0) {
- printf("H5Dopen dataset with single index failed\n");
+ HDprintf("H5Dopen dataset with single index failed\n");
TEST_ERROR;
}
}
@@ -698,7 +717,7 @@ open_dsets(const state_t *s, dsets_state_t *ds)
/* Dataset with implicit index */
if (s->implicit_index) {
if ((ds->implicit_did = H5Dopen2(s->file, DSET_IMPLICIT_NAME, H5P_DEFAULT)) < 0) {
- printf("H5Dopen dataset with implicit index failed\n");
+ HDprintf("H5Dopen dataset with implicit index failed\n");
TEST_ERROR;
}
}
@@ -706,7 +725,7 @@ open_dsets(const state_t *s, dsets_state_t *ds)
/* Dataset with fixed array index */
if (s->fa_index) {
if ((ds->fa_did = H5Dopen2(s->file, DSET_FA_NAME, H5P_DEFAULT)) < 0) {
- printf("H5Dopen dataset with fa index failed\n");
+ HDprintf("H5Dopen dataset with fa index failed\n");
TEST_ERROR;
}
}
@@ -714,7 +733,7 @@ open_dsets(const state_t *s, dsets_state_t *ds)
/* Dataset with extensible array index */
if (s->ea_index) {
if ((ds->ea_did = H5Dopen2(s->file, DSET_EA_NAME, H5P_DEFAULT)) < 0) {
- printf("H5Dopen dataset with ea index failed\n");
+ HDprintf("H5Dopen dataset with ea index failed\n");
TEST_ERROR;
}
}
@@ -722,7 +741,7 @@ open_dsets(const state_t *s, dsets_state_t *ds)
/* Dataset with v2 btree index */
if (s->bt2_index) {
if ((ds->bt2_did = H5Dopen2(s->file, DSET_BT2_NAME, H5P_DEFAULT)) < 0) {
- printf("H5Dopen dataset with ea index failed\n");
+ HDprintf("H5Dopen dataset with ea index failed\n");
TEST_ERROR;
}
}
@@ -765,31 +784,31 @@ close_dsets(const dsets_state_t *ds)
{
/* Close dataset with single index */
if (ds->single_did != badhid && H5Dclose(ds->single_did) < 0) {
- printf("close_dset_real() dataset: single index failed\n");
+ HDprintf("close_dset_real() dataset: single index failed\n");
TEST_ERROR;
}
/* Close dataset with implicit index */
if (ds->implicit_did != badhid && H5Dclose(ds->implicit_did) < 0) {
- printf("close_dset_real() dataset: implicit index failed\n");
+ HDprintf("close_dset_real() dataset: implicit index failed\n");
TEST_ERROR;
}
/* Close dataset with fixed array index */
if (ds->fa_did != badhid && H5Dclose(ds->fa_did) < 0) {
- printf("close_dset_real() dataset: fa index failed\n");
+ HDprintf("close_dset_real() dataset: fa index failed\n");
TEST_ERROR;
}
/* Close dataset with extensible array index */
if (ds->ea_did != badhid && H5Dclose(ds->ea_did) < 0) {
- printf("close_dset_real() : ea index failed\n");
+ HDprintf("close_dset_real() : ea index failed\n");
TEST_ERROR;
}
/* Close dataset with v2 btree index */
if (ds->bt2_did != badhid && H5Dclose(ds->bt2_did) < 0) {
- printf("close_dset_real() dataset: bt2 index failed\n");
+ HDprintf("close_dset_real() dataset: bt2 index failed\n");
TEST_ERROR;
}
@@ -848,7 +867,7 @@ perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *c
result = write_dset_single(GWRITES, s, ds);
if (s->use_np && !np_writer(result, 0, s, np, config)) {
- printf("np_writer() for addition failed\n");
+ HDprintf("np_writer() for addition failed\n");
TEST_ERROR;
}
}
@@ -863,7 +882,7 @@ perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *c
result = write_dset_single(PWRITES, s, ds);
if (s->use_np && !np_writer(result, 0, s, np, config)) {
- printf("np_writer() for addition failed\n");
+ HDprintf("np_writer() for addition failed\n");
TEST_ERROR;
}
}
@@ -884,7 +903,7 @@ perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *c
result = write_dsets_chunks(GWRITES, s, ds, step);
if (s->use_np && !np_writer(result, step, s, np, config)) {
- printf("np_writer() for single full chunk writes failed\n");
+ HDprintf("np_writer() for single full chunk writes failed\n");
TEST_ERROR;
}
}
@@ -902,7 +921,7 @@ perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *c
result = write_dsets_chunks(PWRITES, s, ds, step);
if (s->use_np && !np_writer(result, step, s, np, config)) {
- printf("np_writer() for partial single chunk writes failed\n");
+ HDprintf("np_writer() for partial single chunk writes failed\n");
TEST_ERROR;
}
}
@@ -920,7 +939,7 @@ perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *c
result = write_dsets_chunks(TWRITES, s, ds, step);
if (s->use_np && !np_writer(result, step, s, np, config)) {
- printf("np_writer() for multiple full chunk writes failed\n");
+ HDprintf("np_writer() for multiple full chunk writes failed\n");
TEST_ERROR;
}
}
@@ -939,7 +958,7 @@ perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *c
result = write_dsets_chunks(LWRITES, s, ds, step);
if (s->use_np && !np_writer(result, step, s, np, config)) {
- printf("np_writer() for multiple partial chunk writes failed\n");
+ HDprintf("np_writer() for multiple partial chunk writes failed\n");
TEST_ERROR;
}
}
@@ -954,7 +973,7 @@ perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *c
result = dsets_extent(INCR_EXT, s, ds);
if (s->use_np && !np_writer(result, step, s, np, config)) {
- printf("np_writer() for increasing dimension sizes failed\n");
+ HDprintf("np_writer() for increasing dimension sizes failed\n");
TEST_ERROR;
}
}
@@ -969,7 +988,7 @@ perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *c
result = dsets_extent(DECR_EXT, s, ds);
if (s->use_np && !np_writer(result, step, s, np, config)) {
- printf("np_writer() for decreasing dimension sizes failed\n");
+ HDprintf("np_writer() for decreasing dimension sizes failed\n");
TEST_ERROR;
}
}
@@ -1004,29 +1023,29 @@ write_dsets_chunks(unsigned action, const state_t *s, const dsets_state_t *ds, u
setup_selection(action, which, s, ds, start, stride, count, block);
if (s->implicit_index) {
- if (!write_dset(action, ds->implicit_did, s->filetype, start, stride, count, block)) {
- printf("H5Dwrite to chunked dataset: implicit index dataset failed\n");
+ if (!write_chunks(action, ds->implicit_did, s->filetype, start, stride, count, block)) {
+ HDprintf("H5Dwrite to chunked dataset: implicit index dataset failed\n");
TEST_ERROR;
}
}
if (s->fa_index) {
- if (!write_dset(action, ds->fa_did, s->filetype, start, stride, count, block)) {
- printf("H5Dwrite to chunked dataset: fa index dataset failed\n");
+ if (!write_chunks(action, ds->fa_did, s->filetype, start, stride, count, block)) {
+ HDprintf("H5Dwrite to chunked dataset: fa index dataset failed\n");
TEST_ERROR;
}
}
if (s->ea_index) {
- if (!write_dset(action, ds->ea_did, s->filetype, start, stride, count, block)) {
- printf("H5Dwrite to chunked dataset: ea index dataset failed\n");
+ if (!write_chunks(action, ds->ea_did, s->filetype, start, stride, count, block)) {
+ HDprintf("H5Dwrite to chunked dataset: ea index dataset failed\n");
TEST_ERROR;
}
}
if (s->bt2_index) {
- if (!write_dset(action, ds->bt2_did, s->filetype, start, stride, count, block)) {
- printf("H5Dwrite to chunked dataset: bt2 index dataset failed\n");
+ if (!write_chunks(action, ds->bt2_did, s->filetype, start, stride, count, block)) {
+ HDprintf("H5Dwrite to chunked dataset: bt2 index dataset failed\n");
TEST_ERROR;
}
}
@@ -1163,8 +1182,8 @@ check_set_partial_block(unsigned action, const hsize_t *chunk_dims, hsize_t *blo
* Make the selection and then write to the dataset.
*/
static bool
-write_dset(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *stride, hsize_t *count,
- hsize_t *block)
+write_chunks(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *stride, hsize_t *count,
+ hsize_t *block)
{
hid_t sid = badhid;
hid_t mem_sid = badhid;
@@ -1173,12 +1192,12 @@ write_dset(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *strid
unsigned i;
if ((sid = H5Dget_space(did)) < 0) {
- printf("H5Sget_space failed\n");
+ HDprintf("H5Sget_space failed\n");
TEST_ERROR;
}
if (H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block) < 0) {
- printf("H5Sselect_hyperslab failed\n");
+ HDprintf("H5Sselect_hyperslab failed\n");
TEST_ERROR;
}
@@ -1186,13 +1205,13 @@ write_dset(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *strid
mem_dims[1] = block[1];
if ((mem_sid = H5Screate_simple(2, mem_dims, NULL)) < 0) {
- printf("H5Screate_simple failed\n");
+ HDprintf("H5Screate_simple failed\n");
TEST_ERROR;
}
/* Allocate the buffer for writing */
if ((buf = HDmalloc(block[0] * block[1] * sizeof(unsigned int))) == NULL) {
- printf("HDmalloc failed\n");
+ HDprintf("HDmalloc failed\n");
TEST_ERROR;
}
@@ -1205,12 +1224,12 @@ write_dset(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *strid
}
if (H5Dwrite(did, tid, mem_sid, sid, H5P_DEFAULT, buf) < 0) {
- printf("H5Dwrite failed\n");
+ HDprintf("H5Dwrite failed\n");
TEST_ERROR;
}
if (H5Sclose(sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
@@ -1232,7 +1251,7 @@ error:
return false;
-} /* write_dset() */
+} /* write_chunks() */
/*
* Increase or decrease the dimenion sizes for the specified datasets.
@@ -1284,12 +1303,12 @@ dset_extent_real(unsigned action, hid_t did, const hsize_t *chunk_dims)
hid_t sid = badhid;
if ((sid = H5Dget_space(did)) < 0) {
- printf("H5Sget_space failed\n");
+ HDprintf("H5Sget_space failed\n");
TEST_ERROR;
}
if (H5Sget_simple_extent_dims(sid, dims, max_dims) < 0) {
- printf("H5Sget_simple_extent_dims failed\n");
+ HDprintf("H5Sget_simple_extent_dims failed\n");
TEST_ERROR;
}
@@ -1303,7 +1322,7 @@ dset_extent_real(unsigned action, hid_t did, const hsize_t *chunk_dims)
/* Cannot increase to more than maximum dimension (dim 0) for EA dataset */
if ((max_dims[0] != H5S_UNLIMITED && new[0] > max_dims[0]) ||
(max_dims[1] != H5S_UNLIMITED && new[1] > max_dims[1])) {
- printf("Cannot exceed maximum dimension for dataset\n");
+ HDprintf("Cannot exceed maximum dimension for dataset\n");
TEST_ERROR;
}
@@ -1314,7 +1333,7 @@ dset_extent_real(unsigned action, hid_t did, const hsize_t *chunk_dims)
new[1] = dims[1] - 1;
if (new[0] < chunk_dims[0] || new[1] < chunk_dims[1]) {
- printf("Cannot decrease to less than chunk dimension\n");
+ HDprintf("Cannot decrease to less than chunk dimension\n");
TEST_ERROR;
}
break;
@@ -1325,12 +1344,12 @@ dset_extent_real(unsigned action, hid_t did, const hsize_t *chunk_dims)
} /* end switch */
if (H5Dset_extent(did, new) < 0) {
- printf("H5Dset_extent for dataset failed\n");
+ HDprintf("H5Dset_extent for dataset failed\n");
TEST_ERROR;
}
if (H5Sclose(sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
@@ -1364,8 +1383,8 @@ write_dset_single(unsigned action, const state_t *s, const dsets_state_t *ds)
if (action == PWRITES || action == LWRITES)
check_set_partial_block(action, block, block, start);
- if (!write_dset(action, ds->single_did, s->filetype, start, stride, count, block)) {
- printf("H5Dwrite to dataset with single index dataset failed\n");
+ if (!write_chunks(action, ds->single_did, s->filetype, start, stride, count, block)) {
+ HDprintf("H5Dwrite to dataset with single index dataset failed\n");
TEST_ERROR;
}
@@ -1397,7 +1416,8 @@ error:
* --DECR_EXT: verify the decrease to dataset dimensions sizes
*/
static bool
-verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np)
+verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np,
+ bool fileclosed)
{
unsigned step;
unsigned allowed_writes;
@@ -1412,19 +1432,22 @@ verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *co
dbgf(2, "Verify single full chunk write to dataset with single index; only verify 1 write\n");
if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, 0, s, np)) {
- printf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
/* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
- result = verify_read_dset_single(GWRITES, s, ds);
+ result = verify_dset_single(GWRITES, s, ds, fileclosed);
if (s->use_np && !np_reader(result, 0, s, np)) {
- printf("np_reader() for verifying addition failed\n");
+ HDprintf("np_reader() for verifying addition failed\n");
TEST_ERROR;
}
+ else if (!result)
+ TEST_ERROR;
}
/* Verify a single partial chunk write to dataset with single index */
@@ -1434,18 +1457,22 @@ verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *co
dbgf(2, "Verify single partial chunk write to dataset with single index; only verify 1 write\n");
if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, 0, s, np)) {
- printf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
+
/* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
- result = verify_read_dset_single(PWRITES, s, ds);
+ result = verify_dset_single(PWRITES, s, ds, fileclosed);
if (s->use_np && !np_reader(result, 0, s, np)) {
- printf("np_reader() for verifying addition failed\n");
+ HDprintf("np_reader() for verifying addition failed\n");
TEST_ERROR;
}
+ if (!result)
+ TEST_ERROR;
}
}
@@ -1462,18 +1489,22 @@ verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *co
step);
if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
- printf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
+
/* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
- result = verify_dsets_chunks(GWRITES, s, ds, step);
+ result = verify_dsets_chunks(GWRITES, s, ds, step, fileclosed);
if (s->use_np && !np_reader(result, step, s, np)) {
- printf("np_reader() for verification failed\n");
+ HDprintf("np_reader() for verification failed\n");
TEST_ERROR;
}
+ else if (!result)
+ TEST_ERROR;
}
}
@@ -1487,18 +1518,22 @@ verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *co
step);
if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
- printf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
+
/* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
- result = verify_dsets_chunks(PWRITES, s, ds, step);
+ result = verify_dsets_chunks(PWRITES, s, ds, step, fileclosed);
if (s->use_np && !np_reader(result, step, s, np)) {
- printf("np_reader() for verification failed\n");
+ HDprintf("np_reader() for verification failed\n");
TEST_ERROR;
}
+ else if (!result)
+ TEST_ERROR;
}
}
@@ -1512,18 +1547,22 @@ verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *co
step);
if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
- printf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
+
/* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
- result = verify_dsets_chunks(TWRITES, s, ds, step);
+ result = verify_dsets_chunks(TWRITES, s, ds, step, fileclosed);
if (s->use_np && !np_reader(result, step, s, np)) {
- printf("np_reader() for verification failed\n");
+ HDprintf("np_reader() for verification failed\n");
TEST_ERROR;
}
+ else if (!result)
+ TEST_ERROR;
}
}
@@ -1538,18 +1577,22 @@ verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *co
step);
if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
- printf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
+
/* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
- result = verify_dsets_chunks(LWRITES, s, ds, step);
+ result = verify_dsets_chunks(LWRITES, s, ds, step, fileclosed);
if (s->use_np && !np_reader(result, step, s, np)) {
- printf("np_reader() for verification failed\n");
+ HDprintf("np_reader() for verification failed\n");
TEST_ERROR;
}
+ else if (!result)
+ TEST_ERROR;
}
}
@@ -1560,18 +1603,21 @@ verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *co
step + 1);
if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
- printf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
+
/* Wait for a few ticks for the update to happen */
decisleep(config->tick_len * s->update_interval);
result = verify_dsets_extent(INCR_EXT, s, ds, step + 1);
if (s->use_np && !np_reader(result, step, s, np)) {
- printf("np_reader() for failed\n");
+ HDprintf("np_reader() for failed\n");
TEST_ERROR;
}
+ else if (!result)
+ TEST_ERROR;
}
}
@@ -1582,7 +1628,7 @@ verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *co
step + 1);
if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
- printf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
/* Wait for a few ticks for the update to happen */
@@ -1591,9 +1637,11 @@ verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *co
result = verify_dsets_extent(DECR_EXT, s, ds, step + 1);
if (s->use_np && !np_reader(result, step, s, np)) {
- printf("np_reader() for verification failed\n");
+ HDprintf("np_reader() for verification failed\n");
TEST_ERROR;
}
+ else if (!result)
+ TEST_ERROR;
}
}
}
@@ -1614,7 +1662,8 @@ error:
* LWRITEs: verify `which` write that covers multiple partial chunks
*/
static bool
-verify_dsets_chunks(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which)
+verify_dsets_chunks(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which,
+ bool fileclosed)
{
hsize_t start[2] = {0, 0};
hsize_t stride[2] = {0, 0};
@@ -1627,29 +1676,33 @@ verify_dsets_chunks(unsigned action, const state_t *s, const dsets_state_t *ds,
setup_selection(action, which, s, ds, start, stride, count, block);
if (s->implicit_index) {
- if (!verify_read_dset(action, ds->implicit_did, s->filetype, start, stride, count, block)) {
- printf("verify_read_dset() to dataset with implicit index failed\n");
+ if (!verify_chunks(action, ds->implicit_did, s->filetype, start, stride, count, block, fileclosed,
+ s->flush_raw_data)) {
+ HDprintf("verify_chunks() to dataset with implicit index failed\n");
TEST_ERROR;
}
}
if (s->fa_index) {
- if (!verify_read_dset(action, ds->fa_did, s->filetype, start, stride, count, block)) {
- printf("verify_read_dset() to dataset with fixed array index failed\n");
+ if (!verify_chunks(action, ds->fa_did, s->filetype, start, stride, count, block, fileclosed,
+ s->flush_raw_data)) {
+ HDprintf("verify_chunks() to dataset with fixed array index failed\n");
TEST_ERROR;
}
}
if (s->ea_index) {
- if (!verify_read_dset(action, ds->ea_did, s->filetype, start, stride, count, block)) {
- printf("verify_read_dset() to dataset with extensible array index failed\n");
+ if (!verify_chunks(action, ds->ea_did, s->filetype, start, stride, count, block, fileclosed,
+ s->flush_raw_data)) {
+ HDprintf("verify_chunks() to dataset with extensible array index failed\n");
TEST_ERROR;
}
}
if (s->bt2_index) {
- if (!verify_read_dset(action, ds->bt2_did, s->filetype, start, stride, count, block)) {
- printf("verify_read_dset() to dataset with bt2 index failed\n");
+ if (!verify_chunks(action, ds->bt2_did, s->filetype, start, stride, count, block, fileclosed,
+ s->flush_raw_data)) {
+ HDprintf("verify_chunks() to dataset with bt2 index failed\n");
TEST_ERROR;
}
}
@@ -1666,8 +1719,8 @@ error:
* Verify the data read from the dataset is as expected.
*/
static bool
-verify_read_dset(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *stride, hsize_t *count,
- hsize_t *block)
+verify_chunks(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t *stride, hsize_t *count,
+ hsize_t *block, bool fileclosed, bool flush_raw_data)
{
hid_t mem_sid = badhid;
hid_t sid = badhid;
@@ -1677,64 +1730,80 @@ verify_read_dset(unsigned action, hid_t did, hid_t tid, hsize_t *start, hsize_t
/* Refresh the dataset */
if (H5Drefresh(did) < 0) {
- printf("H5Drefresh dataset failed\n");
+ HDprintf("H5Drefresh dataset failed\n");
TEST_ERROR;
}
if ((sid = H5Dget_space(did)) < 0) {
- printf("H5Dget_space dataset failed\n");
+ HDprintf("H5Dget_space dataset failed\n");
TEST_ERROR;
}
/* Make the selection the file dataspace */
if (H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, block) < 0) {
- printf("H5Sselect to dataset failed\n");
+ HDprintf("H5Sselect to dataset failed\n");
TEST_ERROR;
}
mem_dims[0] = block[0];
mem_dims[1] = block[1];
if ((mem_sid = H5Screate_simple(2, mem_dims, NULL)) < 0) {
- printf("H5Screate_simple failed\n");
+ HDprintf("H5Screate_simple failed\n");
TEST_ERROR;
}
/* Allocate the buffer for reading */
if ((rbuf = HDmalloc(block[0] * block[1] * sizeof(unsigned int))) == NULL) {
- printf("HDmalloc failed\n");
+ HDprintf("HDmalloc failed\n");
TEST_ERROR;
}
/* Read the data from the dataset into `rbuf` */
if (H5Dread(did, tid, mem_sid, sid, H5P_DEFAULT, rbuf) < 0) {
- printf("H5Dread from dataset failed\n");
+ HDprintf("H5Dread from dataset failed\n");
TEST_ERROR;
}
/* Verify the data read in `rbuf` is as the fill value expected */
for (i = 0; i < block[0] * block[1]; i++) {
- if (action == GWRITES || action == TWRITES) {
- if (rbuf[i] != FILL_FULL) {
- printf("Invalid value for dataset for GWRITES/TWRITES\n");
- TEST_ERROR;
+ if (flush_raw_data || fileclosed) {
+ if (action == GWRITES || action == TWRITES) {
+ if (rbuf[i] != FILL_FULL) {
+ HDprintf("Invalid value for dataset for GWRITES/TWRITES: %d\n", rbuf[i]);
+ TEST_ERROR;
+ }
+ }
+ else {
+ HDassert(action == PWRITES || action == LWRITES);
+ if (rbuf[i] != FILL_PARTIAL) {
+ HDprintf("Invalid value for dataset for GWRITES/TWRITES: %d\n", rbuf[i]);
+ TEST_ERROR;
+ }
}
}
- else {
- HDassert(action == PWRITES || action == LWRITES);
- if (rbuf[i] != FILL_PARTIAL) {
- printf("Invalid value for dataset for GWRITES/TWRITES\n");
- TEST_ERROR;
+ else { /* No flush && not closing file */
+ if (action == GWRITES || action == TWRITES) {
+ if (rbuf[i] != FILL_FULL && rbuf[i] != FILL_INIT) {
+ HDprintf("Invalid value for dataset for GWRITES/TWRITES\n");
+ TEST_ERROR;
+ }
+ }
+ else {
+ if (rbuf[i] != FILL_PARTIAL && rbuf[i] != FILL_INIT) {
+ HDprintf("Invalid value for dataset for GWRITES/TWRITES\n");
+ TEST_ERROR;
+ }
}
}
}
if (H5Sclose(sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
if (H5Sclose(mem_sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
@@ -1756,7 +1825,7 @@ error:
return false;
-} /* verify_read_dset() */
+} /* verify_chunks() */
/*
* Verify the increase or decrease of dimenion sizes for the specified datasets.
@@ -1779,7 +1848,7 @@ verify_dsets_extent(unsigned action, const state_t *s, const dsets_state_t *ds,
if (s->fa_index) {
dbgf(2, "Verify dataset extent for FA dataset\n");
if (!verify_dset_extent_real(action, ds->fa_did, rows, cols, which)) {
- printf("verify_read_dset() to dataset with fixed array index failed\n");
+ HDprintf("verify_read_dset() to dataset with fixed array index failed\n");
TEST_ERROR;
}
}
@@ -1787,7 +1856,7 @@ verify_dsets_extent(unsigned action, const state_t *s, const dsets_state_t *ds,
if (s->ea_index) {
dbgf(2, "Verify dataset extent for EA dataset\n");
if (!verify_dset_extent_real(action, ds->fa_did, rows, cols, which)) {
- printf("verify_read_dset() to dataset with fixed array index failed\n");
+ HDprintf("verify_read_dset() to dataset with fixed array index failed\n");
TEST_ERROR;
}
}
@@ -1795,7 +1864,7 @@ verify_dsets_extent(unsigned action, const state_t *s, const dsets_state_t *ds,
if (s->bt2_index) {
dbgf(2, "Verify dataset extent for BT2 dataset\n");
if (!verify_dset_extent_real(action, ds->bt2_did, rows, cols, which)) {
- printf("verify_read_dset() to dataset with fixed array index failed\n");
+ HDprintf("verify_read_dset() to dataset with fixed array index failed\n");
TEST_ERROR;
}
}
@@ -1818,17 +1887,17 @@ verify_dset_extent_real(unsigned action, hid_t did, unsigned rows, unsigned cols
/* Refresh the dataset */
if (H5Drefresh(did) < 0) {
- printf("H5Drefresh dataset failed\n");
+ HDprintf("H5Drefresh dataset failed\n");
TEST_ERROR;
}
if ((sid = H5Dget_space(did)) < 0) {
- printf("H5Dget_space dataset failed\n");
+ HDprintf("H5Dget_space dataset failed\n");
TEST_ERROR;
}
if (H5Sget_simple_extent_dims(sid, dims, NULL) < 0) {
- printf("H5Sget_simple_extent_dims() failed\n");
+ HDprintf("H5Sget_simple_extent_dims() failed\n");
TEST_ERROR;
}
@@ -1851,7 +1920,7 @@ verify_dset_extent_real(unsigned action, hid_t did, unsigned rows, unsigned cols
} /* end switch */
if (H5Sclose(sid) < 0) {
- printf("H5Sclose failed\n");
+ HDprintf("H5Sclose failed\n");
TEST_ERROR;
}
@@ -1871,7 +1940,7 @@ error:
* Verify that the data read from the dataset with single index is as unexpected.
*/
static bool
-verify_read_dset_single(unsigned action, const state_t *s, const dsets_state_t *ds)
+verify_dset_single(unsigned action, const state_t *s, const dsets_state_t *ds, bool fileclosed)
{
hsize_t block[2] = {s->rows, s->cols};
hsize_t count[2] = {1, 1};
@@ -1884,8 +1953,9 @@ verify_read_dset_single(unsigned action, const state_t *s, const dsets_state_t *
if (action == PWRITES)
check_set_partial_block(action, block, block, start);
- if (!verify_read_dset(action, ds->single_did, s->filetype, start, stride, count, block)) {
- printf("verify_read_dset() to dataset with single index failed\n");
+ if (!verify_chunks(action, ds->single_did, s->filetype, start, stride, count, block, fileclosed,
+ s->flush_raw_data)) {
+ HDprintf("verify_read_dset() to dataset with single index failed\n");
TEST_ERROR;
}
@@ -1894,7 +1964,7 @@ verify_read_dset_single(unsigned action, const state_t *s, const dsets_state_t *
error:
return false;
-} /* verify_read_dset_single() */
+} /* verify_dset_single() */
/*
* Named pipes handling
@@ -1918,36 +1988,36 @@ np_init(np_state_t *np, bool writer)
/* If the named pipes are present at the start of the test, remove them */
if (HDaccess(np->fifo_writer_to_reader, F_OK) == 0)
if (HDremove(np->fifo_writer_to_reader) != 0) {
- printf("HDremove fifo_writer_to_reader failed\n");
+ HDprintf("HDremove fifo_writer_to_reader failed\n");
TEST_ERROR;
}
if (HDaccess(np->fifo_reader_to_writer, F_OK) == 0)
if (HDremove(np->fifo_reader_to_writer) != 0) {
- printf("HDremove fifo_reader_to_writer failed\n");
+ HDprintf("HDremove fifo_reader_to_writer failed\n");
TEST_ERROR;
}
/* Writer creates two named pipes(FIFO) */
if (HDmkfifo(np->fifo_writer_to_reader, 0600) < 0) {
- printf("HDmkfifo fifo_writer_to_reader failed\n");
+ HDprintf("HDmkfifo fifo_writer_to_reader failed\n");
TEST_ERROR;
}
if (HDmkfifo(np->fifo_reader_to_writer, 0600) < 0) {
- printf("HDmkfifo fifo_reader_to_writer failed\n");
+ HDprintf("HDmkfifo fifo_reader_to_writer failed\n");
TEST_ERROR;
}
}
/* Both the writer and reader open the pipes */
if ((np->fd_writer_to_reader = HDopen(np->fifo_writer_to_reader, O_RDWR)) < 0) {
- printf("HDopen fifo_writer_to_reader failed\n");
+ HDprintf("HDopen fifo_writer_to_reader failed\n");
TEST_ERROR;
}
if ((np->fd_reader_to_writer = HDopen(np->fifo_reader_to_writer, O_RDWR)) < 0) {
- printf("HDopen fifo_reader_to_writer failed\n");
+ HDprintf("HDopen fifo_reader_to_writer failed\n");
TEST_ERROR;
}
@@ -1966,24 +2036,24 @@ np_close(np_state_t *np, bool writer)
{
/* Both the writer and reader close the named pipes */
if (HDclose(np->fd_writer_to_reader) < 0) {
- printf("HDclose fd_writer_to_reader failed\n");
+ HDprintf("HDclose fd_writer_to_reader failed\n");
TEST_ERROR;
}
if (HDclose(np->fd_reader_to_writer) < 0) {
- printf("HDclose fd_reader_to_writer failed\n");
+ HDprintf("HDclose fd_reader_to_writer failed\n");
TEST_ERROR;
}
/* Reader finishes last and deletes the named pipes */
if (!writer) {
if (HDremove(np->fifo_writer_to_reader) != 0) {
- printf("HDremove fifo_writer_to_reader failed\n");
+ HDprintf("HDremove fifo_writer_to_reader failed\n");
TEST_ERROR;
}
if (HDremove(np->fifo_reader_to_writer) != 0) {
- printf("HDremove fifo_reader_to_writer failed\n");
+ HDprintf("HDremove fifo_reader_to_writer failed\n");
TEST_ERROR;
}
}
@@ -2003,7 +2073,7 @@ np_writer(bool result, unsigned step, const state_t *s, np_state_t *np, H5F_vfd_
/* The action fails */
if (!result) {
- printf("action failed\n");
+ HDprintf("action failed\n");
H5_FAILED();
AT();
@@ -2021,7 +2091,7 @@ np_writer(bool result, unsigned step, const state_t *s, np_state_t *np, H5F_vfd_
/* Bump up the value of notify to tell the reader to start reading */
np->notify++;
if (HDwrite(np->fd_writer_to_reader, &np->notify, sizeof(int)) < 0) {
- printf("HDwrite failed\n");
+ HDprintf("HDwrite failed\n");
TEST_ERROR;
}
@@ -2038,7 +2108,7 @@ np_writer(bool result, unsigned step, const state_t *s, np_state_t *np, H5F_vfd_
/* Handshake between writer and reader */
if (!np_confirm_verify_notify(np->fd_reader_to_writer, step, s, np)) {
- printf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
}
@@ -2059,7 +2129,7 @@ np_reader(bool result, unsigned step, const state_t *s, np_state_t *np)
{
/* The verification fails */
if (!result) {
- printf("verify action failed\n");
+ HDprintf("verify action failed\n");
H5_FAILED();
AT();
@@ -2076,7 +2146,7 @@ np_reader(bool result, unsigned step, const state_t *s, np_state_t *np)
/* Send back the same notify value for acknowledgement:
* --inform the writer to move to the next step */
if (HDwrite(np->fd_reader_to_writer, &np->notify, sizeof(int)) < 0) {
- printf("HDwrite failed\n");
+ HDprintf("HDwrite failed\n");
TEST_ERROR;
}
}
@@ -2098,17 +2168,17 @@ np_confirm_verify_notify(int fd, unsigned step, const state_t *s, np_state_t *np
if (step % s->csteps == 0) {
np->verify++;
if (HDread(fd, &np->notify, sizeof(int)) < 0) {
- printf("HDread failed\n");
+ HDprintf("HDread failed\n");
TEST_ERROR;
}
if (np->notify == -1) {
- printf("reader/writer failed to verify\n");
+ HDprintf("reader/writer failed to verify\n");
TEST_ERROR;
}
if (np->notify != np->verify) {
- printf("received message %d, expecting %d\n", np->notify, np->verify);
+ HDprintf("received message %d, expecting %d\n", np->notify, np->verify);
TEST_ERROR;
}
}
@@ -2120,6 +2190,89 @@ error:
} /* np_confirm_verify_notify() */
/*
+ * When flush of raw data is disabled, the following is done by the writer and reader:
+ * Writer:
+ * Close the file
+ * Notify the reader that the file is closed
+ * Reader:
+ * Confirm the message from the writer that the file is closed
+ * Verify the data
+ */
+static bool
+closing_on_noflush(bool writer, state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np)
+{
+ HDassert(s->use_np);
+
+ if (writer) {
+ if (!close_dsets(ds)) {
+ HDprintf("close_dsets() failed\n");
+ TEST_ERROR;
+ }
+
+ dbgf(2, "Writer closes the file (flush of raw data is disabled)\n");
+ if (H5Fclose(s->file) < 0) {
+ HDprintf("H5Fclose failed\n");
+ TEST_ERROR;
+ }
+
+ /* Bump up the value of notify to tell the reader the file is closed */
+ dbgf(2, "Writer notifies reader that the file is closed (flush of raw data is disabled)\n");
+ np->notify++;
+ if (HDwrite(np->fd_writer_to_reader, &np->notify, sizeof(int)) < 0) {
+ HDprintf("HDwrite failed\n");
+ TEST_ERROR;
+ }
+
+ if (!np_close(np, writer)) {
+ HDprintf("np_close() failed\n");
+ TEST_ERROR;
+ }
+ }
+ else {
+ /* Wait for a few ticks for the file to close in writer */
+ decisleep(config->tick_len * s->update_interval);
+
+ dbgf(2, "Reader checks notify value from writer (flush of raw data is disabled)\n");
+ if (!np_confirm_verify_notify(np->fd_writer_to_reader, 0, s, np)) {
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ TEST_ERROR;
+ }
+
+ /* Close the named pipes */
+ if (!np_close(np, writer)) {
+ HDprintf("np_close() failed\n");
+ TEST_ERROR;
+ }
+
+ /* Turn off named pipes */
+ s->use_np = false;
+
+ /* Verify the dataset again without named pipes */
+ dbgf(2, "Reader verifies data after writer closes the file (flush of raw data is disabled)\n");
+ if (!verify_dsets_operations(s, ds, config, np, true)) {
+ HDprintf("verify_dsets_operations() failed\n");
+ TEST_ERROR
+ }
+
+ if (!close_dsets(ds)) {
+ HDprintf("close_dsets() failed\n");
+ TEST_ERROR;
+ }
+
+ dbgf(2, "Reader closes the file (flush of raw data is disabled)\n");
+ if (H5Fclose(s->file) < 0) {
+ HDprintf("H5Fclose failed\n");
+ TEST_ERROR;
+ }
+ }
+
+ return true;
+
+error:
+ return false;
+
+} /* closing_on_noflush() */
+/*
* Main
*/
int
@@ -2134,7 +2287,7 @@ main(int argc, char **argv)
dsets_state_t ds;
if (!state_init(&s, argc, argv)) {
- printf("state_init() failed\n");
+ HDprintf("state_init() failed\n");
TEST_ERROR;
}
@@ -2145,16 +2298,16 @@ main(int argc, char **argv)
else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_dsetchks_reader") == 0)
writer = false;
else {
- printf("unknown personality, expected vfd_swmr_dsetchks_{reader,writer}\n");
+ HDprintf("unknown personality, expected vfd_swmr_dsetchks_{reader,writer}\n");
TEST_ERROR;
}
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(&config, 4, 7, writer, FALSE, 128, "./dsetchks-shadow");
+ init_vfd_swmr_config(&config, 4, 7, writer, s.flush_raw_data, 128, "./dsetchks-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, 4096, &config)) < 0) {
- printf("vfd_swmr_create_fapl() failed\n");
+ HDprintf("vfd_swmr_create_fapl() failed\n");
TEST_ERROR;
}
@@ -2166,70 +2319,83 @@ main(int argc, char **argv)
if (writer) {
if ((s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) {
- printf("H5Fcreate failed\n");
+ HDprintf("H5Fcreate failed\n");
TEST_ERROR;
}
if (!create_dsets(&s, &ds)) {
- printf("create_dsets() failed\n");
+ HDprintf("create_dsets() failed\n");
TEST_ERROR;
}
}
else {
if ((s.file = H5Fopen(s.filename, H5F_ACC_RDONLY, fapl)) < 0) {
- printf("H5Fopen failed\n");
+ HDprintf("H5Fopen failed\n");
TEST_ERROR;
}
if (!open_dsets(&s, &ds)) {
- printf("open_dsets() failed\n");
+ HDprintf("open_dsets() failed\n");
TEST_ERROR;
}
}
/* Initiailze named pipes */
if (s.use_np && !np_init(&np, writer)) {
- printf("np_init() failed\n");
+ HDprintf("np_init() failed\n");
TEST_ERROR;
}
if (writer) {
if (!perform_dsets_operations(&s, &ds, &config, &np)) {
- printf("perform_dsets_operations() failed\n");
+ HDprintf("perform_dsets_operations() failed\n");
TEST_ERROR;
}
}
else {
- if (!verify_dsets_operations(&s, &ds, &config, &np)) {
- printf("perform_dsets_operations() failed\n");
+ if (!verify_dsets_operations(&s, &ds, &config, &np, false)) {
+ HDprintf("perform_dsets_operations() failed\n");
TEST_ERROR;
}
}
- if (!close_dsets(&ds)) {
- printf("close_dsets() failed\n");
- TEST_ERROR;
- }
-
if (H5Pclose(fapl) < 0) {
- printf("H5Pclose failed\n");
+ HDprintf("H5Pclose failed\n");
TEST_ERROR;
}
if (H5Pclose(fcpl) < 0) {
- printf("H5Pclose failed\n");
+ HDprintf("H5Pclose failed\n");
TEST_ERROR;
}
- if (H5Fclose(s.file) < 0) {
- printf("H5Fclose failed\n");
- TEST_ERROR;
+ /* When flush of raw data is disabled, special handling is performed
+ * via closing_on_noflush() when closing the file.
+ * Nothing needs to be done for -x or -y options
+ * (increase and decrease dataset dimension sizes).
+ */
+ if (!s.flush_raw_data && !s.xincrs && !s.ydecrs && s.use_np) {
+
+ if (!closing_on_noflush(writer, &s, &ds, &config, &np))
+ TEST_ERROR
}
+ else {
- if (s.use_np && !np_close(&np, writer)) {
- printf("np_close() failed\n");
- TEST_ERROR;
+ if (!close_dsets(&ds)) {
+ HDprintf("close_dsets() failed\n");
+ TEST_ERROR;
+ }
+
+ if (H5Fclose(s.file) < 0) {
+ HDprintf("H5Fclose failed\n");
+ TEST_ERROR;
+ }
+
+ if (s.use_np && !np_close(&np, writer)) {
+ HDprintf("np_close() failed\n");
+ TEST_ERROR;
+ }
}
return EXIT_SUCCESS;
diff --git a/test/vfd_swmr_dsetops_writer.c b/test/vfd_swmr_dsetops_writer.c
index 26f8977..f98843d 100644
--- a/test/vfd_swmr_dsetops_writer.c
+++ b/test/vfd_swmr_dsetops_writer.c
@@ -46,17 +46,19 @@ typedef struct {
unsigned int csteps; /* For -c <csteps> option */
bool use_np; /* For -N option */
bool use_vfd_swmr; /* For -S option */
+ bool flush_raw_data; /* For -U option */
bool compact; /* -p option: create compact dataset */
- bool compact_write; /* -o option: write to the whole compact dataset */
+ bool compact_write; /* -t option: write to the whole compact dataset */
unsigned int compact_elmts; /* -e <elmts> option: # of elments for the compact dataset */
bool contig; /* -g option: create contiguous dataset */
bool chunked; /* -k option: create chunked datasets with 5 indexing types */
unsigned int rows; /* -m <rows> option for contiguous and/or chunked datasets */
unsigned int cols; /* -n <cols option for contiguous and/or chunked datasets */
- unsigned int swrites; /* -s <swrites> option: sequential writes to contiguous and/or chunked datasets */
- unsigned int rwrites; /* -r <rwrites> option: random writes to contiguous and/or chunked datasets */
- unsigned int lwrites; /* -l <lwrites> option: hyperslab writes to contiguous and/or chunked datasets */
- unsigned int wwrites; /* -w <wwrites> option: modify raw data to contiguous and/or chunked datasets */
+ unsigned int swrites; /* -s <swrites> option: sequential writes to contiguous and/or chunked datasets */
+ unsigned int rwrites; /* -r <rwrites> option: random writes to contiguous and/or chunked datasets */
+ unsigned int lwrites; /* -l <lwrites> option: hyperslab writes to contiguous and/or chunked datasets */
+ unsigned int wwrites; /* -w <wwrites> option: modify raw data to contiguous and/or chunked datasets */
+ unsigned int lastwrite; /* The last operation (-s, -r, -l or -w) performed. */
} state_t;
/* Initializations for state_t */
@@ -65,8 +67,9 @@ typedef struct {
{ \
.filename = "", .file = H5I_INVALID_HID, .filetype = H5T_NATIVE_UINT32, \
.update_interval = READER_WAIT_TICKS, .csteps = 1, .use_np = true, .use_vfd_swmr = true, \
- .compact = false, .compact_write = false, .compact_elmts = MAX_COMPACT_ELMS, .contig = false, \
- .rows = 256, .cols = 512, .swrites = 0, .rwrites = 0, .lwrites = 0, .wwrites = 0 \
+ .flush_raw_data = true, .compact = false, .compact_write = false, .compact_elmts = MAX_COMPACT_ELMS, \
+ .contig = false, .rows = 10, .cols = 5, .swrites = 0, .rwrites = 0, .lwrites = 0, .wwrites = 0, \
+ .lastwrite = 0 \
}
/* Structure to hold info for different dataset types */
@@ -132,8 +135,8 @@ static bool open_dset_real(const state_t *s, hid_t *did, hid_t *sid, const char
static bool close_dsets(const dsets_state_t *ds);
static bool close_dset_real(hid_t did, hid_t sid);
-static bool write_dset_contig_chunked(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config,
- np_state_t *np);
+static bool perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config,
+ np_state_t *np);
static bool dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned step);
static bool dset_setup(unsigned action, unsigned which, const state_t *s, hsize_t *start, hsize_t *stride,
hsize_t *count, hsize_t *block, hid_t *mem_sid, unsigned int **buf);
@@ -141,12 +144,18 @@ static bool write_dset(hid_t did, hid_t tid, hid_t mem_sid, hid_t file_sid, hsiz
hsize_t *count, hsize_t *block, unsigned int *buf);
static bool write_dset_compact(const state_t *s, const dsets_state_t *ds);
-static bool verify_write_dset_contig_chunked(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config,
- np_state_t *np);
-static bool verify_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which);
-static bool verify_read_dset(hid_t did, hid_t tid, hid_t mem_sid, hid_t file_sid, hsize_t *start,
- hsize_t *stride, hsize_t *count, hsize_t *block, unsigned int *vbuf);
-static bool verify_read_dset_compact(const state_t *s, const dsets_state_t *ds);
+static bool verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config,
+ np_state_t *np, bool fileclosed);
+static bool verify_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which,
+ bool fileclosed);
+static bool verify_dset(hid_t did, hid_t tid, hid_t mem_sid, hid_t file_sid, hsize_t *start, hsize_t *stride,
+ size_t *count, hsize_t *block, unsigned int *vbuf, bool fileclosed,
+ bool flush_raw_data);
+static bool verify_dset_compact(const state_t *s, const dsets_state_t *ds, bool fileclosed,
+ bool flush_raw_data);
+
+static bool closing_on_noflush(bool writer, state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config,
+ np_state_t *np);
static const hid_t badhid = H5I_INVALID_HID;
@@ -174,7 +183,7 @@ usage(const char *progname)
" [-p] [-e elmts] [-o]\n"
" [-g] [-k] [-m rows] [-n cols]\n"
" [-s swrites] [-r rwrites] [-l lwrites] [-w writes]\n"
- " [-u nticks] [-c csteps] [-S] [-N] [-q] [-b]\n"
+ " [-u nticks] [-c csteps] [-U] [-S] [-N] [-q] [-b]\n"
"\n"
"-p: create a dataset with compact layout\n"
"-e elmts: # of <elmts> for the compact dataset\n"
@@ -193,6 +202,7 @@ usage(const char *progname)
" (default is 4)\n"
"-c csteps: `csteps` steps communication interval between reader and writer\n"
" (default is 1)\n"
+ "-U: disable flush of raw data (default is flushing raw data)\n"
"-S: do not use VFD SWMR\n"
"-N: do not use named pipes for test synchronization\n"
"-q: silence printouts, few messages\n"
@@ -215,7 +225,7 @@ state_init(state_t *s, int argc, char **argv)
{
unsigned long tmp;
int ch;
- char * tfile;
+ char * tfile = NULL;
char * end;
*s = ALL_HID_INITIALIZER;
@@ -227,7 +237,12 @@ state_init(state_t *s, int argc, char **argv)
esnprintf(s->progname, sizeof(s->progname), "%s", tfile);
- while ((ch = getopt(argc, argv, "pte:gkm:n:s:r:l:w:bqSNu:c:")) != -1) {
+ if (tfile) {
+ HDfree(tfile);
+ tfile = NULL;
+ }
+
+ while ((ch = getopt(argc, argv, "pte:gkm:n:s:r:l:w:bqSNUu:c:")) != -1) {
switch (ch) {
case 'p': /* compact dataset */
@@ -246,6 +261,10 @@ state_init(state_t *s, int argc, char **argv)
s->chunked = true;
break;
+ case 'U': /* Disable flush of raw data */
+ s->flush_raw_data = false;
+ break;
+
case 'q':
verbosity = 0;
break;
@@ -329,6 +348,21 @@ state_init(state_t *s, int argc, char **argv)
TEST_ERROR;
}
+ /* Enable compact write (-t) without compact dataset (-p) */
+ if (s->compact_write && !s->compact) {
+ HDprintf("Enable compact write without compact dataset\n");
+ usage(s->progname);
+ goto error;
+ }
+
+ /* Enable sequential/random/hyperslab/raw data writes (-s/-r/-l/-w) without contiguous/chunked dataset
+ * (-g/-k) */
+ if ((s->swrites || s->rwrites || s->lwrites || s->wwrites) && !(s->contig || s->chunked)) {
+ HDprintf("Enable sequential/random/hypuerslab/raw data writes without contiguous/chunked dataset\n");
+ usage(s->progname);
+ goto error;
+ }
+
/* -c <csteps> cannot be zero */
if (!s->csteps) {
HDprintf("communication interval cannot be zero\n");
@@ -365,6 +399,9 @@ state_init(state_t *s, int argc, char **argv)
return true;
error:
+ if (tfile)
+ HDfree(tfile);
+
return false;
} /* state_init() */
@@ -818,6 +855,8 @@ error:
*/
/*
+ * Write to whole compact dataset
+ *
* Perform writes for contiguous and chunked datasets:
* --SEQ_WRITE: sequential writes
* --RANDOM_WRITE: random writes
@@ -825,76 +864,93 @@ error:
* --MODIFY_DATA: raw data modifications
*/
static bool
-write_dset_contig_chunked(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np)
+perform_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np)
{
unsigned step;
bool result;
- HDassert(s->contig || s->chunked);
-
- /* Perform sequential writes for contiguous and/or chunked datasets */
- if (s->swrites) {
+ /* Perform writes to the whole compact dataset */
+ if (s->compact) {
- for (step = 0; (step < s->swrites && step < (s->rows * s->cols)); step++) {
- dbgf(2, "Sequential writes %u to dataset\n", step);
+ if (s->compact_write) {
+ dbgf(2, "Writes all to compact dataset\n");
- result = dsets_action(SEQ_WRITE, s, ds, step);
+ result = write_dset_compact(s, ds);
- if (s->use_np && !np_writer(result, step, s, np, config)) {
- HDprintf("np_writer() for sequential writes failed\n");
+ if (s->use_np && !np_writer(result, 0, s, np, config)) {
+ HDprintf("np_writer() for addition failed\n");
TEST_ERROR;
}
}
}
- /* Perform random writes for contiguous and/or chunked datasets */
- if (s->rwrites) {
- unsigned newstep;
+ /* Perform writes for contiguous and/or chunked datasets */
+ if (s->contig || s->chunked) {
- /* Set up random seed which will be the same for both writer and reader */
- HDsrandom(RANDOM_SEED);
+ /* Perform sequential writes */
+ if (s->swrites) {
- for (step = 0; (step < s->rwrites && step < (s->rows * s->cols)); step++) {
- dbgf(2, "Random writes %u to dataset\n", step);
+ for (step = 0; (step < s->swrites && step < (s->rows * s->cols)); step++) {
+ dbgf(2, "Sequential writes %u to dataset\n", step);
- newstep = (unsigned int)HDrandom() % (s->rows * s->cols);
- HDprintf("Random step is %u\n", newstep);
- result = dsets_action(RANDOM_WRITE, s, ds, newstep);
+ result = dsets_action(SEQ_WRITE, s, ds, step);
- if (s->use_np && !np_writer(result, step, s, np, config)) {
- HDprintf("np_writer() for random writes failed\n");
- TEST_ERROR;
+ if (s->use_np && !np_writer(result, step, s, np, config)) {
+ HDprintf("np_writer() for sequential writes failed\n");
+ TEST_ERROR;
+ }
}
}
- }
- /* Perform hyperslab writes for contiguous and/or chunked datasets */
- if (s->lwrites) {
- unsigned k;
+ /* Perform random writes */
+ if (s->rwrites) {
+ unsigned newstep;
- for (step = 0, k = 0; (step < s->lwrites && k < (s->rows * s->cols)); step++, k += s->cols) {
- dbgf(2, "Hyperslab writes %u to dataset\n", step);
+ /* Set up random seed which will be the same for both writer and reader */
+ HDsrandom(RANDOM_SEED);
- result = dsets_action(HYPER_WRITE, s, ds, k);
+ for (step = 0; (step < s->rwrites && step < (s->rows * s->cols)); step++) {
+ dbgf(2, "Random writes %u to dataset\n", step);
- if (s->use_np && !np_writer(result, step, s, np, config)) {
- HDprintf("np_writer() for hyperslab writes failed\n");
- TEST_ERROR;
+ newstep = (unsigned int)HDrandom() % (s->rows * s->cols);
+ dbgf(2, "Random step is %u\n", newstep);
+ result = dsets_action(RANDOM_WRITE, s, ds, newstep);
+
+ if (s->use_np && !np_writer(result, step, s, np, config)) {
+ HDprintf("np_writer() for random writes failed\n");
+ TEST_ERROR;
+ }
}
}
- }
- /* Perform raw data modifications for contiguous and/or chunked datasets */
- if (s->wwrites) {
+ /* Perform hyperslab writes */
+ if (s->lwrites) {
+ unsigned k;
- for (step = 0; (step < s->wwrites && step < (s->rows * s->cols)); step++) {
- dbgf(2, "Modify raw data %u to dataset\n", step);
+ for (step = 0, k = 0; (step < s->lwrites && k < (s->rows * s->cols)); step++, k += s->cols) {
+ dbgf(2, "Hyperslab writes %u to dataset\n", step);
- result = dsets_action(MODIFY_DATA, s, ds, step);
+ result = dsets_action(HYPER_WRITE, s, ds, k);
- if (s->use_np && !np_writer(result, step, s, np, config)) {
- HDprintf("np_writer() for modify raw data failed\n");
- TEST_ERROR;
+ if (s->use_np && !np_writer(result, step, s, np, config)) {
+ HDprintf("np_writer() for hyperslab writes failed\n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ /* Perform raw data modifications */
+ if (s->wwrites) {
+
+ for (step = 0; (step < s->wwrites && step < (s->rows * s->cols)); step++) {
+ dbgf(2, "Modify raw data %u to dataset\n", step);
+
+ result = dsets_action(MODIFY_DATA, s, ds, step);
+
+ if (s->use_np && !np_writer(result, step, s, np, config)) {
+ HDprintf("np_writer() for modify raw data failed\n");
+ TEST_ERROR;
+ }
}
}
}
@@ -902,9 +958,10 @@ write_dset_contig_chunked(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *
return true;
error:
+
return false;
-} /* write_dset_contig_chunked() */
+} /* perform_dsets_operations() */
/*
* Perform the "action" for each of the datasets specified on the command line:
@@ -1128,6 +1185,8 @@ error:
*/
/*
+ * Verify writes to the compact dataset.
+ *
* Verify writes for contiguous and chunked datasets:
* --SEQ_WRITE: sequential writes
* --RANDOM_WRITE: random writes
@@ -1135,109 +1194,162 @@ error:
* --MODIFY_DATA: raw data modifications
*/
static bool
-verify_write_dset_contig_chunked(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np)
+verify_dsets_operations(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np,
+ bool fileclosed)
{
unsigned step;
bool result;
- HDassert(s->contig || s->chunked);
-
- /* Start verifying sequential writes for contiguous and/or chunked datasets */
- if (s->swrites) {
+ /* Start verifying data written to the compact dataset */
+ if (s->compact) {
- for (step = 0; (step < s->swrites && step < (s->rows * s->cols)); step++) {
- dbgf(2, "Verify sequential writes %u to dataset\n", step);
+ if (s->compact_write) {
+ dbgf(2, "Verify writes to compact dataset\n");
- if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
+ if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, 0, s, np)) {
HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
TEST_ERROR;
}
/* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
- result = verify_dsets_action(SEQ_WRITE, s, ds, step);
+ result = verify_dset_compact(s, ds, fileclosed, config->flush_raw_data);
- if (s->use_np && !np_reader(result, step, s, np)) {
+ if (s->use_np && !np_reader(result, 0, s, np)) {
HDprintf("np_reader() for verifying addition failed\n");
TEST_ERROR;
}
+ else if (!result)
+ TEST_ERROR;
}
}
- /* Start verifying random writes for contiguous and/or chunked datasets */
- if (s->rwrites) {
- unsigned newstep;
+ /* Verify writes for contiguous and/or chunked datasets */
+ if (s->contig || s->chunked) {
- /* Set up random seed which will be the same for both writer and reader */
- HDsrandom(RANDOM_SEED);
+ /* Start verifying sequential writes */
+ /* When flush of raw data is disabled, only verify data for the last write operation on file close */
+ if ((s->swrites && !fileclosed) || (fileclosed && s->lastwrite == SEQ_WRITE)) {
- for (step = 0; (step < s->rwrites && step < (s->rows * s->cols)); step++) {
- dbgf(2, "Verify random writes %u to dataset\n", step);
+ s->lastwrite = SEQ_WRITE;
- newstep = (unsigned int)HDrandom() % (s->rows * s->cols);
- HDprintf("Random step is %u\n", newstep);
+ for (step = 0; (step < s->swrites && step < (s->rows * s->cols)); step++) {
+ dbgf(2, "Verify sequential writes %u to dataset\n", step);
- if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
- HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
- TEST_ERROR;
- }
+ if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ TEST_ERROR;
+ }
- /* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ /* Wait for a few ticks for the update to happen */
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
- result = verify_dsets_action(RANDOM_WRITE, s, ds, newstep);
+ result = verify_dsets_action(SEQ_WRITE, s, ds, step, fileclosed);
- if (s->use_np && !np_reader(result, step, s, np)) {
- HDprintf("np_reader() for verifying addition failed\n");
- TEST_ERROR;
+ if (s->use_np && !np_reader(result, step, s, np)) {
+ HDprintf("np_reader() for verifying addition failed\n");
+ TEST_ERROR;
+ }
+ else if (!result)
+ TEST_ERROR;
}
}
- }
- /* Start verifying hyperslab writes for contiguous and/or chunked datasets */
- if (s->lwrites) {
- unsigned k;
+ /* Start verifying random writes */
+ /* When flush of raw data is disabled, only verify data for the last write operation on file close */
+ if ((s->rwrites && !fileclosed) || (fileclosed && s->lastwrite == RANDOM_WRITE)) {
+ unsigned newstep;
- for (step = 0, k = 0; (step < s->lwrites && k < (s->rows * s->cols)); step++, k += s->cols) {
- dbgf(2, "Verify hyperslab writes %u to dataset\n", step);
+ s->lastwrite = RANDOM_WRITE;
- if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
- HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
- TEST_ERROR;
- }
+ /* Set up random seed which will be the same for both writer and reader */
+ HDsrandom(RANDOM_SEED);
- /* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ for (step = 0; (step < s->rwrites && step < (s->rows * s->cols)); step++) {
+ dbgf(2, "Verify random writes %u to dataset\n", step);
- result = verify_dsets_action(HYPER_WRITE, s, ds, k);
+ newstep = (unsigned int)HDrandom() % (s->rows * s->cols);
+ dbgf(2, "Random step is %u\n", newstep);
- if (s->use_np && !np_reader(result, step, s, np)) {
- HDprintf("np_reader() for verifying addition failed\n");
- TEST_ERROR;
+ if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ TEST_ERROR;
+ }
+
+ /* Wait for a few ticks for the update to happen */
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
+
+ result = verify_dsets_action(RANDOM_WRITE, s, ds, newstep, fileclosed);
+
+ if (s->use_np && !np_reader(result, step, s, np)) {
+ HDprintf("np_reader() for verifying addition failed\n");
+ TEST_ERROR;
+ }
+ else if (!result)
+ TEST_ERROR;
}
}
- }
- /* Start verifying raw data modifications for contiguous and/or chunked datasets */
- if (s->wwrites) {
+ /* Start verifying hyperslab writes */
+ /* When flush of raw data is disabled, only verify data for the last write operation on file close */
+ if ((s->lwrites && !fileclosed) || (fileclosed && s->lastwrite == HYPER_WRITE)) {
+ unsigned k;
- for (step = 0; (step < s->wwrites && step < (s->rows * s->cols)); step++) {
- dbgf(2, "Verify raw data modification %u to dataset\n", step);
+ s->lastwrite = HYPER_WRITE;
- if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
- HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
- TEST_ERROR;
+ for (step = 0, k = 0; (step < s->lwrites && k < (s->rows * s->cols)); step++, k += s->cols) {
+ dbgf(2, "Verify hyperslab writes %u to dataset\n", step);
+
+ if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ TEST_ERROR;
+ }
+
+ /* Wait for a few ticks for the update to happen */
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
+
+ result = verify_dsets_action(HYPER_WRITE, s, ds, k, fileclosed);
+
+ if (s->use_np && !np_reader(result, step, s, np)) {
+ HDprintf("np_reader() for verifying addition failed\n");
+ TEST_ERROR;
+ }
+ else if (!result)
+ TEST_ERROR;
}
+ }
- /* Wait for a few ticks for the update to happen */
- decisleep(config->tick_len * s->update_interval);
+ /* Start verifying raw data modifications */
+ /* When flush of raw data is disabled, only verify data for the last write operation on file close */
+ if ((s->wwrites && !fileclosed) || (fileclosed && s->lastwrite == MODIFY_DATA)) {
- result = verify_dsets_action(MODIFY_DATA, s, ds, step);
+ s->lastwrite = MODIFY_DATA;
- if (s->use_np && !np_reader(result, step, s, np)) {
- HDprintf("np_reader() for verifying addition failed\n");
- TEST_ERROR;
+ for (step = 0; (step < s->wwrites && step < (s->rows * s->cols)); step++) {
+ dbgf(2, "Verify raw data modification %u to dataset\n", step);
+
+ if (s->use_np && !np_confirm_verify_notify(np->fd_writer_to_reader, step, s, np)) {
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ TEST_ERROR;
+ }
+
+ /* Wait for a few ticks for the update to happen */
+ if (!fileclosed)
+ decisleep(config->tick_len * s->update_interval);
+
+ result = verify_dsets_action(MODIFY_DATA, s, ds, step, fileclosed);
+
+ if (s->use_np && !np_reader(result, step, s, np)) {
+ HDprintf("np_reader() for verifying addition failed\n");
+ TEST_ERROR;
+ }
+ else if (!result)
+ TEST_ERROR;
}
}
}
@@ -1247,7 +1359,7 @@ verify_write_dset_contig_chunked(state_t *s, dsets_state_t *ds, H5F_vfd_swmr_con
error:
return false;
-} /* verify_write_dset_contig_chunked() */
+} /* Verify_dsets_operations() */
/*
* Verify the data read from each of the datasets specified on the command line
@@ -1258,7 +1370,8 @@ error:
* MODIFY_DATA: `which` raw data modification
*/
static bool
-verify_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which)
+verify_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds, unsigned which,
+ bool fileclosed)
{
hsize_t start[2];
hsize_t stride[2];
@@ -1275,9 +1388,9 @@ verify_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds,
/* Verify the data read for the contiguous dataset */
if (s->contig) {
- if (!verify_read_dset(ds->contig_did, s->filetype, mem_sid, ds->contig_sid, start, stride, count,
- block, vbuf)) {
- HDprintf("H5Dwrite to contiguous dataset failed\n");
+ if (!verify_dset(ds->contig_did, s->filetype, mem_sid, ds->contig_sid, start, stride, count, block,
+ vbuf, fileclosed, s->flush_raw_data)) {
+ HDprintf("verify_dset() to contiguous dataset failed\n");
TEST_ERROR;
}
}
@@ -1285,33 +1398,33 @@ verify_dsets_action(unsigned action, const state_t *s, const dsets_state_t *ds,
/* Verify the data read for the chunked datasets */
if (s->chunked) {
- if (!verify_read_dset(ds->single_did, s->filetype, mem_sid, ds->single_sid, start, stride, count,
- block, vbuf)) {
- HDprintf("H5Dwrite to chunked dataset: single index dataset failed\n");
+ if (!verify_dset(ds->single_did, s->filetype, mem_sid, ds->single_sid, start, stride, count, block,
+ vbuf, fileclosed, s->flush_raw_data)) {
+ HDprintf("verify_dset() to chunked dataset: single index dataset failed\n");
TEST_ERROR;
}
- if (!verify_read_dset(ds->implicit_did, s->filetype, mem_sid, ds->implicit_sid, start, stride, count,
- block, vbuf)) {
- HDprintf("H5Dwrite to chunked dataset: implicit index dataset failed\n");
+ if (!verify_dset(ds->implicit_did, s->filetype, mem_sid, ds->implicit_sid, start, stride, count,
+ block, vbuf, fileclosed, s->flush_raw_data)) {
+ HDprintf("verify_dset() to chunked dataset: implicit index dataset failed\n");
TEST_ERROR;
}
- if (!verify_read_dset(ds->fa_did, s->filetype, mem_sid, ds->fa_sid, start, stride, count, block,
- vbuf)) {
- HDprintf("H5Dwrite to chunked dataset: fa index dataset failed\n");
+ if (!verify_dset(ds->fa_did, s->filetype, mem_sid, ds->fa_sid, start, stride, count, block, vbuf,
+ fileclosed, s->flush_raw_data)) {
+ HDprintf("verify_dset() to chunked dataset: fa index dataset failed\n");
TEST_ERROR;
}
- if (!verify_read_dset(ds->ea_did, s->filetype, mem_sid, ds->ea_sid, start, stride, count, block,
- vbuf)) {
- HDprintf("H5Dwrite to chunked dataset: ea index dataset failed\n");
+ if (!verify_dset(ds->ea_did, s->filetype, mem_sid, ds->ea_sid, start, stride, count, block, vbuf,
+ fileclosed, s->flush_raw_data)) {
+ HDprintf("verify_dset() to chunked dataset: ea index dataset failed\n");
TEST_ERROR;
}
- if (!verify_read_dset(ds->bt2_did, s->filetype, mem_sid, ds->bt2_sid, start, stride, count, block,
- vbuf)) {
- HDprintf("H5Dwrite to chunked dataset: bt2 index dataset failed\n");
+ if (!verify_dset(ds->bt2_did, s->filetype, mem_sid, ds->bt2_sid, start, stride, count, block, vbuf,
+ fileclosed, s->flush_raw_data)) {
+ HDprintf("verify_dset() to chunked dataset: bt2 index dataset failed\n");
TEST_ERROR;
}
}
@@ -1334,8 +1447,8 @@ error:
* `vbuf` contains the data expected from the read.
*/
static bool
-verify_read_dset(hid_t did, hid_t tid, hid_t mem_sid, hid_t file_sid, hsize_t *start, hsize_t *stride,
- hsize_t *count, hsize_t *block, unsigned int *vbuf)
+verify_dset(hid_t did, hid_t tid, hid_t mem_sid, hid_t file_sid, hsize_t *start, hsize_t *stride,
+ hsize_t *count, hsize_t *block, unsigned int *vbuf, bool fileclosed, bool flush_raw_data)
{
unsigned int *rbuf = NULL;
unsigned i;
@@ -1365,9 +1478,16 @@ verify_read_dset(hid_t did, hid_t tid, hid_t mem_sid, hid_t file_sid, hsize_t *s
}
/* Verify the data read in `rbuf` is as `vbuf` */
- for (i = 0; i < count[1]; i++)
- if (rbuf[i] != vbuf[i])
- TEST_ERROR;
+ for (i = 0; i < count[1]; i++) {
+ if (flush_raw_data || fileclosed) {
+ if (rbuf[i] != vbuf[i])
+ TEST_ERROR;
+ }
+ else { /* No flush && not closing file */
+ if (rbuf[i] != vbuf[i] && rbuf[0] != 0) /* FILL VALUE ?? */
+ TEST_ERROR;
+ }
+ }
if (rbuf)
HDfree(rbuf);
@@ -1379,17 +1499,23 @@ error:
HDfree(rbuf);
return false;
-} /* verify_read_dset() */
+} /* verify_dset() */
/*
* Verify that the data read from the compact dataset is as unexpected.
*/
static bool
-verify_read_dset_compact(const state_t *s, const dsets_state_t *ds)
+verify_dset_compact(const state_t *s, const dsets_state_t *ds, bool fileclosed, bool flush_raw_data)
{
unsigned int *rbuf;
unsigned i;
+ /* Refresh the dataset */
+ if (H5Drefresh(ds->compact_did) < 0) {
+ HDprintf("H5Drefresh dataset failed\n");
+ TEST_ERROR;
+ }
+
if ((rbuf = HDmalloc(s->compact_elmts * sizeof(unsigned int))) == NULL) {
HDprintf("HDmalloc buffer for compact dataset failed\n");
goto error;
@@ -1400,11 +1526,18 @@ verify_read_dset_compact(const state_t *s, const dsets_state_t *ds)
TEST_ERROR;
}
- for (i = 0; i < s->compact_elmts; i++)
- if (rbuf[i] != (i + 1)) {
- HDprintf("Invalid value for compact dataset element\n");
- TEST_ERROR;
+ for (i = 0; i < s->compact_elmts; i++) {
+ if (flush_raw_data || fileclosed) {
+ if (rbuf[i] != (i + 1)) {
+ HDprintf("Invalid value for compact dataset element\n");
+ TEST_ERROR;
+ }
+ }
+ else { /* No flush && not closing file */
+ if (rbuf[i] != (i + 1) && rbuf[0] != 0) /* FILL VALUE ?? */
+ TEST_ERROR;
}
+ }
if (rbuf)
HDfree(rbuf);
@@ -1416,7 +1549,7 @@ error:
HDfree(rbuf);
return false;
-} /* verify_read_dset_compact() */
+} /* verify_dset_compact() */
/*
* Named pipes handling
@@ -1535,9 +1668,8 @@ np_writer(bool result, unsigned step, const state_t *s, np_state_t *np, H5F_vfd_
HDwrite(np->fd_writer_to_reader, &np->notify, sizeof(int));
goto error;
}
- /* The action succeeds */
}
- else {
+ else { /* The action succeeds */
/* At communication interval, notify the reader and wait for its response */
if (step % s->csteps == 0) {
/* Bump up the value of notify to tell the reader to start reading */
@@ -1642,6 +1774,90 @@ error:
} /* np_confirm_verify_notify() */
/*
+ * When flush of raw data is disabled, the following is done by the writer and reader:
+ * Writer:
+ * Close the file
+ * Notify the reader that the file is closed
+ * Reader:
+ * Confirm the message from the writer that the file is closed
+ * Verify the data
+ */
+static bool
+closing_on_noflush(bool writer, state_t *s, dsets_state_t *ds, H5F_vfd_swmr_config_t *config, np_state_t *np)
+{
+ HDassert(s->use_np);
+
+ if (writer) {
+ if (!close_dsets(ds)) {
+ HDprintf("close_dsets() failed\n");
+ TEST_ERROR;
+ }
+
+ dbgf(2, "Writer closes the file (flush of raw data is disabled)\n");
+ if (H5Fclose(s->file) < 0) {
+ HDprintf("H5Fclose failed\n");
+ TEST_ERROR;
+ }
+
+ /* Bump up the value of notify to tell the reader the file is closed */
+ dbgf(2, "Writer notifies reader that the file is closed (flush of raw data is disabled)\n");
+ np->notify++;
+ if (HDwrite(np->fd_writer_to_reader, &np->notify, sizeof(int)) < 0) {
+ HDprintf("HDwrite failed\n");
+ TEST_ERROR;
+ }
+
+ if (!np_close(np, writer)) {
+ HDprintf("np_close() failed\n");
+ TEST_ERROR;
+ }
+ }
+ else {
+ /* Wait for a few ticks for the file to close in writer ?? need to this or not? */
+ decisleep(config->tick_len * s->update_interval);
+
+ dbgf(2, "Reader checks notify value from writer (flush of raw data is disabled)\n");
+ if (!np_confirm_verify_notify(np->fd_writer_to_reader, 0, s, np)) {
+ HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
+ TEST_ERROR;
+ }
+
+ /* Close the named pipes */
+ if (!np_close(np, writer)) {
+ HDprintf("np_close() failed\n");
+ TEST_ERROR;
+ }
+
+ /* Turn off named pipes */
+ s->use_np = false;
+
+ /* Verify the dataset again without named pipes */
+ dbgf(2, "Reader verifies data after writer closes the file (flush of raw data is disabled)\n");
+ if (!verify_dsets_operations(s, ds, config, np, true)) {
+ HDprintf("verify_dsets_operations() failed\n");
+ TEST_ERROR
+ }
+
+ if (!close_dsets(ds)) {
+ HDprintf("close_dsets() failed\n");
+ TEST_ERROR;
+ }
+
+ dbgf(2, "Reader closes the file (flush of raw data is disabled)\n");
+ if (H5Fclose(s->file) < 0) {
+ HDprintf("H5Fclose failed\n");
+ TEST_ERROR;
+ }
+ }
+
+ return true;
+
+error:
+ return false;
+
+} /* closing_on_noflush() */
+
+/*
* Main
*/
int
@@ -1655,7 +1871,6 @@ main(int argc, char **argv)
H5F_vfd_swmr_config_t config;
np_state_t np;
dsets_state_t ds;
- bool result;
if (!state_init(&s, argc, argv)) {
HDprintf("state_init() failed\n");
@@ -1674,7 +1889,7 @@ main(int argc, char **argv)
}
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(&config, 4, 7, writer, FALSE, 128, "./dsetops-shadow");
+ init_vfd_swmr_config(&config, 4, 7, writer, s.flush_raw_data, 128, "./dsetops-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, 4096, &config)) < 0) {
@@ -1718,62 +1933,19 @@ main(int argc, char **argv)
if (writer) {
- /* Perform writes to the whole compact dataset */
- if (s.compact && s.compact_write) {
- dbgf(2, "Writes all to compact dataset\n");
-
- result = write_dset_compact(&s, &ds);
-
- if (s.use_np && !np_writer(result, 0, &s, &np, &config)) {
- HDprintf("np_writer() for addition failed\n");
- TEST_ERROR;
- }
- }
-
- if (s.contig || s.chunked) {
- /* Perform writes for contiguous and/or chunked datasets */
- if (!write_dset_contig_chunked(&s, &ds, &config, &np)) {
- HDprintf("write_dset_contig_chunked() failed\n");
- TEST_ERROR;
- }
+ if (!perform_dsets_operations(&s, &ds, &config, &np)) {
+ HDprintf("perform_dsets_operations() failed\n");
+ TEST_ERROR;
}
}
else {
- /* Start verifying data written to the compact dataset */
- if (s.compact && s.compact_write) {
- dbgf(2, "Verify writes to compact dataset\n");
-
- if (s.use_np && !np_confirm_verify_notify(np.fd_writer_to_reader, 0, &s, &np)) {
- HDprintf("np_confirm_verify_notify() verify/notify not in sync failed\n");
- TEST_ERROR;
- }
- /* Wait for a few ticks for the update to happen */
- decisleep(config.tick_len * s.update_interval);
-
- result = verify_read_dset_compact(&s, &ds);
-
- if (s.use_np && !np_reader(result, 0, &s, &np)) {
- HDprintf("np_reader() for verifying addition failed\n");
- TEST_ERROR;
- }
- }
-
- if (s.contig || s.chunked) {
-
- /* Verify writes for contiguous and/or chunked datasets */
- if (!verify_write_dset_contig_chunked(&s, &ds, &config, &np)) {
- HDprintf("verify_write_dset_contig_chunked() failed\n");
- TEST_ERROR;
- }
+ if (!verify_dsets_operations(&s, &ds, &config, &np, false)) {
+ HDprintf("perform_dsets_operations() failed\n");
+ TEST_ERROR;
}
}
- if (!close_dsets(&ds)) {
- HDprintf("close_dsets() failed\n");
- TEST_ERROR;
- }
-
if (H5Pclose(fapl) < 0) {
HDprintf("H5Pclose failed\n");
TEST_ERROR;
@@ -1784,14 +1956,27 @@ main(int argc, char **argv)
TEST_ERROR;
}
- if (H5Fclose(s.file) < 0) {
- HDprintf("H5Fclose failed\n");
- TEST_ERROR;
+ if (!s.flush_raw_data && s.use_np) {
+
+ if (!closing_on_noflush(writer, &s, &ds, &config, &np))
+ TEST_ERROR
}
+ else {
- if (s.use_np && !np_close(&np, writer)) {
- HDprintf("np_close() failed\n");
- TEST_ERROR;
+ if (!close_dsets(&ds)) {
+ HDprintf("close_dsets() failed\n");
+ TEST_ERROR;
+ }
+
+ if (H5Fclose(s.file) < 0) {
+ HDprintf("H5Fclose failed\n");
+ TEST_ERROR;
+ }
+
+ if (s.use_np && !np_close(&np, writer)) {
+ HDprintf("np_close() failed\n");
+ TEST_ERROR;
+ }
}
return EXIT_SUCCESS;
diff --git a/test/vfd_swmr_generator.c b/test/vfd_swmr_generator.c
index 4b87072..16b1d4b 100644
--- a/test/vfd_swmr_generator.c
+++ b/test/vfd_swmr_generator.c
@@ -126,7 +126,7 @@ gen_skeleton(const char *filename, hbool_t verbose, hbool_t vfd_swmr_write, int
return -1;
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(config, 4, 10, vfd_swmr_write, FALSE, 128, "generator-shadow");
+ init_vfd_swmr_config(config, 4, 10, vfd_swmr_write, TRUE, 128, "generator-shadow");
}
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c
new file mode 100644
index 0000000..e21f931
--- /dev/null
+++ b/test/vfd_swmr_gperf_writer.c
@@ -0,0 +1,2979 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Description of this program:
+ * This program checks the performance of group creations for VFD SWMR.
+ * Currently the group creation time, H5Fopen and H5Fclose time are measured.
+ * After compiling the program,
+ * ./vfd_swmr_gperf_writer -n 1000 -P -N 5 -q
+ * will generate 1000 groups, each group has 5 attributes.
+ * ./vfd_swmr_gperf_writer -n 1000 -P -N 0 -q
+ * will generate 1000 empty groups.
+ * ./vfd_swmr_gperf_writer -n 1000 -P -l 1 -q
+ * will generate 1000 groups with 1 level of nested groups,(like /g1/g2)
+ * each group has one attribute.
+ * ./vfd_swmr_gperf_writer -n 1000 -P -S -G -V -N 5 -l 1 -m 8 -t 4 -B 16384 -s 8192
+ * will generate 1000 groups with 1 level of nested groups,(like /g1/g2)
+ * each group has 5 attributes and the attribute type is variable length string.
+ * The groups is created without using VFD SWMR;
+ * The groups are created with the earliest file format(old-styled)
+ * The program is run with max_lag = 8, tick_len = 4;
+ * The page buffer size is 16384 bytes. The page size is 8192 bytes.
+ *
+ */
+#define H5F_FRIEND /*suppress error about including H5Fpkg */
+
+#include "hdf5.h"
+
+#include "H5Fpkg.h"
+#include "H5HGprivate.h"
+#include "H5VLprivate.h"
+
+#include "testhdf5.h"
+#include "vfd_swmr_common.h"
+
+#ifndef H5_HAVE_WIN32_API
+
+#define VS_ATTR_NAME_LEN 21
+
+#define TIME_PASSED(X, Y) \
+ ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0
+
+typedef struct {
+ hid_t file, filetype, one_by_one_sid;
+ char filename[PATH_MAX];
+ char progname[PATH_MAX];
+ unsigned int asteps;
+ unsigned int nsteps;
+ bool use_vfd_swmr;
+ bool old_style_grp;
+ char grp_op_pattern;
+ bool grp_op_test;
+ char at_pattern;
+ bool attr_test;
+ uint32_t max_lag;
+ uint32_t tick_len;
+ bool gperf;
+ double min_gc_time;
+ double max_gc_time;
+ double mean_gc_time;
+ double total_gc_time;
+ double total_time;
+ double mean_time;
+ double fo_total_time;
+ double fc_total_time;
+ unsigned int num_attrs;
+ bool vlstr_test;
+ unsigned int ps;
+ unsigned int pbs;
+ unsigned int nglevels;
+} state_t;
+
+#define ALL_HID_INITIALIZER \
+ (state_t) \
+ { \
+ .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \
+ .filetype = H5T_NATIVE_UINT32, .asteps = 1, .nsteps = 100, .use_vfd_swmr = true, \
+ .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \
+ .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_gc_time = 100., \
+ .max_gc_time = 0., .mean_gc_time = 0., .total_gc_time = 0., .total_time = 0., .mean_time = 0., \
+ .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, .vlstr_test = false, .ps = 4096, \
+ .pbs = 4096, .nglevels = 0 \
+ }
+
+static void
+usage(const char *progname)
+{
+ fprintf(stderr,
+ "usage: ./%s -P -n 1000 -N 5 -q (create 1000 groups, each group has 5 attributes)\n"
+ "Options: \n"
+ " [-P] [-S] [-G] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n"
+ " [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n"
+ " [-N num_attrs] [-V] [-b] [-A at_pattern] [-a steps] [-q]\n"
+ "\n"
+ "-P: carry out the performance test\n"
+ "-S: do not use VFD SWMR\n"
+ "-G: old-style type of group\n"
+ "-t tick_len: length of a tick in tenths of a second.\n"
+ "-m max_lag: maximum expected lag(in ticks) between writer and readers\n"
+ "-B pbs: page Buffer Size in bytes:\n"
+ " The default value is 4K(4096).\n"
+ "-s ps: page size used by page aggregation, page buffer and \n"
+ " the metadata file. \n"
+ "-n ngroups: the number of groups\n"
+ "-l ng_levels: the number of level of nested groups. \n"
+ " If all the groups are under the root group, \n"
+ " this number should be 0.\n"
+ "-N num_attrs: the number of attributes \n"
+ "-V use variable length string attributes for performance test\n"
+ "-b: write data in big-endian byte order\n"
+ " (For the performance test, -V overwrites -b)\n"
+ "-A at_pattern: `at_pattern' for different attribute tests\n"
+ " The value of `at_pattern` is one of the following:\n"
+ " `compact` - Attributes added in compact storage\n"
+ " `dense` - An attribute added in dense storage\n"
+ " `compact-del` - Attributes added and then one\n"
+ " attribute deleted, in compact \n"
+ " `dense-del` - Attributes added until the storage\n"
+ " is dense then an attribute deleted\n"
+ " the storge still in dense\n"
+ " `compact-add-to-dense` - Attributes added first in compact\n"
+ " then in dense storage\n"
+ " `dense-del-to-compact` - Attributes added until the storage\n"
+ " is dense, then several attributes \n"
+ " deleted, the storage changed to\n"
+ " compact\n"
+ " `modify` - An attribute added then modified\n"
+ " `add-vstr` - A VL string attribute added\n"
+ " `remove-vstr` - A VL string attribute added then\n"
+ " deleted\n"
+ " `modify-vstr` - A VL string attribute added then \n"
+ " modified \n"
+ " `add-ohr-block` - An attribute is added and this forces\n"
+ " the creation of object header\n"
+ " continuation block \n"
+ " `del-ohr-block` - An attribute is added and this forces\n"
+ " the creation of object header\n"
+ " continuation block and then this \n"
+ " attribute is deleted so the \n"
+ " object header continuation block is \n"
+ " removed. \n"
+ "-O grp_op_pattern: `grp_op_pattern' for different group operation tests\n"
+ " The value of `grp_op_pattern` is one of the following:\n"
+ " `grp-creation` - A group is created.\n"
+ " `grp-deletion` - An existing group is deleted.\n"
+ " `grp-move` - A group is moved to become \n"
+ " another group. \n"
+ " `grp-ins-links` - Links are inserted, including\n"
+ " both hard and soft links. \n"
+ " `grp-del-links` - Links are deleted, including\n"
+ " both hard ans soft links. \n"
+ " `grp-compact-t-dense` - Links are inserted to the group.\n"
+ " The link storage of this group \n"
+ " changed from compact to dense. \n"
+ " The links include both hard and\n"
+ " soft links. \n"
+ " `grp-dense-t-compact` - Links are inserted to the group\n"
+ " The link storage of this group \n"
+ " changed from compact to dense. \n"
+ " Then several links are deleted.\n"
+ " The link storage changed from \n"
+ " dense to compact again. \n"
+ " The links include both hard and\n"
+ " soft links. \n"
+ "-a steps: `steps` between adding attributes\n"
+ " (Don't recommend to use this option for performance test.)\n"
+ "-q: silence printouts, few messages\n"
+ "\n",
+ progname);
+ exit(EXIT_FAILURE);
+}
+
+static bool
+state_init(state_t *s, int argc, char **argv)
+{
+ unsigned long tmp;
+ int ch;
+ const hsize_t dims = 1;
+ char * tfile = NULL;
+ char * end;
+
+ *s = ALL_HID_INITIALIZER;
+
+ if (H5_basename(argv[0], &tfile) < 0) {
+ printf("H5_basename failed\n");
+ TEST_ERROR;
+ }
+
+ esnprintf(s->progname, sizeof(s->progname), "%s", tfile);
+
+ if (tfile) {
+ HDfree(tfile);
+ tfile = NULL;
+ }
+
+ if (argc == 1)
+ usage(s->progname);
+ while ((ch = getopt(argc, argv, "PSGa:bVt:m:B:s:n:qA:N:l:O:")) != -1) {
+ switch (ch) {
+ case 'P':
+ s->gperf = true;
+ break;
+ case 'S':
+ s->use_vfd_swmr = false;
+ break;
+ case 'G':
+ s->old_style_grp = true;
+ break;
+ case 'a':
+ case 'n':
+ case 'N':
+ case 'l':
+ case 't':
+ case 'm':
+ case 'B':
+ case 's':
+ errno = 0;
+ tmp = HDstrtoul(optarg, &end, 0);
+ if (end == optarg || *end != '\0') {
+ printf("couldn't parse `-%c` argument `%s`\n", ch, optarg);
+ TEST_ERROR;
+ }
+ else if (errno != 0) {
+ printf("couldn't parse `-%c` argument `%s`\n", ch, optarg);
+ TEST_ERROR;
+ }
+ else if (tmp > UINT_MAX) {
+ printf("`-%c` argument `%lu` too large\n", ch, tmp);
+ TEST_ERROR;
+ }
+
+ if (ch == 'a')
+ s->asteps = (unsigned)tmp;
+ else if (ch == 'n')
+ s->nsteps = (unsigned)tmp;
+ else if (ch == 'N')
+ s->num_attrs = (unsigned)tmp;
+ else if (ch == 'l')
+ s->nglevels = (unsigned)tmp;
+ else if (ch == 't')
+ s->tick_len = (unsigned)tmp;
+ else if (ch == 'm')
+ s->max_lag = (unsigned)tmp;
+ else if (ch == 's')
+ s->ps = (unsigned)tmp;
+ else if (ch == 'B')
+ s->pbs = (unsigned)tmp;
+ break;
+ case 'b':
+ s->filetype = H5T_STD_U32BE;
+ break;
+ case 'V':
+ s->vlstr_test = true;
+ break;
+ case 'O':
+ if (HDstrcmp(optarg, "grp-creation") == 0)
+ s->grp_op_pattern = 'c';
+ else if (HDstrcmp(optarg, "grp-deletion") == 0)
+ s->grp_op_pattern = 'd';
+ else if (HDstrcmp(optarg, "grp-move") == 0)
+ s->grp_op_pattern = 'm';
+ else if (HDstrcmp(optarg, "grp-ins-links") == 0)
+ s->grp_op_pattern = 'i';
+ else if (HDstrcmp(optarg, "grp-del-links") == 0)
+ s->grp_op_pattern = 'D';
+ else if (HDstrcmp(optarg, "grp-compact-t-dense") == 0)
+ s->grp_op_pattern = 't';
+ else if (HDstrcmp(optarg, "grp-dense-t-compact") == 0)
+ s->grp_op_pattern = 'T';
+ else {
+ printf("Invalid -O argument \"%s\"", optarg);
+ TEST_ERROR;
+ }
+ break;
+ case 'A':
+ if (HDstrcmp(optarg, "compact") == 0)
+ s->at_pattern = 'c';
+ else if (HDstrcmp(optarg, "dense") == 0)
+ s->at_pattern = 'd';
+ else if (HDstrcmp(optarg, "compact-add-to-dense") == 0)
+ s->at_pattern = 't';
+ else if (HDstrcmp(optarg, "compact-del") == 0)
+ s->at_pattern = 'C';
+ else if (HDstrcmp(optarg, "dense-del") == 0)
+ s->at_pattern = 'D';
+ else if (HDstrcmp(optarg, "dense-del-to-compact") == 0)
+ s->at_pattern = 'T';
+ else if (HDstrcmp(optarg, "modify") == 0)
+ s->at_pattern = 'M';
+ else if (HDstrcmp(optarg, "add-vstr") == 0)
+ s->at_pattern = 'v';
+ else if (HDstrcmp(optarg, "remove-vstr") == 0)
+ s->at_pattern = 'r';
+ else if (HDstrcmp(optarg, "modify-vstr") == 0)
+ s->at_pattern = 'm';
+ else if (HDstrcmp(optarg, "add-ohr-block") == 0)
+ s->at_pattern = 'a';
+ else if (HDstrcmp(optarg, "del-ohr-block") == 0)
+ s->at_pattern = 'R';
+ else {
+ printf("Invalid -A argument \"%s\"", optarg);
+ TEST_ERROR;
+ }
+ break;
+ case 'q':
+ verbosity = 0;
+ break;
+ case '?':
+ default:
+ usage(s->progname);
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (s->grp_op_pattern != ' ')
+ s->grp_op_test = true;
+ if (s->at_pattern != ' ')
+ s->attr_test = true;
+
+ if (!s->grp_op_test) {
+ if (s->asteps < 1 || s->asteps > s->nsteps) {
+ printf("attribute interval is out of bounds\n");
+ TEST_ERROR;
+ }
+ }
+
+ if (s->grp_op_test && s->attr_test) {
+ printf("Cannot test both group operation and attribute tests!\n");
+ printf("Attribute tests are ignored.\n");
+ }
+
+ if (argc > 0) {
+ printf("unexpected command-line arguments\n");
+ TEST_ERROR;
+ }
+
+ /* space for attributes */
+ if ((s->one_by_one_sid = H5Screate_simple(1, &dims, &dims)) < 0) {
+ printf("H5Screate_simple failed\n");
+ TEST_ERROR;
+ }
+
+ esnprintf(s->filename, sizeof(s->filename), "vfd_swmr_group.h5");
+
+ return true;
+
+error:
+ if (tfile)
+ HDfree(tfile);
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: check_ohr_num_chunk
+ *
+ * Purpose: Check if the number of object header chunks is as expected.
+ *
+ * Parameters: hid_t oid
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * bool one_chunk_ohr
+ * flag to indicate if the object header chunk is 1 or greater
+ * 1: true
+ * greater than 1: false
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+check_ohr_num_chunk(hid_t g, bool one_chunk_ohr)
+{
+
+ H5O_native_info_t ninfo;
+
+ /* Get the object information */
+ if (H5Oget_native_info(g, &ninfo, H5O_NATIVE_INFO_HDR) < 0) {
+ printf("H5Oget_native_info failed\n");
+ TEST_ERROR;
+ }
+
+ if (true == one_chunk_ohr) {
+ if (ninfo.hdr.nchunks != 1) {
+ printf("Object header should have only one chunk,but it is not.\n");
+ TEST_ERROR;
+ }
+ }
+ else {
+ if (ninfo.hdr.nchunks <= 1) {
+ printf("Object header should have more than one chunk,but it is not.\n");
+ TEST_ERROR;
+ }
+ }
+
+ return true;
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_attr
+ *
+ * Purpose: Add attributes to a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t oid
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group name. The group name is "group-which".
+ *
+ * unsigned num_attrs
+ * The number of attributes to be created
+ *
+ * const char*aname_fmt
+ * The attribute name template used to create unique attribute names.
+ *
+ * unsigned int g_which
+ * This parameter is used to generate correct group name in a key
+ * debugging message.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_attr(state_t *s, hid_t oid, unsigned int which, unsigned num_attrs, const char *aname_fmt,
+ unsigned int g_which)
+{
+
+ char attrname[VS_ATTR_NAME_LEN];
+ unsigned u;
+ unsigned attr_value;
+ hid_t aid = H5I_INVALID_HID;
+ hid_t amtype = H5I_INVALID_HID;
+ hid_t atype = s->filetype;
+ hid_t sid = s->one_by_one_sid;
+
+ /* Need to obtain native datatype for H5Aread */
+ if ((amtype = H5Tget_native_type(atype, H5T_DIR_ASCEND)) < 0) {
+ printf("H5Tget_native_type failed\n");
+ TEST_ERROR;
+ }
+
+ for (u = 0; u < num_attrs; u++) {
+
+ /* Create attribute */
+ /* Construct attribute name like attr-0-0 */
+ HDsprintf(attrname, aname_fmt, which, u);
+ if ((aid = H5Acreate2(oid, attrname, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
+ printf("H5Acreate2 failed\n");
+ TEST_ERROR;
+ }
+
+ attr_value = u + which;
+
+ dbgf(1, "setting attribute %s on group %u to %u\n", attrname, g_which, u + which);
+
+ /* Write data into the attribute */
+ if (H5Awrite(aid, amtype, &attr_value) < 0) {
+ printf("H5Awrite failed\n");
+ TEST_ERROR;
+ }
+
+ /* Close attribute */
+ if (H5Aclose(aid) < 0) {
+ printf("H5Aclose failed\n");
+ TEST_ERROR;
+ }
+
+ /* If coming to an "object header continuation block" test,
+ * we need to check if this test behaves as expected. */
+ if (s->at_pattern == 'a' || s->at_pattern == 'R') {
+ if (false == check_ohr_num_chunk(oid, false)) {
+ printf("An object header continuation block should be created. \n");
+ printf("But it is not.\n");
+ TEST_ERROR;
+ }
+ }
+
+ } /* end for */
+
+ if (H5Tclose(amtype) < 0) {
+ TEST_ERROR;
+ }
+
+ return true;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Aclose(aid);
+ H5Tclose(amtype);
+ }
+ H5E_END_TRY;
+
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_vlstr_attr
+ *
+ * Purpose: Add a variable length string attribute to a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ * The group name is "group-which" and the attribute name
+ * is "attr-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is for the "vstr" test.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_vlstr_attr(state_t *s, hid_t g, unsigned int which)
+{
+
+ hid_t aid = H5I_INVALID_HID;
+ hid_t atype = H5I_INVALID_HID;
+ char name[VS_ATTR_NAME_LEN];
+ char *astr_val = NULL;
+ hid_t sid = s->one_by_one_sid;
+
+ /* Allocate buffer for the VL string value */
+ astr_val = HDmalloc(VS_ATTR_NAME_LEN);
+ if (astr_val == NULL) {
+ printf("Allocate memory for VL string failed.\n");
+ TEST_ERROR;
+ }
+
+ /* Assign the VL string value and the attribute name.. */
+ HDsprintf(astr_val, "%u", which);
+ esnprintf(name, sizeof(name), "attr-%u", which);
+
+ dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which);
+
+ /* Create a datatype to refer to. */
+ if ((atype = H5Tcopy(H5T_C_S1)) < 0) {
+ printf("Cannot create variable length datatype.\n");
+ TEST_ERROR;
+ }
+
+ if (H5Tset_size(atype, H5T_VARIABLE) < 0) {
+ printf("Cannot set variable length datatype.\n");
+ TEST_ERROR;
+ }
+
+ /* Generate the VL string attribute.*/
+ if ((aid = H5Acreate2(g, name, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
+ printf("H5Acreate2 failed.\n");
+ TEST_ERROR;
+ }
+
+ if (H5Awrite(aid, atype, &astr_val) < 0) {
+ printf("H5Awrite failed.\n");
+ TEST_ERROR;
+ }
+
+ if (H5Tclose(atype) < 0) {
+ printf("H5Tclose() failed\n");
+ TEST_ERROR;
+ }
+ if (H5Aclose(aid) < 0) {
+ printf("H5Aclose() failed\n");
+ TEST_ERROR;
+ }
+
+ HDfree(astr_val);
+
+ return true;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Aclose(aid);
+ H5Tclose(atype);
+ }
+ H5E_END_TRY;
+
+ if (astr_val)
+ HDfree(astr_val);
+
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_vlstr_attrs
+ *
+ * Purpose: Add variable length string attributes to a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ * The group name is "group-which". The attribute names
+ * are "attr-which","attr-which+1"....
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is for the performance test that has the VL string type.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_vlstr_attrs(state_t *s, hid_t g, unsigned int which, unsigned int num_attrs)
+{
+ unsigned u;
+ bool ret_value = true;
+ for (u = 0; u < num_attrs; u++) {
+ ret_value = add_vlstr_attr(s, g, u + which);
+ if (ret_value == false)
+ break;
+ }
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_default_group_attr
+ *
+ * Purpose: Add an attribute to a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ * The group name is "group-which" and the attribute name
+ * is "attr-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used for the "dense" storage test.
+ * It is also used by the group-only, "add-ohr-block"
+ * and "del-ohr-block" tests.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_default_group_attr(state_t *s, hid_t g, unsigned int which)
+{
+
+ const char *aname_format = "attr-%u-%u";
+
+ /* Note: the number of attributes can be configurable,
+ * the default number of attribute is 1.
+ */
+ /* If the vl string attribute type is chosen. */
+ if (s->vlstr_test == true)
+ return add_vlstr_attrs(s, g, which, s->num_attrs);
+ else
+ return add_attr(s, g, which, s->num_attrs, aname_format, which);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: del_one_attr
+ *
+ * Purpose: delete one attribute in a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t obj_id
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * bool is_dense
+ * if the deleted attribute is for checking the dense storage
+ *
+ * bool is_vl_or_ohrc
+ * if the deleted attribute is a VL string or for object header
+ * continuation check test
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ * The group name is "group-which" and the attribute names
+ * according to if this attribute is a VL string or for checking
+ * the dense storage or the storage transition from dense to
+ * compact.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+del_one_attr(state_t *s, hid_t obj_id, bool is_dense, bool is_vl_or_ohrc, unsigned int which)
+{
+
+ char attrname[VS_ATTR_NAME_LEN];
+
+ /*attribute name template for the dense storage related deletion operation */
+ const char *aname_format_d = "attr-d-%u-%u";
+
+ /*attribute name template used for general attribute deletion operation */
+ const char *aname_format = "attr-%u-%u";
+
+ /*attribute name template used for VL string attribute deletion
+ * or object header continuation check operations */
+ const char *aname_format_vl = "attr-%u";
+
+ dbgf(2, "writer: coming to delete the attribute.\n");
+
+ /* Construct the attribute name */
+ if (is_dense == true)
+ HDsprintf(attrname, aname_format_d, which, 0);
+ else if (is_vl_or_ohrc == true)
+ HDsprintf(attrname, aname_format_vl, which, 0);
+ else
+ HDsprintf(attrname, aname_format, which, 0);
+
+ /* Delete the attribute */
+ if (H5Adelete(obj_id, attrname) < 0) {
+ printf("H5Adelete() failed\n");
+ TEST_ERROR;
+ }
+
+ /* If coming to an "object header continuation block" test,
+ * we need to check if this test behaves as expected. */
+ if (s->at_pattern == 'R') {
+ if (false == check_ohr_num_chunk(obj_id, true)) {
+ printf("The object header chunk should not continue. \n");
+ TEST_ERROR;
+ }
+ }
+ return true;
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_del_vlstr_attr
+ *
+ * Purpose: Add a variable length string attribute
+ * then delete this attribute in this a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ * The group name is "group-which" and the attribute name
+ * is "attr-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is for the "remove-vstr" test.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_del_vlstr_attr(state_t *s, hid_t g, unsigned int which)
+{
+
+ bool ret_value = false;
+
+ /* Add a VL string attribute then delete it. */
+ ret_value = add_vlstr_attr(s, g, which);
+ if (ret_value == true)
+ ret_value = del_one_attr(s, g, false, true, which);
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: modify_attr
+ *
+ * Purpose: Modify the value of an attribute in a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * const char*aname_fmt
+ * The attribute name template used to create unique attribute names.
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group name. The group name is "group-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+modify_attr(state_t *s, hid_t g, const char *aname_fmt, unsigned int which)
+{
+
+ char attrname[VS_ATTR_NAME_LEN];
+ hid_t aid = H5I_INVALID_HID;
+ hid_t amtype = H5I_INVALID_HID;
+ unsigned int modify_value;
+
+ HDsprintf(attrname, aname_fmt, which, 0);
+ if ((aid = H5Aopen(g, attrname, H5P_DEFAULT)) < 0) {
+ printf("H5Aopen failed\n");
+ TEST_ERROR;
+ }
+
+ if ((amtype = H5Tget_native_type(s->filetype, H5T_DIR_ASCEND)) < 0) {
+ printf("H5Tget_native_type failed\n");
+ TEST_ERROR;
+ }
+
+ /* Make a large number to verify the change easily */
+ modify_value = which + 10000;
+
+ if (H5Awrite(aid, amtype, &modify_value) < 0) {
+ printf("H5Awrite failed\n");
+ TEST_ERROR;
+ }
+ if (H5Tclose(amtype) < 0) {
+ printf("H5Tclose failed\n");
+ TEST_ERROR;
+ }
+ if (H5Aclose(aid) < 0) {
+ printf("H5Aclose failed\n");
+ TEST_ERROR;
+ }
+
+ return true;
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Aclose(aid);
+ H5Tclose(aid);
+ }
+ H5E_END_TRY;
+
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: modify_vlstr_attr
+ *
+ * Purpose: Modify the value of an VL string attribute in a group.
+ *
+ * Parameters:
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group name. The group name is "group-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+modify_vlstr_attr(hid_t g, unsigned int which)
+{
+
+ hid_t aid = H5I_INVALID_HID;
+ hid_t atype = H5I_INVALID_HID;
+ char name[VS_ATTR_NAME_LEN];
+ char *astr_val = NULL;
+
+ astr_val = HDmalloc(VS_ATTR_NAME_LEN);
+ if (astr_val == NULL) {
+ printf("Allocate memory for VL string failed.\n");
+ TEST_ERROR;
+ }
+
+ /* Change the VL string value and create the attribute name. */
+ HDsprintf(astr_val, "%u%c", which, 'A');
+ esnprintf(name, sizeof(name), "attr-%u", which);
+
+ dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which);
+
+ /* Create a datatype to refer to. */
+ if ((atype = H5Tcopy(H5T_C_S1)) < 0) {
+ printf("Cannot create variable length datatype.\n");
+ TEST_ERROR;
+ }
+
+ if (H5Tset_size(atype, H5T_VARIABLE) < 0) {
+ printf("Cannot set variable length datatype.\n");
+ TEST_ERROR;
+ }
+
+ /* Open this attribute. */
+ if ((aid = H5Aopen(g, name, H5P_DEFAULT)) < 0) {
+ printf("H5Aopen failed.\n");
+ TEST_ERROR;
+ }
+
+ dbgf(1, "The modified VL string value is %s \n", astr_val);
+
+ if (H5Awrite(aid, atype, &astr_val) < 0) {
+ printf("H5Awrite failed.\n");
+ TEST_ERROR;
+ }
+
+ if (H5Tclose(atype) < 0) {
+ printf("H5Tclose() failed\n");
+ TEST_ERROR;
+ }
+
+ if (H5Aclose(aid) < 0) {
+ printf("H5Aclose() failed\n");
+ TEST_ERROR;
+ }
+
+ HDfree(astr_val);
+
+ return true;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Aclose(aid);
+ H5Tclose(atype);
+ }
+ H5E_END_TRY;
+
+ if (astr_val)
+ HDfree(astr_val);
+
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_modify_vlstr_attr
+ *
+ * Purpose: Add a variable length string attribute
+ * then modify this attribute in the group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ * The group name is "group-which" and the attribute name
+ * is "attr-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is for the "modify-vstr" test.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_modify_vlstr_attr(state_t *s, hid_t g, unsigned int which)
+{
+
+ bool ret_value = false;
+ ret_value = add_vlstr_attr(s, g, which);
+ if (true == ret_value)
+ ret_value = modify_vlstr_attr(g, which);
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_attrs_compact
+ *
+ * Purpose: Add some attributes to the group.
+ * the number of attributes should be the maximal number of
+ * attributes that the compact storage can hold
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * hid_t gcpl
+ * Object creation property list ID
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ * The group name is "group-which" and the attribute name
+ * is "attr-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is for the "modify-vstr" test.
+ * For attribute compact/dense storage, check the reference
+ * manual of H5Pget_attr_phase_change.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
+{
+
+ unsigned max_compact = 0;
+ unsigned min_dense = 0;
+ const char *aname_format = "attr-%u-%u";
+
+ if (s->old_style_grp)
+ max_compact = 2;
+ else {
+ /* Obtain the maximal number of attributes to be stored in compact
+ * storage and the minimal number of attributes to be stored in
+ * dense storage. */
+ if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) {
+ printf("H5Pget_attr_phase_change() failed\n");
+ TEST_ERROR;
+ }
+ }
+
+ /* Add max_compact attributes, these attributes are stored in
+ * compact storage. */
+ return add_attr(s, g, which, max_compact, aname_format, which);
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_attrs_compact_dense
+ *
+ * Purpose: Add some attributes to the group.
+ * First, the number of attributes should be the maximal number
+ * of attributes that the compact storage can hold.
+ * Then, add another atribute, the storage becomes dense.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * hid_t gcpl
+ * Object creation property list ID
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is for the "compact-to-dense" test.
+ * For attribute compact/dense storage, check the reference
+ * manual of H5Pget_attr_phase_change.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
+{
+
+ unsigned max_compact = 0;
+ unsigned min_dense = 0;
+ const char *aname_format = "attr-d-%u-%u";
+ bool ret_value = false;
+
+ if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) {
+ printf("H5Pget_attr_phase_change failed\n");
+ TEST_ERROR;
+ }
+
+ /* Add attributes, until just before converting to dense storage */
+ ret_value = add_attrs_compact(s, g, gcpl, which);
+
+ /* Add another attribute, the storage becomes dense. */
+ if (ret_value == true)
+ ret_value = add_attr(s, g, which + max_compact, 1, aname_format, which);
+
+ return ret_value;
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: del_attrs_compact_dense_compact
+ *
+ * Purpose: delete some attributes in the group.
+ * The number of attributes are deleted in such a way
+ * that the attribute storage changes from compact to
+ * dense then to compact again.
+ *
+ * Parameters: hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * hid_t gcpl
+ * Object creation property list ID
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is an internal function used by the
+ * "dense-del-to-compact" test.
+ * For attribute compact/dense storage, check the reference
+ * manual of H5Pget_attr_phase_change.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+del_attrs_compact_dense_compact(hid_t obj_id, hid_t gcpl, unsigned int which)
+{
+
+ unsigned max_compact = 0;
+ unsigned min_dense = 0;
+ unsigned u = 0;
+
+ char attrname[VS_ATTR_NAME_LEN];
+ const char *aname_format = "attr-%u-%u";
+ const char *adname_format = "attr-d-%u-%u";
+
+ /* Obtain the maximal number of attributes to be stored in compact
+ * storage and the minimal number of attributes to be stored in
+ * dense storage. */
+ if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) {
+ printf("H5Pget_attr_phase_change failed\n");
+ TEST_ERROR;
+ }
+ u = max_compact + 1;
+
+ /* delete a number of attributes so that the attribute storage just becomes dense.*/
+ for (u--; u >= (min_dense - 1); u--) {
+ HDsprintf(attrname, aname_format, which, max_compact - u);
+ if (H5Adelete(obj_id, attrname) < 0) {
+ printf("H5Adelete failed\n");
+ TEST_ERROR;
+ }
+ }
+
+ /* The writer deletes another attribute, the storage is
+ * still dense. However, the attribute to be deleted
+ * doesn't follow the previous for loop. It may be
+ * in different location in the object header. Just add
+ * a litter variation to check if this operation is successful.
+ * The attribute name to be deleted is attr-max_compact+which-0
+ */
+
+ HDsprintf(attrname, adname_format, max_compact + which, 0);
+ if (H5Adelete(obj_id, attrname) < 0) {
+ printf("H5Adelete failed\n");
+ TEST_ERROR;
+ }
+
+ return true;
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_del_attrs_compact
+ *
+ * Purpose: Add some attributes to the group and then delete one attribute.
+ * First, the number of attributes to be added should be the
+ * maximal number of attributes that the compact storage can hold.
+ * Then, delete one atribute, the storage is still compact.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * hid_t gcpl
+ * Object creation property list ID
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is for the "compact-del" test.
+ * For attribute compact/dense storage, check the reference
+ * manual of H5Pget_attr_phase_change.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_del_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
+{
+
+ bool ret_value = false;
+ ret_value = add_attrs_compact(s, g, gcpl, which);
+ if (ret_value == true) {
+ dbgf(2, "writer: before deleting the attribute.\n");
+ ret_value = del_one_attr(s, g, false, false, which);
+ }
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_del_attrs_compact_dense
+ *
+ * Purpose: Add some attributes to the group and then delete one attribute.
+ * First, the number of attributes to be added exceeds
+ * the maximal number of attributes that the compact storage can hold.
+ * The storage changes from compact to dense.
+ * Then, delete one atribute, the storage is still dense.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * hid_t gcpl
+ * Object creation property list ID
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is for the "dense-del" test.
+ * For attribute compact/dense storage, check the reference
+ * manual of H5Pget_attr_phase_change.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_del_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
+{
+
+ bool ret_value = false;
+ unsigned max_compact = 0;
+ unsigned min_dense = 0;
+
+ if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) {
+ printf("H5Pget_attr_phase_change failed\n");
+ TEST_ERROR;
+ }
+
+ ret_value = add_attrs_compact_dense(s, g, gcpl, which);
+ if (ret_value == true)
+ ret_value = del_one_attr(s, g, true, false, which + max_compact);
+
+ return ret_value;
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_del_attrs_compact_dense_compact
+ *
+ * Purpose: Add attributes to the group and then delete some of them.
+ * First, the number of attributes to be added exceeds
+ * the maximal number of attributes that the compact storage can hold.
+ * The storage changes from compact to dense.
+ * Then, delete some attributes, the storage changes from
+ * dense to compact again.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * hid_t gcpl
+ * Object creation property list ID
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is for the "dense-del-to-compact" test.
+ * For attribute compact/dense storage, check the reference
+ * manual of H5Pget_attr_phase_change.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_del_attrs_compact_dense_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
+{
+
+ bool ret_value = false;
+ ret_value = add_attrs_compact_dense(s, g, gcpl, which);
+ if (ret_value == true)
+ ret_value = del_attrs_compact_dense_compact(g, gcpl, which);
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_modify_default_group_attr
+ *
+ * Purpose: Add an attribute then modify the value to a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ * The group name is "group-which" and the attribute name
+ * is "attr-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used for the "modify" test.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_modify_default_group_attr(state_t *s, hid_t g, unsigned int which)
+{
+
+ bool ret_value = false;
+ const char *aname_format = "attr-%u";
+ ret_value = add_default_group_attr(s, g, which);
+ if (ret_value == true)
+ ret_value = modify_attr(s, g, aname_format, which);
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: del_ohr_block_attr
+ *
+ * Purpose: Add an attribute to force creation of object header
+ * continuation block and remove this attribute to delete
+ * the object header continuation block
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ * The group name is "group-which" and the attribute name
+ * is "attr-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used for the
+ * "deletion of object header continuation block" test.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+del_ohr_block_attr(state_t *s, hid_t g, unsigned int which)
+{
+
+ bool ret_value = false;
+ ret_value = add_default_group_attr(s, g, which);
+ if (ret_value == true)
+ ret_value = del_one_attr(s, g, false, true, which);
+ return ret_value;
+}
+/*-------------------------------------------------------------------------
+ * Function: add_group_attribute
+ *
+ * Purpose: Check the attribute test pattern and then call the
+ * correponding test function..
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * hid_t gcpl
+ * Object creation property list ID
+ *
+ * unsigned int which
+ * The number of iterations for group creation, use to generate
+ * newly created group and attribute names.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the write_group() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+add_group_attribute(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
+{
+
+ bool ret_value = false;
+ char test_pattern = s->at_pattern;
+
+ switch (test_pattern) {
+ case 'c':
+ ret_value = add_attrs_compact(s, g, gcpl, which);
+ break;
+ case 't':
+ ret_value = add_attrs_compact_dense(s, g, gcpl, which);
+ break;
+ case 'C':
+ ret_value = add_del_attrs_compact(s, g, gcpl, which);
+ break;
+ case 'D':
+ ret_value = add_del_attrs_compact_dense(s, g, gcpl, which);
+ break;
+ case 'T':
+ ret_value = add_del_attrs_compact_dense_compact(s, g, gcpl, which);
+ break;
+ case 'M':
+ ret_value = add_modify_default_group_attr(s, g, which);
+ break;
+ case 'v':
+ ret_value = add_vlstr_attr(s, g, which);
+ break;
+ case 'r':
+ ret_value = add_del_vlstr_attr(s, g, which);
+ break;
+ case 'm':
+ ret_value = add_modify_vlstr_attr(s, g, which);
+ break;
+ case 'R':
+ ret_value = del_ohr_block_attr(s, g, which);
+ break;
+ case 'a':
+ case 'd':
+ case ' ':
+ default:
+ ret_value = add_default_group_attr(s, g, which);
+ break;
+ }
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: write_group
+ *
+ * Purpose: Create a group and carry out attribute operations(add,delete etc.)
+ * according to the attribute test pattern.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations for group creation
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the main() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+write_group(state_t *s, unsigned int which)
+{
+ char name[sizeof("/group-9999999999")];
+ hid_t g = H5I_INVALID_HID;
+ hid_t dummy_d = H5I_INVALID_HID;
+ hid_t gcpl = H5I_INVALID_HID;
+ bool result = true;
+ H5G_info_t group_info;
+ struct timespec start_time, end_time;
+ double temp_time;
+
+ if (which >= s->nsteps) {
+ printf("Number of created groups is out of bounds\n");
+ TEST_ERROR;
+ }
+
+ esnprintf(name, sizeof(name), "/group-%u", which);
+
+ if (s->old_style_grp)
+ gcpl = H5P_DEFAULT;
+ else {
+ gcpl = H5Pcreate(H5P_GROUP_CREATE);
+ if (gcpl < 0) {
+ printf("H5Pcreate failed\n");
+ TEST_ERROR;
+ }
+
+ /* If we test the dense storage, change the attribute phase. */
+ if (s->at_pattern == 'd') {
+ if (H5Pset_attr_phase_change(gcpl, 0, 0) < 0) {
+ printf("H5Pset_attr_phase_change failed for the dense storage.\n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ if (s->gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
+
+ fprintf(stderr, "HDclock_gettime failed");
+
+ TEST_ERROR;
+ }
+ }
+
+ if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) {
+ printf("H5Gcreate2 failed\n");
+ TEST_ERROR;
+ }
+
+ if (s->gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
+
+ fprintf(stderr, "HDclock_gettime failed");
+
+ TEST_ERROR;
+ }
+
+ temp_time = TIME_PASSED(start_time, end_time);
+ if (temp_time < s->min_gc_time)
+ s->min_gc_time = temp_time;
+ if (temp_time > s->max_gc_time)
+ s->max_gc_time = temp_time;
+ s->total_gc_time += temp_time;
+ }
+
+ /* We need to create a dummy dataset for the object header continuation block test. */
+ if (s->at_pattern == 'a' || s->at_pattern == 'R') {
+ if ((dummy_d = H5Dcreate2(g, "Dataset", H5T_NATIVE_INT, s->one_by_one_sid, H5P_DEFAULT, H5P_DEFAULT,
+ H5P_DEFAULT)) < 0) {
+ printf("H5Dcreate2 failed\n");
+ TEST_ERROR;
+ }
+ }
+ /* We only need to check the first group */
+ if (which == 0) {
+ if (H5Gget_info(g, &group_info) < 0) {
+ printf("H5Gget_info failed\n");
+ TEST_ERROR;
+ }
+
+ if (s->old_style_grp) {
+ if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ printf("Old-styled group test: but the group is not in old-style. \n");
+ TEST_ERROR;
+ }
+ dbgf(2, "Writer: group is created with the old-style.\n");
+ }
+ else {
+ if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ printf("The created group should NOT be in old-style . \n");
+ TEST_ERROR;
+ }
+ dbgf(2, "Writer: group is created with the new-style.\n");
+ }
+ }
+
+ /* If coming to an "object header continuation block" test,
+ * we need to check if this test behaves as expected. */
+ if (s->at_pattern == 'a' || s->at_pattern == 'R') {
+ if (false == check_ohr_num_chunk(g, true)) {
+ printf("An object header continuation block should NOT be created. \n");
+ printf("But it is created.\n");
+ TEST_ERROR;
+ }
+ }
+
+ /* Then carry out the attribute operation. */
+ if (s->asteps != 0 && which % s->asteps == 0)
+ result = add_group_attribute(s, g, gcpl, which);
+
+ if (s->at_pattern == 'a' || s->at_pattern == 'R') {
+ if (H5Dclose(dummy_d) < 0) {
+ printf("H5Dclose failed\n");
+ TEST_ERROR;
+ }
+ }
+
+ if (H5Gclose(g) < 0) {
+ printf("H5Gclose failed\n");
+ TEST_ERROR;
+ }
+
+ if (!s->old_style_grp && H5Pclose(gcpl) < 0) {
+ printf("H5Pclose failed\n");
+ TEST_ERROR;
+ }
+
+ return result;
+
+error:
+
+ H5E_BEGIN_TRY
+ {
+ H5Gclose(g);
+ if (s->at_pattern == 'a' || s->at_pattern == 'R')
+ H5Dclose(dummy_d);
+ if (!s->old_style_grp)
+ H5Pclose(gcpl);
+ }
+ H5E_END_TRY;
+
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: create_group_id
+ *
+ * Purpose: Create a group and return the group ID.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations for group creation
+ * This is used to generate the group name.
+ *
+ * bool dense_to_compact
+ * true if this function is used to test the transition from dense to
+ * compact, false if the test is from compact to dense.
+ *
+ * Return: Success: the group ID
+ * Failure: -1
+ *
+ * Note: Only used by testing the link storage transit functions.
+ *-------------------------------------------------------------------------
+ */
+
+static hid_t
+create_group_id(state_t *s, unsigned int which, bool dense_to_compact)
+{
+
+ char name[sizeof("/group-9999999999")];
+ hid_t g = H5I_INVALID_HID;
+ hid_t gcpl = H5I_INVALID_HID;
+ H5G_info_t group_info;
+
+ if (which >= s->nsteps) {
+ printf("Number of created groups is out of bounds\n");
+ TEST_ERROR;
+ }
+
+ gcpl = H5Pcreate(H5P_GROUP_CREATE);
+ if (gcpl < 0) {
+ printf("H5Pcreate failed\n");
+ TEST_ERROR;
+ }
+
+ if (dense_to_compact) {
+ if (H5Pset_link_phase_change(gcpl, 2, 2) < 0) {
+ printf("H5Pset_link_phase_change failed for dense to compact.\n");
+ TEST_ERROR;
+ }
+ }
+ else {
+ if (H5Pset_link_phase_change(gcpl, 1, 1) < 0) {
+ printf("H5Pset_attr_phase_change failed for compact to dense.\n");
+ TEST_ERROR;
+ }
+ }
+
+ esnprintf(name, sizeof(name), "/group-%u", which);
+ if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) {
+ printf("H5Gcreate2 failed\n");
+ TEST_ERROR;
+ }
+
+ if (H5Gget_info(g, &group_info) < 0) {
+ printf("H5Gget_info failed\n");
+ TEST_ERROR;
+ }
+
+ /* The storage type should always be compact when a group is created. */
+ if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) {
+ printf("New-style group link storage test:. \n");
+ printf(" still be compact after group creation. \n");
+ TEST_ERROR;
+ }
+
+ if (H5Pclose(gcpl) < 0) {
+ printf("H5Pclose failed\n");
+ TEST_ERROR;
+ }
+
+ return g;
+
+error:
+
+ H5E_BEGIN_TRY
+ {
+ H5Pclose(gcpl);
+ }
+ H5E_END_TRY;
+
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: close_group_id
+ *
+ * Purpose: Verify is a group is closed successfully.
+ *
+ * Parameters: hid_t g
+ * The ID of the group to be closed.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is used by the link storage transit functions.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+close_group_id(hid_t g)
+{
+
+ if (H5Gclose(g) < 0) {
+ printf("H5Gclose failed\n");
+ TEST_ERROR;
+ }
+
+ return true;
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: create_group
+ *
+ * Purpose: Create a group
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations for group creation
+ * This is used to generate the group name.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the main() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+create_group(state_t *s, unsigned int which)
+{
+
+ char name[sizeof("/group-9999999999")];
+ hid_t g = H5I_INVALID_HID;
+ H5G_info_t group_info;
+
+ if (which >= s->nsteps) {
+ printf("Number of created groups is out of bounds\n");
+ TEST_ERROR;
+ }
+
+ esnprintf(name, sizeof(name), "/group-%u", which);
+ if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
+ printf("H5Gcreate2 failed\n");
+ TEST_ERROR;
+ }
+
+ if (H5Gget_info(g, &group_info) < 0) {
+ printf("H5Gget_info failed\n");
+ TEST_ERROR;
+ }
+
+ if (s->old_style_grp) {
+ if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ printf("Old-styled group test: but the group is not in old-style. \n");
+ TEST_ERROR;
+ }
+ dbgf(2, "Writer: group is created with the old-style.\n");
+ }
+ else {
+ if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ printf("The created group should NOT be in old-style . \n");
+ TEST_ERROR;
+ }
+ dbgf(2, "Writer: group is created with the new-style.\n");
+ }
+
+ if (H5Gclose(g) < 0) {
+ printf("H5Gclose failed\n");
+ TEST_ERROR;
+ }
+
+ return true;
+
+error:
+
+ H5E_BEGIN_TRY
+ {
+ H5Gclose(g);
+ }
+ H5E_END_TRY;
+
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: delete_one_link
+ *
+ * Purpose: Delete a link(either hard/soft) in group operation tests.
+ * according to the group test pattern.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t obj_id
+ * The HDF5 object ID that the deleted link is attached to.
+ *
+ * const char *name
+ * The name of the link to be deleted.
+ *
+ * short link_storage
+ * <=0: link storage is ignored.
+ * 1: link storage should be compact after link deletion..
+ * >1: link storage should be dense after link deletion.
+ *
+ * unsigned int which
+ * The number of iterations for group creation
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is used by delete_groups() and delete_links() functions.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+delete_one_link(state_t *s, hid_t obj_id, const char *name, short link_storage, unsigned int which)
+{
+
+ H5G_info_t group_info;
+
+ if (which >= s->nsteps) {
+ printf("Number of created groups is out of bounds\n");
+ TEST_ERROR;
+ }
+
+ if (H5Ldelete(obj_id, name, H5P_DEFAULT) < 0) {
+ printf("H5Ldelete failed\n");
+ TEST_ERROR;
+ }
+
+ if (link_storage > 0) {
+
+ if (s->old_style_grp) {
+ printf("Old style group doesn't support the indexed storage.\n");
+ TEST_ERROR;
+ }
+
+ if (H5Gget_info(obj_id, &group_info) < 0) {
+ printf("H5Gget_info failed\n");
+ TEST_ERROR;
+ }
+
+ if (link_storage == 1) {
+
+ if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) {
+ printf("The group link storage should be compact. \n");
+ TEST_ERROR;
+ }
+ }
+ else {
+
+ if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) {
+ printf("The group link storage should be dense. \n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ return true;
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: delete_group
+ *
+ * Purpose: Delete a group and carry out group operations(add,delete etc.)
+ * according to the group operation test pattern.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations for group creation
+ * This is used to generate the group name
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the group_operations() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+delete_group(state_t *s, unsigned int which)
+{
+
+ char name[sizeof("/group-9999999999")];
+ bool ret_value = create_group(s, which);
+ if (ret_value == true) {
+ esnprintf(name, sizeof(name), "/group-%u", which);
+ ret_value = delete_one_link(s, s->file, name, 0, which);
+ }
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: move_one_group
+ *
+ * Purpose: A helper function used by the move_group operation.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t obj_id
+ * ID of the object this group is attached to
+ *
+ * const char *name
+ * The original group name
+ *
+ * const char *newname
+ * The new group name
+ *
+ * unsigned int which
+ * The number of iterations for group creation
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the move_group() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, unsigned int which)
+{
+
+ if (which >= s->nsteps) {
+ printf("Number of created groups is out of bounds\n");
+ TEST_ERROR;
+ }
+
+ if (H5Lmove(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
+ printf("H5Ldelete failed\n");
+ TEST_ERROR;
+ }
+
+ return true;
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: move_group
+ *
+ * Purpose: Move a group to another group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations for group creation
+ * used to generate the group name.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the group_operations() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+move_group(state_t *s, unsigned int which)
+{
+
+ char name[sizeof("/group-9999999999")];
+ char new_name[sizeof("/new-group-9999999999")];
+ bool ret_value = create_group(s, which);
+ if (ret_value == true) {
+ esnprintf(name, sizeof(name), "/group-%u", which);
+ esnprintf(new_name, sizeof(new_name), "/new-group-%u", which);
+ ret_value = move_one_group(s, s->file, name, new_name, which);
+ }
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: insert_one_link
+ *
+ * Purpose: A helper function used to attach a link to a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t obj_id
+ * ID of the object this link is attached to
+ *
+ * const char *name
+ * The name of the target object used by creating links
+ *
+ * const char *newname
+ * The name of the linked objects
+ *
+ * bool is_hard
+ * true if inserting a hard link
+ * false if inserting a soft link
+ *
+ * short link_storage
+ * <=0: link storage is ignored.
+ * 1: link storage should be compact.
+ * >1: link storage should be dense.
+
+ * unsigned int which
+ * The number of iterations for group creation
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the insert_links and link storage transit functions.
+ * For link storage, we test at both the writer and the reader.
+ *-------------------------------------------------------------------------
+*/
+
+static bool
+insert_one_link(state_t *s, hid_t obj_id, const char *name, const char *newname, bool is_hard,
+ short link_storage, unsigned int which)
+{
+
+ H5G_info_t group_info;
+
+ if (which >= s->nsteps) {
+ printf("Number of created groups is out of bounds\n");
+ TEST_ERROR;
+ }
+
+ /* For storage transit and insert_links cases, we
+ * create links in different style, just add a little
+ * variation of the tests.*/
+ if (is_hard) {
+ if (link_storage > 0) {
+ if (H5Lcreate_hard(s->file, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
+ printf("H5Lcreate_hard failed\n");
+ TEST_ERROR;
+ }
+ }
+ else {
+ if (H5Lcreate_hard(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
+ printf("H5Lcreate_hard failed\n");
+ TEST_ERROR;
+ }
+ }
+ }
+ else {
+ if (link_storage > 0) {
+ if (H5Lcreate_soft("/", obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
+ printf("H5Lcreate_soft failed\n");
+ TEST_ERROR;
+ }
+ }
+ else {
+ if (H5Lcreate_soft(name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
+ printf("H5Lcreate_soft failed.\n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ if (link_storage > 0) {
+
+ if (s->old_style_grp) {
+ printf("Old style group doesn't support dense or compact storage.\n");
+ TEST_ERROR;
+ }
+
+ if (H5Gget_info(obj_id, &group_info) < 0) {
+ printf("H5Gget_info failed\n");
+ TEST_ERROR;
+ }
+
+ if (link_storage == 1) {
+ if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) {
+ printf("The group link storage should be compact. \n");
+ TEST_ERROR;
+ }
+ }
+ else {
+ if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) {
+ printf("The group link storage should be dense. \n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ return true;
+
+error:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: insert_links
+ *
+ * Purpose: create links with a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations
+ * used to generate the group name.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the group_operations() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+insert_links(state_t *s, unsigned int which)
+{
+
+ char name[sizeof("/group-9999999999")];
+ char hd_name[sizeof("/hd-group-9999999999")];
+ char st_name[sizeof("/st-group-9999999999")];
+
+ bool ret_value = create_group(s, which);
+ if (ret_value == true) {
+ esnprintf(name, sizeof(name), "/group-%u", which);
+ esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which);
+ esnprintf(st_name, sizeof(st_name), "/st-group-%u", which);
+ ret_value = insert_one_link(s, s->file, name, hd_name, true, 0, which);
+ if (ret_value == true)
+ ret_value = insert_one_link(s, s->file, name, st_name, false, 0, which);
+ }
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: delete_links
+ *
+ * Purpose: create links with a group and then delete them successfully.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations
+ * used to generate the group name.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the group_operations() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+delete_links(state_t *s, unsigned int which)
+{
+
+ char name[sizeof("/group-9999999999")];
+ char hd_name[sizeof("/hd-group-9999999999")];
+ char st_name[sizeof("/st-group-9999999999")];
+
+ bool ret_value = insert_links(s, which);
+ if (ret_value == true) {
+ esnprintf(name, sizeof(name), "/group-%u", which);
+ esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which);
+ esnprintf(st_name, sizeof(st_name), "/st-group-%u", which);
+ ret_value = delete_one_link(s, s->file, hd_name, 0, which);
+ if (ret_value == true)
+ ret_value = delete_one_link(s, s->file, st_name, 0, which);
+ }
+
+ return ret_value;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: transit_storage_compact_to_dense
+ *
+ * Purpose: Add links so that the link storage transits from
+ * compact to dense.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations used to generate the group name.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the group_operations() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+transit_storage_compact_to_dense(state_t *s, unsigned int which)
+{
+
+ char name[sizeof("/group-9999999999")];
+ char hd_name[sizeof("/hd-group-9999999999")];
+ char st_name[sizeof("/st-group-9999999999")];
+
+ hid_t g = create_group_id(s, which, false);
+ if (g < 0) {
+ printf("create_group_id failed\n");
+ TEST_ERROR;
+ }
+
+ /* First insert a hard link, compact storage. */
+ esnprintf(name, sizeof(name), "/group-%u", which);
+ esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which);
+ if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) {
+ printf("insert_one_link for compact storage failed\n");
+ TEST_ERROR;
+ }
+
+ /* Then insert a soft link, the storage becomes dense. */
+ esnprintf(st_name, sizeof(st_name), "st-group-%u", which);
+ if (insert_one_link(s, g, name, st_name, false, 2, which) == false) {
+ printf("insert_one_link for dense storage failed\n");
+ TEST_ERROR;
+ }
+
+ if (close_group_id(g) == false) {
+ printf("insert_one_link for dense storage failed\n");
+ TEST_ERROR;
+ }
+
+ return true;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Gclose(g);
+ }
+ H5E_END_TRY;
+
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: transit_storage_dense_to_compact
+ *
+ * Purpose: Add or delete links so that the link storage transits from
+ * compact to dense then to compact.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations used to generate the group name.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the group_operations() function.
+ *-------------------------------------------------------------------------
+ */
+
+static bool
+transit_storage_dense_to_compact(state_t *s, unsigned int which)
+{
+
+ char name[sizeof("/group-9999999999")];
+ char hd_name[sizeof("/hd-group-9999999999")];
+ char st_name[sizeof("st-group-9999999999")];
+ char st2_name[sizeof("st2-group-9999999999")];
+
+ hid_t g = create_group_id(s, which, true);
+ if (g < 0) {
+ printf("create_group_id failed\n");
+ TEST_ERROR;
+ }
+
+ /* Insert a link, storage is compact. */
+ esnprintf(name, sizeof(name), "/group-%u", which);
+ esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which);
+ if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) {
+ printf("insert_one_link for compact storage failed\n");
+ TEST_ERROR;
+ }
+
+ /* Insert a link, storage is still compact. */
+ esnprintf(st_name, sizeof(st_name), "st-group-%u", which);
+ if (insert_one_link(s, g, name, st_name, false, 1, which) == false) {
+ printf("insert_one_link for compact storage failed\n");
+ TEST_ERROR;
+ }
+
+ /* Insert a link, storage becomes dense. */
+ esnprintf(st2_name, sizeof(st2_name), "st2-group-%u", which);
+ if (insert_one_link(s, g, name, st2_name, false, 2, which) == false) {
+ printf("insert_one_link for dense storage failed\n");
+ TEST_ERROR;
+ }
+
+ /* Delete a link, storage is still dense */
+ if (delete_one_link(s, g, st_name, 2, which) == false) {
+ printf("delete_one_link for dense storage failed\n");
+ TEST_ERROR;
+ }
+
+ /* Delete another link, storage becomes compact */
+ if (delete_one_link(s, g, st2_name, 1, which) == false) {
+ printf("delete_one_link for compact storage failed\n");
+ TEST_ERROR;
+ }
+
+ if (close_group_id(g) == false) {
+ printf("insert_one_link for dense storage failed\n");
+ TEST_ERROR;
+ }
+
+ return true;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Gclose(g);
+ }
+ H5E_END_TRY;
+
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: group_operations
+ *
+ * Purpose: Carry out group and attribute operations(add,delete etc.)
+ * according to the group operation and attribute test patterns.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int which
+ * The number of iterations for group creation
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the main() function. The check of attribute
+ * operations is inside the write_group() function.
+ *-------------------------------------------------------------------------
+ */
+static bool
+group_operations(state_t *s, unsigned int which)
+{
+
+ bool ret_value = false;
+ char test_pattern = s->grp_op_pattern;
+
+ switch (test_pattern) {
+ case 'c':
+ ret_value = create_group(s, which);
+ break;
+ case 'd':
+ ret_value = delete_group(s, which);
+ break;
+ case 'm':
+ ret_value = move_group(s, which);
+ break;
+ case 'i':
+ ret_value = insert_links(s, which);
+ break;
+ case 'D':
+ ret_value = delete_links(s, which);
+ break;
+ case 't':
+ ret_value = transit_storage_compact_to_dense(s, which);
+ break;
+ case 'T':
+ ret_value = transit_storage_dense_to_compact(s, which);
+ break;
+ case ' ':
+ default:
+ ret_value = write_group(s, which);
+ break;
+ }
+ return ret_value;
+}
+
+static unsigned int grp_counter = 0;
+
+/*-------------------------------------------------------------------------
+ * Function: UI_Pow
+ *
+ * Purpose: Helper function to obtain the power 'n' of
+ * an unsigned integer 'x'
+ * Similar to pow(x,y) but for an unsigned integer.
+ *
+ * Parameters: unsigned int x
+ * unsigned int n
+ *
+ * Return: Return an unsigned integer of value of pow(x,n)
+ * Note: If the returned value is > 2^32-1, an overflow
+ * may occur. For our testing purpose, this may never happen.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static unsigned int
+UI_Pow(unsigned int x, unsigned int n)
+{
+ unsigned int i; /* Variable used in loop grp_counter */
+ unsigned int number = 1;
+
+ for (i = 0; i < n; ++i)
+ number *= x;
+
+ return (number);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: obtain_tree_level_elems
+ *
+ * Purpose: Helper function to obtain the maximum number of elements
+ * at one level.
+ *
+ * Parameters: unsigned int total_ele
+ * The total number of elements of a tree(excluding the root)
+ *
+ * unsigned int level
+ * The number of nested levels
+ * (If every element of the tree is under the root,
+ * the level is 0.)
+ *
+ * Return: Return the maximum number of elements at one level
+ *
+ * Example: If the total number of elements is 6 and level is 1,
+ * the maximum number of elements is 2.The tree is
+ * a perfectly balanced tree.
+ * Such as:
+ * 0
+ * 1 2
+ * 3 4 5 6
+ *
+ * If the total number of elements is 5 and level is 1,
+ * the maximum number of elements is still 2. The
+ * tree is not balanced, there is no element on the
+ * right-most leaf but the level is still 1.
+ * Such as:
+ * 0
+ * 1 2
+ * 3 4 5
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static unsigned int
+obtain_tree_level_elems(unsigned int total_ele, unsigned int level)
+{
+
+ assert(level <= total_ele);
+ /* if every element is under the root, just return the total number of elements. */
+ if (level == 0)
+ return total_ele;
+ else {
+ unsigned int test_elems_level = 0;
+ unsigned total = 0;
+ unsigned int i = 1;
+ /* Obtain the maximum number of elements for a level with the brutal force way. */
+ while (total < total_ele) {
+ test_elems_level++;
+ total = 0;
+ for (i = 1; i <= level + 1; i++)
+ total += UI_Pow(test_elems_level, i);
+ }
+ if (total == total_ele)
+ dbgf(2, "Perfectly match: Number of elements per level is %u\n", test_elems_level);
+ return test_elems_level;
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: gen_tree_struct
+ *
+ * Purpose: Generate the nested groups
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file
+ * and some VFD SWMR configuration parameters
+ *
+ * unsigned int level
+ * The number of nested levels +1
+ * (Note: If every element of the tree is under the root,
+ * the level is 1 in this function.)
+ * unsigned num_elems_per_level
+ * The maximum number of element in a level
+ * hid_t group_id
+ * The ID of the parent group
+ *
+ * Return: Success: true
+ * Failure: false
+ */
+static bool
+gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgrp_id)
+{
+
+ char name[sizeof("group-9999999999")];
+ unsigned int i;
+ hid_t grp_id;
+ bool result = true;
+ H5G_info_t group_info;
+ struct timespec start_time, end_time;
+ double temp_time;
+
+ if (level > 0 && grp_counter < s->nsteps) {
+
+ for (i = 0; i < ne_per_level; i++) {
+
+ /* For each i a group is created.
+ Use grp_counter to generate the group name.
+ printf("id: %u,level: %u, index: %u\n",id,level,i);
+ */
+ esnprintf(name, sizeof(name), "group-%u", grp_counter);
+ if (grp_counter == s->nsteps)
+ break;
+
+ dbgf(2, "writer in nested group: step %d\n", grp_counter);
+ if (s->gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
+ fprintf(stderr, "HDclock_gettime failed");
+ TEST_ERROR;
+ }
+ }
+
+ if ((grp_id = H5Gcreate2(pgrp_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
+ printf("H5Gcreate2 failed\n");
+ TEST_ERROR;
+ }
+
+ if (s->gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
+
+ fprintf(stderr, "HDclock_gettime failed");
+
+ TEST_ERROR;
+ }
+
+ temp_time = TIME_PASSED(start_time, end_time);
+ if (temp_time < s->min_gc_time)
+ s->min_gc_time = temp_time;
+ if (temp_time > s->max_gc_time)
+ s->max_gc_time = temp_time;
+ s->total_gc_time += temp_time;
+ }
+
+ /* Just check the first group information. */
+ if (grp_counter == 0) {
+ if (H5Gget_info(grp_id, &group_info) < 0) {
+ printf("H5Gget_info failed\n");
+ TEST_ERROR;
+ }
+
+ if (s->old_style_grp) {
+ if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ printf("Old-styled group test: but the group is not in old-style. \n");
+ TEST_ERROR;
+ }
+ dbgf(2, "Writer: group is created with the old-style.\n");
+ }
+ else {
+ if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ printf("The created group should NOT be in old-style . \n");
+ TEST_ERROR;
+ }
+ dbgf(2, "Writer: group is created with the new-style.\n");
+ }
+ }
+
+ /* Then carry out the attribute operation. */
+ if (s->asteps != 0 && grp_counter % s->asteps == 0)
+ result = add_default_group_attr(s, grp_id, grp_counter);
+
+ if (result == false) {
+ printf("Cannot create group attributes. \n");
+ TEST_ERROR;
+ }
+ grp_counter++;
+
+ /* Generate groups in the next level */
+ result = gen_tree_struct(s, level - 1, ne_per_level, grp_id);
+ if (result == false) {
+ printf("Cannot create nested groups. \n");
+ TEST_ERROR;
+ }
+
+ /* close the group ID. No problem. */
+ if (H5Gclose(grp_id) < 0) {
+ printf("H5Gclose failed. \n");
+ TEST_ERROR;
+ }
+ }
+ }
+
+ return true;
+
+error:
+
+ H5E_BEGIN_TRY
+ {
+ H5Gclose(grp_id);
+ }
+ H5E_END_TRY;
+
+ return false;
+}
+
+int
+main(int argc, char **argv)
+{
+ hid_t fapl = H5I_INVALID_HID, fcpl = H5I_INVALID_HID;
+ unsigned step;
+ bool writer = false;
+ state_t s;
+ const char * personality;
+ H5F_vfd_swmr_config_t config;
+ bool wg_ret = false;
+ struct timespec start_time, end_time;
+ unsigned int num_elems_per_level;
+
+ if (!state_init(&s, argc, argv)) {
+ printf("state_init failed\n");
+ TEST_ERROR;
+ }
+
+ personality = HDstrstr(s.progname, "vfd_swmr_gperf_");
+
+ if (personality != NULL && HDstrcmp(personality, "vfd_swmr_gperf_writer") == 0)
+ writer = true;
+ else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_gperf_reader") == 0)
+ writer = false;
+ else {
+ printf("unknown personality, expected vfd_swmr_gperf_{reader,writer}\n");
+ TEST_ERROR;
+ }
+
+ if (writer == false) {
+ printf("Reader is skipped for the performance tests.\n");
+ return EXIT_SUCCESS;
+ }
+
+ /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
+ init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow");
+
+ /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST)
+ * as the second parameter of H5Pset_libver_bound() that is called by
+ * vfd_swmr_create_fapl. Otherwise, the latest file format(H5F_LIBVER_LATEST)
+ * should be used as the second parameter of H5Pset_libver_bound().
+ * Also pass the use_vfd_swmr, only_meta_page, page buffer size, config to vfd_swmr_create_fapl().*/
+ if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, s.pbs, &config)) < 0) {
+ printf("vfd_swmr_create_fapl failed\n");
+ TEST_ERROR;
+ }
+
+ /* Set fs_strategy (file space strategy) and fs_page_size (file space page size) */
+ if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s.ps)) < 0) {
+ HDprintf("vfd_swmr_create_fcpl() failed");
+ TEST_ERROR;
+ }
+
+ if (s.nglevels > 0) {
+ if (s.grp_op_pattern != ' ' || s.at_pattern != ' ') {
+ printf("For nested group creation test, only the default option is supported.\n");
+ printf("Please re-run the tests with the appopriate option.\n");
+ TEST_ERROR;
+ }
+ }
+
+ if (s.gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
+ fprintf(stderr, "HDclock_gettime failed");
+ TEST_ERROR;
+ }
+ }
+
+ s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl);
+
+ if (s.gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
+ fprintf(stderr, "HDclock_gettime failed");
+ TEST_ERROR;
+ }
+
+ s.fo_total_time = TIME_PASSED(start_time, end_time);
+ }
+
+ if (s.file < 0) {
+ printf("H5Fcreate failed\n");
+ TEST_ERROR;
+ }
+
+ /* If generating nested groups, calculate the maximum number of
+ elements per level. */
+ if (s.nglevels > 0)
+ num_elems_per_level = obtain_tree_level_elems(s.nsteps, s.nglevels);
+
+ if (s.gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
+ fprintf(stderr, "HDclock_gettime failed");
+ TEST_ERROR;
+ }
+ }
+
+ /* If generating nested groups */
+ if (s.nglevels > 0) {
+
+ /* for the recursive call, the groups under the root is treated as one level */
+ wg_ret = gen_tree_struct(&s, s.nglevels + 1, num_elems_per_level, s.file);
+ if (wg_ret == false) {
+ printf("write nested group failed at group counter %u\n", grp_counter);
+ TEST_ERROR;
+ }
+ }
+ else {
+ for (step = 0; step < s.nsteps; step++) {
+
+ dbgf(2, "writer: step %d\n", step);
+ wg_ret = group_operations(&s, step);
+ if (wg_ret == false) {
+ printf("write_group failed at step %d\n", step);
+ TEST_ERROR;
+ }
+ }
+ }
+
+ if (s.gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
+
+ fprintf(stderr, "HDclock_gettime failed");
+ TEST_ERROR;
+ }
+
+ s.total_time = TIME_PASSED(start_time, end_time);
+ s.mean_time = s.total_time / s.nsteps;
+ s.mean_gc_time = s.total_gc_time / s.nsteps;
+ }
+
+ if (H5Pclose(fapl) < 0) {
+ printf("H5Pclose failed\n");
+ TEST_ERROR;
+ }
+
+ if (H5Pclose(fcpl) < 0) {
+ printf("H5Pclose failed\n");
+ TEST_ERROR;
+ }
+
+ if (H5Sclose(s.one_by_one_sid) < 0) {
+ printf("H5Sclose failed\n");
+ TEST_ERROR;
+ }
+
+ if (s.gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
+
+ fprintf(stderr, "HDclock_gettime failed");
+
+ TEST_ERROR;
+ }
+ }
+
+ if (H5Fclose(s.file) < 0) {
+ printf("H5Fclose failed\n");
+ TEST_ERROR;
+ }
+
+ if (s.gperf) {
+
+ if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
+
+ fprintf(stderr, "HDclock_gettime failed");
+
+ TEST_ERROR;
+ }
+
+ s.fc_total_time = TIME_PASSED(start_time, end_time);
+ }
+
+ /* Performance statistics summary */
+ if (s.gperf) {
+
+ if (verbosity != 0) {
+
+ fprintf(stdout, "\nPerformance Test Configuration: ");
+ if (s.use_vfd_swmr)
+ fprintf(stdout, " Using VFD SWMR \n");
+ else
+ fprintf(stdout, " Not using VFD SWMR \n");
+
+ if (s.old_style_grp)
+ fprintf(stdout, " Groups: Created via the earlist file format(old-style) \n");
+ else
+ fprintf(stdout, " Groups: Created via the latest file format(new-style) \n");
+
+ fprintf(stdout, "\n");
+
+ fprintf(stdout, "The length of a tick = %u\n", s.tick_len);
+ fprintf(stdout, "The maximum expected lag(in ticks)= %u\n", s.max_lag);
+ fprintf(stdout, "The page size(in bytes) = %u\n", s.ps);
+ fprintf(stdout, "The page buffer size(in bytes) = %u\n", s.pbs);
+ fprintf(stdout, "\n");
+ fprintf(stdout, "Number of groups = %u\n", s.nsteps);
+ fprintf(stdout, "Group Nested levels = %u\n", s.nglevels);
+ fprintf(stdout, "Number of attributes = %u\n", s.num_attrs);
+ fprintf(stdout, "Number of element per attribute = 1\n");
+ if (s.vlstr_test)
+ fprintf(stdout, "Attribute datatype is variable length string. \n");
+ else if (s.filetype == H5T_STD_U32BE)
+ fprintf(stdout, "Attribute datatype is big-endian unsigned 32-bit integer.\n");
+ else
+ fprintf(stdout, "Attribute datatype is native unsigned 32-bit integer.\n");
+
+ fprintf(stdout, "\n");
+ fprintf(stdout,
+ "(If the nested level is 0, all the groups are created directly under the root.)\n\n");
+ fprintf(stdout, "group creation maximum time =%lf\n", s.max_gc_time);
+ fprintf(stdout, "group creation minimum time =%lf\n", s.min_gc_time);
+ }
+
+ fprintf(stdout, "group creation total time = %lf\n", s.total_gc_time);
+ fprintf(stdout, "group creation mean time(per group) = %lf\n", s.mean_gc_time);
+ fprintf(stdout, "group creation and attributes generation total time = %lf\n", s.total_time);
+ fprintf(stdout, "group creation and attributes generation mean time(per group) = %lf\n", s.mean_time);
+ fprintf(stdout, "H5Fcreate time = %lf\n", s.fo_total_time);
+ fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time);
+ }
+
+ return EXIT_SUCCESS;
+
+error:
+ H5E_BEGIN_TRY
+ {
+ H5Pclose(fapl);
+ H5Pclose(fcpl);
+ H5Sclose(s.one_by_one_sid);
+ H5Fclose(s.file);
+ }
+ H5E_END_TRY;
+
+ return EXIT_FAILURE;
+}
+
+#else /* H5_HAVE_WIN32_API */
+
+int
+main(void)
+{
+ HDfprintf(stderr, "Non-POSIX platform. Skipping.\n");
+ return EXIT_SUCCESS;
+} /* end main() */
+
+#endif /* H5_HAVE_WIN32_API */
diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c
index f491353..c240ee5 100644
--- a/test/vfd_swmr_group_writer.c
+++ b/test/vfd_swmr_group_writer.c
@@ -153,8 +153,10 @@ state_init(state_t *s, int argc, char **argv)
esnprintf(s->progname, sizeof(s->progname), "%s", tfile);
- if (tfile)
+ if (tfile) {
HDfree(tfile);
+ tfile = NULL;
+ }
while ((ch = getopt(argc, argv, "SGa:bc:n:Nqu:A:O:")) != -1) {
switch (ch) {
@@ -3031,8 +3033,8 @@ verify_group(state_t *s, unsigned int which)
esnprintf(name, sizeof(name), "/group-%u", which);
- if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) {
- HDprintf("H5Gopen failed\n");
+ if ((g = H5Gopen2(s->file, name, H5P_DEFAULT)) < 0) {
+ HDprintf("H5Gopen2 failed\n");
TEST_ERROR;
}
@@ -4078,8 +4080,8 @@ vrfy_create_group(state_t *s, unsigned int which)
esnprintf(name, sizeof(name), "/group-%u", which);
- if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) {
- HDprintf("H5Gopen failed\n");
+ if ((g = H5Gopen2(s->file, name, H5P_DEFAULT)) < 0) {
+ HDprintf("H5Gopen2 failed\n");
TEST_ERROR;
}
@@ -4195,8 +4197,8 @@ vrfy_create_group_id(state_t *s, unsigned int which, bool dense_to_compact)
esnprintf(name, sizeof(name), "/group-%u", which);
- if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) {
- HDprintf("H5Gopen failed\n");
+ if ((g = H5Gopen2(s->file, name, H5P_DEFAULT)) < 0) {
+ HDprintf("H5Gopen2 failed\n");
TEST_ERROR;
}
@@ -4569,8 +4571,8 @@ vrfy_move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newn
TEST_ERROR;
}
- if ((g = H5Gopen(obj_id, newname, H5P_DEFAULT)) < 0) {
- HDprintf("H5Gopen failed\n");
+ if ((g = H5Gopen2(obj_id, newname, H5P_DEFAULT)) < 0) {
+ HDprintf("H5Gopen2 failed\n");
TEST_ERROR;
}
@@ -4985,7 +4987,7 @@ main(int argc, char **argv)
}
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(&config, 4, 7, writer, FALSE, 128, "./group-shadow");
+ init_vfd_swmr_config(&config, 4, 7, writer, TRUE, 128, "./group-shadow");
/* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST)
* as the second parameter of H5Pset_libver_bound() that is called by
diff --git a/test/vfd_swmr_reader.c b/test/vfd_swmr_reader.c
index cc4d918..6265cae 100644
--- a/test/vfd_swmr_reader.c
+++ b/test/vfd_swmr_reader.c
@@ -320,7 +320,7 @@ read_records(const char *filename, hbool_t verbose, FILE *verbose_file, unsigned
}
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(config, 4, 5, FALSE, FALSE, 128, "./rw-shadow");
+ init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, 128, "./rw-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config)) < 0) {
diff --git a/test/vfd_swmr_remove_reader.c b/test/vfd_swmr_remove_reader.c
index b729ee4..4389b05 100644
--- a/test/vfd_swmr_remove_reader.c
+++ b/test/vfd_swmr_remove_reader.c
@@ -304,7 +304,7 @@ read_records(const char *filename, unsigned verbose, unsigned long nseconds, uns
goto error;
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(config, 4, 5, FALSE, FALSE, 128, "./rw-shadow");
+ init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, 128, "./rw-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config)) < 0) {
diff --git a/test/vfd_swmr_remove_writer.c b/test/vfd_swmr_remove_writer.c
index b8b1303..8df8fa8 100644
--- a/test/vfd_swmr_remove_writer.c
+++ b/test/vfd_swmr_remove_writer.c
@@ -87,7 +87,7 @@ open_skeleton(const char *filename, unsigned verbose, unsigned old H5_ATTR_UNUSE
goto error;
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(config, 4, 5, TRUE, FALSE, 128, "./rw-shadow");
+ init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, 128, "./rw-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, config)) < 0)
diff --git a/test/vfd_swmr_sparse_reader.c b/test/vfd_swmr_sparse_reader.c
index a39b357..943c375 100644
--- a/test/vfd_swmr_sparse_reader.c
+++ b/test/vfd_swmr_sparse_reader.c
@@ -208,7 +208,7 @@ read_records(const char *filename, unsigned verbose, unsigned long nrecords, uns
goto error;
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(config, 4, 5, FALSE, FALSE, 128, "./rw-shadow");
+ init_vfd_swmr_config(config, 4, 5, FALSE, TRUE, 128, "./rw-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(FALSE, TRUE, FALSE, 4096, config)) < 0) {
diff --git a/test/vfd_swmr_sparse_writer.c b/test/vfd_swmr_sparse_writer.c
index 53b6ec9..56d19f3 100644
--- a/test/vfd_swmr_sparse_writer.c
+++ b/test/vfd_swmr_sparse_writer.c
@@ -87,7 +87,7 @@ open_skeleton(const char *filename, unsigned verbose)
goto error;
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(config, 4, 5, TRUE, FALSE, 128, "./rw-shadow");
+ init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, 128, "./rw-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, config)) < 0)
diff --git a/test/vfd_swmr_vlstr_reader.c b/test/vfd_swmr_vlstr_reader.c
index 5a112cd..fa9d7b4 100644
--- a/test/vfd_swmr_vlstr_reader.c
+++ b/test/vfd_swmr_vlstr_reader.c
@@ -116,7 +116,7 @@ main(int argc, char **argv)
errx(EXIT_FAILURE, "unexpected command-line arguments");
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(&config, 4, 7, false, FALSE, 128, "./vlstr-shadow");
+ init_vfd_swmr_config(&config, 4, 7, false, TRUE, 128, "./vlstr-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
fapl = vfd_swmr_create_fapl(true, use_vfd_swmr, sel == TEST_OOB, 4096, &config);
@@ -140,7 +140,7 @@ main(int argc, char **argv)
if (fid == badhid)
errx(EXIT_FAILURE, "H5Fcreate");
- /* content 1 seq 1 short
+ /* content 0 seq 1 short
* content 1 seq 1 long long long long long long long long
* content 1 seq 1 medium medium medium
*/
@@ -178,6 +178,11 @@ main(int argc, char **argv)
dbgf(2, ": read which %d seq %d tail %s\n", scanned_content.which, scanned_content.seq,
scanned_content.tail);
H5Dclose(dset[which]);
+
+ if (content[which] != NULL) {
+ HDfree(content[which]);
+ content[which] = NULL;
+ }
}
if (caught_out_of_bounds)
diff --git a/test/vfd_swmr_vlstr_writer.c b/test/vfd_swmr_vlstr_writer.c
index f338428..4f7376e 100644
--- a/test/vfd_swmr_vlstr_writer.c
+++ b/test/vfd_swmr_vlstr_writer.c
@@ -185,7 +185,7 @@ main(int argc, char **argv)
errx(EXIT_FAILURE, "unexpected command-line arguments");
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(&config, 4, 7, true, FALSE, 128, "./vlstr-shadow");
+ init_vfd_swmr_config(&config, 4, 7, true, TRUE, 128, "./vlstr-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
fapl = vfd_swmr_create_fapl(true, use_vfd_swmr, sel == TEST_OOB, 4096, &config);
diff --git a/test/vfd_swmr_writer.c b/test/vfd_swmr_writer.c
index c5b62c8..4693554 100644
--- a/test/vfd_swmr_writer.c
+++ b/test/vfd_swmr_writer.c
@@ -89,7 +89,7 @@ open_skeleton(const char *filename, hbool_t verbose, FILE *verbose_file, unsigne
return -1;
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(config, 4, 5, TRUE, FALSE, 128, "./rw-shadow");
+ init_vfd_swmr_config(config, 4, 5, TRUE, TRUE, 128, "./rw-shadow");
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */
if ((fapl = vfd_swmr_create_fapl(TRUE, TRUE, FALSE, 4096, config)) < 0)
diff --git a/test/vfd_swmr_zoo_writer.c b/test/vfd_swmr_zoo_writer.c
index d89fd16..13794d9 100644
--- a/test/vfd_swmr_zoo_writer.c
+++ b/test/vfd_swmr_zoo_writer.c
@@ -474,7 +474,7 @@ main(int argc, char **argv)
parse_command_line_options(argc, argv);
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(&vfd_swmr_config, TICK_LEN, 7, writer, FALSE, 128, "./zoo-shadow");
+ init_vfd_swmr_config(&vfd_swmr_config, TICK_LEN, 7, writer, TRUE, 128, "./zoo-shadow");
/* ? turn off use latest format argument via 1st argument? since later on it reset to early format */
/* use_latest_format, use_vfd_swmr, only_meta_page, page_buf_size, config */