summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvchoi-hdfgroup <55293060+vchoi-hdfgroup@users.noreply.github.com>2021-04-30 18:07:33 (GMT)
committerGitHub <noreply@github.com>2021-04-30 18:07:33 (GMT)
commit67c75039d5aafb8148cd9fa1eabb97cb94b4da62 (patch)
treeab3536e454d3e0f35cd7d46eb07e9aca0d45fa31
parent49600e5e8441a487190d1e9879e7d6be5820c44c (diff)
parent4042f4c2d4b5bf824fdcfc313d906e466c88ddb7 (diff)
downloadhdf5-67c75039d5aafb8148cd9fa1eabb97cb94b4da62.zip
hdf5-67c75039d5aafb8148cd9fa1eabb97cb94b4da62.tar.gz
hdf5-67c75039d5aafb8148cd9fa1eabb97cb94b4da62.tar.bz2
Merge pull request #9 from HDFGroup/feature/vfd_swmr
Feature/vfd swmr
-rw-r--r--test/testvfdswmr.sh.in155
-rw-r--r--test/vfd_swmr_common.c4
-rw-r--r--test/vfd_swmr_group_writer.c2847
3 files changed, 2858 insertions, 148 deletions
diff --git a/test/testvfdswmr.sh.in b/test/testvfdswmr.sh.in
index c64f9de..979f5a9 100644
--- a/test/testvfdswmr.sh.in
+++ b/test/testvfdswmr.sh.in
@@ -54,17 +54,20 @@ fi
BIGSET_n=25 # -n option: # of iterations
BIGSET_few_s=20 # -s option: # of datasets (for few_big test)
BIGSET_many_s=500 # -s option: # of datasets (for many_small test)
-GROUP_n=100 # -n option: # of groups (for vfd_swmr_group_writer.c)
+GROUP_n=40 # -n option: # of groups (for group test)
+GROUP_attr_n=1 # -n option: # of groups (for group attribute test)
+
if [[ "$HDF5TestExpress" -eq 0 ]] ; then # Setting for exhaustive run
BIGSET_n=50
BIGSET_few_s=40
BIGSET_many_s=1000
GROUP_n=400
+ GROUP_attr_n=4
elif [[ "$HDF5TestExpress" -gt 1 ]]; then # Setting for quick run
BIGSET_n=10
BIGSET_few_s=10
BIGSET_many_s=100
- GROUP_n=40
+ GROUP_n=20
fi
###############################################################################
@@ -153,7 +156,7 @@ if [ $rc -ne 0 ] ; then
fi
all_tests="generator expand shrink expand_shrink sparse vlstr_null vlstr_oob zoo groups attrdset"
-all_tests="${all_tests} few_big many_small"
+all_tests="${all_tests} groups_attrs os_groups_attrs few_big many_small"
tests=${all_tests}
if [ $# -gt 0 ]; then
@@ -668,7 +671,7 @@ for options in "-p -g -a 10 -v -m -d 10 -c 3 -u 5" "-k -a 20 -v -m -d 5"; do
done
#
-# Make sure that we can create GROUP_n groups (40, 100, or 400 depending on the HDF5TestExpress level)
+# Make sure that we can create GROUP_n groups (20, 40, or 400 depending on the HDF5TestExpress level)
# while a reader waits for each to appear.
#
if [ ${do_groups:-no} = yes ]; then
@@ -705,6 +708,150 @@ if [ ${do_groups:-no} = yes ]; then
rm -f vfd_swmr_group_reader.*.{out,rc}
fi
+# The group attribute test takes longer.
+# So for standard run and quick run, we
+# shorten the number of tests. The standard
+# run covers all the features we need to
+# test. The quick run doesn't cover the
+# attribute storage change between dense and
+# compact.
+# The exhaustive run tries to test a feature
+# per test from scratch.
+#
+grp_attr_list=(
+ "compact"
+ "dense"
+ "compact-del"
+ "dense-del"
+ "compact-add-to-dense"
+ "dense-del-to-compact"
+ "modify"
+ "add-vstr"
+ "remove-vstr"
+ "modify-vstr"
+ )
+grp_sub_attr_list=(
+ "dense-del-to-compact"
+ "modify"
+ "remove-vstr"
+ "modify-vstr"
+ )
+
+grp_short_sub_attr_list=(
+ "dense"
+ "modify"
+ "remove-vstr"
+ "modify-vstr"
+ )
+
+if [[ "$HDF5TestExpress" -eq 1 ]] ; then #Setting for standard run
+ grp_attr_list=("${grp_sub_attr_list[@]}")
+elif [[ "$HDF5TestExpress" -gt 1 ]] ; then #Setting for quick run
+ grp_attr_list=("${grp_short_sub_attr_list[@]}")
+fi
+
+for options in ${grp_attr_list[*]}; do
+ if [ ${do_groups_attrs:-no} = no ]; then
+ continue
+ fi
+ echo launch vfd_swmr_group attribute: $options
+ catch_out_err_and_rc vfd_swmr_group_writer \
+ ../vfd_swmr_group_writer -q -c 1 -n $GROUP_attr_n -a 1 -A $options &
+ pid_writer=$!
+
+ catch_out_err_and_rc vfd_swmr_group_reader \
+ ../vfd_swmr_group_reader -q -c 1 -n $GROUP_attr_n -a 1 -A $options &
+ pid_reader=$!
+
+ # Wait for the reader to finish before signalling 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_group_reader.rc) -ne 0 ]; then
+ echo reader had error
+ nerrors=$((nerrors + 1))
+ fi
+
+ # 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}
+ rm -f vfd_swmr_group_reader.*.{out,rc}
+done
+
+# The following tests are for add/del/modify attributes for
+# groups created with the old-style.
+# Check https://portal.hdfgroup.org/display/HDF5/Groups for
+# the detailed group implementation note.
+# The 'compact' and 'compact-del' are the attribute addition
+# and deletion tests. Other test names have the same meaning
+# as those of the new-style group tests.
+#
+os_grp_attr_list=(
+ "compact"
+ "compact-del"
+ "modify"
+ "add-vstr"
+ "remove-vstr"
+ "modify-vstr"
+ )
+os_grp_sub_attr_list=(
+ "modify"
+ "remove-vstr"
+ "modify-vstr"
+ )
+if [[ "$HDF5TestExpress" -gt 0 ]] ; then #Setting for standard run
+ os_grp_attr_list=("${os_grp_sub_attr_list[@]}")
+fi
+
+for options in ${os_grp_attr_list[*]}; do
+ if [ ${do_os_groups_attrs:-no} = no ]; then
+ continue
+ fi
+ echo launch vfd_swmr_group attribute with old-style group: $options
+ catch_out_err_and_rc vfd_swmr_group_writer \
+ ../vfd_swmr_group_writer -q -G -c 1 -n $GROUP_attr_n -a 1 -A $options &
+ pid_writer=$!
+
+ catch_out_err_and_rc vfd_swmr_group_reader \
+ ../vfd_swmr_group_reader -q -G -c 1 -n $GROUP_attr_n -a 1 -A $options &
+ pid_reader=$!
+
+ # Wait for the reader to finish before signalling 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_group_reader.rc) -ne 0 ]; then
+ echo reader had error
+ nerrors=$((nerrors + 1))
+ fi
+
+ # 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}
+ rm -f vfd_swmr_group_reader.*.{out,rc}
+done
+
+
+
+
for options in "-d 1" "-d 1 -F" "-d 2" "-d 2 -F" "-d 1 -V" "-d 1 -M" "-d 1 -V -F" "-d 1 -M -F"; do
if [ ${do_many_small:-no} = no ]; then
continue
diff --git a/test/vfd_swmr_common.c b/test/vfd_swmr_common.c
index 68e0b9c..aed9cbe 100644
--- a/test/vfd_swmr_common.c
+++ b/test/vfd_swmr_common.c
@@ -391,6 +391,10 @@ vfd_swmr_create_fapl(bool use_latest_format, bool use_vfd_swmr, bool only_meta_p
if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
return H5I_INVALID_HID;
}
+ else {/* Currently this is used only for old-styled group implementation tests.*/
+ if (H5Pset_libver_bounds(fapl, H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST) < 0)
+ return H5I_INVALID_HID;
+ }
/* Enable page buffering */
if (H5Pset_page_buffer_size(fapl, 4096, only_meta_pages ? 100 : 0, 0) < 0)
diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c
index 25ee8c5..7f083c8 100644
--- a/test/vfd_swmr_group_writer.c
+++ b/test/vfd_swmr_group_writer.c
@@ -24,17 +24,27 @@
#ifndef H5_HAVE_WIN32_API
#define READER_WAIT_TICKS 3
+#define VS_ATTR_NAME_LEN 21
typedef struct {
- hid_t file, filetype, one_by_one_sid;
- char filename[PATH_MAX];
- char progname[PATH_MAX];
- unsigned int asteps;
- unsigned int csteps;
- unsigned int nsteps;
- unsigned int update_interval;
- bool use_vfd_swmr;
- bool use_named_pipes;
+ hid_t file, filetype, one_by_one_sid;
+ char filename[PATH_MAX];
+ char progname[PATH_MAX];
+ unsigned int asteps;
+ unsigned int csteps;
+ unsigned int nsteps;
+ unsigned int update_interval;
+ bool use_vfd_swmr;
+ bool old_style_grp;
+ bool use_named_pipes;
+ char at_pattern;
+ bool attr_test;
+ uint32_t max_lag;
+ uint32_t tick_len;
+ int np_fd_w_to_r;
+ int np_fd_r_to_w;
+ int np_notify;
+ int np_verify;
} state_t;
#define ALL_HID_INITIALIZER \
@@ -43,26 +53,58 @@ typedef struct {
.file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \
.filetype = H5T_NATIVE_UINT32, .asteps = 10, .csteps = 10, .nsteps = 100, .update_interval = READER_WAIT_TICKS, \
.use_vfd_swmr = true, \
+ .old_style_grp = false, \
.use_named_pipes = true \
- }
+ , .at_pattern = ' ' \
+ , .attr_test = false \
+ , .tick_len = 4 \
+ , .max_lag = 7 \
+ , .np_fd_w_to_r = -1 \
+ , .np_fd_r_to_w = -1 \
+ , .np_notify = 0 \
+ , .np_verify = 0 }
+
static void
usage(const char *progname)
{
- fprintf(stderr, "usage: %s [-S] [-a steps] [-b] [-c]\n"
- " [-n iterations] [-N] [-q] [-u numb_ticks]\n"
- "\n"
- "-S: do not use VFD SWMR\n"
- "-a steps: `steps` between adding attributes\n"
- "-b: write data in big-endian byte order\n"
- "-c steps: `steps` between communication between the writer and reader\n"
- "-n ngroups: the number of groups\n"
- "-N: do not use named pipes, mainly for running the writer and reader seperately\n"
- "-u numb_tcks: `numb_ticks` for the reader to wait before verification\n"
- "-q: silence printouts, few messages\n"
- "\n",
- progname);
- exit(EXIT_FAILURE);
+ fprintf(stderr, "usage: %s [-S] [-G] [-a steps] [-b] [-c]\n"
+ " [-n iterations] [-N] [-q] [-u numb_ticks] [-A at_pattern]\n"
+ "\n"
+ "-S: do not use VFD SWMR\n"
+ "-G: old-style type of group\n"
+ "-a steps: `steps` between adding attributes\n"
+ "-b: write data in big-endian byte order\n"
+ "-c steps: `steps` between communication between the writer and reader\n"
+ "-n ngroups: the number of groups\n"
+ "-N: do not use named pipes, \n"
+ " mainly for running the writer and reader seperately\n"
+ "-u numb_ticks: `numb_ticks` for the reader to wait before verification\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"
+ "-q: silence printouts, few messages\n"
+ "\n",
+ progname);
+ exit(EXIT_FAILURE);
}
static bool
@@ -87,17 +129,20 @@ state_init(state_t *s, int argc, char **argv)
if (tfile)
HDfree(tfile);
- while ((ch = getopt(argc, argv, "Sa:bc:n:Nqu:")) != -1) {
+ while ((ch = getopt(argc, argv, "SGa:bc:n:Nqu:A:")) != -1) {
switch (ch) {
case 'S':
s->use_vfd_swmr = false;
break;
+ case 'G':
+ s->old_style_grp = true;
+ break;
case 'a':
case 'c':
case 'n':
case 'u':
errno = 0;
- tmp = strtoul(optarg, &end, 0);
+ tmp = HDstrtoul(optarg, &end, 0);
if (end == optarg || *end != '\0') {
H5_FAILED(); AT();
printf("couldn't parse `-%c` argument `%s`\n", ch, optarg);
@@ -127,6 +172,33 @@ state_init(state_t *s, int argc, char **argv)
case 'N':
s->use_named_pipes = false;
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 {
+ H5_FAILED(); AT();
+ printf("Invalid -A argument \"%s\"", optarg);
+ goto error;
+ }
+ break;
case 'q':
verbosity = 0;
break;
@@ -171,72 +243,1428 @@ state_init(state_t *s, int argc, char **argv)
error:
if (tfile)
HDfree(tfile);
+ return false;
+}
+
+/* Named Pipe Subroutine: np_wr_send_receive
+ * Description:
+ * The writer sends a message to the reader,
+ * then waits for max_lag ticks,
+ * then checks the returned message from the reader.
+ * Return:
+ * True if succeed
+ * False if an error occurs in any step above.
+ * An error is mostly caused by an unexpected
+ * notification number from the message sent
+ * by the reader.
+ */
+static bool np_wr_send_receive(state_t *s) {
+
+ unsigned int i;
+ /* Bump up the value of notify to notice the reader to start to read */
+ s->np_notify++;
+ if (HDwrite(s->np_fd_w_to_r, &(s->np_notify), sizeof(int)) < 0) {
+ H5_FAILED(); AT();
+ printf("HDwrite failed\n");
+ goto error;
+ }
+
+ /* During the wait, writer makes repeated HDF5 API calls
+ * to trigger EOT at approximately the correct time */
+ for(i = 0; i < s->max_lag + 1; i++) {
+ decisleep(s->tick_len);
+ H5E_BEGIN_TRY {
+ H5Aexists(s->file, "nonexistent");
+ } H5E_END_TRY;
+ }
+ /* Receive the same value from the reader and verify it before
+ * going to the next step */
+ (s->np_verify)++;
+ if (HDread(s->np_fd_r_to_w, &(s->np_notify), sizeof(int)) < 0){
+ H5_FAILED(); AT();
+ printf("HDread failed\n");
+ goto error;
+ }
+
+ if (s->np_notify == -1) {
+ H5_FAILED(); AT();
+ printf("reader failed to verify group or attribute operation.\n");
+ goto error;
+ }
+
+ if (s->np_notify != s->np_verify) {
+ H5_FAILED(); AT();
+ printf("received message %d, expecting %d\n", s->np_notify, s->np_verify);
+ goto error;
+ }
+
+ return true;
+
+error:
return false;
+
}
-static bool
-add_group_attribute(const state_t *s, hid_t g, hid_t sid, unsigned int which)
-{
- hid_t aid;
- char name[sizeof("attr-9999999999")];
+/* Named Pipe Subroutine: np_rd_receive
+ * Description:
+ * The reader receives a message from the writer,
+ * then checks if the notification number from
+ * the writer is expected.
+ * Return:
+ * True if succeed
+ * False if an error occurs in any step above.
+ * An error is mostly caused by an unexpected
+ * notification number from the message sent
+ * by the writer.
+ */
+static bool np_rd_receive(state_t *s) {
+
+ /* The writer should have bumped up the value of notify.
+ * Do the same with verify and confirm it */
+ s->np_verify++;
+
+ /* Receive the notify that the writer bumped up the value */
+ if (HDread(s->np_fd_w_to_r, &(s->np_notify), sizeof(int)) < 0) {
+ H5_FAILED(); AT();
+ printf("HDread failed\n");
+ goto error;
+ }
+
+ if (s->np_notify == -1) {
+ H5_FAILED(); AT();
+ printf("writer failed to create group or carry out an attribute operation.\n");
+ goto error;
+ }
+
+ if (s->np_notify != s->np_verify) {
+ H5_FAILED(); AT();
+ printf("received message %d, expecting %d\n", s->np_notify, s->np_verify);
+ goto error;
+ }
+
+ return true;
+
+error:
+ return false;
+}
+
+/* Named Pipe Subroutine: np_rd_send
+ * Description:
+ * The reader sends an acknowledgement to the writer
+ * Return:
+ * True if succeed
+ * False if an error occurs in sending the message.
+ */
+static bool np_rd_send(state_t *s) {
+
+ if (HDwrite(s->np_fd_r_to_w, &(s->np_notify), sizeof(int)) < 0) {
+ H5_FAILED(); AT();
+ printf("HDwrite failed\n");
+ return false;
+ }
+ else
+ return true;
+}
+
+/* Named Pipe Subroutine: np_send_error
+ * Description:
+ * An error (notification number is 1) message is sent
+ * either from the reader or the writer.
+ * A boolean input parameter is used to choose
+ * either reader or writer.
+ * Return:
+ * None
+ */
+static void np_send_error(state_t *s,bool writer) {
+ s->np_notify = -1;
+ if(writer)
+ HDwrite(s->np_fd_w_to_r, &(s->np_notify), sizeof(int));
+ else
+ HDwrite(s->np_fd_r_to_w, &(s->np_notify), sizeof(int));
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_attr
+ *
+ * Purpose: Add attributes to a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * 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) {
+ H5_FAILED(); AT();
+ printf("H5Tget_native_type failed\n");
+ goto 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) {
+ H5_FAILED(); AT();
+ printf("H5Acreate2 failed\n");
+ goto error;
+ }
+
+ attr_value = u+which;
+#if 0
+ // Just for debugging to check if error handling works.
+ attr_value = u+which+1;
+#endif
+
+ 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) {
+ H5_FAILED(); AT();
+ printf("H5Awrite failed\n");
+ goto error;
+ }
+
+ /* Close attribute */
+ if(H5Aclose(aid) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Aclose failed\n");
+ goto error;
+ }
+
+ /* Writer sends a message to reader: an attribute is successfully generated.
+ then wait for the reader to verify and send an acknowledgement message back.*/
+ if (s->use_named_pipes && s->attr_test == true) {
+ dbgf(2, "writer: write attr - ready to send/receive message: %d\n", s->np_notify+1);
+ if(np_wr_send_receive(s) == false) {
+ H5_FAILED(); AT();
+ dbgf(2, "writer: write attr - verification failed.\n");
+ /* Note: This is (mostly) because the verification failure message
+ * from the reader. So don't send the error message back to
+ * the reader. Just stop the test. */
+ goto error2;
+ }
+ }
+
+ } /* end for */
+
+ if(H5Tclose(amtype) < 0) {
+ H5_FAILED(); AT();
+ goto error;
+ }
+ return true;
+
+error:
+ /* Writer needs to send an error message to the reader to stop the test*/
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
+
+error2:
+ H5E_BEGIN_TRY {
+ H5Aclose(aid);
+ H5Tclose(amtype);
+ } H5E_END_TRY;
+
+ return false;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_default_group_attr
+ *
+ * Purpose: Add an attribute to a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * 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 test.
+ *-------------------------------------------------------------------------
+*/
+
+static bool
+add_default_group_attr(state_t *s, hid_t g, unsigned int which) {
+
+ const char* aname_format ="attr-%u";
+
+ /* Note: Since we only add one attribute, the parameter for
+ * the number of attributes is 1. */
+ return add_attr(s,g,which,1,aname_format,which);
+
+}
+
+/*-------------------------------------------------------------------------
+ * 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, named pipe
+ * 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) {
+ H5_FAILED(); AT();
+ printf("Allocate memory for VL string failed.\n");
+ goto 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);
- if ((aid = H5Acreate2(g, name, s->filetype, sid, H5P_DEFAULT,
- H5P_DEFAULT)) < 0) {
+ /* Create a datatype to refer to. */
+ if ((atype = H5Tcopy(H5T_C_S1)) < 0) {
H5_FAILED(); AT();
- printf("H5Acreate2 failed\n");
+ printf("Cannot create variable length datatype.\n");
+ goto error;
+ }
+
+ if (H5Tset_size(atype, H5T_VARIABLE) < 0) {
+ H5_FAILED(); AT();
+ printf("Cannot set variable length datatype.\n");
+ goto error;
+ }
+
+ /* Generate the VL string attribute.*/
+ if ((aid = H5Acreate2(g, name, atype, sid, H5P_DEFAULT,
+ H5P_DEFAULT)) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Acreate2 failed.\n");
+ goto error;
+ }
+
+ if (H5Awrite(aid, atype, &astr_val) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Awrite failed.\n");
+ goto error;
+ }
+
+ if (H5Tclose(atype) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Tclose() failed\n");
+ goto error;
+ }
+ if (H5Aclose(aid) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Aclose() failed\n");
+ goto error;
+ }
+
+ HDfree(astr_val);
+
+ /* Writer sends a message to reader: a VL string attribute is successfully generated.
+ then wait for the reader to verify and send an acknowledgement message back. */
+ if (s->use_named_pipes && s->attr_test == true) {
+ dbgf(2, "writer: write attr - ready to send the message: %d\n", s->np_notify+1);
+ if(np_wr_send_receive(s) == false) {
+ H5_FAILED(); AT();
+ dbgf(2, "writer: write attr - verification failed.\n");
+ goto error2;
+ }
+ }
+
+ return true;
+
+error:
+ /* Writer needs to send an error message to the reader to stop the test*/
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
+ H5E_BEGIN_TRY {
+ H5Aclose(aid);
+ H5Tclose(atype);
+ } H5E_END_TRY;
+
+ if(astr_val)
+ HDfree(astr_val);
+
+error2:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: del_one_attr
+ *
+ * Purpose: delete one attribute in a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * 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
+ * if the deleted attribute is a VL string
+ *
+ * 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,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 operation */
+ 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 == true)
+ HDsprintf(attrname, aname_format_vl, which,0);
+ else
+ HDsprintf(attrname, aname_format, which,0);
+
+ /* Delete the attribute */
+ if(H5Adelete(obj_id, attrname) <0) {
+ H5_FAILED(); AT();
+ printf("H5Adelete() failed\n");
+ goto error;
+ }
+
+ /* Writer sends a message to reader: an attribute is successfully generated.
+ then wait for the reader to verify and send an acknowledgement message back. */
+ if(s->use_named_pipes && s->attr_test == true) {
+ dbgf(2, "writer: delete attr - ready to send the message: %d\n", s->np_notify+1);
+ if(np_wr_send_receive(s) == false) {
+ H5_FAILED(); AT();
+ dbgf(2, "writer: delete attr - verification failed.\n");
+ goto error2;
+ }
+ }
+
+ return true;
+
+error:
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
+
+error2:
+ 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, named pipe
+ * 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, named pipe
+ * 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) {
+ H5_FAILED(); AT();
+ printf("H5Aopen failed\n");
goto error;
}
- if (H5Awrite(aid, H5T_NATIVE_UINT, &which) < 0) {
+ if((amtype = H5Tget_native_type(s->filetype,H5T_DIR_ASCEND))<0) {
+ H5_FAILED(); AT();
+ printf("H5Tget_native_type failed\n");
+ goto error;
+ }
+
+ /* Make a large number to verify the change easily */
+ modify_value = which+10000;
+
+ if (H5Awrite(aid,amtype,&modify_value) <0) {
H5_FAILED(); AT();
printf("H5Awrite failed\n");
goto error;
}
+ if (H5Tclose(amtype) < 0) {
+ H5_FAILED(); AT();
+ goto error;
+ }
+ if (H5Aclose(aid) < 0) {
+ H5_FAILED(); AT();
+ goto error;
+ }
+
+ /* Writer sends a message to reader: an attribute is successfully modified.
+ then wait for the reader to verify and send an acknowledgement message back.*/
+ if (s->use_named_pipes && s->attr_test == true) {
+ dbgf(2, "writer: modify attr - ready to send the message: %d\n", s->np_notify+1);
+ if(np_wr_send_receive(s) == false) {
+ H5_FAILED(); AT();
+ dbgf(2, "writer: write attr - verification failed.\n");
+ /* Note: This is (mostly) because the verification failure message
+ * from the reader. So don't send the error message back to
+ * the reader. Just stop the test. */
+ goto error2;
+ }
+ }
+
+ return true;
+error:
+ /* Writer needs to send an error message to the reader to stop the test*/
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
+ H5E_BEGIN_TRY {
+ H5Aclose(aid);
+ H5Tclose(aid);
+ } H5E_END_TRY;
+
+error2:
+ return false;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: modify_vlstr_attr
+ *
+ * Purpose: Modify the value of an VL string attribute in a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * 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 name. The group name is "group-which".
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ *-------------------------------------------------------------------------
+*/
+
+
+
+static bool
+modify_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;
+
+ astr_val = HDmalloc(VS_ATTR_NAME_LEN);
+ if (astr_val == NULL) {
+ H5_FAILED(); AT();
+ printf("Allocate memory for VL string failed.\n");
+ goto 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) {
+ H5_FAILED(); AT();
+ printf("Cannot create variable length datatype.\n");
+ goto error;
+ }
+
+ if (H5Tset_size(atype, H5T_VARIABLE) < 0) {
+ H5_FAILED(); AT();
+ printf("Cannot set variable length datatype.\n");
+ goto error;
+ }
+
+ /* Open this attribute. */
+ if ((aid = H5Aopen(g, name, H5P_DEFAULT))<0) {
+ H5_FAILED(); AT();
+ printf("H5Aopen failed.\n");
+ goto error;
+ }
+
+ dbgf(1, "The modified VL string value is %s \n", astr_val);
+
+ if (H5Awrite(aid, atype, &astr_val) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Awrite failed.\n");
+ goto error;
+ }
+
+ if (H5Tclose(atype) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Tclose() failed\n");
+ goto error;
+ }
if (H5Aclose(aid) < 0) {
H5_FAILED(); AT();
- printf("H5Aclose failed\n");
+ printf("H5Aclose() failed\n");
goto error;
}
+ HDfree(astr_val);
+
+ /* Writer sends a message to reader: a VL string attribute is successfully generated.
+ then wait for the reader to verify and send an acknowledgement message back. */
+ if (s->use_named_pipes && s->attr_test == true) {
+ dbgf(2, "writer: modify vl attr - ready to send the message: %d\n", s->np_notify+1);
+ if(np_wr_send_receive(s) == false) {
+ H5_FAILED(); AT();
+ dbgf(2, "writer: write attr - verification failed.\n");
+ goto error2;
+ }
+ }
+
return true;
error:
H5E_BEGIN_TRY {
H5Aclose(aid);
+ H5Tclose(atype);
} H5E_END_TRY;
+ if(astr_val)
+ HDfree(astr_val);
+
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
+
+error2:
+ return false;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: add_modify_vlstr_attr
+ *
+ * Purpose: Add a variable length string attribute
+ * then modify this attribute in this a group.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * 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(s,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, named pipe
+ * 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) {
+ H5_FAILED(); AT();
+ printf("H5Pget_attr_phase_change() failed\n");
+ goto error;
+ }
+ }
+
+ /* Add max_compact attributes, these attributes are stored in
+ * compact storage. */
+ return add_attr(s,g,which,max_compact,aname_format,which);
+
+error:
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
+ 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, named pipe
+ * 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) {
+ H5_FAILED(); AT();
+ printf("H5Pget_attr_phase_change failed\n");
+ goto 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:
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
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: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * 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 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(state_t *s,
+ 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) {
+ H5_FAILED(); AT();
+ printf("H5Pget_attr_phase_change failed\n");
+ goto 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) {
+ H5_FAILED(); AT();
+ printf("H5Adelete failed\n");
+ goto error;
+ }
+
+ /* For each attribute deletion, we want to ensure the verification
+ * from the reader.
+ * So writer sends a message to reader: an attribute is successfully deleted.
+ then wait for reader to verify and send an acknowledgement message back. */
+ if(s->use_named_pipes && s->attr_test == true) {
+ dbgf(2, "writer: delete attr - ready to send the message: %d\n", s->np_notify+1);
+ if(np_wr_send_receive(s) == false) {
+ H5_FAILED(); AT();
+ dbgf(2, "writer: delete attr - verification failed.\n");
+ goto error2;
+ }
+ }
+ }
+
+ /* 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) {
+ H5_FAILED(); AT();
+ printf("H5Adelete failed\n");
+ goto error;
+ }
+ /* Again we need to notify the reader via Named pipe. */
+ if(s->use_named_pipes && s->attr_test == true) {
+ dbgf(2, "writer: delete attr - ready to send the message: %d\n", s->np_notify+1);
+ if(np_wr_send_receive(s) == false) {
+ H5_FAILED(); AT();
+ dbgf(2, "writer: delete attr - verification failed.\n");
+ goto error2;
+ }
+ }
+
+ /* The following comments are left here in case in the future we want to
+ * use HDF5 function to verify the attribute storage */
+#if 0
+ // May H5Oget_info3 -- obtain the number of attributes.
+ //Check the number of attributes >=min_dense.
+ //We may use the internal function
+ //is_dense = H5O__is_attr_dense_test(dataset) to check if it is dense in the future.
+ //
+#endif
+
+ return true;
+
+error:
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
+
+error2:
+ 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, named pipe
+ * 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, named pipe
+ * 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) {
+ H5_FAILED(); AT();
+ printf("H5Pget_attr_phase_change failed\n");
+ goto 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:
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
+ 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, named pipe
+ * 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(s,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, named pipe
+ * 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" storage 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: 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, named pipe
+ * 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 '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, named pipe
+ * 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 gcpl = H5I_INVALID_HID;
bool result = true;
+ H5G_info_t group_info;
if (which >= s->nsteps) {
H5_FAILED(); AT();
- printf("group order is out of bounds\n");
+ printf("Number of created groups is out of bounds\n");
goto error;
}
esnprintf(name, sizeof(name), "/group-%d", which);
- if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
+ if(s->old_style_grp)
+ gcpl = H5P_DEFAULT;
+ else {
+ gcpl = H5Pcreate(H5P_GROUP_CREATE);
+ if(gcpl <0) {
+ H5_FAILED(); AT();
+ printf("H5Pcreate failed\n");
+ goto 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) {
+ H5_FAILED(); AT();
+ printf("H5Pset_attr_phase_change failed for the dense storage.\n");
+ goto error;
+ }
+ }
+ }
+
+ if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl,
+ H5P_DEFAULT)) < 0) {
H5_FAILED(); AT();
printf("H5Gcreate2 failed\n");
goto error;
}
- if (s->asteps != 0 && which % s->asteps == 0)
- result = add_group_attribute(s, g, s->one_by_one_sid, which);
+ if(H5Gget_info(g,&group_info) <0) {
+ H5_FAILED(); AT();
+ printf("H5Gget_info failed\n");
+ goto error;
+ }
+
+ if(s->old_style_grp) {
+ if(group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ H5_FAILED(); AT();
+ printf("Old-styled group test: but the group is not in old-style. \n");
+ goto error;
+ }
+ dbgf(2,"Writer: group is created with the old-style.\n");
+ }
+ else {
+ if(group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ H5_FAILED(); AT();
+ printf("The created group should NOT be in old-style . \n");
+ goto error;
+ }
+ dbgf(2,"Writer: group is created with the new-style.\n");
+
+ }
+ /* If an attribute test is turned on and named pipes are used,
+ * the writer should send and receive messages after the group creation.
+ * This will distinguish an attribute operation error from an
+ * group creation error.
+ * Writer sends a message to reader: an attribute is successfully generated.
+ * then wait for the reader to verify and send an acknowledgement message back.*/
+ if (s->use_named_pipes && s->attr_test == true) {
+ dbgf(2, "writer: ready to send the message: %d\n", s->np_notify+1);
+ if(np_wr_send_receive(s) == false) {
+ H5_FAILED(); AT();
+ /* Note: This is (mostly) because the verification failure message
+ * from the reader. So don't send the error message back to
+ * the reader. Just stop the test. */
+ goto error2;
+ }
+ }
+
+ /* Then carry out the attribute operation. */
+ if (s->asteps != 0 && which % s->asteps == 0)
+ result = add_group_attribute(s, g, gcpl,which);
if (H5Gclose(g) < 0) {
H5_FAILED(); AT();
@@ -244,26 +1672,454 @@ write_group(state_t *s, unsigned int which)
goto error;
}
+ if(!s->old_style_grp && H5Pclose(gcpl) <0) {
+ H5_FAILED(); AT();
+ printf("H5Pclose failed\n");
+ goto error;
+ }
+
return result;
error:
+ /* Writer needs to send an error message to the reader to stop the test*/
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,true);
+
+error2:
+
H5E_BEGIN_TRY {
H5Gclose(g);
+ if(!s->old_style_grp)
+ H5Pclose(gcpl);
+ } H5E_END_TRY;
+
+ return false;
+
+}
+/*-------------------------------------------------------------------------
+ * Function: check_attr_storage_type
+ *
+ * Purpose: Check if the attribute storage type is correct
+ *
+ * Parameters: hid_t oid
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * bool is_compact
+ * true if the attribute is stored in compact storage
+ * false if the attribute is stored in dense storage
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ *-------------------------------------------------------------------------
+*/
+
+static bool
+check_attr_storage_type(hid_t g,
+ bool is_compact) {
+
+ H5O_native_info_t ninfo;
+
+ /* Get the object information */
+ if(H5Oget_native_info(g, &ninfo, H5O_NATIVE_INFO_HDR|H5O_NATIVE_INFO_META_SIZE) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Oget_native_info failed\n");
+ goto error;
+ }
+
+ if(is_compact) {
+ if(ninfo.meta_size.attr.index_size != 0 ||
+ ninfo.meta_size.attr.heap_size != 0) {
+ H5_FAILED(); AT();
+ printf("Should be in compact storage,but it is not.\n");
+ goto error;
+ }
+ }
+ else {
+ if(ninfo.meta_size.attr.index_size == 0 ||
+ ninfo.meta_size.attr.heap_size == 0) {
+ H5_FAILED(); AT();
+ printf("Should be in dense storage,but it is not.\n");
+ goto error;
+ }
+ }
+
+ return true;
+
+error:
+ return false;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: vrfy_attr
+ *
+ * Purpose: Verify is a group attribute value is as expected.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * 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".
+ *
+ * const char*aname
+ * The attribute name
+ *
+ * unsigned int g_which
+ * This parameter is used to generate correct group name in a key
+ * debugging message.
+ *
+ * bool check_storage
+ * a flag to indicate if the storage check is on
+ *
+ * bool is_compact
+ * true if the attribute is stored in compact storage
+ * false if the attribute is stored in dense storage
+ * Note: this parameter is not used if the check_storage
+ * is set to false.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ *-------------------------------------------------------------------------
+*/
+
+static bool
+vrfy_attr(state_t *s,
+ hid_t g,
+ unsigned int which,
+ const char* aname,
+ unsigned int g_which,
+ bool check_storage,
+ bool is_compact) {
+
+ unsigned int read_which;
+ hid_t aid = H5I_INVALID_HID;
+ hid_t amtype = H5I_INVALID_HID;
+
+ /* The reader receives a message from the writer.Then sleep
+ * for a few ticks or stop the test if receiving an error
+ * message.
+ */
+ if(s->use_named_pipes && true == s->attr_test) {
+ if(false == np_rd_receive(s)) {
+ H5_FAILED(); AT();
+ /* Since receiving the error message from the writer,
+ * just stop the test. */
+ goto error2;
+ }
+ decisleep(s->tick_len * s->update_interval);
+ dbgf(1, "Reader: finish reading the message: %d\n",s->np_notify);
+ }
+
+ /* Go ahead to read the attribute. */
+ dbgf(1, "verifying attribute %s on group %u equals %u\n", aname, g_which,
+ which);
+
+ if ((amtype = H5Tget_native_type(s->filetype,H5T_DIR_ASCEND)) <0) {
+ H5_FAILED(); AT();
+ printf("H5Tget_native_type failed\n");
+ goto error;
+ }
+
+ if ((aid = H5Aopen(g, aname, H5P_DEFAULT)) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Aopen failed\n");
+ goto error;
+ }
+
+ if (H5Aread(aid, amtype, &read_which) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Aread failed\n");
+ goto error;
+ }
+
+ if (H5Aclose(aid) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Aclose failed\n");
+ goto error;
+ }
+
+ if(read_which != which) {
+ H5_FAILED(); AT();
+ dbgf(2, "reader: the add_attribute verfication failed,expected value is %d\n", which);
+ dbgf(2, "reader: the add_attribute verfication failed, the value is %d\n", read_which);
+ printf("The add_attribute verification failed\n");
+ goto error;
+ }
+
+
+ if(!s->old_style_grp && check_storage == true) {
+ if(false == check_attr_storage_type(g,is_compact)) {
+ H5_FAILED(); AT();
+ printf("The attribute storage type is wrong. \n");
+ goto error;
+ }
+ dbgf(2, "reader: finish checking the storage type: %d\n", s->np_notify);
+
+ }
+
+ /* If the read value is expected, send back an OK message to the writer. */
+ if(s->use_named_pipes && s->attr_test == true) {
+ if(np_rd_send(s)==false)
+ goto error;
+ dbgf(2, "reader: finish sending back the message: %d\n", s->np_notify);
+ }
+ return true;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Tclose(amtype);
+ H5Aclose(aid);
} H5E_END_TRY;
+ /* Send back an error message to the writer so that the writer can stop. */
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,false);
+error2:
return false;
+
}
+/*-------------------------------------------------------------------------
+ * Function: verify_default_group_attr
+ *
+ * Purpose: Check if the reader can retrieve the correct value of a
+ * group attribute corrected by the writer.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The expected attribute value. It is also used to construct the
+ * group name.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used for the "dense" storage test.
+ * It is also used by the group-only test.
+ *-------------------------------------------------------------------------
+*/
+
static bool
-verify_group_attribute(hid_t g, unsigned int which)
+verify_default_group_attr(state_t*s,hid_t g, unsigned int which)
{
+ char attrname[VS_ATTR_NAME_LEN];
+ const char* aname_format = "attr-%u";
+ HDsprintf(attrname, aname_format, which);
+ return vrfy_attr(s,g,which,attrname,which,false,true);
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_modify_attr
+ *
+ * Purpose: Check if the reader can retrieve the correct value of
+ * an attribute in a group, first the original value then
+ * the modified value.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * The expected attribute value. It is also used to construct the
+ * group name. The modified attribute value can be derived from
+ * the expected attribute value.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used for the "modified" test.
+ *-------------------------------------------------------------------------
+*/
+
+static bool
+verify_modify_attr(state_t *s, hid_t g, unsigned int which) {
+
+ bool ret = false;
+ const char* aname_fmt ="attr-%u";
unsigned int read_which;
- hid_t aid;
- char name[sizeof("attr-9999999999")];
+ hid_t aid = H5I_INVALID_HID;
+ hid_t amtype = H5I_INVALID_HID;
+ char attrname[VS_ATTR_NAME_LEN];
+
+ /* First verify the original attribute value */
+ ret = verify_default_group_attr(s,g,which);
+
+ /* Then the modified value */
+ if(ret == true) {
+
+ /* The reader receives a message from the writer.Then sleep
+ * for a few ticks or stop the test if receiving an error
+ * message.
+ */
+ if(s->use_named_pipes && true == s->attr_test) {
+ if(false == np_rd_receive(s)) {
+ H5_FAILED(); AT();
+ goto error2;
+ }
+ decisleep(s->tick_len * s->update_interval);
+ dbgf(1, "Reader: finish reading the message: %d\n",s->np_notify);
+ }
+
+ /* Go ahead to read the attribute. */
+ esnprintf(attrname, sizeof(attrname), aname_fmt, which);
+ if ((amtype = H5Tget_native_type(s->filetype,H5T_DIR_ASCEND)) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Tget_native_type failed\n");
+ goto error;
+ }
+
+ if ((aid = H5Aopen(g, attrname, H5P_DEFAULT)) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Aopen failed\n");
+ goto error;
+ }
+
+ if (H5Aread(aid, amtype, &read_which) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Aread failed\n");
+ goto error;
+ }
+
+ if(H5Tclose(amtype) <0) {
+ H5_FAILED(); AT();
+ printf("H5Tclose failed.\n");
+ goto error;
+ }
+
+ if (H5Aclose(aid) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Aclose failed\n");
+ goto error;
+ }
+
+ /* verify the modified value */
+ if(read_which != (which+10000)) {
+ H5_FAILED(); AT();
+ dbgf(2, "reader: the modified_attr() expected value is %d\n", (-1)*(int)which);
+ dbgf(2, "reader: the modified_attr() actual value is %d\n", read_which);
+ printf("The modify_attribute verification failed.\n");
+ goto error;
+ }
+
+ /* The reader sends an OK message back to the writer. */
+ if(s->use_named_pipes && s->attr_test == true) {
+ if(np_rd_send(s)==false)
+ goto error2;
+ dbgf(2, "reader: modify_attr finish sending back the message: %d\n", s->np_notify);
+ }
+ return true;
+
+ }
+ return false;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Aclose(aid);
+ H5Tclose(amtype);
+ } H5E_END_TRY;
+
+ /* The reader needs to send an error message back to the writer to stop the test.*/
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,false);
+
+error2:
+
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_group_vlstr_attr
+ *
+ * Purpose: Check if the reader can retrieve the correct value of
+ * a variable length string attribute created by the writer.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * Use to derieve the expected attribute value. It is also used
+ * to construct the group name.
+ *
+ * bool vrfy_mod
+ * true if this function is used for the modified VL string test.
+ * false if this function is just used for the VL string test.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is an internal function used by
+ * both the "vlstr" and the "modify-vstr" tests.
+ *-------------------------------------------------------------------------
+*/
+
+
+static bool
+verify_group_vlstr_attr(state_t*s, hid_t g, unsigned int which, bool vrfy_mod)
+{
+ hid_t aid = H5I_INVALID_HID;
+ hid_t atype = H5I_INVALID_HID;
+ char name[VS_ATTR_NAME_LEN];
+
+ char *astr_val_exp;
+ char * astr_val;
+
+ /* The reader receives a message from the writer.Then sleep
+ * for a few ticks or stop the test if the received message
+ * is an error message.
+ */
+ if(s->use_named_pipes && true == s->attr_test) {
+ if(false == np_rd_receive(s)) {
+ H5_FAILED(); AT();
+ goto error2;
+ }
+ decisleep(s->tick_len * s->update_interval);
+ dbgf(1, "Reader: finish reading the message: %d\n",s->np_notify);
+ }
+
+ /* Go ahead to read the VL string attribute. */
+ astr_val_exp = HDmalloc(VS_ATTR_NAME_LEN);
+ if (astr_val_exp == NULL) {
+ H5_FAILED(); AT();
+ printf("Allocate memory for expected buffer failed.\n");
+ goto error;
+ }
esnprintf(name, sizeof(name), "attr-%u", which);
- dbgf(1, "verifying attribute %s on group %u equals %u\n", name, which, which);
+ /* Construct the expected VL string value,depending if
+ * it is the modified value or the original value. */
+ if(vrfy_mod == true)
+ HDsprintf(astr_val_exp,"%u%c",which,'A');
+ else
+ HDsprintf(astr_val_exp,"%u",which);
+
+ dbgf(1, "verifying attribute %s on group %u equals %u\n", name, which,
+ which);
+
+ dbgf(1,"expected vl attr is= %s\n",astr_val_exp);
if ((aid = H5Aopen(g, name, H5P_DEFAULT)) < 0) {
H5_FAILED(); AT();
@@ -271,57 +2127,766 @@ verify_group_attribute(hid_t g, unsigned int which)
goto error;
}
- if (H5Aread(aid, H5T_NATIVE_UINT, &read_which) < 0) {
+ /* Create a VL string datatype */
+ if ((atype = H5Tcopy(H5T_C_S1)) < 0) {
H5_FAILED(); AT();
- printf("H5Aread failed\n");
+ printf("Cannot create variable length datatype.\n");
goto error;
}
- if (read_which != which) {
+ if (H5Tset_size(atype, H5T_VARIABLE) < 0) {
H5_FAILED(); AT();
- printf("H5Aread wrong value\n");
+ printf("Cannot set variable length datatype.\n");
goto error;
}
+ if (H5Aread(aid, atype, &astr_val) < 0) {
+ H5_FAILED(); AT();
+ printf("Cannot read the attribute.\n");
+ goto error;
+ }
+
+ dbgf(1,"read attr is= %s\n",astr_val);
+ if (HDstrcmp(astr_val, astr_val_exp) != 0) {
+ H5_FAILED(); AT();
+ dbgf(2, "reader: the vl add_attribute verfication failed,expected value is %s\n", astr_val_exp);
+ dbgf(2, "reader: the vl add_attribute verfication failed, the value is %s\n", astr_val);
+ printf("The vl add_attribute verification failed\n");
+ goto error;
+ }
+
+ if(H5Tclose(atype) <0) {
+ H5_FAILED(); AT();
+ printf("H5Tclose failed.\n");
+ goto error;
+ }
+
if (H5Aclose(aid) < 0) {
H5_FAILED(); AT();
- printf("H5Aread failed\n");
+ printf("H5Aclose failed.\n");
goto error;
}
+ H5free_memory(astr_val);
+ HDfree(astr_val_exp);
+
+ /* Reader sends an OK message back to the reader */
+ if(s->use_named_pipes && s->attr_test == true) {
+ if(np_rd_send(s)==false)
+ goto error2;
+ dbgf(2, "reader: finish sending back the message: %d\n", s->np_notify);
+ }
+
return true;
error:
H5E_BEGIN_TRY {
H5Aclose(aid);
+ H5Tclose(atype);
} H5E_END_TRY;
+ if(astr_val)
+ H5free_memory(astr_val);
+ if(astr_val_exp)
+ HDfree(astr_val_exp);
+ /* The reader sends an error message to the writer to stop the test.*/
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,false);
+
+error2:
+
+ return false;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_del_one_attr
+ *
+ * Purpose: verify if an attribute is successfully deleted.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * const char* aname
+ * The name of the attribute to be deleted.
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is an internal function used by "remove-vlstr",
+ * "compact-del","dense-del",dense-del-to-compact" tests.
+ *-------------------------------------------------------------------------
+*/
+
+
+static bool
+verify_del_one_attr(state_t *s,
+ hid_t g,
+ const char *aname,
+ bool check_storage,
+ bool is_compact) {
+
+
+ htri_t attr_exists = FALSE;
+
+ /* The reader receives a message from the writer.Then sleep
+ * for a few ticks or stop the test if the received message
+ * is an error message.
+ */
+ if(s->use_named_pipes && true == s->attr_test) {
+ if(false == np_rd_receive(s)) {
+ H5_FAILED(); AT();
+ goto error2;
+ }
+ decisleep(s->tick_len * s->update_interval);
+ dbgf(1, "Reader: finish reading the message: %d\n",s->np_notify);
+ }
+
+ /* Check if the deleted attribute still exists. */
+ attr_exists = H5Aexists_by_name(g,".",aname,H5P_DEFAULT);
+ if(attr_exists == FALSE) {
+ dbgf(1,"verify_del_attrs_compact() test: \n");
+ dbgf(1," attribute %s is successfully deleted. \n",aname);
+ }
+ else if(attr_exists == TRUE) {
+ dbgf(1,"verify_del_attrs_compact() test failed \n");
+ goto error;
+ }
+ else{
+ dbgf(1,"H5Aexists_by_name failed \n");
+ goto error;
+ }
+
+ if(!s->old_style_grp && check_storage == true) {
+ if(false == check_attr_storage_type(g,is_compact)) {
+ H5_FAILED(); AT();
+ printf("The attribute storage type is wrong. \n");
+ goto error;
+ }
+ dbgf(2, "reader: finish checking the storage type: %d\n", s->np_notify);
+
+ }
+
+ /* Reader sends an OK message back to the reader */
+ if(s->use_named_pipes && s->attr_test == true) {
+ if(np_rd_send(s)==false)
+ goto error;
+ dbgf(2, "reader: finish sending back the message: %d\n", s->np_notify);
+ }
+
+ return true;
+error:
+ /* The reader sends an error message to the writer to stop the test.*/
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,false);
+
+error2:
+ return false;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_remove_vlstr_attr
+ *
+ * Purpose: Verify if an variable length string attribute is
+ * successfully deleted by the writer.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * Use to derieve the expected attribute value added
+ * by the writer. It is also used to construct
+ * the attribute name.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is for the "remove-vstr" test.
+ * Also note this function first verifies if
+ * a variable length attribute is added then
+ * it verifies if it is deleted successfully.
+ *-------------------------------------------------------------------------
+*/
+
+static bool
+verify_remove_vlstr_attr(state_t* s,hid_t g, unsigned int which)
+{
+ bool ret = false;
+ char attrname[VS_ATTR_NAME_LEN];
+ const char* aname_format = "attr-%u";
+
+ ret = verify_group_vlstr_attr(s,g,which,false);
+ if(ret == true) {
+ HDsprintf(attrname,aname_format,which);
+ ret = verify_del_one_attr(s,g,attrname,false,false);
+ }
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_modify_vlstr_attr
+ *
+ * Purpose: Verify if an variable length string attribute is
+ * successfully modified by the writer.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigned int which
+ * Use to derieve the expected attribute value added
+ * by the writer. It is also used to construct
+ * the attribute name.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is for the "modify-vstr" test.
+ * Also note this function first verifies if
+ * a variable length attribute is added then
+ * it verifies if it is modified successfully.
+ *-------------------------------------------------------------------------
+*/
+
+static bool
+verify_modify_vlstr_attr(state_t *s, hid_t g, unsigned int which){
+
+ bool ret = false;
+
+ ret = verify_group_vlstr_attr(s,g,which,false);
+ if(ret == true)
+ ret = verify_group_vlstr_attr(s,g,which,true);
+ return ret;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_attrs_compact
+ *
+ * Purpose: verify if attributes are successfully added for the compact
+ * storage.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigend max_c
+ * The maximal number of attributes the compact storage
+ * can hold
+ *
+ * unsigned int which
+ * Use to derieve the expected attribute value added
+ * by the writer. It is also used to construct the
+ * attribute names.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used by the "compact" test.
+ *-------------------------------------------------------------------------
+*/
+
+static bool
+verify_attrs_compact(state_t *s, hid_t g, unsigned max_c, unsigned int which) {
+
+ unsigned u;
+ bool ret = true;
+ const char* aname_format = "attr-%u-%u";
+ char attrname[VS_ATTR_NAME_LEN];
+
+ /* Need to verify the added attribute one by one. */
+ for (u = 0; u < max_c; u++) {
+
+ HDsprintf(attrname, aname_format, which,u);
+ if(false == vrfy_attr(s,g,u+which,attrname,which,true,true)) {
+ ret = false;
+ break;
+ }
+
+ }
+ return ret;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_attrs_compact_dense
+ *
+ * Purpose: verify if attributes are successfully added first in the
+ * compact storage then in the dense storage.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigend max_c
+ * The maximal number of attributes the compact storage
+ * can hold
+ *
+ * unsigned int which
+ * Use to derieve the expected attribute value added
+ * by the writer. It is also used to construct
+ * attribute names.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used by the "compact-dense" test.
+ *-------------------------------------------------------------------------
+*/
+
+
+static bool
+verify_attrs_compact_dense(state_t *s, hid_t g, unsigned max_c, unsigned int which) {
+
+ const char* aname_format = "attr-d-%u-%u";
+ char attrname[VS_ATTR_NAME_LEN];
+
+ bool ret = verify_attrs_compact(s,g,max_c,which);
+
+ if(ret == true) {
+
+ /* Now the storage is in dense. Verify if the
+ * retrieved value is correct. */
+ HDsprintf(attrname, aname_format, max_c+which,0);
+ ret = vrfy_attr(s,g,which+max_c,attrname,which,true,false);
+ if(ret == false)
+ dbgf(1,"verify_attrs_compact_dense failed \n");
+
+ }
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_del_attrs_compact
+ *
+ * Purpose: verify if an attribute in compact storage is successfully
+ * deleted.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigend max_c
+ * The maximal number of attributes the compact storage
+ * can hold
+ *
+ * unsigned int which
+ * Use to derieve the expected attribute value added
+ * by the writer. It is also used to construct
+ * attribute names.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used by the "compact-del" test.
+ * Also note this function first verifies if
+ * attributes are successfully added in compact storage then
+ * it verifies if one added attribute is deleted successfully.
+ *-------------------------------------------------------------------------
+*/
+
+static bool
+verify_del_attrs_compact(state_t *s, hid_t g, unsigned max_c, unsigned int which) {
+
+ const char* aname_format = "attr-%u-%u";
+ char attrname[VS_ATTR_NAME_LEN];
+
+ bool ret = verify_attrs_compact(s,g,max_c,which);
+
+ if(ret == true) {
+ /* The writer only deletes the attribute attr-which-0 */
+ HDsprintf(attrname,aname_format,which,0);
+ ret = verify_del_one_attr(s,g,attrname,true,true);
+ }
+
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_del_attrs_compact_dense
+ *
+ * Purpose: verify if an attribute in dense storage is successfully
+ * deleted.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigend max_c
+ * The maximal number of attributes the compact storage
+ * can hold
+ *
+ * unsigned int which
+ * Use to derieve the expected attribute value added
+ * by the writer. It is also used to construct
+ * attribute names.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used by the "dense-del" test.
+ * Also note this function first verifies if
+ * attributes are successfully added in compact storage then
+ * in dense storage. Afterwards,
+ * it verifies if one added attribute is deleted successfully.
+ *-------------------------------------------------------------------------
+*/
+
+
+static bool
+verify_del_attrs_compact_dense(state_t *s,
+ hid_t g,
+ unsigned max_c,
+ unsigned int which) {
+
+ const char* aname_format = "attr-d-%u-%u";
+ char attrname[VS_ATTR_NAME_LEN];
+
+ bool ret = verify_attrs_compact_dense(s,g,max_c,which);
+
+ if(ret == true) {
+ /* The writer only deletes the attribute attr-d-which-0 */
+ HDsprintf(attrname,aname_format,max_c+which,0);
+ ret = verify_del_one_attr(s,g,attrname,true,false);
+ }
+
+ return ret;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_del_attrs_compact_dense_compact
+ *
+ * Purpose: verify that the attributes are deleted successfully
+ * even the attribute storage changes from dense to
+ * compact.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * and some VFD SWMR configuration parameters
+ *
+ * hid_t g
+ * HDF5 object ID (in this file: means group ID)
+ *
+ * unsigend max_c
+ * The maximal number of attributes the compact storage
+ * can hold
+ *
+ * unsigend min_d
+ * The minimal number of attributes to be stored in
+ * dense storage
+ *
+ * unsigned int which
+ * Use to derieve the expected attribute value added
+ * by the writer. It is also used to construct
+ * attribute names.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This function is used by the "dense-del-to-compact" test.
+ * Also note this function first verifies if
+ * attributes are successfully added in compact storage then
+ * in dense storage. Afterwards,
+ * it verifies if some added attributes are deleted successfully
+ * until the storage changes from dense to compact.
+ *-------------------------------------------------------------------------
+*/
+
+
+static bool
+verify_del_attrs_compact_dense_compact(state_t *s,
+ hid_t g,
+ unsigned max_c,
+ unsigned min_d,
+ unsigned int which) {
+
+ unsigned u;
+ const char* aname_format = "attr-%u-%u";
+ char attrname[VS_ATTR_NAME_LEN];
+
+ /* Verify the attributes are added correctly from
+ * compact to dense storage*/
+ bool ret = verify_attrs_compact_dense(s,g,max_c,which);
+
+ if(ret == true) {
+
+ /* Then verify the deletion of attributes
+ * from dense to compact.
+ */
+ u = max_c + 1;
+ for(u--;u>=(min_d-1);u--) {
+ HDsprintf(attrname, aname_format, which,max_c-u);
+ if(u==(min_d-1))
+ ret = verify_del_one_attr(s,g,attrname,true,true);
+ else
+ ret = verify_del_one_attr(s,g,attrname,true,false);
+ }
+
+ /* Just verify one more deleted attribute by the writer.
+ The storage is still compact. */
+ HDsprintf(attrname,aname_format,max_c+which,0);
+ ret = verify_del_one_attr(s,g,attrname,true,true);
+ }
+
+ return ret;
+
+}
+
+/*-------------------------------------------------------------------------
+ * Function: verify_group_attribute
+ *
+ * Purpose: Check the attribute test pattern and then call the
+ * correponding verification function.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * 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
+ * group and attribute names.
+ *
+ *
+ * Return: Success: true
+ * Failure: false
+ *
+ * Note: This is called by the verify_group() function.
+ *-------------------------------------------------------------------------
+*/
+
+
+static bool
+verify_group_attribute(state_t *s, hid_t g, unsigned int which)
+{
+ char test_pattern = s->at_pattern;
+ bool ret = false;
+ unsigned max_compact = 0;
+ unsigned min_dense = 0;
+ hid_t gcpl = H5I_INVALID_HID;
+
+ /* For tests "compact","compact-to-dense","compact-del",
+ * "dense-del", "dense-del-to-compact",
+ * the maximal number of attributes for the compact storage
+ * and the minimal number of attributes for the dense storage
+ * are needed. So obtain them here
+ * When testing the old-style group creation case, only max_compact
+ * matters. To reduce the testing time, we set max_compact to 2.*/
+ switch (test_pattern) {
+ case 'c':
+ case 't':
+ case 'C':
+ case 'D':
+ case 'T':
+ if(s->old_style_grp)
+ max_compact = 2;
+ else {
+ if((gcpl = H5Gget_create_plist(g)) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Gget_create_plist failed\n");
+ goto error;
+ }
+ if (H5Pget_attr_phase_change(gcpl,&max_compact,&min_dense) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Pget_attr_phase_change failed\n");
+ goto error;
+ }
+ if(H5Pclose(gcpl) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Pclose failed\n");
+ goto error;
+ }
+ }
+ break;
+ case 'v':
+ case 'd':
+ case 'M':
+ case 'm':
+ case 'r':
+ case ' ':
+ default:
+ break;
+ }
+
+ /* Distribute the verification test. */
+ switch (test_pattern) {
+ case 'c':
+ ret = verify_attrs_compact(s, g, max_compact, which);
+ break;
+ case 't':
+ ret = verify_attrs_compact_dense(s, g, max_compact, which);
+ break;
+ case 'C':
+ ret = verify_del_attrs_compact(s, g, max_compact, which);
+ break;
+ case 'D':
+ ret = verify_del_attrs_compact_dense(s, g, max_compact, which);
+ break;
+ case 'T':
+ ret = verify_del_attrs_compact_dense_compact(s, g, max_compact, min_dense, which);
+ break;
+ case 'M':
+ ret = verify_modify_attr(s, g, which);
+ break;
+ case 'v':
+ ret = verify_group_vlstr_attr(s,g, which,false);
+ break;
+ case 'r':
+ ret = verify_remove_vlstr_attr(s,g, which);
+ break;
+ case 'm':
+ ret = verify_modify_vlstr_attr(s,g, which);
+ break;
+ case 'd':
+ case ' ':
+ default:
+ ret = verify_default_group_attr(s, g, which);
+ break;
+ }
+
+ return ret;
+
+error:
+ /* Still to finish the handshaking */
+ if(s->use_named_pipes && s->attr_test == true) {
+ np_rd_receive(s);
+ np_send_error(s,false);
+ }
return false;
}
+/*-------------------------------------------------------------------------
+ * Function: verify_group
+ *
+ * Purpose: verify the success of group creation and
+ * carry out the test for attribute operations(add,delete etc.)
+ * according to the attribute test pattern.
+ *
+ * Parameters: state_t *s
+ * The struct that stores information of HDF5 file, named pipe
+ * 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
verify_group(state_t *s, unsigned int which)
{
char name[sizeof("/group-9999999999")];
hid_t g = H5I_INVALID_HID;
bool result = true;
+ H5G_info_t group_info;
+
+ /* The reader receives a message from the writer.Then sleep
+ * for a few ticks or stop the test if the received message
+ * is an error message.
+ */
+ if(s->use_named_pipes && true == s->attr_test) {
+
+ if(false == np_rd_receive(s)) {
+ H5_FAILED(); AT();
+ goto error2;
+ }
+ decisleep(s->tick_len * s->update_interval);
+ dbgf(1, "reader: finish reading the message: %d\n",s->np_notify);
+
+ }
if (which >= s->nsteps) {
H5_FAILED(); AT();
- printf("Group order is out of bounds\n");
+ printf("Number of created groups is out of bounds\n");
goto error;
}
esnprintf(name, sizeof(name), "/group-%d", which);
- if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) {
+
+ if((g = H5Gopen(s->file, name, H5P_DEFAULT)) <0) {
H5_FAILED(); AT();
printf("H5Gopen failed\n");
goto error;
}
+ if(H5Gget_info(g,&group_info) <0) {
+ H5_FAILED(); AT();
+ printf("H5Gget_info failed\n");
+ goto error;
+ }
+
+ dbgf(2,"Storage info is %d\n",group_info.storage_type);
+ if(s->old_style_grp) {
+ if(group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ H5_FAILED(); AT();
+ printf("Reader - Old-styled group: but the group is not in old-style. \n");
+ goto error;
+ }
+ dbgf(2,"Reader: verify that the group is created with the old-style.\n");
+ }
+ else {
+ if(group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) {
+ H5_FAILED(); AT();
+ printf("Reader - The created group should NOT be in old-style . \n");
+ goto error;
+ }
+ dbgf(2,"Reader: verify that the group is created with the new-style.\n");
+
+ }
+
+ /* Reader sends an OK message back to the reader */
+ if(s->use_named_pipes && s->attr_test == true) {
+
+ if(np_rd_send(s)==false)
+ goto error;
+ dbgf(1, "Reader: finish sending back the message: %d\n",s->np_notify);
+
+ }
+
+ /* Check if we need to skip the attribute test for this group. */
if (s->asteps != 0 && which % s->asteps == 0)
- result = verify_group_attribute(g, which);
+ result = verify_group_attribute(s, g, which);
else
result = true;
@@ -334,11 +2899,19 @@ verify_group(state_t *s, unsigned int which)
return result;
error:
+
H5E_BEGIN_TRY {
H5Gclose(g);
} H5E_END_TRY;
+ /* The reader sends an error message to the writer to stop the test.*/
+ if(s->use_named_pipes && s->attr_test == true)
+ np_send_error(s,false);
+
+error2:
+
return false;
+
}
int
@@ -354,7 +2927,8 @@ main(int argc, char **argv)
const char *fifo_reader_to_writer = "./fifo_group_reader_to_writer";
int fd_writer_to_reader = -1, fd_reader_to_writer = -1;
int notify = 0, verify = 0;
- unsigned int i;
+ bool wg_ret = false;
+ bool vg_ret = false;
if (!state_init(&s, argc, argv)) {
H5_FAILED(); AT();
@@ -362,11 +2936,13 @@ main(int argc, char **argv)
goto error;
}
- personality = strstr(s.progname, "vfd_swmr_group_");
+ personality = HDstrstr(s.progname, "vfd_swmr_group_");
- if (personality != NULL && strcmp(personality, "vfd_swmr_group_writer") == 0)
+ if (personality != NULL &&
+ HDstrcmp(personality, "vfd_swmr_group_writer") == 0)
writer = true;
- else if (personality != NULL && strcmp(personality, "vfd_swmr_group_reader") == 0)
+ else if (personality != NULL &&
+ HDstrcmp(personality, "vfd_swmr_group_reader") == 0)
writer = false;
else {
H5_FAILED(); AT();
@@ -377,8 +2953,12 @@ 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");
- /* use_latest_format, use_vfd_swmr, only_meta_page, config */
- if ((fapl = vfd_swmr_create_fapl(true, s.use_vfd_swmr, true, &config)) < 0) {
+ /* 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, config to vfd_swmr_create_fapl().*/
+ if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, &config)) < 0) {
H5_FAILED(); AT();
printf("vfd_swmr_create_fapl failed\n");
goto error;
@@ -440,123 +3020,94 @@ main(int argc, char **argv)
goto error;
}
+ /* Pass the named pipe information to the struct of state_t s, for attribute tests.*/
+ if(s.use_named_pipes) {
+ s.np_fd_w_to_r = fd_writer_to_reader;
+ s.np_fd_r_to_w = fd_reader_to_writer;
+ s.np_notify = notify;
+ s.np_verify = verify;
+ s.tick_len = config.tick_len;
+ s.max_lag = config.max_lag;
+ }
+
+ /* For attribute test, force the named pipe to communicate in every step.
+ * This will avoid the fake verification error from the reader when using the named pipe.
+ * If the named pipe is not forced to communicate in every step, the reader may go ahead
+ * to verify the group and the attribute operations before the writer has a chance to
+ * carry out the corresponding operations. */
+ if (s.at_pattern != ' ') {
+ s.attr_test = true;
+ if(s.use_named_pipes)
+ s.csteps = 1;
+ }
+
if (writer) {
for (step = 0; step < s.nsteps; step++) {
dbgf(2, "writer: step %d\n", step);
- if (!write_group(&s, step)) {
+ wg_ret = write_group(&s, step);
+
+ if(wg_ret == false) {
H5_FAILED(); AT();
- printf("write_group failed\n");
+ printf("write_group failed at step %d\n",step);
/* At communication interval, notifies the reader about the failture and quit */
- if (s.use_named_pipes && (step % s.csteps == 0)) {
- notify = -1;
- HDwrite(fd_writer_to_reader, &notify, sizeof(int));
- }
-
+ if (s.use_named_pipes && s.attr_test !=true && step % s.csteps == 0)
+ np_send_error(&s,true);
goto error;
- } else {
- /* At communication interval, notifies the reader and waits for its response */
- if (s.use_named_pipes && (step % s.csteps == 0)) {
- /* Bump up the value of notify to notice the reader to start to read */
- notify++;
- if (HDwrite(fd_writer_to_reader, &notify, sizeof(int)) < 0) {
- H5_FAILED(); AT();
- printf("HDwrite failed\n");
- goto error;
- }
-
- /* During the wait, writer makes repeated HDF5 API calls
- * to trigger EOT at approximately the correct time */
- for(i = 0; i < config.max_lag + 1; i++) {
- decisleep(config.tick_len);
- H5E_BEGIN_TRY {
- H5Aexists(s.file, "nonexistent");
- } H5E_END_TRY;
- }
-
- /* Receive the same value from the reader and verify it before
- * going to the next step */
- verify++;
- if (HDread(fd_reader_to_writer, &notify, sizeof(int)) < 0) {
- H5_FAILED(); AT();
- printf("HDread failed\n");
- goto error;
- }
+ }
+ else {
- if (notify == -1) {
- H5_FAILED(); AT();
- printf("reader failed to verify group\n");
- goto error;
- }
+ /* At communication interval, notifies the reader and waits for its response */
+ if (s.use_named_pipes && s.attr_test != true && step % s.csteps == 0) {
- if (notify != verify) {
+ if(np_wr_send_receive(&s) == false) {
H5_FAILED(); AT();
- printf("received message %d, expecting %d\n", notify, verify);
+ dbgf(2, "writer: write group - verification failed.\n");
goto error;
}
}
}
}
- }
- else {
- for (step = 0; step < s.nsteps; step++) {
- dbgf(2, "reader: step %d\n", step);
-
- /* At communication interval, waits for the writer to finish creation before starting verification
- */
- if (s.use_named_pipes && (step % s.csteps == 0)) {
- /* The writer should have bumped up the value of notify.
- * Do the same with verify and confirm it */
- verify++;
-
- /* Receive the notify that the writer bumped up the value */
- if (HDread(fd_writer_to_reader, &notify, sizeof(int)) < 0) {
- H5_FAILED(); AT();
- printf("HDread failed\n");
- goto error;
- }
-
- if (notify == -1) {
- H5_FAILED(); AT();
- printf("writer failed to create group\n");
- goto error;
- }
+ } else {
+ for (step = 0; step < s.nsteps;step++) {
+ dbgf(1, "reader: step %d\n", step);
- if (notify != verify) {
+ /* At communication interval, waits for the writer to finish creation before starting verification */
+ if (s.use_named_pipes && s.attr_test != true && step % s.csteps == 0) {
+ if(false == np_rd_receive(&s)) {
H5_FAILED(); AT();
- printf("received message %d, expecting %d\n", notify, verify);
goto error;
}
}
- /* Wait for a few ticks for the update to happen */
- if (s.use_named_pipes)
+ /* For the default test, wait for a few ticks for the update to happen */
+ if(s.use_named_pipes && s.attr_test== false)
decisleep(config.tick_len * s.update_interval);
- /* Start to verify group */
- if (!verify_group(&s, step)) {
- H5_FAILED(); AT();
+ vg_ret = verify_group(&s, step);
+
+ if (vg_ret == false) {
+
printf("verify_group failed\n");
+ H5_FAILED(); AT();
/* At communication interval, tell the writer about the failure and exit */
- if (s.use_named_pipes && (step % s.csteps == 0)) {
- notify = -1;
- HDwrite(fd_reader_to_writer, &notify, sizeof(int));
- }
-
+ if (s.use_named_pipes && s.attr_test != true && step % s.csteps == 0)
+ np_send_error(&s,false);
goto error;
- } else {
- if (s.use_named_pipes && (step % s.csteps == 0)) {
- /* Send back the same nofity value for acknowledgement to tell the writer
- * move to the next step */
- if (HDwrite(fd_reader_to_writer, &notify, sizeof(int)) < 0) {
- H5_FAILED(); AT();
- printf("HDwrite failed\n");
+
+ }
+ else {
+
+ /* Send back the same nofity value for acknowledgement to tell the writer
+ * move to the next step. */
+ if (s.use_named_pipes && s.attr_test!=true && step % s.csteps == 0) {
+ if(np_rd_send(&s)==false)
goto error;
- }
}
}
+
}
}
@@ -572,6 +3123,12 @@ main(int argc, char **argv)
goto error;
}
+ if (H5Sclose(s.one_by_one_sid) < 0) {
+ H5_FAILED(); AT();
+ printf("H5Sclose failed\n");
+ goto error;
+ }
+
if (H5Fclose(s.file) < 0) {
H5_FAILED(); AT();
printf("H5Fclose failed\n");
@@ -612,6 +3169,7 @@ error:
H5E_BEGIN_TRY {
H5Pclose(fapl);
H5Pclose(fcpl);
+ H5Sclose(s.one_by_one_sid);
H5Fclose(s.file);
} H5E_END_TRY;
@@ -627,6 +3185,7 @@ error:
}
return EXIT_FAILURE;
+
}
#else /* H5_HAVE_WIN32_API */