From 83de84f88d1ac0f7960031c816857a62e0c6cee9 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Tue, 29 Jun 2021 10:42:11 -0500 Subject: Add the Makefile.am for the performance. --- test/Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/Makefile.am b/test/Makefile.am index 2d76946..dcd1264 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -54,6 +54,7 @@ SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) links_env$(EXEEXT) \ vfd_swmr_group_reader$(EXEEXT) vfd_swmr_group_writer$(EXEEXT) \ vfd_swmr_vlstr_reader$(EXEEXT) vfd_swmr_vlstr_writer$(EXEEXT) \ vfd_swmr_zoo_reader$(EXEEXT) vfd_swmr_zoo_writer$(EXEEXT) \ + vfd_swmr_gperf_reader$(EXEEXT) vfd_swmr_gperf_writer$(EXEEXT) \ vds_env$(EXEEXT) \ vds_swmr_gen$(EXEEXT) vds_swmr_reader$(EXEEXT) vds_swmr_writer$(EXEEXT) if HAVE_SHARED_CONDITIONAL @@ -111,6 +112,7 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version \ vfd_swmr_vlstr_reader vfd_swmr_vlstr_writer \ vfd_swmr_zoo_reader vfd_swmr_zoo_writer \ vfd_swmr_attrdset_reader vfd_swmr_attrdset_writer \ + vfd_swmr_gperf_reader vfd_swmr_gperf_writer \ vfd_swmr_check_compat \ swmr_check_compat_vfd vds_env vds_swmr_gen vds_swmr_reader vds_swmr_writer \ mirror_vfd @@ -177,6 +179,7 @@ vfd_swmr_zoo_reader_SOURCES=vfd_swmr_zoo_writer.c genall5.c vfd_swmr_bigset_reader_SOURCES=vfd_swmr_bigset_writer.c vfd_swmr_group_reader_SOURCES=vfd_swmr_group_writer.c +vfd_swmr_gperf_reader_SOURCES=vfd_swmr_gperf_writer.c vfd_swmr_dsetops_reader_SOURCES=vfd_swmr_dsetops_writer.c vfd_swmr_attrdset_writer_SOURCES=vfd_swmr_attrdset_writer.c -- cgit v0.12 From b4cd03bd54f5eb09072f2e6d92948610778b4604 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Tue, 29 Jun 2021 11:54:28 -0500 Subject: Add the first version of group performance code. --- test/vfd_swmr_gperf_writer.c | 5261 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5261 insertions(+) create mode 100644 test/vfd_swmr_gperf_writer.c diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c new file mode 100644 index 0000000..9996798 --- /dev/null +++ b/test/vfd_swmr_gperf_writer.c @@ -0,0 +1,5261 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define H5F_FRIEND /*suppress error about including H5Fpkg */ + +#include "hdf5.h" + +#include "H5Fpkg.h" +#include "H5HGprivate.h" +#include "H5VLprivate.h" + +#include "testhdf5.h" +#include "vfd_swmr_common.h" + +#ifndef H5_HAVE_WIN32_API + +#define READER_WAIT_TICKS 3 +#define VS_ATTR_NAME_LEN 21 + +#define TIME_PASSED(X,Y) \ + ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 + +typedef struct { + hid_t file, filetype, one_by_one_sid; + char filename[PATH_MAX]; + char progname[PATH_MAX]; + unsigned int asteps; + unsigned int csteps; + unsigned int nsteps; + unsigned int update_interval; + bool use_vfd_swmr; + bool old_style_grp; + bool use_named_pipes; + char grp_op_pattern; + bool grp_op_test; + 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; + bool gperf; + double min_time; + double max_time; + double mean_time; + double total_time; + unsigned int num_attrs; +} state_t; + +#define ALL_HID_INITIALIZER \ + (state_t) \ + { \ + .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ + .filetype = H5T_NATIVE_UINT32, .asteps = 10, .csteps = 10, .nsteps = 100, \ + .update_interval = READER_WAIT_TICKS, .use_vfd_swmr = true, .old_style_grp = false, \ + .use_named_pipes = true, .grp_op_pattern = ' ', .grp_op_test = false, .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, .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ + .total_time = 0.,.num_attrs = 1 \ + } + +static void +usage(const char *progname) +{ + fprintf(stderr, + "usage: %s [-S] [-G] [-a steps] [-b] [-c] [-n iterations]\n" + " [-N] [-q] [-u numb_ticks] [-A at_pattern] [-O grp_op_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" + " `add-ohr-block` - An attribute is added and this forces\n" + " the creation of object header\n" + " continuation block \n" + " `del-ohr-block` - An attribute is added and this forces\n" + " the creation of object header\n" + " continuation block and then this \n" + " attribute is deleted so the \n" + " object header continuation block is \n" + " removed. \n" + "-O grp_op_pattern: `grp_op_pattern' for different group operation tests\n" + " The value of `grp_op_pattern` is one of the following:\n" + " `grp-creation` - A group is created.\n" + " `grp-deletion` - An existing group is deleted.\n" + " `grp-move` - A group is moved to become \n" + " another group. \n" + " `grp-ins-links` - Links are inserted, including\n" + " both hard and soft links. \n" + " `grp-del-links` - Links are deleted, including\n" + " both hard ans soft links. \n" + " `grp-compact-t-dense` - Links are inserted to the group.\n" + " The link storage of this group \n" + " changed from compact to dense. \n" + " The links include both hard and\n" + " soft links. \n" + " `grp-dense-t-compact` - Links are inserted to the group\n" + " The link storage of this group \n" + " changed from compact to dense. \n" + " Then several links are deleted.\n" + " The link storage changed from \n" + " dense to compact again. \n" + " The links include both hard and\n" + " soft links. \n" + "-q: silence printouts, few messages\n" + "\n", + progname); + exit(EXIT_FAILURE); +} + +static bool +state_init(state_t *s, int argc, char **argv) +{ + unsigned long tmp; + int ch; + const hsize_t dims = 1; + char * tfile = NULL; + char * end; + + *s = ALL_HID_INITIALIZER; + + if (H5_basename(argv[0], &tfile) < 0) { + printf("H5_basename failed\n"); + TEST_ERROR; + } + + esnprintf(s->progname, sizeof(s->progname), "%s", tfile); + + if (tfile) + HDfree(tfile); + + while ((ch = getopt(argc, argv, "PSGa:bc:n:Nqu:A:O:")) != -1) { + switch (ch) { + case 'P': + s->gperf = true; + break; + case 'S': + s->use_vfd_swmr = false; + break; + case 'G': + s->old_style_grp = true; + break; + case 'a': + case 'c': + case 'n': + case 'u': + errno = 0; + tmp = HDstrtoul(optarg, &end, 0); + if (end == optarg || *end != '\0') { + printf("couldn't parse `-%c` argument `%s`\n", ch, optarg); + TEST_ERROR; + } + else if (errno != 0) { + printf("couldn't parse `-%c` argument `%s`\n", ch, optarg); + TEST_ERROR; + } + else if (tmp > UINT_MAX) { + printf("`-%c` argument `%lu` too large\n", ch, tmp); + TEST_ERROR; + } + + if (ch == 'a') + s->asteps = (unsigned)tmp; + else if (ch == 'c') + s->csteps = (unsigned)tmp; + else if (ch == 'n') + s->nsteps = (unsigned)tmp; + else if (ch == 'u') + s->update_interval = (unsigned)tmp; + break; + case 'b': + s->filetype = H5T_STD_U32BE; + break; + case 'N': + s->use_named_pipes = false; + break; + case 'O': + if (HDstrcmp(optarg, "grp-creation") == 0) + s->grp_op_pattern = 'c'; + else if (HDstrcmp(optarg, "grp-deletion") == 0) + s->grp_op_pattern = 'd'; + else if (HDstrcmp(optarg, "grp-move") == 0) + s->grp_op_pattern = 'm'; + else if (HDstrcmp(optarg, "grp-ins-links") == 0) + s->grp_op_pattern = 'i'; + else if (HDstrcmp(optarg, "grp-del-links") == 0) + s->grp_op_pattern = 'D'; + else if (HDstrcmp(optarg, "grp-compact-t-dense") == 0) + s->grp_op_pattern = 't'; + else if (HDstrcmp(optarg, "grp-dense-t-compact") == 0) + s->grp_op_pattern = 'T'; + else { + printf("Invalid -O argument \"%s\"", optarg); + TEST_ERROR; + } + break; + case 'A': + if (HDstrcmp(optarg, "compact") == 0) + s->at_pattern = 'c'; + else if (HDstrcmp(optarg, "dense") == 0) + s->at_pattern = 'd'; + else if (HDstrcmp(optarg, "compact-add-to-dense") == 0) + s->at_pattern = 't'; + else if (HDstrcmp(optarg, "compact-del") == 0) + s->at_pattern = 'C'; + else if (HDstrcmp(optarg, "dense-del") == 0) + s->at_pattern = 'D'; + else if (HDstrcmp(optarg, "dense-del-to-compact") == 0) + s->at_pattern = 'T'; + else if (HDstrcmp(optarg, "modify") == 0) + s->at_pattern = 'M'; + else if (HDstrcmp(optarg, "add-vstr") == 0) + s->at_pattern = 'v'; + else if (HDstrcmp(optarg, "remove-vstr") == 0) + s->at_pattern = 'r'; + else if (HDstrcmp(optarg, "modify-vstr") == 0) + s->at_pattern = 'm'; + else if (HDstrcmp(optarg, "add-ohr-block") == 0) + s->at_pattern = 'a'; + else if (HDstrcmp(optarg, "del-ohr-block") == 0) + s->at_pattern = 'R'; + else { + printf("Invalid -A argument \"%s\"", optarg); + TEST_ERROR; + } + break; + case 'q': + verbosity = 0; + break; + case '?': + default: + usage(s->progname); + break; + } + } + argc -= optind; + argv += optind; + + if (s->grp_op_pattern != ' ') + s->grp_op_test = true; + if (s->at_pattern != ' ') + s->attr_test = true; + + if (!s->grp_op_test) { + if (s->asteps < 1 || s->asteps > s->nsteps) { + printf("attribute interval is out of bounds\n"); + TEST_ERROR; + } + } + + if (s->grp_op_test && s->attr_test) { + printf("Cannot test both group operation and attribute tests!\n"); + printf("Attribute tests are ignored.\n"); + } + + if (s->csteps < 1 || s->csteps > s->nsteps) { + printf("communication interval is out of bounds\n"); + TEST_ERROR; + } + + if (argc > 0) { + printf("unexpected command-line arguments\n"); + TEST_ERROR; + } + + /* space for attributes */ + if ((s->one_by_one_sid = H5Screate_simple(1, &dims, &dims)) < 0) { + printf("H5Screate_simple failed\n"); + TEST_ERROR; + } + + esnprintf(s->filename, sizeof(s->filename), "vfd_swmr_group.h5"); + + return true; + +error: + if (tfile) + HDfree(tfile); + return false; +} + +/* 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) { + printf("HDwrite failed\n"); + TEST_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) { + printf("HDread failed\n"); + TEST_ERROR; + } + + if (s->np_notify == -1) { + printf("reader failed to verify group or attribute operation.\n"); + TEST_ERROR; + } + + if (s->np_notify != s->np_verify) { + printf("received message %d, expecting %d\n", s->np_notify, s->np_verify); + TEST_ERROR; + } + + return true; + +error: + return false; +} + +/* 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) { + printf("HDread failed\n"); + TEST_ERROR; + } + + if (s->np_notify == -1) { + printf("writer failed to create group or carry out an attribute operation.\n"); + TEST_ERROR; + } + + if (s->np_notify != s->np_verify) { + printf("received message %d, expecting %d\n", s->np_notify, s->np_verify); + TEST_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: check_ohr_num_chunk + * + * Purpose: Check if the number of object header chunks is as expected. + * + * Parameters: hid_t oid + * HDF5 object ID (in this file: means group ID) + * + * bool one_chunk_ohr + * flag to indicate if the object header chunk is 1 or greater + * 1: true + * greater than 1: false + * + * Return: Success: true + * Failure: false + * + *------------------------------------------------------------------------- + */ + +static bool +check_ohr_num_chunk(hid_t g, bool one_chunk_ohr) +{ + + H5O_native_info_t ninfo; + + /* Get the object information */ + if (H5Oget_native_info(g, &ninfo, H5O_NATIVE_INFO_HDR) < 0) { + printf("H5Oget_native_info failed\n"); + TEST_ERROR; + } + + if (true == one_chunk_ohr) { + if (ninfo.hdr.nchunks != 1) { + printf("Object header should have only one chunk,but it is not.\n"); + TEST_ERROR; + } + } + else { + if (ninfo.hdr.nchunks <= 1) { + printf("Object header should have more than one chunk,but it is not.\n"); + TEST_ERROR; + } + } + + return true; + +error: + return false; +} + +/*------------------------------------------------------------------------- + * Function: add_attr + * + * Purpose: Add attributes to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, 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) { + printf("H5Tget_native_type failed\n"); + TEST_ERROR; + } + + for (u = 0; u < num_attrs; u++) { + + /* Create attribute */ + /* Construct attribute name like attr-0-0 */ + HDsprintf(attrname, aname_fmt, which, u); + if ((aid = H5Acreate2(oid, attrname, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Acreate2 failed\n"); + TEST_ERROR; + } + + attr_value = u + which; + + dbgf(1, "setting attribute %s on group %u to %u\n", attrname, g_which, u + which); + + /* Write data into the attribute */ + if (H5Awrite(aid, amtype, &attr_value) < 0) { + printf("H5Awrite failed\n"); + TEST_ERROR; + } + + /* Close attribute */ + if (H5Aclose(aid) < 0) { + printf("H5Aclose failed\n"); + TEST_ERROR; + } + + /* If coming to an "object header continuation block" test, + * we need to check if this test behaves as expected. */ + if (s->at_pattern == 'a' || s->at_pattern == 'R') { + if (false == check_ohr_num_chunk(oid, false)) { + printf("An object header continuation block should be created. \n"); + printf("But it is not.\n"); + TEST_ERROR; + } + } + + /* 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) { + TEST_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, "add-ohr-block" + * and "del-ohr-block" tests. + *------------------------------------------------------------------------- + */ + +static bool +add_default_group_attr(state_t *s, hid_t g, unsigned int which) +{ + + const char *aname_format = "attr-%u"; + + /* 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) { + printf("Allocate memory for VL string failed.\n"); + TEST_ERROR; + } + + /* Assign the VL string value and the attribute name.. */ + HDsprintf(astr_val, "%u", which); + esnprintf(name, sizeof(name), "attr-%u", which); + + dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which); + + /* Create a datatype to refer to. */ + if ((atype = H5Tcopy(H5T_C_S1)) < 0) { + printf("Cannot create variable length datatype.\n"); + TEST_ERROR; + } + + if (H5Tset_size(atype, H5T_VARIABLE) < 0) { + printf("Cannot set variable length datatype.\n"); + TEST_ERROR; + } + + /* Generate the VL string attribute.*/ + if ((aid = H5Acreate2(g, name, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Acreate2 failed.\n"); + TEST_ERROR; + } + + if (H5Awrite(aid, atype, &astr_val) < 0) { + printf("H5Awrite failed.\n"); + TEST_ERROR; + } + + if (H5Tclose(atype) < 0) { + printf("H5Tclose() failed\n"); + TEST_ERROR; + } + if (H5Aclose(aid) < 0) { + printf("H5Aclose() failed\n"); + TEST_ERROR; + } + + HDfree(astr_val); + + /* 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_or_ohrc + * if the deleted attribute is a VL string or for object header + * continuation check test + * + * unsigned int which + * The number of iterations for group creation, use to generate + * newly created group and attribute names. + * The group name is "group-which" and the attribute names + * according to if this attribute is a VL string or for checking + * the dense storage or the storage transition from dense to + * compact. + * + * + * Return: Success: true + * Failure: false + * + *------------------------------------------------------------------------- + */ + +static bool +del_one_attr(state_t *s, hid_t obj_id, bool is_dense, bool is_vl_or_ohrc, unsigned int which) +{ + + char attrname[VS_ATTR_NAME_LEN]; + + /*attribute name template for the dense storage related deletion operation */ + const char *aname_format_d = "attr-d-%u-%u"; + + /*attribute name template used for general attribute deletion operation */ + const char *aname_format = "attr-%u-%u"; + + /*attribute name template used for VL string attribute deletion + * or object header continuation check operations */ + const char *aname_format_vl = "attr-%u"; + + dbgf(2, "writer: coming to delete the attribute.\n"); + + /* Construct the attribute name */ + if (is_dense == true) + HDsprintf(attrname, aname_format_d, which, 0); + else if (is_vl_or_ohrc == true) + HDsprintf(attrname, aname_format_vl, which, 0); + else + HDsprintf(attrname, aname_format, which, 0); + + /* Delete the attribute */ + if (H5Adelete(obj_id, attrname) < 0) { + printf("H5Adelete() failed\n"); + TEST_ERROR; + } + + /* If coming to an "object header continuation block" test, + * we need to check if this test behaves as expected. */ + if (s->at_pattern == 'R') { + if (false == check_ohr_num_chunk(obj_id, true)) { + printf("The object header chunk should not continue. \n"); + TEST_ERROR; + } + } + /* 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) { + printf("H5Aopen failed\n"); + TEST_ERROR; + } + + if ((amtype = H5Tget_native_type(s->filetype, H5T_DIR_ASCEND)) < 0) { + printf("H5Tget_native_type failed\n"); + TEST_ERROR; + } + + /* Make a large number to verify the change easily */ + modify_value = which + 10000; + + if (H5Awrite(aid, amtype, &modify_value) < 0) { + printf("H5Awrite failed\n"); + TEST_ERROR; + } + if (H5Tclose(amtype) < 0) { + printf("H5Tclose failed\n"); + TEST_ERROR; + } + if (H5Aclose(aid) < 0) { + printf("H5Aclose failed\n"); + TEST_ERROR; + } + + /* 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) { + printf("Allocate memory for VL string failed.\n"); + TEST_ERROR; + } + + /* Change the VL string value and create the attribute name. */ + HDsprintf(astr_val, "%u%c", which, 'A'); + esnprintf(name, sizeof(name), "attr-%u", which); + + dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which); + + /* Create a datatype to refer to. */ + if ((atype = H5Tcopy(H5T_C_S1)) < 0) { + printf("Cannot create variable length datatype.\n"); + TEST_ERROR; + } + + if (H5Tset_size(atype, H5T_VARIABLE) < 0) { + printf("Cannot set variable length datatype.\n"); + TEST_ERROR; + } + + /* Open this attribute. */ + if ((aid = H5Aopen(g, name, H5P_DEFAULT)) < 0) { + printf("H5Aopen failed.\n"); + TEST_ERROR; + } + + dbgf(1, "The modified VL string value is %s \n", astr_val); + + if (H5Awrite(aid, atype, &astr_val) < 0) { + printf("H5Awrite failed.\n"); + TEST_ERROR; + } + + if (H5Tclose(atype) < 0) { + printf("H5Tclose() failed\n"); + TEST_ERROR; + } + + if (H5Aclose(aid) < 0) { + printf("H5Aclose() failed\n"); + TEST_ERROR; + } + + HDfree(astr_val); + + /* 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) { + printf("H5Pget_attr_phase_change() failed\n"); + TEST_ERROR; + } + } + + /* Add max_compact attributes, these attributes are stored in + * compact storage. */ + return add_attr(s, g, which, max_compact, aname_format, which); + +error: + 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) { + printf("H5Pget_attr_phase_change failed\n"); + TEST_ERROR; + } + + /* Add attributes, until just before converting to dense storage */ + ret_value = add_attrs_compact(s, g, gcpl, which); + + /* Add another attribute, the storage becomes dense. */ + if (ret_value == true) + ret_value = add_attr(s, g, which + max_compact, 1, aname_format, which); + + return ret_value; + +error: + 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) { + printf("H5Pget_attr_phase_change failed\n"); + TEST_ERROR; + } + u = max_compact + 1; + + /* delete a number of attributes so that the attribute storage just becomes dense.*/ + for (u--; u >= (min_dense - 1); u--) { + HDsprintf(attrname, aname_format, which, max_compact - u); + if (H5Adelete(obj_id, attrname) < 0) { + printf("H5Adelete failed\n"); + TEST_ERROR; + } + + /* 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) { + printf("H5Adelete failed\n"); + TEST_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) { + printf("H5Pget_attr_phase_change failed\n"); + TEST_ERROR; + } + + ret_value = add_attrs_compact_dense(s, g, gcpl, which); + if (ret_value == true) + ret_value = del_one_attr(s, g, true, false, which + max_compact); + + return ret_value; + +error: + 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" test. + *------------------------------------------------------------------------- + */ + +static bool +add_modify_default_group_attr(state_t *s, hid_t g, unsigned int which) +{ + + bool ret_value = false; + const char *aname_format = "attr-%u"; + ret_value = add_default_group_attr(s, g, which); + if (ret_value == true) + ret_value = modify_attr(s, g, aname_format, which); + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: del_ohr_block_attr + * + * Purpose: Add an attribute to force creation of object header + * continuation block and remove this attribute to delete + * the object header continuation block + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, 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 + * "deletion of object header continuation block" test. + *------------------------------------------------------------------------- + */ + +static bool +del_ohr_block_attr(state_t *s, hid_t g, unsigned int which) +{ + + bool ret_value = false; + ret_value = add_default_group_attr(s, g, which); + if (ret_value == true) + ret_value = del_one_attr(s, g, false, true, which); + return ret_value; +} +/*------------------------------------------------------------------------- + * Function: add_group_attribute + * + * Purpose: Check the attribute test pattern and then call the + * correponding test function.. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, 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 'R': + ret_value = del_ohr_block_attr(s, g, which); + break; + case 'a': + case 'd': + case ' ': + default: + ret_value = add_default_group_attr(s, g, which); + break; + } + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: write_group + * + * Purpose: Create a group and carry out attribute operations(add,delete etc.) + * according to the attribute test pattern. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, 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 dummy_d = H5I_INVALID_HID; + hid_t gcpl = H5I_INVALID_HID; + bool result = true; + H5G_info_t group_info; + struct timespec start_time, end_time; + double temp_time; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + esnprintf(name, sizeof(name), "/group-%u", which); + +#if 0 + if (s->old_style_grp) + gcpl = H5P_DEFAULT; + else { + gcpl = H5Pcreate(H5P_GROUP_CREATE); + if (gcpl < 0) { + printf("H5Pcreate failed\n"); + TEST_ERROR; + } + + /* If we test the dense storage, change the attribute phase. */ + if (s->at_pattern == 'd') { + if (H5Pset_attr_phase_change(gcpl, 0, 0) < 0) { + printf("H5Pset_attr_phase_change failed for the dense storage.\n"); + TEST_ERROR; + } + } + } +#endif + + if(s->gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + + } + + + } + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + if(s->gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + + } + + + temp_time = TIME_PASSED(start_time,end_time); + if(temp_time < s->min_time) + s->min_time = temp_time; + if(temp_time > s->max_time) + s->max_time = temp_time; + s->total_time += temp_time; + } + + +#if 0 + /* We need to create a dummy dataset for the object header continuation block test. */ + if (s->at_pattern == 'a' || s->at_pattern == 'R') { + if ((dummy_d = H5Dcreate2(g, "Dataset", H5T_NATIVE_INT, s->one_by_one_sid, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + printf("H5Dcreate2 failed\n"); + TEST_ERROR; + } + } + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (s->old_style_grp) { + if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("Old-styled group test: but the group is not in old-style. \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the old-style.\n"); + } + else { + if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the new-style.\n"); + } + + /* If coming to an "object header continuation block" test, + * we need to check if this test behaves as expected. */ + if (s->at_pattern == 'a' || s->at_pattern == 'R') { + if (false == check_ohr_num_chunk(g, true)) { + printf("An object header continuation block should NOT be created. \n"); + printf("But it is created.\n"); + TEST_ERROR; + } + } + + /* 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 (s->at_pattern == 'a' || s->at_pattern == 'R') { + if (H5Dclose(dummy_d) < 0) { + printf("H5Dclose failed\n"); + TEST_ERROR; + } + } +#endif + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + + return result; + +error: + + + H5E_BEGIN_TRY { + H5Gclose(g); + } + 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) { + printf("H5Oget_native_info failed\n"); + TEST_ERROR; + } + + if (is_compact) { + if (ninfo.meta_size.attr.index_size != 0 || ninfo.meta_size.attr.heap_size != 0) { + printf("Should be in compact storage,but it is not.\n"); + TEST_ERROR; + } + } + else { + if (ninfo.meta_size.attr.index_size == 0 || ninfo.meta_size.attr.heap_size == 0) { + printf("Should be in dense storage,but it is not.\n"); + TEST_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 storage should be in compact + * false if the attribute storage should be in dense + * 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) { + printf("H5Tget_native_type failed\n"); + TEST_ERROR; + } + + if ((aid = H5Aopen(g, aname, H5P_DEFAULT)) < 0) { + printf("H5Aopen failed\n"); + TEST_ERROR; + } + + if (H5Aread(aid, amtype, &read_which) < 0) { + printf("H5Aread failed\n"); + TEST_ERROR; + } + + if (H5Aclose(aid) < 0) { + printf("H5Aclose failed\n"); + TEST_ERROR; + } + + if (read_which != which) { + printf("reader: the add_attribute verfication failed,expected value is %d\n", which); + printf("reader: the add_attribute verfication failed, the value is %d\n", read_which); + printf("The add_attribute verification failed\n"); + TEST_ERROR; + } + + if (!s->old_style_grp && check_storage == true) { + if (false == check_attr_storage_type(g, is_compact)) { + printf("The attribute storage type is wrong. \n"); + TEST_ERROR; + } + dbgf(2, "reader: finish checking the storage type: %d\n", s->np_notify); + } + + /* If coming to an "object header continuation block" test, + * we need to check if this test behaves as expected. */ + if (s->at_pattern == 'a' || s->at_pattern == 'R') { + if (false == check_ohr_num_chunk(g, false)) { + printf("An object header continuation block should be created. \n"); + printf("But it is not.\n"); + printf("Verification of 'object header continuation block test' failed.\n"); + TEST_ERROR; + } + } + + /* 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) { + printf("named pipe reader send message error\n"); + TEST_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, "add-ohr-block" + * and "del-ohr-block" tests. + *------------------------------------------------------------------------- + */ + +static bool +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 = 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) { + printf("H5Tget_native_type failed\n"); + TEST_ERROR; + } + + if ((aid = H5Aopen(g, attrname, H5P_DEFAULT)) < 0) { + printf("H5Aopen failed\n"); + TEST_ERROR; + } + + if (H5Aread(aid, amtype, &read_which) < 0) { + printf("H5Aread failed\n"); + TEST_ERROR; + } + + if (H5Tclose(amtype) < 0) { + printf("H5Tclose failed.\n"); + TEST_ERROR; + } + + if (H5Aclose(aid) < 0) { + printf("H5Aclose failed\n"); + TEST_ERROR; + } + + /* verify the modified value */ + if (read_which != (which + 10000)) { + printf("reader: the modified_attr() expected value is %d\n", which + 10000); + printf("reader: the modified_attr() actual value is %d\n", read_which); + printf("The modify_attribute verification failed.\n"); + TEST_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) { + printf("Allocate memory for expected buffer failed.\n"); + TEST_ERROR; + } + + esnprintf(name, sizeof(name), "attr-%u", 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) { + printf("H5Aopen failed\n"); + TEST_ERROR; + } + + /* Create a VL string datatype */ + if ((atype = H5Tcopy(H5T_C_S1)) < 0) { + printf("Cannot create variable length datatype.\n"); + TEST_ERROR; + } + + if (H5Tset_size(atype, H5T_VARIABLE) < 0) { + printf("Cannot set variable length datatype.\n"); + TEST_ERROR; + } + + if (H5Aread(aid, atype, &astr_val) < 0) { + printf("Cannot read the attribute.\n"); + TEST_ERROR; + } + + dbgf(1, "read attr is= %s\n", astr_val); + if (HDstrcmp(astr_val, astr_val_exp) != 0) { + printf("reader: the vl add_attribute verfication failed,expected value is %s\n", astr_val_exp); + printf("reader: the vl add_attribute verfication failed, the value is %s\n", astr_val); + printf("The vl add_attribute verification failed\n"); + TEST_ERROR; + } + + if (H5Tclose(atype) < 0) { + printf("H5Tclose failed.\n"); + TEST_ERROR; + } + + if (H5Aclose(aid) < 0) { + printf("H5Aclose failed.\n"); + TEST_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. + * + * bool check_storage + * a flag to indicate if the storage check is on + * + * bool is_compact + * true if after this attribute is deleted, + * the storage should still be in compact, false + * if the storage should be in dense. + * Note: this parameter is not used if the check_storage + * is set to false. + + * 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) { + printf("The supposed deleted attribute %s still exists \n", aname); + printf("verify_del_attrs_compact() test failed \n"); + TEST_ERROR; + } + else { + printf("H5Aexists_by_name failed \n"); + TEST_ERROR; + } + + if (!s->old_style_grp && check_storage == true) { + if (false == check_attr_storage_type(g, is_compact)) { + printf("The attribute storage type is wrong. \n"); + TEST_ERROR; + } + dbgf(2, "reader: finish checking the storage type: %d\n", s->np_notify); + } + + /* If coming to an "object header continuation block" test, + * we need to check if this test behaves as expected. */ + if (s->at_pattern == 'R') { + if (false == check_ohr_num_chunk(g, true)) { + printf("An object header continuation block should be removed. \n"); + printf("But it is NOT.\n"); + printf("Verification of an 'object header continuation block test' failed.\n"); + TEST_ERROR; + } + } + + /* Reader sends an OK message back to the reader */ + if (s->use_named_pipes && s->attr_test == true) { + if (np_rd_send(s) == false) + TEST_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); + } + 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_del_ohr_block_attr + * + * Purpose: Verify that an attribute is added to force creation of + * object header continuation block and remove this attribute + * to delete the object header continuation block + + * Parameters: state_t *s + * The struct that stores information of HDF5 file, 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_del_ohr_block_attr(state_t *s, hid_t g, unsigned int which) +{ + + bool ret_value = false; + char attrname[VS_ATTR_NAME_LEN]; + const char *aname_format = "attr-%u"; + + ret_value = verify_default_group_attr(s, g, which); + if (ret_value == true) { + HDsprintf(attrname, aname_format, which); + ret_value = verify_del_one_attr(s, g, attrname, false, true); + } + return ret_value; +} +/*------------------------------------------------------------------------- + * 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) { + printf("H5Gget_create_plist failed\n"); + TEST_ERROR; + } + if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { + printf("H5Pget_attr_phase_change failed\n"); + TEST_ERROR; + } + if (H5Pclose(gcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + } + break; + case 'v': + case 'd': + case 'M': + case 'm': + case 'r': + case 'a': + 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 'R': + ret = verify_del_ohr_block_attr(s, g, which); + break; + case 'a': + 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) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + esnprintf(name, sizeof(name), "/group-%u", which); + + if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) { + printf("H5Gopen failed\n"); + TEST_ERROR; + } + + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_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) { + printf("Reader - Old-styled group: but the group is not in old-style. \n"); + TEST_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) { + printf("Reader - The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Reader: verify that the group is created with the new-style.\n"); + } + + /* If coming to an "object header continuation block" test, + * we need to check if this test behaves as expected. */ + if (s->at_pattern == 'a' || s->at_pattern == 'R') { + if (false == check_ohr_num_chunk(g, true)) { + printf("An object header continuation block should NOT be created. \n"); + printf("But it is created.\n"); + printf("Verification of an 'object header continuation block test' failed.\n"); + TEST_ERROR; + } + } + + /* Reader sends an OK message back to the writer */ + if (s->use_named_pipes && s->attr_test == true) { + + if (np_rd_send(s) == false) + TEST_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(s, g, which); + else + result = true; + + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + 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; +} + +/*------------------------------------------------------------------------- + * Function: create_group_id + * + * Purpose: Create a group and return the group ID. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations for group creation + * This is used to generate the group name. + * + * bool dense_to_compact + * true if this function is used to test the transition from dense to + * compact, false if the test is from compact to dense. + * + * Return: Success: the group ID + * Failure: -1 + * + * Note: Only used by testing the link storage transit functions. + *------------------------------------------------------------------------- + */ + +static hid_t +create_group_id(state_t *s, unsigned int which, bool dense_to_compact) +{ + + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + hid_t gcpl = H5I_INVALID_HID; + H5G_info_t group_info; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + gcpl = H5Pcreate(H5P_GROUP_CREATE); + if (gcpl < 0) { + printf("H5Pcreate failed\n"); + TEST_ERROR; + } + + if (dense_to_compact) { + if (H5Pset_link_phase_change(gcpl, 2, 2) < 0) { + printf("H5Pset_link_phase_change failed for dense to compact.\n"); + TEST_ERROR; + } + } + else { + if (H5Pset_link_phase_change(gcpl, 1, 1) < 0) { + printf("H5Pset_attr_phase_change failed for compact to dense.\n"); + TEST_ERROR; + } + } + + esnprintf(name, sizeof(name), "/group-%u", which); + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + /* The storage type should always be compact when a group is created. */ + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("New-style group link storage test:. \n"); + printf(" still be compact after group creation. \n"); + TEST_ERROR; + } + + if (H5Pclose(gcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + /* If a grp_op_test is turned on and named pipes are used, + * the writer should send and receive messages after the group creation. + * Writer sends a message to reader: a group is successfully created. + * then wait for the reader to verify and send an acknowledgement message back.*/ + if (s->use_named_pipes && s->grp_op_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; + } + } + + return g; + +error: + /* Writer needs to send an error message to the reader to stop the test*/ + if (s->use_named_pipes && s->grp_op_test == true) + np_send_error(s, true); + +error2: + + H5E_BEGIN_TRY + { + H5Pclose(gcpl); + } + H5E_END_TRY; + + return -1; +} + +/*------------------------------------------------------------------------- + * Function: close_group_id + * + * Purpose: Verify is a group is closed successfully. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * hid_t g + * The ID of the group to be closed. + * + * Return: Success: true + * Failure: false + * + * Note: This is used by the link storage transit functions. + *------------------------------------------------------------------------- + */ + +static bool +close_group_id(state_t *s, hid_t g) +{ + + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + /* If a grp_op_test is turned on and named pipes are used, for + * link storage test, + * Writer sends a message to reader: the group is successfully closed. + * then wait for the reader to verify and send an acknowledgement message back.*/ + if (s->use_named_pipes && s->grp_op_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(); + 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->grp_op_test == true) + np_send_error(s, true); + +error2: + + return false; +} + +/*------------------------------------------------------------------------- + * Function: create_group + * + * Purpose: Create a group + * + * 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 + * This is used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the main() function. + *------------------------------------------------------------------------- + */ + +static bool +create_group(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + H5G_info_t group_info; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + esnprintf(name, sizeof(name), "/group-%u", which); + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (s->old_style_grp) { + if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("Old-styled group test: but the group is not in old-style. \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the old-style.\n"); + } + else { + if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the new-style.\n"); + } + + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + /* Writer sends a message to reader, + * then wait for the reader to verify and send an acknowledgement message back.*/ + if (s->use_named_pipes && s->grp_op_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(); + 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->grp_op_test == true) + np_send_error(s, true); + +error2: + + H5E_BEGIN_TRY + { + H5Gclose(g); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: delete_one_link + * + * Purpose: Delete a link(either hard/soft) in group operation tests. + * according to the group test pattern. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * hid_t obj_id + * The HDF5 object ID that the deleted link is attached to. + * + * const char *name + * The name of the link to be deleted. + * + * short link_storage + * <=0: link storage is ignored. + * 1: link storage should be compact after link deletion.. + * >1: link storage should be dense after link deletion. + * + * unsigned int which + * The number of iterations for group creation + * + * + * Return: Success: true + * Failure: false + * + * Note: This is used by delete_groups() and delete_links() functions. + *------------------------------------------------------------------------- + */ + +static bool +delete_one_link(state_t *s, hid_t obj_id, const char *name, short link_storage, unsigned int which) +{ + + H5G_info_t group_info; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + if (H5Ldelete(obj_id, name, H5P_DEFAULT) < 0) { + printf("H5Ldelete failed\n"); + TEST_ERROR; + } + + if (link_storage > 0) { + + if (s->old_style_grp) { + printf("Old style group doesn't support the indexed storage.\n"); + TEST_ERROR; + } + + if (H5Gget_info(obj_id, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (link_storage == 1) { + + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("The group link storage should be compact. \n"); + TEST_ERROR; + } + } + else { + + if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { + printf("The group link storage should be dense. \n"); + TEST_ERROR; + } + } + } + + /* Writer sends a message to reader: + * then wait for the reader to verify and send an acknowledgement message back.*/ + if (s->use_named_pipes && s->grp_op_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(); + 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->grp_op_test == true) + np_send_error(s, true); + +error2: + + return false; +} + +/*------------------------------------------------------------------------- + * Function: delete_group + * + * Purpose: Delete a group and carry out group operations(add,delete etc.) + * according to the group operation test pattern. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations for group creation + * This is used to generate the group name + * + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +delete_group(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + bool ret_value = create_group(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + ret_value = delete_one_link(s, s->file, name, 0, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: move_one_group + * + * Purpose: A helper function used by the move_group operation. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * hid_t obj_id + * ID of the object this group is attached to + * + * const char *name + * The original group name + * + * const char *newname + * The new group name + * + * unsigned int which + * The number of iterations for group creation + * + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the move_group() function. + *------------------------------------------------------------------------- + */ + +static bool +move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, unsigned int which) +{ + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + if (H5Lmove(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Ldelete failed\n"); + TEST_ERROR; + } + + /* Writer sends a message to reader: + * then wait for the reader to verify and send an acknowledgement message back.*/ + if (s->use_named_pipes && s->grp_op_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(); + 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->grp_op_test == true) + np_send_error(s, true); + +error2: + + return false; +} + +/*------------------------------------------------------------------------- + * Function: move_group + * + * Purpose: Move a group to another group. + * + * 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 + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +move_group(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char new_name[sizeof("/new-group-9999999999")]; + bool ret_value = create_group(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(new_name, sizeof(new_name), "/new-group-%u", which); + ret_value = move_one_group(s, s->file, name, new_name, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: insert_one_link + * + * Purpose: A helper function used to attach a link to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * hid_t obj_id + * ID of the object this link is attached to + * + * const char *name + * The name of the target object used by creating links + * + * const char *newname + * The name of the linked objects + * + * bool is_hard + * true if inserting a hard link + * false if inserting a soft link + * + * short link_storage + * <=0: link storage is ignored. + * 1: link storage should be compact. + * >1: link storage should be dense. + + * unsigned int which + * The number of iterations for group creation + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the insert_links and link storage transit functions. + * For link storage, we test at both the writer and the reader. + *------------------------------------------------------------------------- +*/ + +static bool +insert_one_link(state_t *s, hid_t obj_id, const char *name, const char *newname, bool is_hard, + short link_storage, unsigned int which) +{ + + H5G_info_t group_info; + + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + /* For storage transit and insert_links cases, we + * create links in different style, just add a little + * variation of the tests.*/ + if (is_hard) { + if (link_storage > 0) { + if (H5Lcreate_hard(s->file, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_hard failed\n"); + TEST_ERROR; + } + } + else { + if (H5Lcreate_hard(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_hard failed\n"); + TEST_ERROR; + } + } + } + else { + if (link_storage > 0) { + if (H5Lcreate_soft("/", obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_soft failed\n"); + TEST_ERROR; + } + } + else { + if (H5Lcreate_soft(name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_soft failed.\n"); + TEST_ERROR; + } + } + } + + if (link_storage > 0) { + + if (s->old_style_grp) { + printf("Old style group doesn't support dense or compact storage.\n"); + TEST_ERROR; + } + + if (H5Gget_info(obj_id, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (link_storage == 1) { + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("The group link storage should be compact. \n"); + TEST_ERROR; + } + } + else { + if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { + printf("The group link storage should be dense. \n"); + TEST_ERROR; + } + } + } + + /* Writer sends a message to reader, + * then wait for the reader to verify and send an acknowledgement message back.*/ + if (s->use_named_pipes && s->grp_op_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(); + 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->grp_op_test == true) + np_send_error(s, true); + +error2: + + return false; +} + +/*------------------------------------------------------------------------- + * Function: insert_links + * + * Purpose: create links with a group. + * + * 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 + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +insert_links(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("/st-group-9999999999")]; + + bool ret_value = create_group(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); + esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); + ret_value = insert_one_link(s, s->file, name, hd_name, true, 0, which); + if (ret_value == true) + ret_value = insert_one_link(s, s->file, name, st_name, false, 0, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: delete_links + * + * Purpose: create links with a group and then delete them successfully. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +delete_links(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("/st-group-9999999999")]; + + bool ret_value = insert_links(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); + esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); + ret_value = delete_one_link(s, s->file, hd_name, 0, which); + if (ret_value == true) + ret_value = delete_one_link(s, s->file, st_name, 0, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: transit_storage_compact_to_dense + * + * Purpose: Add links so that the link storage transits from + * compact to dense. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +transit_storage_compact_to_dense(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("/st-group-9999999999")]; + + hid_t g = create_group_id(s, which, false); + if (g < 0) { + printf("create_group_id failed\n"); + TEST_ERROR; + } + + /* First insert a hard link, compact storage. */ + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); + if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { + printf("insert_one_link for compact storage failed\n"); + TEST_ERROR; + } + + /* Then insert a soft link, the storage becomes dense. */ + esnprintf(st_name, sizeof(st_name), "st-group-%u", which); + if (insert_one_link(s, g, name, st_name, false, 2, which) == false) { + printf("insert_one_link for dense storage failed\n"); + TEST_ERROR; + } + + if (close_group_id(s, g) == false) { + printf("insert_one_link for dense storage failed\n"); + TEST_ERROR; + } + + return true; + +error: + H5E_BEGIN_TRY + { + H5Gclose(g); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: transit_storage_dense_to_compact + * + * Purpose: Add or delete links so that the link storage transits from + * compact to dense then to compact. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * unsigned int which + * The number of iterations used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +transit_storage_dense_to_compact(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("st-group-9999999999")]; + char st2_name[sizeof("st2-group-9999999999")]; + + hid_t g = create_group_id(s, which, true); + if (g < 0) { + printf("create_group_id failed\n"); + TEST_ERROR; + } + + /* Insert a link, storage is compact. */ + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); + if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { + printf("insert_one_link for compact storage failed\n"); + TEST_ERROR; + } + + /* Insert a link, storage is still compact. */ + esnprintf(st_name, sizeof(st_name), "st-group-%u", which); + if (insert_one_link(s, g, name, st_name, false, 1, which) == false) { + printf("insert_one_link for compact storage failed\n"); + TEST_ERROR; + } + + /* Insert a link, storage becomes dense. */ + esnprintf(st2_name, sizeof(st2_name), "st2-group-%u", which); + if (insert_one_link(s, g, name, st2_name, false, 2, which) == false) { + printf("insert_one_link for dense storage failed\n"); + TEST_ERROR; + } + + /* Delete a link, storage is still dense */ + if (delete_one_link(s, g, st_name, 2, which) == false) { + printf("delete_one_link for dense storage failed\n"); + TEST_ERROR; + } + + /* Delete another link, storage becomes compact */ + if (delete_one_link(s, g, st2_name, 1, which) == false) { + printf("delete_one_link for compact storage failed\n"); + TEST_ERROR; + } + + if (close_group_id(s, g) == false) { + printf("insert_one_link for dense storage failed\n"); + TEST_ERROR; + } + + return true; + +error: + H5E_BEGIN_TRY + { + H5Gclose(g); + } + H5E_END_TRY; + + return false; +} + +/*------------------------------------------------------------------------- + * Function: group_operations + * + * Purpose: Carry out group and attribute operations(add,delete etc.) + * according to the group operation and attribute test patterns. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, 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. The check of attribute + * operations is inside the write_group() function. + *------------------------------------------------------------------------- + */ +static bool +group_operations(state_t *s, unsigned int which) +{ + + bool ret_value = false; + char test_pattern = s->grp_op_pattern; + + switch (test_pattern) { + case 'c': + ret_value = create_group(s, which); + break; + case 'd': + ret_value = delete_group(s, which); + break; + case 'm': + ret_value = move_group(s, which); + break; + case 'i': + ret_value = insert_links(s, which); + break; + case 'D': + ret_value = delete_links(s, which); + break; + case 't': + ret_value = transit_storage_compact_to_dense(s, which); + break; + case 'T': + ret_value = transit_storage_dense_to_compact(s, which); + break; + case ' ': + default: + ret_value = write_group(s, which); + break; + } + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_create_group + * + * Purpose: Verify if a group can be created successfully. + * + * 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 + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the verify_group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_create_group(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + H5G_info_t group_info; + + dbgf(2, "reader: ready to send the message: \n"); + + /* 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->grp_op_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) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + esnprintf(name, sizeof(name), "/group-%u", which); + + if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) { + printf("H5Gopen failed\n"); + TEST_ERROR; + } + + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_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) { + printf("Reader - Old-styled group: but the group is not in old-style. \n"); + TEST_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) { + printf("Reader - The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Reader: verify that the group is created with the new-style.\n"); + } + + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + /* Reader sends an OK message back to the writer */ + if (s->use_named_pipes && s->grp_op_test == true) { + + if (np_rd_send(s) == false) + TEST_ERROR; + dbgf(1, "Reader: finish sending back the message: %d\n", s->np_notify); + } + + return true; + +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->grp_op_test == true) + np_send_error(s, false); + +error2: + + return false; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_create_group_id + * + * Purpose: Verify if a group is created successfully and return the group + * ID. + * + * 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 + * used to generate the group name. + * + * bool dense_to_compact + * true if this function is used to test the transition from dense to + * compact, false if the test is from compact to dense. + * + * Return: Success: the group ID + * Failure: -1 + * + * Note: This function is used by the link storage transit functions. + *------------------------------------------------------------------------- + */ + +static hid_t +vrfy_create_group_id(state_t *s, unsigned int which, bool dense_to_compact) +{ + + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + hid_t gcpl = H5I_INVALID_HID; + H5G_info_t group_info; + unsigned max_compact = 0; + unsigned min_dense = 0; + + dbgf(2, "reader: ready to receive a message: \n"); + /* 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->grp_op_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) { + printf("Number of the created groups is out of bounds\n"); + TEST_ERROR; + } + + esnprintf(name, sizeof(name), "/group-%u", which); + + if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) { + printf("H5Gopen failed\n"); + TEST_ERROR; + } + + if ((gcpl = H5Gget_create_plist(g)) < 0) { + printf("H5Gget_create_plist failed\n"); + TEST_ERROR; + } + + if (H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) { + printf("H5Pget_link_phase_change failed\n"); + TEST_ERROR; + } + + if (dense_to_compact) { + if (max_compact != 2) { + printf("For storage check from dense to compact:\n"); + printf(" The max_compact should be 2.\n"); + printf(" But the actual value is %d.\n", max_compact); + TEST_ERROR; + } + else if (min_dense != 2) { + printf("For storage check from dense to compact:\n"); + printf(" The min_dense should be 2.\n"); + printf(" But the actual value is %d.\n", min_dense); + TEST_ERROR; + } + } + else { + if (max_compact != 1) { + printf("For storage check from dense to compact:\n"); + printf(" The max_compact should be 1.\n"); + printf(" But the actual value is %d.\n", max_compact); + TEST_ERROR; + } + else if (min_dense != 1) { + printf("For storage check from dense to compact:\n"); + printf(" The min_dense should be 1.\n"); + printf(" But the actual value is %d.\n", min_dense); + TEST_ERROR; + } + } + + if (H5Pclose(gcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + /* When the group is created, the storage type is always compact. */ + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("Old-styled group test: but the group is not in old-style. \n"); + TEST_ERROR; + } + + dbgf(2, "Storage info is %d\n", group_info.storage_type); + + /* Reader sends an OK message back to the reader */ + if (s->use_named_pipes && s->grp_op_test == true) { + + if (np_rd_send(s) == false) + TEST_ERROR; + dbgf(1, "Reader: finish sending back the message: %d\n", s->np_notify); + } + + return g; + +error: + + H5E_BEGIN_TRY + { + H5Gclose(g); + H5Pclose(gcpl); + } + H5E_END_TRY; + + /* The reader sends an error message to the writer to stop the test.*/ + if (s->use_named_pipes && s->grp_op_test == true) + np_send_error(s, false); + +error2: + + return -1; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_close_group_id + * + * Purpose: Verify if a group is closed successfully. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * hid_t g + * The ID of the group to be closed. + * + * Return: Success: true + * Failure: false + * + * Note: This is used by the link storage transit functions. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_close_group_id(state_t *s, hid_t g) +{ + + /* 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->grp_op_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 (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + /* Reader sends an OK message back to the reader */ + if (s->use_named_pipes && s->grp_op_test == true) { + + if (np_rd_send(s) == false) + TEST_ERROR; + dbgf(1, "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->grp_op_test == true) + np_send_error(s, false); + +error2: + return false; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_one_link_exist + * + * Purpose: Verify if a link exists or not. The link storage is + * also checked. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * hid_t obj_id + * The ID of the object the link is attached to + * + * bool expect_exist + * A flag that indicates if this link is expected to exist + * + * short link_storage + * <=0: link storage check is ignored. + * 1: link storage is expected to be compact. + * >1: link storage is expected to be dense. + * + * Return: Success: true + * Failure: false + * + * Note: Helper function to check if links are inserted or deleted. + * The link storage is also checked. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_one_link_exist(state_t *s, hid_t obj_id, const char *name, bool expect_exist, short link_storage) +{ + + int link_exists = 0; + H5G_info_t group_info; + + dbgf(2, "reader: ready to send the message: \n"); + /* 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->grp_op_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); + } + + link_exists = H5Lexists(obj_id, name, H5P_DEFAULT); + + if (link_exists < 0) { + printf("H5Lexists error\n"); + TEST_ERROR; + } + else if (link_exists == 1) { + if (expect_exist == false) { + printf("This link should be moved or deleted but it still exists.\n"); + TEST_ERROR; + } + } + else if (link_exists == 0) { + if (expect_exist == true) { + printf("This link should exist but it is moved or deleted.\n"); + TEST_ERROR; + } + } + + if (link_storage > 0) { + + if (s->old_style_grp) { + printf("Old style group doesn't support the indexed storage.\n"); + TEST_ERROR; + } + + if (H5Gget_info(obj_id, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (link_storage == 1) { + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("The group link storage should be compact. \n"); + TEST_ERROR; + } + } + else { + if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { + printf("The group link storage should be dense. \n"); + TEST_ERROR; + } + } + } + + /* Reader sends an OK message back to the reader */ + if (s->use_named_pipes && s->grp_op_test == true) { + if (np_rd_send(s) == false) { + TEST_ERROR; + } + dbgf(1, "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->grp_op_test == true) + np_send_error(s, false); + +error2: + + return false; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_delete_group + * + * Purpose: Verify if a group can be deleted successfully. + * + * 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 + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the verify_group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_delete_group(state_t *s, unsigned int which) +{ + + bool ret_value = false; + char name[sizeof("/group-9999999999")]; + + ret_value = vrfy_create_group(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + ret_value = vrfy_one_link_exist(s, s->file, name, false, 0); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_move_one_group + * + * Purpose: A helper function to verify the move_group operation successfully. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * hid_t obj_id + * ID of the object this group is attached to + * + * const char *name + * The original group name + * + * const char *newname + * The new group name + * + * unsigned int which + * The number of iterations for group creation + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the verify_move_group() function. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, unsigned int which) +{ + + hid_t g = H5I_INVALID_HID; + H5G_info_t group_info; + int link_exists = 0; + + dbgf(2, "reader: ready to send the message: \n"); + /* 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->grp_op_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) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + link_exists = H5Lexists(obj_id, name, H5P_DEFAULT); + if (link_exists < 0) { + printf("H5Lexists error\n"); + TEST_ERROR; + } + else if (link_exists == 1) { + printf("This link should be moved but it still exists.\n"); + TEST_ERROR; + } + + if ((g = H5Gopen(obj_id, newname, H5P_DEFAULT)) < 0) { + printf("H5Gopen failed\n"); + TEST_ERROR; + } + + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_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) { + printf("Reader - Old-styled group: but the group is not in old-style. \n"); + TEST_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) { + printf("Reader - The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Reader: verify that the group is created with the new-style.\n"); + } + + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + + /* Reader sends an OK message back to the reader */ + if (s->use_named_pipes && s->grp_op_test == true) { + + if (np_rd_send(s) == false) { + TEST_ERROR; + } + dbgf(1, "Reader: finish sending back the message: %d\n", s->np_notify); + } + + return true; + +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->grp_op_test == true) + np_send_error(s, false); + +error2: + + return false; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_move_group + * + * Purpose: Verify if a group can be moved successfully. + * + * 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 + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the verify_group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_move_group(state_t *s, unsigned int which) +{ + + char name[sizeof("/group-9999999999")]; + char new_name[sizeof("/new-group-9999999999")]; + bool ret_value = vrfy_create_group(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + esnprintf(new_name, sizeof(new_name), "/new-group-%u", which); + ret_value = vrfy_move_one_group(s, s->file, name, new_name, which); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_insert_links + * + * Purpose: Verify if the links are inserted successfully. + * + * 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 + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the verify_group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_insert_links(state_t *s, unsigned int which) +{ + + bool ret_value = false; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("/st-group-9999999999")]; + + ret_value = vrfy_create_group(s, which); + + if (ret_value == true) { + esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); + esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); + ret_value = vrfy_one_link_exist(s, s->file, hd_name, true, 0); + if (ret_value == true) + ret_value = vrfy_one_link_exist(s, s->file, st_name, true, 0); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_delete_links + * + * Purpose: Verify if the links created with a group are deleted successfully. + * + * 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 + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the verify_group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_delete_links(state_t *s, unsigned int which) +{ + + bool ret_value = false; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("/st-group-9999999999")]; + + /* First verify if the links are inserted correctly */ + ret_value = vrfy_insert_links(s, which); + + /* Then if these links are deleted correctly. */ + if (ret_value == true) { + esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); + esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); + ret_value = vrfy_one_link_exist(s, s->file, hd_name, false, 0); + if (ret_value == true) + ret_value = vrfy_one_link_exist(s, s->file, st_name, false, 0); + } + + return ret_value; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_transit_storage_compact_to_dense + * + * Purpose: Verify if the link storage successfully transits from + * compact to dense. + * + * 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 + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the verify_group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_transit_storage_compact_to_dense(state_t *s, unsigned int which) +{ + + hid_t g = H5I_INVALID_HID; + char hd_name[sizeof("hd-group-9999999999")]; + char st_name[sizeof("st-group-9999999999")]; + + g = vrfy_create_group_id(s, which, false); + if (g < 0) { + printf("verify create_group_id failed\n"); + TEST_ERROR; + } + + esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); + if (vrfy_one_link_exist(s, g, hd_name, true, 1) == false) { + printf("verify the compact storage failed for 'link compact to dense' test\n"); + TEST_ERROR; + } + + esnprintf(st_name, sizeof(st_name), "st-group-%u", which); + if (vrfy_one_link_exist(s, g, st_name, true, 2) == false) { + printf("verify the dense link storage failed for 'link compact to dense' test\n"); + TEST_ERROR; + } + + if (vrfy_close_group_id(s, g) == false) { + printf("verify the group close for 'link compact to dense' test\n"); + TEST_ERROR; + } + return true; + +error: + H5E_BEGIN_TRY + { + H5Gclose(g); + } + H5E_END_TRY; + return false; +} + +/*------------------------------------------------------------------------- + * Function: vrfy_transit_storage_dense_to_compact + * + * Purpose: Verify if the link storage successfully transits from + * compact to dense then to compact. + * + * 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 + * used to generate the group name. + * + * Return: Success: true + * Failure: false + * + * Note: This is called by the verify_group_operations() function. + *------------------------------------------------------------------------- + */ + +static bool +vrfy_transit_storage_dense_to_compact(state_t *s, unsigned int which) +{ + + hid_t g = H5I_INVALID_HID; + char hd_name[sizeof("hd-group-9999999999")]; + char st_name[sizeof("st-group-9999999999")]; + char st2_name[sizeof("st2-group-9999999999")]; + + g = vrfy_create_group_id(s, which, true); + if (g < 0) { + printf("verify create_group_id failed\n"); + TEST_ERROR; + } + + /* Add a link, verify it is still the compact storage */ + esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); + if (vrfy_one_link_exist(s, g, hd_name, true, 1) == false) { + printf("verify the compact storage failed for 'link compact to dense' test\n"); + TEST_ERROR; + } + + /* Add another link, verify it is still the compact storage */ + esnprintf(st_name, sizeof(st_name), "st-group-%u", which); + if (vrfy_one_link_exist(s, g, st_name, true, 1) == false) { + printf("verify the compact link storage failed for 'link compact to dense' test\n"); + TEST_ERROR; + } + + /* Add the third link, verify it becomes the dense storage */ + esnprintf(st2_name, sizeof(st2_name), "st2-group-%u", which); + if (vrfy_one_link_exist(s, g, st2_name, true, 2) == false) { + printf("verify the dense link storage failed for 'link compact to dense' test\n"); + TEST_ERROR; + } + + /* Remove a link, verify the link doesn't exist and still dense storage */ + if (vrfy_one_link_exist(s, g, st_name, false, 2) == false) { + printf("verify the dense link storage failed for 'link compact to dense' test\n"); + TEST_ERROR; + } + + /* Remove a link, verify the link doesn't exist and it becomes compact storage */ + if (vrfy_one_link_exist(s, g, st2_name, false, 1) == false) { + printf("verify the compact link storage failed for 'link compact to dense' test\n"); + TEST_ERROR; + } + + if (vrfy_close_group_id(s, g) == false) { + printf("verify the group close for 'link compact to dense' test\n"); + TEST_ERROR; + } + return true; + +error: + H5E_BEGIN_TRY + { + H5Gclose(g); + } + H5E_END_TRY; + return false; +} + +/*------------------------------------------------------------------------- + * Function: verify_group_operations + * + * 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_operations(state_t *s, unsigned int which) +{ + bool ret_value = false; + char test_pattern = s->grp_op_pattern; + + switch (test_pattern) { + case 'c': + ret_value = vrfy_create_group(s, which); + break; + case 'd': + ret_value = vrfy_delete_group(s, which); + break; + case 'm': + ret_value = vrfy_move_group(s, which); + break; + case 'i': + ret_value = vrfy_insert_links(s, which); + break; + case 'D': + ret_value = vrfy_delete_links(s, which); + break; + case 't': + ret_value = vrfy_transit_storage_compact_to_dense(s, which); + break; + case 'T': + ret_value = vrfy_transit_storage_dense_to_compact(s, which); + break; + case ' ': + default: + ret_value = verify_group(s, which); + break; + } + return ret_value; +} + +int +main(int argc, char **argv) +{ + hid_t fapl = H5I_INVALID_HID, fcpl = H5I_INVALID_HID; + unsigned step; + bool writer = false; + state_t s; + const char * personality; + H5F_vfd_swmr_config_t config; + const char * fifo_writer_to_reader = "./fifo_group_writer_to_reader"; + 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; + bool wg_ret = false; + bool vg_ret = false; + + if (!state_init(&s, argc, argv)) { + printf("state_init failed\n"); + TEST_ERROR; + } + + personality = HDstrstr(s.progname, "vfd_swmr_gperf_"); + + if (personality != NULL && HDstrcmp(personality, "vfd_swmr_gperf_writer") == 0) + writer = true; + else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_gperf_reader") == 0) + writer = false; + else { + printf("unknown personality, expected vfd_swmr_gperf_{reader,writer}\n"); + TEST_ERROR; + } + + /* 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"); + + /* 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) { + printf("vfd_swmr_create_fapl failed\n"); + TEST_ERROR; + } + + if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { + printf("H5Pcreate failed\n"); + TEST_ERROR; + } + + if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, 1) < 0) { + printf("H5Pset_file_space_strategy failed\n"); + TEST_ERROR; + } + + if (writer) + s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl); + else + s.file = H5Fopen(s.filename, H5F_ACC_RDONLY, fapl); + + if (s.file < 0) { + printf("H5Fcreate/open failed\n"); + TEST_ERROR; + } + + /* Use two named pipes(FIFO) to coordinate the writer and reader for + * two-way communication so that the two sides can move forward together. + * One is for the writer to write to the reader. + * The other one is for the reader to signal the writer. */ + if (s.use_named_pipes && writer) { + /* Writer creates two named pipes(FIFO) */ + if (HDmkfifo(fifo_writer_to_reader, 0600) < 0) { + printf("HDmkfifo failed\n"); + TEST_ERROR; + } + + if (HDmkfifo(fifo_reader_to_writer, 0600) < 0) { + printf("HDmkfifo failed\n"); + TEST_ERROR; + } + } + + /* Both the writer and reader open the pipes */ + if (s.use_named_pipes && (fd_writer_to_reader = HDopen(fifo_writer_to_reader, O_RDWR)) < 0) { + printf("HDopen failed\n"); + TEST_ERROR; + } + + if (s.use_named_pipes && (fd_reader_to_writer = HDopen(fifo_reader_to_writer, O_RDWR)) < 0) { + printf("HDopen failed\n"); + TEST_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.attr_test && s.use_named_pipes) + s.csteps = 1; + + /* For group operation test, force the named pipe to communicate in every step. */ + if (s.grp_op_test && s.use_named_pipes) + s.csteps = 1; + + if (writer) { + for (step = 0; step < s.nsteps; step++) { + dbgf(2, "writer: step %d\n", step); + + wg_ret = group_operations(&s, step); + + if (wg_ret == false) { + + /* At communication interval, notifies the reader about the failure and quit */ + if (s.use_named_pipes && s.attr_test != true && s.grp_op_test != true && step % s.csteps == 0) + np_send_error(&s, true); + printf("write_group failed at step %d\n", step); + TEST_ERROR; + } + else { + + /* At communication interval, notifies the reader and waits for its response */ + if (s.use_named_pipes && s.attr_test != true && s.grp_op_test != true && + step % s.csteps == 0) { + + if (np_wr_send_receive(&s) == false) { + printf("writer: write group - verification failed.\n"); + TEST_ERROR; + } + } + } + } + s.mean_time = s.total_time/s.nsteps; + fprintf(stdout, "group creation min. time = %lf\n", s.min_time); + fprintf(stdout, "group creation max. time = %lf\n", s.max_time); + fprintf(stdout, "group creation mean time = %lf\n", s.mean_time); + fprintf(stdout, "group creation total time = %lf\n", s.total_time); + } + else { + for (step = 0; step < s.nsteps; step++) { + dbgf(1, "reader: step %d\n", step); + + /* At communication interval, waits for the writer to finish creation before starting verification + */ + if (s.use_named_pipes && s.attr_test != true && s.grp_op_test != true && step % s.csteps == 0) { + if (false == np_rd_receive(&s)) { + TEST_ERROR; + } + } + + /* 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); + + vg_ret = verify_group_operations(&s, step); + + if (vg_ret == false) { + + printf("verify_group_operations failed\n"); + + /* At communication interval, tell the writer about the failure and exit */ + if (s.use_named_pipes && s.attr_test != true && s.grp_op_test != true && step % s.csteps == 0) + np_send_error(&s, false); + TEST_ERROR; + } + 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 && s.grp_op_test != true && + step % s.csteps == 0) { + if (np_rd_send(&s) == false) { + TEST_ERROR; + } + } + } + } + } + + if (H5Pclose(fapl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + if (H5Pclose(fcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + if (H5Sclose(s.one_by_one_sid) < 0) { + printf("H5Sclose failed\n"); + TEST_ERROR; + } + + if (H5Fclose(s.file) < 0) { + printf("H5Fclose failed\n"); + TEST_ERROR; + } + + /* Both the writer and reader close the named pipes */ + if (s.use_named_pipes && HDclose(fd_writer_to_reader) < 0) { + printf("HDclose failed\n"); + TEST_ERROR; + } + + if (s.use_named_pipes && HDclose(fd_reader_to_writer) < 0) { + printf("HDclose failed\n"); + TEST_ERROR; + } + + /* Reader finishes last and deletes the named pipes */ + if (s.use_named_pipes && !writer) { + if (HDremove(fifo_writer_to_reader) != 0) { + printf("HDremove failed\n"); + TEST_ERROR; + } + + if (HDremove(fifo_reader_to_writer) != 0) { + printf("HDremove failed\n"); + TEST_ERROR; + } + } + + return EXIT_SUCCESS; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl); + H5Pclose(fcpl); + H5Sclose(s.one_by_one_sid); + H5Fclose(s.file); + } + H5E_END_TRY; + + if (s.use_named_pipes && fd_writer_to_reader >= 0) + HDclose(fd_writer_to_reader); + + if (s.use_named_pipes && fd_reader_to_writer >= 0) + HDclose(fd_reader_to_writer); + + if (s.use_named_pipes && !writer) { + HDremove(fifo_writer_to_reader); + HDremove(fifo_reader_to_writer); + } + + return EXIT_FAILURE; +} + +#else /* H5_HAVE_WIN32_API */ + +int +main(void) +{ + HDfprintf(stderr, "Non-POSIX platform. Skipping.\n"); + return EXIT_SUCCESS; +} /* end main() */ + +#endif /* H5_HAVE_WIN32_API */ -- cgit v0.12 From 3dc6265bae206cd0705a0a5dfb9c5bd2f67c57ed Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Jun 2021 16:57:20 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_gperf_writer.c | 71 ++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index 9996798..f030db9 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -26,8 +26,8 @@ #define READER_WAIT_TICKS 3 #define VS_ATTR_NAME_LEN 21 -#define TIME_PASSED(X,Y) \ - ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 +#define TIME_PASSED(X, Y) \ + ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 typedef struct { hid_t file, filetype, one_by_one_sid; @@ -66,8 +66,8 @@ typedef struct { .update_interval = READER_WAIT_TICKS, .use_vfd_swmr = true, .old_style_grp = false, \ .use_named_pipes = true, .grp_op_pattern = ' ', .grp_op_test = false, .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, .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ - .total_time = 0.,.num_attrs = 1 \ + .np_notify = 0, .np_verify = 0, .gperf = false, .min_time = 100., .max_time = 0., .mean_time = 0., \ + .total_time = 0., .num_attrs = 1 \ } static void @@ -1734,14 +1734,14 @@ add_group_attribute(state_t *s, hid_t g, hid_t gcpl, unsigned int which) static bool write_group(state_t *s, unsigned int which) { - char name[sizeof("/group-9999999999")]; - hid_t g = H5I_INVALID_HID; - hid_t dummy_d = H5I_INVALID_HID; - hid_t gcpl = H5I_INVALID_HID; - bool result = true; - H5G_info_t group_info; + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + hid_t dummy_d = H5I_INVALID_HID; + hid_t gcpl = H5I_INVALID_HID; + bool result = true; + H5G_info_t group_info; struct timespec start_time, end_time; - double temp_time; + double temp_time; if (which >= s->nsteps) { printf("Number of created groups is out of bounds\n"); @@ -1770,42 +1770,36 @@ write_group(state_t *s, unsigned int which) } #endif - if(s->gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + if (s->gperf) { - fprintf(stderr, "HDclock_gettime failed"); - - TEST_ERROR; - - } + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } } if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { printf("H5Gcreate2 failed\n"); TEST_ERROR; } - if(s->gperf) { + if (s->gperf) { - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); - - TEST_ERROR; - - } + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } - temp_time = TIME_PASSED(start_time,end_time); - if(temp_time < s->min_time) + temp_time = TIME_PASSED(start_time, end_time); + if (temp_time < s->min_time) s->min_time = temp_time; - if(temp_time > s->max_time) + if (temp_time > s->max_time) s->max_time = temp_time; - s->total_time += temp_time; + s->total_time += temp_time; } - #if 0 /* We need to create a dummy dataset for the object header continuation block test. */ @@ -1880,13 +1874,12 @@ write_group(state_t *s, unsigned int which) TEST_ERROR; } - return result; error: - - H5E_BEGIN_TRY { + H5E_BEGIN_TRY + { H5Gclose(g); } H5E_END_TRY; @@ -5132,11 +5125,11 @@ main(int argc, char **argv) } } } - s.mean_time = s.total_time/s.nsteps; - fprintf(stdout, "group creation min. time = %lf\n", s.min_time); - fprintf(stdout, "group creation max. time = %lf\n", s.max_time); - fprintf(stdout, "group creation mean time = %lf\n", s.mean_time); - fprintf(stdout, "group creation total time = %lf\n", s.total_time); + s.mean_time = s.total_time / s.nsteps; + fprintf(stdout, "group creation min. time = %lf\n", s.min_time); + fprintf(stdout, "group creation max. time = %lf\n", s.max_time); + fprintf(stdout, "group creation mean time = %lf\n", s.mean_time); + fprintf(stdout, "group creation total time = %lf\n", s.total_time); } else { for (step = 0; step < s.nsteps; step++) { -- cgit v0.12 From 9d07011f4e2d8c5fd870c61e855d13a688940a18 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Fri, 2 Jul 2021 13:02:33 -0500 Subject: More code to performance check. --- test/vfd_swmr_gperf_writer.c | 62 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index 9996798..cf12585 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -55,6 +55,8 @@ typedef struct { double max_time; double mean_time; double total_time; + double fo_total_time; + double fc_total_time; unsigned int num_attrs; } state_t; @@ -66,8 +68,9 @@ typedef struct { .update_interval = READER_WAIT_TICKS, .use_vfd_swmr = true, .old_style_grp = false, \ .use_named_pipes = true, .grp_op_pattern = ' ', .grp_op_test = false, .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, .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ - .total_time = 0.,.num_attrs = 1 \ + .np_notify = 0, .np_verify = 0, .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ + .total_time = 0., .fo_total_time = 0., \ + .fc_total_time = 0., .num_attrs = 1 \ } static void @@ -5005,6 +5008,7 @@ main(int argc, char **argv) int notify = 0, verify = 0; bool wg_ret = false; bool vg_ret = false; + struct timespec start_time, end_time; if (!state_init(&s, argc, argv)) { printf("state_init failed\n"); @@ -5045,11 +5049,38 @@ main(int argc, char **argv) TEST_ERROR; } + if(s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + + } + } + + if (writer) s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl); else s.file = H5Fopen(s.filename, H5F_ACC_RDONLY, fapl); + if(s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + + } + + + s.fo_total_time = TIME_PASSED(start_time,end_time); + fprintf(stdout, "H5Fopen time = %lf\n", s.fo_total_time); + } + if (s.file < 0) { printf("H5Fcreate/open failed\n"); TEST_ERROR; @@ -5194,11 +5225,38 @@ main(int argc, char **argv) TEST_ERROR; } + if(s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + + } + + } + if (H5Fclose(s.file) < 0) { printf("H5Fclose failed\n"); TEST_ERROR; } + if(s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + + } + + s.fc_total_time = TIME_PASSED(start_time,end_time); + fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); + } + + /* Both the writer and reader close the named pipes */ if (s.use_named_pipes && HDclose(fd_writer_to_reader) < 0) { printf("HDclose failed\n"); -- cgit v0.12 From b1e75e7816b6d0fdfa9842156dd6ae5d6d816823 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Jul 2021 18:14:04 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_gperf_writer.c | 65 +++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index a3b5455..ab0fd57 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -68,9 +68,8 @@ typedef struct { .update_interval = READER_WAIT_TICKS, .use_vfd_swmr = true, .old_style_grp = false, \ .use_named_pipes = true, .grp_op_pattern = ' ', .grp_op_test = false, .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, .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ - .total_time = 0., .fo_total_time = 0., \ - .fc_total_time = 0., .num_attrs = 1 \ + .np_notify = 0, .np_verify = 0, .gperf = false, .min_time = 100., .max_time = 0., .mean_time = 0., \ + .total_time = 0., .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1 \ } static void @@ -5001,7 +5000,7 @@ main(int argc, char **argv) int notify = 0, verify = 0; bool wg_ret = false; bool vg_ret = false; - struct timespec start_time, end_time; + struct timespec start_time, end_time; if (!state_init(&s, argc, argv)) { printf("state_init failed\n"); @@ -5042,38 +5041,34 @@ main(int argc, char **argv) TEST_ERROR; } - if(s.gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + if (s.gperf) { - fprintf(stderr, "HDclock_gettime failed"); + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - TEST_ERROR; + fprintf(stderr, "HDclock_gettime failed"); - } + TEST_ERROR; + } } - if (writer) s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl); else s.file = H5Fopen(s.filename, H5F_ACC_RDONLY, fapl); - if(s.gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + if (s.gperf) { - fprintf(stderr, "HDclock_gettime failed"); - - TEST_ERROR; + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - } + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } - s.fo_total_time = TIME_PASSED(start_time,end_time); - fprintf(stdout, "H5Fopen time = %lf\n", s.fo_total_time); + s.fo_total_time = TIME_PASSED(start_time, end_time); + fprintf(stdout, "H5Fopen time = %lf\n", s.fo_total_time); } - + if (s.file < 0) { printf("H5Fcreate/open failed\n"); TEST_ERROR; @@ -5218,16 +5213,14 @@ main(int argc, char **argv) TEST_ERROR; } - if(s.gperf) { + if (s.gperf) { - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - - fprintf(stderr, "HDclock_gettime failed"); - - TEST_ERROR; + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - } + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } } if (H5Fclose(s.file) < 0) { @@ -5235,21 +5228,19 @@ main(int argc, char **argv) TEST_ERROR; } - if(s.gperf) { + if (s.gperf) { - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - - fprintf(stderr, "HDclock_gettime failed"); + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - TEST_ERROR; + fprintf(stderr, "HDclock_gettime failed"); - } + TEST_ERROR; + } - s.fc_total_time = TIME_PASSED(start_time,end_time); - fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); + s.fc_total_time = TIME_PASSED(start_time, end_time); + fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); } - /* Both the writer and reader close the named pipes */ if (s.use_named_pipes && HDclose(fd_writer_to_reader) < 0) { printf("HDclose failed\n"); -- cgit v0.12 From da7fec09b999949a0272e28c17ccc9eb01b025d0 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Tue, 3 Aug 2021 15:20:37 -0500 Subject: 1)remove named pipe from the program. 2) make the number of attributes for each group configuratable. The attribute datatype is 32-bit integer. --- test/vfd_swmr_gperf_writer.c | 919 +++---------------------------------------- 1 file changed, 60 insertions(+), 859 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index a3b5455..e0f0bdb 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -10,6 +10,17 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Description of this program: + * This program checks the performance of group creations for VFD SWMR. + * Currently the group creation time, H5Fopen and H5Fclose time are measured. + * After compiling the program, + * ./vfd_swmr_gperf_writer -n 1000 -P -N 5 -a 1 -q + * will generate 1000 groups, each group has 5 attributes. + * ./vfd_swmr_gperf_writer -n 1000 -P -N 0 -q + * will generate 1000 empty groups. + * ./vfd_swmr_gperf_writer -n 1000 -P -q + * will generate 1000 groups,for every ten groups, an attribute is generated. +*/ #define H5F_FRIEND /*suppress error about including H5Fpkg */ #include "hdf5.h" @@ -23,7 +34,6 @@ #ifndef H5_HAVE_WIN32_API -#define READER_WAIT_TICKS 3 #define VS_ATTR_NAME_LEN 21 #define TIME_PASSED(X, Y) \ @@ -34,22 +44,15 @@ typedef struct { 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 grp_op_pattern; bool grp_op_test; 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; bool gperf; double min_time; double max_time; @@ -64,11 +67,11 @@ typedef struct { (state_t) \ { \ .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, .grp_op_pattern = ' ', .grp_op_test = false, .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, .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ + .filetype = H5T_NATIVE_UINT32, .asteps = 10, .nsteps = 100, \ + .use_vfd_swmr = true, .old_style_grp = false, \ + .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ + .attr_test = false, .tick_len = 4, .max_lag = 7, \ + .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ .total_time = 0., .fo_total_time = 0., \ .fc_total_time = 0., .num_attrs = 1 \ } @@ -77,18 +80,15 @@ static void usage(const char *progname) { fprintf(stderr, - "usage: %s [-S] [-G] [-a steps] [-b] [-c] [-n iterations]\n" - " [-N] [-q] [-u numb_ticks] [-A at_pattern] [-O grp_op_pattern]\n" + "usage: %s [-S] [-G] [-a steps] [-b] [-n iterations]\n" + " [-N num_attrs] [-q] [-A at_pattern] [-O grp_op_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" + "-N: the number of attributes \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" @@ -169,7 +169,7 @@ state_init(state_t *s, int argc, char **argv) if (tfile) HDfree(tfile); - while ((ch = getopt(argc, argv, "PSGa:bc:n:Nqu:A:O:")) != -1) { + while ((ch = getopt(argc, argv, "PSGa:bn:qA:N:O:")) != -1) { switch (ch) { case 'P': s->gperf = true; @@ -181,9 +181,8 @@ state_init(state_t *s, int argc, char **argv) s->old_style_grp = true; break; case 'a': - case 'c': case 'n': - case 'u': + case 'N': errno = 0; tmp = HDstrtoul(optarg, &end, 0); if (end == optarg || *end != '\0') { @@ -201,19 +200,14 @@ state_init(state_t *s, int argc, char **argv) if (ch == 'a') s->asteps = (unsigned)tmp; - else if (ch == 'c') - s->csteps = (unsigned)tmp; else if (ch == 'n') s->nsteps = (unsigned)tmp; - else if (ch == 'u') - s->update_interval = (unsigned)tmp; + else if (ch == 'N') + s->num_attrs = (unsigned)tmp; break; case 'b': s->filetype = H5T_STD_U32BE; break; - case 'N': - s->use_named_pipes = false; - break; case 'O': if (HDstrcmp(optarg, "grp-creation") == 0) s->grp_op_pattern = 'c'; @@ -293,11 +287,6 @@ state_init(state_t *s, int argc, char **argv) printf("Attribute tests are ignored.\n"); } - if (s->csteps < 1 || s->csteps > s->nsteps) { - printf("communication interval is out of bounds\n"); - TEST_ERROR; - } - if (argc > 0) { printf("unexpected command-line arguments\n"); TEST_ERROR; @@ -319,147 +308,6 @@ error: 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) { - printf("HDwrite failed\n"); - TEST_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) { - printf("HDread failed\n"); - TEST_ERROR; - } - - if (s->np_notify == -1) { - printf("reader failed to verify group or attribute operation.\n"); - TEST_ERROR; - } - - if (s->np_notify != s->np_verify) { - printf("received message %d, expecting %d\n", s->np_notify, s->np_verify); - TEST_ERROR; - } - - return true; - -error: - return false; -} - -/* 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) { - printf("HDread failed\n"); - TEST_ERROR; - } - - if (s->np_notify == -1) { - printf("writer failed to create group or carry out an attribute operation.\n"); - TEST_ERROR; - } - - if (s->np_notify != s->np_verify) { - printf("received message %d, expecting %d\n", s->np_notify, s->np_verify); - TEST_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: check_ohr_num_chunk * @@ -597,20 +445,6 @@ add_attr(state_t *s, hid_t oid, unsigned int which, unsigned num_attrs, const ch } } - /* 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 */ @@ -621,11 +455,6 @@ add_attr(state_t *s, hid_t oid, unsigned int which, unsigned num_attrs, const ch 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); @@ -668,11 +497,12 @@ static bool add_default_group_attr(state_t *s, hid_t g, unsigned int which) { - const char *aname_format = "attr-%u"; + const char *aname_format = "attr-%u-%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); + /* Note: the number of attributes can be configurable, + * the default number of attribute is 1. + */ + return add_attr(s, g, which, s->num_attrs, aname_format, which); } /*------------------------------------------------------------------------- @@ -757,24 +587,9 @@ add_vlstr_attr(state_t *s, hid_t g, unsigned int which) 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); @@ -785,7 +600,6 @@ error: if (astr_val) HDfree(astr_val); -error2: return false; } @@ -863,25 +677,9 @@ del_one_attr(state_t *s, hid_t obj_id, bool is_dense, bool is_vl_or_ohrc, unsign TEST_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; } @@ -988,26 +786,8 @@ modify_attr(state_t *s, hid_t g, const char *aname_fmt, unsigned int which) TEST_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); @@ -1015,7 +795,6 @@ error: } H5E_END_TRY; -error2: return false; } @@ -1099,18 +878,6 @@ modify_vlstr_attr(state_t *s, hid_t g, unsigned int which) 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: @@ -1124,10 +891,6 @@ error: if (astr_val) HDfree(astr_val); - if (s->use_named_pipes && s->attr_test == true) - np_send_error(s, true); - -error2: return false; } @@ -1228,8 +991,6 @@ add_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which) 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; } @@ -1288,8 +1049,6 @@ add_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which) return ret_value; error: - if (s->use_named_pipes && s->attr_test == true) - np_send_error(s, true); return false; } @@ -1353,20 +1112,6 @@ del_attrs_compact_dense_compact(state_t *s, hid_t obj_id, hid_t gcpl, unsigned i printf("H5Adelete failed\n"); TEST_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 @@ -1382,34 +1127,10 @@ del_attrs_compact_dense_compact(state_t *s, hid_t obj_id, hid_t gcpl, unsigned i printf("H5Adelete failed\n"); TEST_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; } @@ -1510,8 +1231,6 @@ add_del_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which) return ret_value; error: - if (s->use_named_pipes && s->attr_test == true) - np_send_error(s, true); return false; } @@ -1753,7 +1472,6 @@ write_group(state_t *s, unsigned int which) esnprintf(name, sizeof(name), "/group-%u", which); -#if 0 if (s->old_style_grp) gcpl = H5P_DEFAULT; else { @@ -1771,7 +1489,6 @@ write_group(state_t *s, unsigned int which) } } } -#endif if (s->gperf) { @@ -1782,7 +1499,8 @@ write_group(state_t *s, unsigned int which) TEST_ERROR; } } - if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) { printf("H5Gcreate2 failed\n"); TEST_ERROR; } @@ -1804,7 +1522,6 @@ write_group(state_t *s, unsigned int which) s->total_time += temp_time; } -#if 0 /* We need to create a dummy dataset for the object header continuation block test. */ if (s->at_pattern == 'a' || s->at_pattern == 'R') { if ((dummy_d = H5Dcreate2(g, "Dataset", H5T_NATIVE_INT, s->one_by_one_sid, H5P_DEFAULT, H5P_DEFAULT, @@ -1843,23 +1560,6 @@ write_group(state_t *s, unsigned int which) } } - /* 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) @@ -1871,12 +1571,17 @@ write_group(state_t *s, unsigned int which) TEST_ERROR; } } -#endif + if (H5Gclose(g) < 0) { printf("H5Gclose failed\n"); TEST_ERROR; } + if (!s->old_style_grp && H5Pclose(gcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + return result; error: @@ -1884,11 +1589,16 @@ error: H5E_BEGIN_TRY { H5Gclose(g); + if (s->at_pattern == 'a' || s->at_pattern == 'R') + H5Dclose(dummy_d); + if (!s->old_style_grp) + H5Pclose(gcpl); } H5E_END_TRY; return false; } + /*------------------------------------------------------------------------- * Function: check_attr_storage_type * @@ -1987,22 +1697,6 @@ vrfy_attr(state_t *s, hid_t g, unsigned int which, const char *aname, unsigned i 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); @@ -2038,7 +1732,6 @@ vrfy_attr(state_t *s, hid_t g, unsigned int which, const char *aname, unsigned i printf("The attribute storage type is wrong. \n"); TEST_ERROR; } - dbgf(2, "reader: finish checking the storage type: %d\n", s->np_notify); } /* If coming to an "object header continuation block" test, @@ -2052,14 +1745,6 @@ vrfy_attr(state_t *s, hid_t g, unsigned int which, const char *aname, unsigned i } } - /* 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) { - printf("named pipe reader send message error\n"); - TEST_ERROR; - } - dbgf(2, "reader: finish sending back the message: %d\n", s->np_notify); - } return true; error: @@ -2069,11 +1754,6 @@ error: 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; } @@ -2155,20 +1835,6 @@ verify_modify_attr(state_t *s, hid_t g, unsigned int 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) { @@ -2204,12 +1870,6 @@ verify_modify_attr(state_t *s, hid_t g, unsigned int which) TEST_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; @@ -2222,12 +1882,6 @@ error: } 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; } @@ -2270,20 +1924,6 @@ verify_group_vlstr_attr(state_t *s, hid_t g, unsigned int which, bool vrfy_mod) 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) { @@ -2346,13 +1986,6 @@ verify_group_vlstr_attr(state_t *s, hid_t g, unsigned int which, bool vrfy_mod) 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: @@ -2367,12 +2000,6 @@ error: 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; } @@ -2415,20 +2042,6 @@ verify_del_one_attr(state_t *s, hid_t g, const char *aname, bool check_storage, 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) { @@ -2450,7 +2063,6 @@ verify_del_one_attr(state_t *s, hid_t g, const char *aname, bool check_storage, printf("The attribute storage type is wrong. \n"); TEST_ERROR; } - dbgf(2, "reader: finish checking the storage type: %d\n", s->np_notify); } /* If coming to an "object header continuation block" test, @@ -2464,20 +2076,8 @@ verify_del_one_attr(state_t *s, hid_t g, const char *aname, bool check_storage, } } - /* Reader sends an OK message back to the reader */ - if (s->use_named_pipes && s->attr_test == true) { - if (np_rd_send(s) == false) - TEST_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; } @@ -3005,11 +2605,6 @@ verify_group_attribute(state_t *s, hid_t g, unsigned int which) 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; } @@ -3043,21 +2638,6 @@ verify_group(state_t *s, unsigned int which) 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) { printf("Number of created groups is out of bounds\n"); TEST_ERROR; @@ -3102,14 +2682,6 @@ verify_group(state_t *s, unsigned int which) } } - /* Reader sends an OK message back to the writer */ - if (s->use_named_pipes && s->attr_test == true) { - - if (np_rd_send(s) == false) - TEST_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(s, g, which); @@ -3131,12 +2703,6 @@ error: } 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; } @@ -3220,30 +2786,9 @@ create_group_id(state_t *s, unsigned int which, bool dense_to_compact) TEST_ERROR; } - /* If a grp_op_test is turned on and named pipes are used, - * the writer should send and receive messages after the group creation. - * Writer sends a message to reader: a group is successfully created. - * then wait for the reader to verify and send an acknowledgement message back.*/ - if (s->use_named_pipes && s->grp_op_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; - } - } - return g; error: - /* Writer needs to send an error message to the reader to stop the test*/ - if (s->use_named_pipes && s->grp_op_test == true) - np_send_error(s, true); - -error2: H5E_BEGIN_TRY { @@ -3282,28 +2827,9 @@ close_group_id(state_t *s, hid_t g) TEST_ERROR; } - /* If a grp_op_test is turned on and named pipes are used, for - * link storage test, - * Writer sends a message to reader: the group is successfully closed. - * then wait for the reader to verify and send an acknowledgement message back.*/ - if (s->use_named_pipes && s->grp_op_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(); - 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->grp_op_test == true) - np_send_error(s, true); - -error2: - return false; } @@ -3371,25 +2897,9 @@ create_group(state_t *s, unsigned int which) TEST_ERROR; } - /* Writer sends a message to reader, - * then wait for the reader to verify and send an acknowledgement message back.*/ - if (s->use_named_pipes && s->grp_op_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(); - 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->grp_op_test == true) - np_send_error(s, true); - -error2: H5E_BEGIN_TRY { @@ -3476,26 +2986,9 @@ delete_one_link(state_t *s, hid_t obj_id, const char *name, short link_storage, } } - /* Writer sends a message to reader: - * then wait for the reader to verify and send an acknowledgement message back.*/ - if (s->use_named_pipes && s->grp_op_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(); - 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->grp_op_test == true) - np_send_error(s, true); - -error2: - return false; } @@ -3578,26 +3071,9 @@ move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, TEST_ERROR; } - /* Writer sends a message to reader: - * then wait for the reader to verify and send an acknowledgement message back.*/ - if (s->use_named_pipes && s->grp_op_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(); - 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->grp_op_test == true) - np_send_error(s, true); - -error2: - return false; } @@ -3745,26 +3221,9 @@ insert_one_link(state_t *s, hid_t obj_id, const char *name, const char *newname, } } - /* Writer sends a message to reader, - * then wait for the reader to verify and send an acknowledgement message back.*/ - if (s->use_named_pipes && s->grp_op_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(); - 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->grp_op_test == true) - np_send_error(s, true); - -error2: - return false; } @@ -4088,23 +3547,6 @@ vrfy_create_group(state_t *s, unsigned int which) hid_t g = H5I_INVALID_HID; H5G_info_t group_info; - dbgf(2, "reader: ready to send the message: \n"); - - /* 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->grp_op_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) { printf("Number of created groups is out of bounds\n"); TEST_ERROR; @@ -4143,13 +3585,6 @@ vrfy_create_group(state_t *s, unsigned int which) TEST_ERROR; } - /* Reader sends an OK message back to the writer */ - if (s->use_named_pipes && s->grp_op_test == true) { - - if (np_rd_send(s) == false) - TEST_ERROR; - dbgf(1, "Reader: finish sending back the message: %d\n", s->np_notify); - } return true; @@ -4161,12 +3596,6 @@ error: } H5E_END_TRY; - /* The reader sends an error message to the writer to stop the test.*/ - if (s->use_named_pipes && s->grp_op_test == true) - np_send_error(s, false); - -error2: - return false; } @@ -4206,22 +3635,6 @@ vrfy_create_group_id(state_t *s, unsigned int which, bool dense_to_compact) unsigned max_compact = 0; unsigned min_dense = 0; - dbgf(2, "reader: ready to receive a message: \n"); - /* 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->grp_op_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) { printf("Number of the created groups is out of bounds\n"); TEST_ERROR; @@ -4291,14 +3704,6 @@ vrfy_create_group_id(state_t *s, unsigned int which, bool dense_to_compact) dbgf(2, "Storage info is %d\n", group_info.storage_type); - /* Reader sends an OK message back to the reader */ - if (s->use_named_pipes && s->grp_op_test == true) { - - if (np_rd_send(s) == false) - TEST_ERROR; - dbgf(1, "Reader: finish sending back the message: %d\n", s->np_notify); - } - return g; error: @@ -4310,12 +3715,6 @@ error: } H5E_END_TRY; - /* The reader sends an error message to the writer to stop the test.*/ - if (s->use_named_pipes && s->grp_op_test == true) - np_send_error(s, false); - -error2: - return -1; } @@ -4342,43 +3741,16 @@ static bool vrfy_close_group_id(state_t *s, hid_t g) { - /* 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->grp_op_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 (H5Gclose(g) < 0) { printf("H5Gclose failed\n"); TEST_ERROR; } - /* Reader sends an OK message back to the reader */ - if (s->use_named_pipes && s->grp_op_test == true) { - - if (np_rd_send(s) == false) - TEST_ERROR; - dbgf(1, "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->grp_op_test == true) - np_send_error(s, false); - -error2: return false; } @@ -4418,21 +3790,6 @@ vrfy_one_link_exist(state_t *s, hid_t obj_id, const char *name, bool expect_exis int link_exists = 0; H5G_info_t group_info; - dbgf(2, "reader: ready to send the message: \n"); - /* 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->grp_op_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); - } link_exists = H5Lexists(obj_id, name, H5P_DEFAULT); @@ -4479,24 +3836,10 @@ vrfy_one_link_exist(state_t *s, hid_t obj_id, const char *name, bool expect_exis } } - /* Reader sends an OK message back to the reader */ - if (s->use_named_pipes && s->grp_op_test == true) { - if (np_rd_send(s) == false) { - TEST_ERROR; - } - dbgf(1, "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->grp_op_test == true) - np_send_error(s, false); - -error2: - return false; } @@ -4572,22 +3915,6 @@ vrfy_move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newn H5G_info_t group_info; int link_exists = 0; - dbgf(2, "reader: ready to send the message: \n"); - /* 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->grp_op_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) { printf("Number of created groups is out of bounds\n"); TEST_ERROR; @@ -4634,15 +3961,6 @@ vrfy_move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newn TEST_ERROR; } - /* Reader sends an OK message back to the reader */ - if (s->use_named_pipes && s->grp_op_test == true) { - - if (np_rd_send(s) == false) { - TEST_ERROR; - } - dbgf(1, "Reader: finish sending back the message: %d\n", s->np_notify); - } - return true; error: @@ -4653,12 +3971,6 @@ error: } H5E_END_TRY; - /* The reader sends an error message to the writer to stop the test.*/ - if (s->use_named_pipes && s->grp_op_test == true) - np_send_error(s, false); - -error2: - return false; } @@ -4986,6 +4298,7 @@ verify_group_operations(state_t *s, unsigned int which) return ret_value; } + int main(int argc, char **argv) { @@ -4995,10 +4308,6 @@ main(int argc, char **argv) state_t s; const char * personality; H5F_vfd_swmr_config_t config; - const char * fifo_writer_to_reader = "./fifo_group_writer_to_reader"; - 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; bool wg_ret = false; bool vg_ret = false; struct timespec start_time, end_time; @@ -5079,127 +4388,55 @@ main(int argc, char **argv) TEST_ERROR; } - /* Use two named pipes(FIFO) to coordinate the writer and reader for - * two-way communication so that the two sides can move forward together. - * One is for the writer to write to the reader. - * The other one is for the reader to signal the writer. */ - if (s.use_named_pipes && writer) { - /* Writer creates two named pipes(FIFO) */ - if (HDmkfifo(fifo_writer_to_reader, 0600) < 0) { - printf("HDmkfifo failed\n"); - TEST_ERROR; - } - if (HDmkfifo(fifo_reader_to_writer, 0600) < 0) { - printf("HDmkfifo failed\n"); - TEST_ERROR; - } - } + if (writer) { + if (s.gperf) { - /* Both the writer and reader open the pipes */ - if (s.use_named_pipes && (fd_writer_to_reader = HDopen(fifo_writer_to_reader, O_RDWR)) < 0) { - printf("HDopen failed\n"); - TEST_ERROR; - } + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - if (s.use_named_pipes && (fd_reader_to_writer = HDopen(fifo_reader_to_writer, O_RDWR)) < 0) { - printf("HDopen failed\n"); - TEST_ERROR; - } + fprintf(stderr, "HDclock_gettime failed"); - /* 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; + TEST_ERROR; + } } - /* 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.attr_test && s.use_named_pipes) - s.csteps = 1; - - /* For group operation test, force the named pipe to communicate in every step. */ - if (s.grp_op_test && s.use_named_pipes) - s.csteps = 1; - - if (writer) { for (step = 0; step < s.nsteps; step++) { dbgf(2, "writer: step %d\n", step); wg_ret = group_operations(&s, step); if (wg_ret == false) { - - /* At communication interval, notifies the reader about the failure and quit */ - if (s.use_named_pipes && s.attr_test != true && s.grp_op_test != true && step % s.csteps == 0) - np_send_error(&s, true); printf("write_group failed at step %d\n", step); TEST_ERROR; } - else { + } + if (s.gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - /* At communication interval, notifies the reader and waits for its response */ - if (s.use_named_pipes && s.attr_test != true && s.grp_op_test != true && - step % s.csteps == 0) { + fprintf(stderr, "HDclock_gettime failed"); - if (np_wr_send_receive(&s) == false) { - printf("writer: write group - verification failed.\n"); - TEST_ERROR; - } - } - } + TEST_ERROR; } + + s.total_time = TIME_PASSED(start_time, end_time); s.mean_time = s.total_time / s.nsteps; - fprintf(stdout, "group creation min. time = %lf\n", s.min_time); - fprintf(stdout, "group creation max. time = %lf\n", s.max_time); - fprintf(stdout, "group creation mean time = %lf\n", s.mean_time); - fprintf(stdout, "group creation total time = %lf\n", s.total_time); + fprintf(stdout, "group creation +5 attrs total time = %lf\n", s.total_time); + fprintf(stdout, "group creation +5 attrs mean time = %lf\n", s.mean_time); + } + } else { for (step = 0; step < s.nsteps; step++) { dbgf(1, "reader: step %d\n", step); - /* At communication interval, waits for the writer to finish creation before starting verification - */ - if (s.use_named_pipes && s.attr_test != true && s.grp_op_test != true && step % s.csteps == 0) { - if (false == np_rd_receive(&s)) { - TEST_ERROR; - } - } - - /* 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); - vg_ret = verify_group_operations(&s, step); if (vg_ret == false) { printf("verify_group_operations failed\n"); - - /* At communication interval, tell the writer about the failure and exit */ - if (s.use_named_pipes && s.attr_test != true && s.grp_op_test != true && step % s.csteps == 0) - np_send_error(&s, false); TEST_ERROR; } - 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 && s.grp_op_test != true && - step % s.csteps == 0) { - if (np_rd_send(&s) == false) { - TEST_ERROR; - } - } - } } } @@ -5249,31 +4486,6 @@ main(int argc, char **argv) fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); } - - /* Both the writer and reader close the named pipes */ - if (s.use_named_pipes && HDclose(fd_writer_to_reader) < 0) { - printf("HDclose failed\n"); - TEST_ERROR; - } - - if (s.use_named_pipes && HDclose(fd_reader_to_writer) < 0) { - printf("HDclose failed\n"); - TEST_ERROR; - } - - /* Reader finishes last and deletes the named pipes */ - if (s.use_named_pipes && !writer) { - if (HDremove(fifo_writer_to_reader) != 0) { - printf("HDremove failed\n"); - TEST_ERROR; - } - - if (HDremove(fifo_reader_to_writer) != 0) { - printf("HDremove failed\n"); - TEST_ERROR; - } - } - return EXIT_SUCCESS; error: @@ -5286,17 +4498,6 @@ error: } H5E_END_TRY; - if (s.use_named_pipes && fd_writer_to_reader >= 0) - HDclose(fd_writer_to_reader); - - if (s.use_named_pipes && fd_reader_to_writer >= 0) - HDclose(fd_reader_to_writer); - - if (s.use_named_pipes && !writer) { - HDremove(fifo_writer_to_reader); - HDremove(fifo_reader_to_writer); - } - return EXIT_FAILURE; } -- cgit v0.12 From 84b8db9485acfc764bb9380721d1464a30771888 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Aug 2021 20:28:31 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_gperf_writer.c | 59 ++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index ac56ee4..389749f 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -10,17 +10,17 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* Description of this program: +/* Description of this program: * This program checks the performance of group creations for VFD SWMR. * Currently the group creation time, H5Fopen and H5Fclose time are measured. - * After compiling the program, + * After compiling the program, * ./vfd_swmr_gperf_writer -n 1000 -P -N 5 -a 1 -q - * will generate 1000 groups, each group has 5 attributes. + * will generate 1000 groups, each group has 5 attributes. * ./vfd_swmr_gperf_writer -n 1000 -P -N 0 -q * will generate 1000 empty groups. * ./vfd_swmr_gperf_writer -n 1000 -P -q * will generate 1000 groups,for every ten groups, an attribute is generated. -*/ + */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ #include "hdf5.h" @@ -34,7 +34,7 @@ #ifndef H5_HAVE_WIN32_API -#define VS_ATTR_NAME_LEN 21 +#define VS_ATTR_NAME_LEN 21 #define TIME_PASSED(X, Y) \ ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0 @@ -67,13 +67,10 @@ typedef struct { (state_t) \ { \ .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ - .filetype = H5T_NATIVE_UINT32, .asteps = 10, .nsteps = 100, \ - .use_vfd_swmr = true, .old_style_grp = false, \ - .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ - .attr_test = false, .tick_len = 4, .max_lag = 7, \ - .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ - .total_time = 0., .fo_total_time = 0., \ - .fc_total_time = 0., .num_attrs = 1 \ + .filetype = H5T_NATIVE_UINT32, .asteps = 10, .nsteps = 100, .use_vfd_swmr = true, \ + .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ + .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_time = 100., .max_time = 0., \ + .mean_time = 0., .total_time = 0., .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1 \ } static void @@ -445,7 +442,6 @@ add_attr(state_t *s, hid_t oid, unsigned int which, unsigned num_attrs, const ch } } - } /* end for */ if (H5Tclose(amtype) < 0) { @@ -1560,7 +1556,6 @@ write_group(state_t *s, unsigned int which) } } - /* Then carry out the attribute operation. */ if (s->asteps != 0 && which % s->asteps == 0) result = add_group_attribute(s, g, gcpl, which); @@ -3585,7 +3580,6 @@ vrfy_create_group(state_t *s, unsigned int which) TEST_ERROR; } - return true; error: @@ -3746,7 +3740,6 @@ vrfy_close_group_id(state_t *s, hid_t g) TEST_ERROR; } - return true; error: @@ -3790,7 +3783,6 @@ vrfy_one_link_exist(state_t *s, hid_t obj_id, const char *name, bool expect_exis int link_exists = 0; H5G_info_t group_info; - link_exists = H5Lexists(obj_id, name, H5P_DEFAULT); if (link_exists < 0) { @@ -4298,7 +4290,6 @@ verify_group_operations(state_t *s, unsigned int which) return ret_value; } - int main(int argc, char **argv) { @@ -4384,17 +4375,16 @@ main(int argc, char **argv) TEST_ERROR; } - if (writer) { - if (s.gperf) { + if (s.gperf) { - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; + TEST_ERROR; + } } - } for (step = 0; step < s.nsteps; step++) { dbgf(2, "writer: step %d\n", step); @@ -4406,21 +4396,20 @@ main(int argc, char **argv) TEST_ERROR; } } - if (s.gperf) { + if (s.gperf) { - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; - } - - s.total_time = TIME_PASSED(start_time, end_time); - s.mean_time = s.total_time / s.nsteps; - fprintf(stdout, "group creation +5 attrs total time = %lf\n", s.total_time); - fprintf(stdout, "group creation +5 attrs mean time = %lf\n", s.mean_time); - } + TEST_ERROR; + } + s.total_time = TIME_PASSED(start_time, end_time); + s.mean_time = s.total_time / s.nsteps; + fprintf(stdout, "group creation +5 attrs total time = %lf\n", s.total_time); + fprintf(stdout, "group creation +5 attrs mean time = %lf\n", s.mean_time); + } } else { for (step = 0; step < s.nsteps; step++) { -- cgit v0.12 From 3cdef1e84c78d3fd776916928547f3adb3d4167b Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Thu, 5 Aug 2021 07:51:44 -0500 Subject: Add the group level support. --- test/vfd_swmr_gperf_writer.c | 217 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 192 insertions(+), 25 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index ac56ee4..04a35ad 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -61,6 +61,7 @@ typedef struct { double fo_total_time; double fc_total_time; unsigned int num_attrs; + unsigned int nglevels; } state_t; #define ALL_HID_INITIALIZER \ @@ -73,15 +74,17 @@ typedef struct { .attr_test = false, .tick_len = 4, .max_lag = 7, \ .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ .total_time = 0., .fo_total_time = 0., \ - .fc_total_time = 0., .num_attrs = 1 \ + .fc_total_time = 0., .num_attrs = 1, .nglevels = 0 \ } + + static void usage(const char *progname) { fprintf(stderr, "usage: %s [-S] [-G] [-a steps] [-b] [-n iterations]\n" - " [-N num_attrs] [-q] [-A at_pattern] [-O grp_op_pattern]\n" + " [-N num_attrs] [-l nested group levels] [-q] [-A at_pattern] [-O grp_op_pattern]\n" "\n" "-S: do not use VFD SWMR\n" "-G: old-style type of group\n" @@ -89,6 +92,9 @@ usage(const char *progname) "-b: write data in big-endian byte order\n" "-n ngroups: the number of groups\n" "-N: the number of attributes \n" + "-l: the number of level of nested groups. \n" + " If all the groups are under the root group, \n" + " this number should be 0.\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" @@ -166,10 +172,14 @@ state_init(state_t *s, int argc, char **argv) esnprintf(s->progname, sizeof(s->progname), "%s", tfile); - if (tfile) + if (tfile) { HDfree(tfile); + tfile = NULL; + } - while ((ch = getopt(argc, argv, "PSGa:bn:qA:N:O:")) != -1) { + if(argc == 1) + usage(s->progname); + while ((ch = getopt(argc, argv, "PSGa:bn:qA:N:l:O:")) != -1) { switch (ch) { case 'P': s->gperf = true; @@ -183,6 +193,7 @@ state_init(state_t *s, int argc, char **argv) case 'a': case 'n': case 'N': + case 'l': errno = 0; tmp = HDstrtoul(optarg, &end, 0); if (end == optarg || *end != '\0') { @@ -204,6 +215,8 @@ state_init(state_t *s, int argc, char **argv) s->nsteps = (unsigned)tmp; else if (ch == 'N') s->num_attrs = (unsigned)tmp; + else if (ch == 'l') + s->nglevels = (unsigned)tmp; break; case 'b': s->filetype = H5T_STD_U32BE; @@ -1599,6 +1612,7 @@ error: return false; } + /*------------------------------------------------------------------------- * Function: check_attr_storage_type * @@ -4298,6 +4312,126 @@ verify_group_operations(state_t *s, unsigned int which) return ret_value; } +static unsigned int grp_counter = 0; +static unsigned int UI_Pow(unsigned int x,unsigned int n) +{ + unsigned int i; /* Variable used in loop grp_counter */ + unsigned int number = 1; + + for (i = 0; i < n; ++i) + number *= x; + + return(number); +} + +static unsigned int obtain_tree_level_elems(unsigned int total_ele,unsigned int level) { + + assert(level <=total_ele); + if(level == 0) + return total_ele; + else { + unsigned int test_elems_level = 0; + unsigned total = 0; + unsigned int i = 1; + while (total 0 && grp_counter nsteps) { + + for(i = 0; i < ne_per_level; i++) { + esnprintf(name, sizeof(name), "group-%u", grp_counter); + if(grp_counter ==s->nsteps) + break; + /* For each i a group is created. + Use grp_counter to generate the group name. + printf("id: %u,level: %u, index: %u\n",id,level,i); + */ + if ((grp_id = H5Gcreate2(pgrp_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + /* Just check the first group information. */ + if(grp_counter == 0) { + if (H5Gget_info(grp_id, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + if (s->old_style_grp) { + if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("Old-styled group test: but the group is not in old-style. \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the old-style.\n"); + } + else { + if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the new-style.\n"); + } + } + + + /* Then carry out the attribute operation. */ + if (s->asteps != 0 && grp_counter % s->asteps == 0) + result = add_default_group_attr(s, grp_id, grp_counter); + + if (result == false) { + printf("Cannot create group attributes. \n"); + TEST_ERROR; + } + grp_counter++; + result = gen_tree_struct(s,level-1,ne_per_level,grp_id); + if (result == false) { + printf("Cannot create nested groups. \n"); + TEST_ERROR; + } + + /* close the group ID. No problem. */ + if(H5Gclose(grp_id)<0) { + printf("H5Gclose failed. \n"); + TEST_ERROR; + } + } + } + + return true; + +error: + + H5E_BEGIN_TRY + { + H5Gclose(grp_id); + } + H5E_END_TRY; + + return false; +} + + + int main(int argc, char **argv) @@ -4311,6 +4445,7 @@ main(int argc, char **argv) bool wg_ret = false; bool vg_ret = false; struct timespec start_time, end_time; + unsigned int num_elems_per_level; if (!state_init(&s, argc, argv)) { printf("state_init failed\n"); @@ -4351,6 +4486,14 @@ main(int argc, char **argv) TEST_ERROR; } + if(s.nglevels >0) { + if(s.grp_op_pattern!=' ' || s.at_pattern!=' '){ + printf("For nested group creation test, only the default option is supported.\n"); + printf("Please re-run the tests with the appopriate option.\n"); + TEST_ERROR; + } + } + if (s.gperf) { if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { @@ -4386,43 +4529,67 @@ main(int argc, char **argv) if (writer) { - if (s.gperf) { + if (s.gperf) { - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; - } - } + TEST_ERROR; + } - for (step = 0; step < s.nsteps; step++) { - dbgf(2, "writer: step %d\n", step); + } - wg_ret = group_operations(&s, step); + if (s.nglevels >0) { - if (wg_ret == false) { - printf("write_group failed at step %d\n", step); + num_elems_per_level = obtain_tree_level_elems(s.nsteps,s.nglevels); + //wg_ret = gen_tree_struct(&s,s.nsteps,s.nglevels,num_elems_per_level,s.file); + /* for the recursive call, the groups under the root is treated as one level */ + wg_ret = gen_tree_struct(&s,s.nglevels+1,num_elems_per_level,s.file); + if(wg_ret == false) { + printf("write nested group failed at group counter %u\n", grp_counter); TEST_ERROR; } } - if (s.gperf) { + else { + for (step = 0; step < s.nsteps; step++) { - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + dbgf(2, "writer: step %d\n", step); + wg_ret = group_operations(&s, step); + if (wg_ret == false) { + printf("write_group failed at step %d\n", step); + TEST_ERROR; + } + } + } - fprintf(stderr, "HDclock_gettime failed"); + if (s.gperf) { - TEST_ERROR; - } + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - s.total_time = TIME_PASSED(start_time, end_time); - s.mean_time = s.total_time / s.nsteps; - fprintf(stdout, "group creation +5 attrs total time = %lf\n", s.total_time); - fprintf(stdout, "group creation +5 attrs mean time = %lf\n", s.mean_time); - } + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + + s.total_time = TIME_PASSED(start_time, end_time); + s.mean_time = s.total_time / s.nsteps; + fprintf(stdout, "group creation +5 attrs total time = %lf\n", s.total_time); + fprintf(stdout, "group creation +5 attrs mean time = %lf\n", s.mean_time); + } } else { + + if (s.nglevels > 0) { + printf("Reader: The nested group creation test is not implemented. Stop!\n"); + TEST_ERROR; + } + if(s.num_attrs >1) { + printf("Reader: number of attribute must be 1 for the default group test. Stop!\n"); + printf("The current number of attributes per group is %u\n",s.num_attrs); + TEST_ERROR; + } + for (step = 0; step < s.nsteps; step++) { dbgf(1, "reader: step %d\n", step); -- cgit v0.12 From 5bf08f0dd7295194b06dacb3f413211c1a90a417 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 5 Aug 2021 13:05:01 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_gperf_writer.c | 110 ++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 58 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index 86a5f70..c1844d4 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -68,17 +68,13 @@ typedef struct { (state_t) \ { \ .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ - .filetype = H5T_NATIVE_UINT32, .asteps = 10, .nsteps = 100, \ - .use_vfd_swmr = true, .old_style_grp = false, \ - .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ - .attr_test = false, .tick_len = 4, .max_lag = 7, \ - .gperf = false, .min_time = 100., .max_time = 0.,.mean_time = 0., \ - .total_time = 0., .fo_total_time = 0., \ - .fc_total_time = 0., .num_attrs = 1, .nglevels = 0 \ + .filetype = H5T_NATIVE_UINT32, .asteps = 10, .nsteps = 100, .use_vfd_swmr = true, \ + .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ + .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_time = 100., .max_time = 0., \ + .mean_time = 0., .total_time = 0., .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, \ + .nglevels = 0 \ } - - static void usage(const char *progname) { @@ -177,7 +173,7 @@ state_init(state_t *s, int argc, char **argv) tfile = NULL; } - if(argc == 1) + if (argc == 1) usage(s->progname); while ((ch = getopt(argc, argv, "PSGa:bn:qA:N:l:O:")) != -1) { switch (ch) { @@ -1610,7 +1606,6 @@ error: return false; } - /*------------------------------------------------------------------------- * Function: check_attr_storage_type * @@ -4308,7 +4303,8 @@ verify_group_operations(state_t *s, unsigned int which) } static unsigned int grp_counter = 0; -static unsigned int UI_Pow(unsigned int x,unsigned int n) +static unsigned int +UI_Pow(unsigned int x, unsigned int n) { unsigned int i; /* Variable used in loop grp_counter */ unsigned int number = 1; @@ -4316,45 +4312,47 @@ static unsigned int UI_Pow(unsigned int x,unsigned int n) for (i = 0; i < n; ++i) number *= x; - return(number); + return (number); } -static unsigned int obtain_tree_level_elems(unsigned int total_ele,unsigned int level) { +static unsigned int +obtain_tree_level_elems(unsigned int total_ele, unsigned int level) +{ - assert(level <=total_ele); - if(level == 0) - return total_ele; - else { + assert(level <= total_ele); + if (level == 0) + return total_ele; + else { unsigned int test_elems_level = 0; - unsigned total = 0; - unsigned int i = 1; - while (total 0 && grp_counter nsteps) { + if (level > 0 && grp_counter < s->nsteps) { - for(i = 0; i < ne_per_level; i++) { + for (i = 0; i < ne_per_level; i++) { esnprintf(name, sizeof(name), "group-%u", grp_counter); - if(grp_counter ==s->nsteps) + if (grp_counter == s->nsteps) break; /* For each i a group is created. Use grp_counter to generate the group name. @@ -4366,7 +4364,7 @@ static bool gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_leve } /* Just check the first group information. */ - if(grp_counter == 0) { + if (grp_counter == 0) { if (H5Gget_info(grp_id, &group_info) < 0) { printf("H5Gget_info failed\n"); TEST_ERROR; @@ -4388,7 +4386,6 @@ static bool gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_leve } } - /* Then carry out the attribute operation. */ if (s->asteps != 0 && grp_counter % s->asteps == 0) result = add_default_group_attr(s, grp_id, grp_counter); @@ -4398,14 +4395,14 @@ static bool gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_leve TEST_ERROR; } grp_counter++; - result = gen_tree_struct(s,level-1,ne_per_level,grp_id); + result = gen_tree_struct(s, level - 1, ne_per_level, grp_id); if (result == false) { printf("Cannot create nested groups. \n"); TEST_ERROR; } - + /* close the group ID. No problem. */ - if(H5Gclose(grp_id)<0) { + if (H5Gclose(grp_id) < 0) { printf("H5Gclose failed. \n"); TEST_ERROR; } @@ -4425,9 +4422,6 @@ error: return false; } - - - int main(int argc, char **argv) { @@ -4481,14 +4475,14 @@ main(int argc, char **argv) TEST_ERROR; } - if(s.nglevels >0) { - if(s.grp_op_pattern!=' ' || s.at_pattern!=' '){ + if (s.nglevels > 0) { + if (s.grp_op_pattern != ' ' || s.at_pattern != ' ') { printf("For nested group creation test, only the default option is supported.\n"); printf("Please re-run the tests with the appopriate option.\n"); TEST_ERROR; } } - + if (s.gperf) { if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { @@ -4533,13 +4527,13 @@ main(int argc, char **argv) } } - if (s.nglevels >0) { + if (s.nglevels > 0) { - num_elems_per_level = obtain_tree_level_elems(s.nsteps,s.nglevels); - //wg_ret = gen_tree_struct(&s,s.nsteps,s.nglevels,num_elems_per_level,s.file); + num_elems_per_level = obtain_tree_level_elems(s.nsteps, s.nglevels); + // wg_ret = gen_tree_struct(&s,s.nsteps,s.nglevels,num_elems_per_level,s.file); /* for the recursive call, the groups under the root is treated as one level */ - wg_ret = gen_tree_struct(&s,s.nglevels+1,num_elems_per_level,s.file); - if(wg_ret == false) { + wg_ret = gen_tree_struct(&s, s.nglevels + 1, num_elems_per_level, s.file); + if (wg_ret == false) { printf("write nested group failed at group counter %u\n", grp_counter); TEST_ERROR; } @@ -4565,7 +4559,7 @@ main(int argc, char **argv) } s.total_time = TIME_PASSED(start_time, end_time); - s.mean_time = s.total_time / s.nsteps; + s.mean_time = s.total_time / s.nsteps; fprintf(stdout, "group creation +5 attrs total time = %lf\n", s.total_time); fprintf(stdout, "group creation +5 attrs mean time = %lf\n", s.mean_time); } @@ -4576,9 +4570,9 @@ main(int argc, char **argv) printf("Reader: The nested group creation test is not implemented. Stop!\n"); TEST_ERROR; } - if(s.num_attrs >1) { + if (s.num_attrs > 1) { printf("Reader: number of attribute must be 1 for the default group test. Stop!\n"); - printf("The current number of attributes per group is %u\n",s.num_attrs); + printf("The current number of attributes per group is %u\n", s.num_attrs); TEST_ERROR; } -- cgit v0.12 From 2b62f2a2638913ed783cd10a049b3e1b1d6c3447 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Tue, 17 Aug 2021 16:12:58 -0500 Subject: Add options fo max_lag, tick_len and page_size. --- test/vfd_swmr_gperf_writer.c | 45 ++++++++++++++++++++++++++++++++++++-------- test/vfd_swmr_group_writer.c | 4 +++- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index c1844d4..fb3cd0c 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -61,6 +61,8 @@ typedef struct { double fo_total_time; double fc_total_time; unsigned int num_attrs; + unsigned int ps; + unsigned int pbs; unsigned int nglevels; } state_t; @@ -72,23 +74,30 @@ typedef struct { .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_time = 100., .max_time = 0., \ .mean_time = 0., .total_time = 0., .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, \ - .nglevels = 0 \ + .ps=4096, .pbs = 4096, .nglevels = 0 \ } static void usage(const char *progname) { fprintf(stderr, - "usage: %s [-S] [-G] [-a steps] [-b] [-n iterations]\n" - " [-N num_attrs] [-l nested group levels] [-q] [-A at_pattern] [-O grp_op_pattern]\n" + "usage: %s [-S] [-G] [-a steps] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" + " [-b] [-n iterations]\n" + " [-N num_attrs] [-l ng_levels] [-q] [-A at_pattern] [-O grp_op_pattern]\n" "\n" "-S: do not use VFD SWMR\n" "-G: old-style type of group\n" "-a steps: `steps` between adding attributes\n" + "-t tick_len: length of a tick in tenths of a second.\n" + "-m max_lag: maximum expected lag(in ticks) between writer and readers\n" + "-B pbs: Page Buffer Size in bytes:\n" + " The default value is 4K(4096).\n" + "-s ps: Page size used by page aggregation, page buffer and \n" + " the metadata file. \n" "-b: write data in big-endian byte order\n" "-n ngroups: the number of groups\n" - "-N: the number of attributes \n" - "-l: the number of level of nested groups. \n" + "-N num_attrs: the number of attributes \n" + "-l ng_levels: the number of level of nested groups. \n" " If all the groups are under the root group, \n" " this number should be 0.\n" "-A at_pattern: `at_pattern' for different attribute tests\n" @@ -175,7 +184,7 @@ state_init(state_t *s, int argc, char **argv) if (argc == 1) usage(s->progname); - while ((ch = getopt(argc, argv, "PSGa:bn:qA:N:l:O:")) != -1) { + while ((ch = getopt(argc, argv, "PSGa:bt:m:B:s:n:qA:N:l:O:")) != -1) { switch (ch) { case 'P': s->gperf = true; @@ -190,6 +199,9 @@ state_init(state_t *s, int argc, char **argv) case 'n': case 'N': case 'l': + case 't': + case 'm': + case 'B': errno = 0; tmp = HDstrtoul(optarg, &end, 0); if (end == optarg || *end != '\0') { @@ -213,6 +225,14 @@ state_init(state_t *s, int argc, char **argv) s->num_attrs = (unsigned)tmp; else if (ch == 'l') s->nglevels = (unsigned)tmp; + else if (ch == 't') + s->tick_len = (unsigned)tmp; + else if (ch == 'm') + s->max_lag = (unsigned)tmp; + else if (ch == 's') + s->ps = (unsigned)tmp; + else if (ch == 'B') + s->pbs = (unsigned)tmp; break; case 'b': s->filetype = H5T_STD_U32BE; @@ -4453,18 +4473,20 @@ main(int argc, char **argv) } /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - init_vfd_swmr_config(&config, 4, 7, writer, FALSE, 128, "./group-shadow"); + //init_vfd_swmr_config(&config, 4, 7, writer, FALSE, 128, "./group-shadow"); + init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow"); /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST) * as the second parameter of H5Pset_libver_bound() that is called by * vfd_swmr_create_fapl. Otherwise, the latest file format(H5F_LIBVER_LATEST) * should be used as the second parameter of H5Pset_libver_bound(). * Also pass the use_vfd_swmr, only_meta_page, config to vfd_swmr_create_fapl().*/ - if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, &config)) < 0) { + if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, s.pbs, &config)) < 0) { printf("vfd_swmr_create_fapl failed\n"); TEST_ERROR; } +#if 0 if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { printf("H5Pcreate failed\n"); TEST_ERROR; @@ -4474,6 +4496,13 @@ main(int argc, char **argv) printf("H5Pset_file_space_strategy failed\n"); TEST_ERROR; } +#endif + + /* Set fs_strategy (file space strategy) and fs_page_size (file space page size) */ + if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s.ps)) < 0) { + HDprintf("vfd_swmr_create_fcpl() failed"); + TEST_ERROR; + } if (s.nglevels > 0) { if (s.grp_op_pattern != ' ' || s.at_pattern != ' ') { diff --git a/test/vfd_swmr_group_writer.c b/test/vfd_swmr_group_writer.c index c758781..6a3230e 100644 --- a/test/vfd_swmr_group_writer.c +++ b/test/vfd_swmr_group_writer.c @@ -153,8 +153,10 @@ state_init(state_t *s, int argc, char **argv) esnprintf(s->progname, sizeof(s->progname), "%s", tfile); - if (tfile) + if (tfile) { HDfree(tfile); + tfile = NULL; + } while ((ch = getopt(argc, argv, "SGa:bc:n:Nqu:A:O:")) != -1) { switch (ch) { -- cgit v0.12 From 4d368b7b5be882b4432b1d9dbdb3741b992ac784 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 17 Aug 2021 21:17:42 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_gperf_writer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index fb3cd0c..c23c9fd 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -74,7 +74,7 @@ typedef struct { .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_time = 100., .max_time = 0., \ .mean_time = 0., .total_time = 0., .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, \ - .ps=4096, .pbs = 4096, .nglevels = 0 \ + .ps = 4096, .pbs = 4096, .nglevels = 0 \ } static void @@ -90,7 +90,7 @@ usage(const char *progname) "-a steps: `steps` between adding attributes\n" "-t tick_len: length of a tick in tenths of a second.\n" "-m max_lag: maximum expected lag(in ticks) between writer and readers\n" - "-B pbs: Page Buffer Size in bytes:\n" + "-B pbs: Page Buffer Size in bytes:\n" " The default value is 4K(4096).\n" "-s ps: Page size used by page aggregation, page buffer and \n" " the metadata file. \n" @@ -4473,7 +4473,7 @@ main(int argc, char **argv) } /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - //init_vfd_swmr_config(&config, 4, 7, writer, FALSE, 128, "./group-shadow"); + // init_vfd_swmr_config(&config, 4, 7, writer, FALSE, 128, "./group-shadow"); init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow"); /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST) @@ -4498,7 +4498,7 @@ main(int argc, char **argv) } #endif - /* Set fs_strategy (file space strategy) and fs_page_size (file space page size) */ + /* Set fs_strategy (file space strategy) and fs_page_size (file space page size) */ if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s.ps)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); TEST_ERROR; -- cgit v0.12 From 79652fa099615b96350e59ed6150497a7b697015 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Wed, 18 Aug 2021 16:04:38 -0500 Subject: 1. Add the VL string type test. 2. Remove the reader test. 3. Fix trivial bugs and remove some warnings. --- test/vfd_swmr_gperf_writer.c | 2783 +++++++----------------------------------- 1 file changed, 463 insertions(+), 2320 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index c23c9fd..15f9522 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -61,6 +61,7 @@ typedef struct { double fo_total_time; double fc_total_time; unsigned int num_attrs; + bool vlstr_test; unsigned int ps; unsigned int pbs; unsigned int nglevels; @@ -74,17 +75,18 @@ typedef struct { .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_time = 100., .max_time = 0., \ .mean_time = 0., .total_time = 0., .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, \ - .ps = 4096, .pbs = 4096, .nglevels = 0 \ + .vlstr_test = false, .ps = 4096, .pbs = 4096, .nglevels = 0 \ } static void usage(const char *progname) { fprintf(stderr, - "usage: %s [-S] [-G] [-a steps] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" - " [-b] [-n iterations]\n" + "usage: %s [-P] [-S] [-G] [-a steps] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" + " [-b] [-n ngroups]\n" " [-N num_attrs] [-l ng_levels] [-q] [-A at_pattern] [-O grp_op_pattern]\n" "\n" + "-P: carry out the performance test\n" "-S: do not use VFD SWMR\n" "-G: old-style type of group\n" "-a steps: `steps` between adding attributes\n" @@ -97,6 +99,7 @@ usage(const char *progname) "-b: write data in big-endian byte order\n" "-n ngroups: the number of groups\n" "-N num_attrs: the number of attributes \n" + "-V vlstr attrs: Use variable length string attribute in the performance test. \n" "-l ng_levels: the number of level of nested groups. \n" " If all the groups are under the root group, \n" " this number should be 0.\n" @@ -184,7 +187,7 @@ state_init(state_t *s, int argc, char **argv) if (argc == 1) usage(s->progname); - while ((ch = getopt(argc, argv, "PSGa:bt:m:B:s:n:qA:N:l:O:")) != -1) { + while ((ch = getopt(argc, argv, "PSGa:bVt:m:B:s:n:qA:N:l:O:")) != -1) { switch (ch) { case 'P': s->gperf = true; @@ -202,6 +205,7 @@ state_init(state_t *s, int argc, char **argv) case 't': case 'm': case 'B': + case 's': errno = 0; tmp = HDstrtoul(optarg, &end, 0); if (end == optarg || *end != '\0') { @@ -237,6 +241,9 @@ state_init(state_t *s, int argc, char **argv) case 'b': s->filetype = H5T_STD_U32BE; break; + case 'V': + s->vlstr_test = true; + break; case 'O': if (HDstrcmp(optarg, "grp-creation") == 0) s->grp_op_pattern = 'c'; @@ -494,46 +501,6 @@ error: } /*------------------------------------------------------------------------- - * 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, "add-ohr-block" - * and "del-ohr-block" tests. - *------------------------------------------------------------------------- - */ - -static bool -add_default_group_attr(state_t *s, hid_t g, unsigned int which) -{ - - const char *aname_format = "attr-%u-%u"; - - /* Note: the number of attributes can be configurable, - * the default number of attribute is 1. - */ - return add_attr(s, g, which, s->num_attrs, aname_format, which); -} - -/*------------------------------------------------------------------------- * Function: add_vlstr_attr * * Purpose: Add a variable length string attribute to a group. @@ -631,6 +598,95 @@ error: return false; } + + +/*------------------------------------------------------------------------- + * Function: add_vlstr_attrs + * + * Purpose: Add variable length string attributes to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, 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". The attribute names + * are "attr-which","attr-which+1".... + * + * + * Return: Success: true + * Failure: false + * + * Note: This is for the performance test that has the VL string type. + *------------------------------------------------------------------------- + */ + +static bool +add_vlstr_attrs(state_t *s, hid_t g, unsigned int which, unsigned int num_attrs) +{ + unsigned u; + bool ret_value = true; + for (u = 0; u < num_attrs; u++) { + ret_value = add_vlstr_attr(s, g, u+which); + if(ret_value == false) + break; + } + + return ret_value; +} + + + +/*------------------------------------------------------------------------- + * Function: add_default_group_attr + * + * Purpose: Add an attribute to a group. + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, 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, "add-ohr-block" + * and "del-ohr-block" tests. + *------------------------------------------------------------------------- + */ + +static bool +add_default_group_attr(state_t *s, hid_t g, unsigned int which) +{ + + const char *aname_format = "attr-%u-%u"; + + /* Note: the number of attributes can be configurable, + * the default number of attribute is 1. + */ + /* If the vl string attribute type is chosen. */ + if(s->vlstr_test == true) + return add_vlstr_attrs(s, g, which, s->num_attrs); + else + return add_attr(s, g, which, s->num_attrs, aname_format, which); +} + + /*------------------------------------------------------------------------- * Function: del_one_attr * @@ -831,10 +887,7 @@ error: * * 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 - * + * Parameters: * hid_t g * HDF5 object ID (in this file: means group ID) * @@ -850,7 +903,7 @@ error: */ static bool -modify_vlstr_attr(state_t *s, hid_t g, unsigned int which) +modify_vlstr_attr(hid_t g, unsigned int which) { hid_t aid = H5I_INVALID_HID; @@ -956,7 +1009,7 @@ 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); + ret_value = modify_vlstr_attr(g, which); return ret_value; } @@ -1088,11 +1141,7 @@ error: * 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 + * Parameters: hid_t g * HDF5 object ID (in this file: means group ID) * * hid_t gcpl @@ -1113,7 +1162,7 @@ error: */ static bool -del_attrs_compact_dense_compact(state_t *s, hid_t obj_id, hid_t gcpl, unsigned int which) +del_attrs_compact_dense_compact(hid_t obj_id, hid_t gcpl, unsigned int which) { unsigned max_compact = 0; @@ -1302,7 +1351,7 @@ add_del_attrs_compact_dense_compact(state_t *s, hid_t g, hid_t gcpl, unsigned in 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); + ret_value = del_attrs_compact_dense_compact(g, gcpl, which); return ret_value; } @@ -1627,49 +1676,122 @@ error: } /*------------------------------------------------------------------------- - * Function: check_attr_storage_type + * Function: create_group_id * - * Purpose: Check if the attribute storage type is correct + * Purpose: Create a group and return the group ID. * - * Parameters: hid_t oid - * HDF5 object ID (in this file: means group ID) + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters * - * bool is_compact - * true if the attribute is stored in compact storage - * false if the attribute is stored in dense storage + * unsigned int which + * The number of iterations for group creation + * This is used to generate the group name. * + * bool dense_to_compact + * true if this function is used to test the transition from dense to + * compact, false if the test is from compact to dense. * - * Return: Success: true - * Failure: false + * Return: Success: the group ID + * Failure: -1 * + * Note: Only used by testing the link storage transit functions. *------------------------------------------------------------------------- */ -static bool -check_attr_storage_type(hid_t g, bool is_compact) +static hid_t +create_group_id(state_t *s, unsigned int which, bool dense_to_compact) { - H5O_native_info_t ninfo; + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + hid_t gcpl = H5I_INVALID_HID; + H5G_info_t group_info; - /* Get the object information */ - if (H5Oget_native_info(g, &ninfo, H5O_NATIVE_INFO_HDR | H5O_NATIVE_INFO_META_SIZE) < 0) { - printf("H5Oget_native_info failed\n"); + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + gcpl = H5Pcreate(H5P_GROUP_CREATE); + if (gcpl < 0) { + printf("H5Pcreate failed\n"); TEST_ERROR; } - if (is_compact) { - if (ninfo.meta_size.attr.index_size != 0 || ninfo.meta_size.attr.heap_size != 0) { - printf("Should be in compact storage,but it is not.\n"); + if (dense_to_compact) { + if (H5Pset_link_phase_change(gcpl, 2, 2) < 0) { + printf("H5Pset_link_phase_change failed for dense to compact.\n"); TEST_ERROR; } } else { - if (ninfo.meta_size.attr.index_size == 0 || ninfo.meta_size.attr.heap_size == 0) { - printf("Should be in dense storage,but it is not.\n"); + if (H5Pset_link_phase_change(gcpl, 1, 1) < 0) { + printf("H5Pset_attr_phase_change failed for compact to dense.\n"); TEST_ERROR; } } + esnprintf(name, sizeof(name), "/group-%u", which); + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); + TEST_ERROR; + } + + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); + TEST_ERROR; + } + + /* The storage type should always be compact when a group is created. */ + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("New-style group link storage test:. \n"); + printf(" still be compact after group creation. \n"); + TEST_ERROR; + } + + if (H5Pclose(gcpl) < 0) { + printf("H5Pclose failed\n"); + TEST_ERROR; + } + + return g; + +error: + + H5E_BEGIN_TRY + { + H5Pclose(gcpl); + } + H5E_END_TRY; + + return -1; +} + +/*------------------------------------------------------------------------- + * Function: close_group_id + * + * Purpose: Verify is a group is closed successfully. + * + * Parameters: hid_t g + * The ID of the group to be closed. + * + * Return: Success: true + * Failure: false + * + * Note: This is used by the link storage transit functions. + *------------------------------------------------------------------------- + */ + +static bool +close_group_id(hid_t g) +{ + + if (H5Gclose(g) < 0) { + printf("H5Gclose failed\n"); + TEST_ERROR; + } + return true; error: @@ -1677,1912 +1799,41 @@ error: } /*------------------------------------------------------------------------- - * Function: vrfy_attr + * Function: create_group * - * Purpose: Verify is a group attribute value is as expected. + * Purpose: Create 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". - * - * 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 storage should be in compact - * false if the attribute storage should be in dense - * Note: this parameter is not used if the check_storage - * is set to false. - * + * The number of iterations for group creation + * This is used to generate the group name. * * Return: Success: true * Failure: false * + * Note: This is called by the main() function. *------------------------------------------------------------------------- */ static bool -vrfy_attr(state_t *s, hid_t g, unsigned int which, const char *aname, unsigned int g_which, - bool check_storage, bool is_compact) +create_group(state_t *s, unsigned int which) { - unsigned int read_which; - hid_t aid = H5I_INVALID_HID; - hid_t amtype = H5I_INVALID_HID; - - /* Go ahead to read the attribute. */ - dbgf(1, "verifying attribute %s on group %u equals %u\n", aname, g_which, which); + char name[sizeof("/group-9999999999")]; + hid_t g = H5I_INVALID_HID; + H5G_info_t group_info; - if ((amtype = H5Tget_native_type(s->filetype, H5T_DIR_ASCEND)) < 0) { - printf("H5Tget_native_type failed\n"); + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); TEST_ERROR; } - if ((aid = H5Aopen(g, aname, H5P_DEFAULT)) < 0) { - printf("H5Aopen failed\n"); - TEST_ERROR; - } - - if (H5Aread(aid, amtype, &read_which) < 0) { - printf("H5Aread failed\n"); - TEST_ERROR; - } - - if (H5Aclose(aid) < 0) { - printf("H5Aclose failed\n"); - TEST_ERROR; - } - - if (read_which != which) { - printf("reader: the add_attribute verfication failed,expected value is %d\n", which); - printf("reader: the add_attribute verfication failed, the value is %d\n", read_which); - printf("The add_attribute verification failed\n"); - TEST_ERROR; - } - - if (!s->old_style_grp && check_storage == true) { - if (false == check_attr_storage_type(g, is_compact)) { - printf("The attribute storage type is wrong. \n"); - TEST_ERROR; - } - } - - /* If coming to an "object header continuation block" test, - * we need to check if this test behaves as expected. */ - if (s->at_pattern == 'a' || s->at_pattern == 'R') { - if (false == check_ohr_num_chunk(g, false)) { - printf("An object header continuation block should be created. \n"); - printf("But it is not.\n"); - printf("Verification of 'object header continuation block test' failed.\n"); - TEST_ERROR; - } - } - - return true; - -error: - H5E_BEGIN_TRY - { - H5Tclose(amtype); - H5Aclose(aid); - } - H5E_END_TRY; - 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, "add-ohr-block" - * and "del-ohr-block" tests. - *------------------------------------------------------------------------- - */ - -static bool -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 = 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) { - - /* Go ahead to read the attribute. */ - esnprintf(attrname, sizeof(attrname), aname_fmt, which); - if ((amtype = H5Tget_native_type(s->filetype, H5T_DIR_ASCEND)) < 0) { - printf("H5Tget_native_type failed\n"); - TEST_ERROR; - } - - if ((aid = H5Aopen(g, attrname, H5P_DEFAULT)) < 0) { - printf("H5Aopen failed\n"); - TEST_ERROR; - } - - if (H5Aread(aid, amtype, &read_which) < 0) { - printf("H5Aread failed\n"); - TEST_ERROR; - } - - if (H5Tclose(amtype) < 0) { - printf("H5Tclose failed.\n"); - TEST_ERROR; - } - - if (H5Aclose(aid) < 0) { - printf("H5Aclose failed\n"); - TEST_ERROR; - } - - /* verify the modified value */ - if (read_which != (which + 10000)) { - printf("reader: the modified_attr() expected value is %d\n", which + 10000); - printf("reader: the modified_attr() actual value is %d\n", read_which); - printf("The modify_attribute verification failed.\n"); - TEST_ERROR; - } - - return true; - } - return false; - -error: - H5E_BEGIN_TRY - { - H5Aclose(aid); - H5Tclose(amtype); - } - H5E_END_TRY; - - 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; - - /* Go ahead to read the VL string attribute. */ - astr_val_exp = HDmalloc(VS_ATTR_NAME_LEN); - if (astr_val_exp == NULL) { - printf("Allocate memory for expected buffer failed.\n"); - TEST_ERROR; - } - - esnprintf(name, sizeof(name), "attr-%u", 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) { - printf("H5Aopen failed\n"); - TEST_ERROR; - } - - /* Create a VL string datatype */ - if ((atype = H5Tcopy(H5T_C_S1)) < 0) { - printf("Cannot create variable length datatype.\n"); - TEST_ERROR; - } - - if (H5Tset_size(atype, H5T_VARIABLE) < 0) { - printf("Cannot set variable length datatype.\n"); - TEST_ERROR; - } - - if (H5Aread(aid, atype, &astr_val) < 0) { - printf("Cannot read the attribute.\n"); - TEST_ERROR; - } - - dbgf(1, "read attr is= %s\n", astr_val); - if (HDstrcmp(astr_val, astr_val_exp) != 0) { - printf("reader: the vl add_attribute verfication failed,expected value is %s\n", astr_val_exp); - printf("reader: the vl add_attribute verfication failed, the value is %s\n", astr_val); - printf("The vl add_attribute verification failed\n"); - TEST_ERROR; - } - - if (H5Tclose(atype) < 0) { - printf("H5Tclose failed.\n"); - TEST_ERROR; - } - - if (H5Aclose(aid) < 0) { - printf("H5Aclose failed.\n"); - TEST_ERROR; - } - - H5free_memory(astr_val); - HDfree(astr_val_exp); - - 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); - - 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. - * - * bool check_storage - * a flag to indicate if the storage check is on - * - * bool is_compact - * true if after this attribute is deleted, - * the storage should still be in compact, false - * if the storage should be in dense. - * Note: this parameter is not used if the check_storage - * is set to false. - - * 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; - - /* 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) { - printf("The supposed deleted attribute %s still exists \n", aname); - printf("verify_del_attrs_compact() test failed \n"); - TEST_ERROR; - } - else { - printf("H5Aexists_by_name failed \n"); - TEST_ERROR; - } - - if (!s->old_style_grp && check_storage == true) { - if (false == check_attr_storage_type(g, is_compact)) { - printf("The attribute storage type is wrong. \n"); - TEST_ERROR; - } - } - - /* If coming to an "object header continuation block" test, - * we need to check if this test behaves as expected. */ - if (s->at_pattern == 'R') { - if (false == check_ohr_num_chunk(g, true)) { - printf("An object header continuation block should be removed. \n"); - printf("But it is NOT.\n"); - printf("Verification of an 'object header continuation block test' failed.\n"); - TEST_ERROR; - } - } - - return true; -error: - 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); - } - 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_del_ohr_block_attr - * - * Purpose: Verify that an attribute is added to force creation of - * object header continuation block and remove this attribute - * to delete the object header continuation block - - * Parameters: state_t *s - * The struct that stores information of HDF5 file, 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_del_ohr_block_attr(state_t *s, hid_t g, unsigned int which) -{ - - bool ret_value = false; - char attrname[VS_ATTR_NAME_LEN]; - const char *aname_format = "attr-%u"; - - ret_value = verify_default_group_attr(s, g, which); - if (ret_value == true) { - HDsprintf(attrname, aname_format, which); - ret_value = verify_del_one_attr(s, g, attrname, false, true); - } - return ret_value; -} -/*------------------------------------------------------------------------- - * 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) { - printf("H5Gget_create_plist failed\n"); - TEST_ERROR; - } - if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) { - printf("H5Pget_attr_phase_change failed\n"); - TEST_ERROR; - } - if (H5Pclose(gcpl) < 0) { - printf("H5Pclose failed\n"); - TEST_ERROR; - } - } - break; - case 'v': - case 'd': - case 'M': - case 'm': - case 'r': - case 'a': - 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 'R': - ret = verify_del_ohr_block_attr(s, g, which); - break; - case 'a': - case 'd': - case ' ': - default: - ret = verify_default_group_attr(s, g, which); - break; - } - - return ret; - -error: - 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; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - esnprintf(name, sizeof(name), "/group-%u", which); - - if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) { - printf("H5Gopen failed\n"); - TEST_ERROR; - } - - if (H5Gget_info(g, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_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) { - printf("Reader - Old-styled group: but the group is not in old-style. \n"); - TEST_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) { - printf("Reader - The created group should NOT be in old-style . \n"); - TEST_ERROR; - } - dbgf(2, "Reader: verify that the group is created with the new-style.\n"); - } - - /* If coming to an "object header continuation block" test, - * we need to check if this test behaves as expected. */ - if (s->at_pattern == 'a' || s->at_pattern == 'R') { - if (false == check_ohr_num_chunk(g, true)) { - printf("An object header continuation block should NOT be created. \n"); - printf("But it is created.\n"); - printf("Verification of an 'object header continuation block test' failed.\n"); - TEST_ERROR; - } - } - - /* Check if we need to skip the attribute test for this group. */ - if (s->asteps != 0 && which % s->asteps == 0) - result = verify_group_attribute(s, g, which); - else - result = true; - - if (H5Gclose(g) < 0) { - printf("H5Gclose failed\n"); - TEST_ERROR; - } - - return result; - -error: - - H5E_BEGIN_TRY - { - H5Gclose(g); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: create_group_id - * - * Purpose: Create a group and return the group ID. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * This is used to generate the group name. - * - * bool dense_to_compact - * true if this function is used to test the transition from dense to - * compact, false if the test is from compact to dense. - * - * Return: Success: the group ID - * Failure: -1 - * - * Note: Only used by testing the link storage transit functions. - *------------------------------------------------------------------------- - */ - -static hid_t -create_group_id(state_t *s, unsigned int which, bool dense_to_compact) -{ - - char name[sizeof("/group-9999999999")]; - hid_t g = H5I_INVALID_HID; - hid_t gcpl = H5I_INVALID_HID; - H5G_info_t group_info; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - gcpl = H5Pcreate(H5P_GROUP_CREATE); - if (gcpl < 0) { - printf("H5Pcreate failed\n"); - TEST_ERROR; - } - - if (dense_to_compact) { - if (H5Pset_link_phase_change(gcpl, 2, 2) < 0) { - printf("H5Pset_link_phase_change failed for dense to compact.\n"); - TEST_ERROR; - } - } - else { - if (H5Pset_link_phase_change(gcpl, 1, 1) < 0) { - printf("H5Pset_attr_phase_change failed for compact to dense.\n"); - TEST_ERROR; - } - } - - esnprintf(name, sizeof(name), "/group-%u", which); - if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) { - printf("H5Gcreate2 failed\n"); - TEST_ERROR; - } - - if (H5Gget_info(g, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - /* The storage type should always be compact when a group is created. */ - if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { - printf("New-style group link storage test:. \n"); - printf(" still be compact after group creation. \n"); - TEST_ERROR; - } - - if (H5Pclose(gcpl) < 0) { - printf("H5Pclose failed\n"); - TEST_ERROR; - } - - return g; - -error: - - H5E_BEGIN_TRY - { - H5Pclose(gcpl); - } - H5E_END_TRY; - - return -1; -} - -/*------------------------------------------------------------------------- - * Function: close_group_id - * - * Purpose: Verify is a group is closed successfully. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * hid_t g - * The ID of the group to be closed. - * - * Return: Success: true - * Failure: false - * - * Note: This is used by the link storage transit functions. - *------------------------------------------------------------------------- - */ - -static bool -close_group_id(state_t *s, hid_t g) -{ - - if (H5Gclose(g) < 0) { - printf("H5Gclose failed\n"); - TEST_ERROR; - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: create_group - * - * Purpose: Create a group - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * This is used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the main() function. - *------------------------------------------------------------------------- - */ - -static bool -create_group(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - hid_t g = H5I_INVALID_HID; - H5G_info_t group_info; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - esnprintf(name, sizeof(name), "/group-%u", which); - if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { - printf("H5Gcreate2 failed\n"); - TEST_ERROR; - } - - if (H5Gget_info(g, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (s->old_style_grp) { - if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("Old-styled group test: but the group is not in old-style. \n"); - TEST_ERROR; - } - dbgf(2, "Writer: group is created with the old-style.\n"); - } - else { - if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("The created group should NOT be in old-style . \n"); - TEST_ERROR; - } - dbgf(2, "Writer: group is created with the new-style.\n"); - } - - if (H5Gclose(g) < 0) { - printf("H5Gclose failed\n"); - TEST_ERROR; - } - - return true; - -error: - - H5E_BEGIN_TRY - { - H5Gclose(g); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: delete_one_link - * - * Purpose: Delete a link(either hard/soft) in group operation tests. - * according to the group test pattern. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * hid_t obj_id - * The HDF5 object ID that the deleted link is attached to. - * - * const char *name - * The name of the link to be deleted. - * - * short link_storage - * <=0: link storage is ignored. - * 1: link storage should be compact after link deletion.. - * >1: link storage should be dense after link deletion. - * - * unsigned int which - * The number of iterations for group creation - * - * - * Return: Success: true - * Failure: false - * - * Note: This is used by delete_groups() and delete_links() functions. - *------------------------------------------------------------------------- - */ - -static bool -delete_one_link(state_t *s, hid_t obj_id, const char *name, short link_storage, unsigned int which) -{ - - H5G_info_t group_info; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - if (H5Ldelete(obj_id, name, H5P_DEFAULT) < 0) { - printf("H5Ldelete failed\n"); - TEST_ERROR; - } - - if (link_storage > 0) { - - if (s->old_style_grp) { - printf("Old style group doesn't support the indexed storage.\n"); - TEST_ERROR; - } - - if (H5Gget_info(obj_id, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (link_storage == 1) { - - if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { - printf("The group link storage should be compact. \n"); - TEST_ERROR; - } - } - else { - - if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { - printf("The group link storage should be dense. \n"); - TEST_ERROR; - } - } - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: delete_group - * - * Purpose: Delete a group and carry out group operations(add,delete etc.) - * according to the group operation test pattern. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * This is used to generate the group name - * - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -delete_group(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - bool ret_value = create_group(s, which); - if (ret_value == true) { - esnprintf(name, sizeof(name), "/group-%u", which); - ret_value = delete_one_link(s, s->file, name, 0, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: move_one_group - * - * Purpose: A helper function used by the move_group operation. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * hid_t obj_id - * ID of the object this group is attached to - * - * const char *name - * The original group name - * - * const char *newname - * The new group name - * - * unsigned int which - * The number of iterations for group creation - * - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the move_group() function. - *------------------------------------------------------------------------- - */ - -static bool -move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, unsigned int which) -{ - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - if (H5Lmove(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Ldelete failed\n"); - TEST_ERROR; - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: move_group - * - * Purpose: Move a group to another group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations for group creation - * used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -move_group(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char new_name[sizeof("/new-group-9999999999")]; - bool ret_value = create_group(s, which); - if (ret_value == true) { - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(new_name, sizeof(new_name), "/new-group-%u", which); - ret_value = move_one_group(s, s->file, name, new_name, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: insert_one_link - * - * Purpose: A helper function used to attach a link to a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * hid_t obj_id - * ID of the object this link is attached to - * - * const char *name - * The name of the target object used by creating links - * - * const char *newname - * The name of the linked objects - * - * bool is_hard - * true if inserting a hard link - * false if inserting a soft link - * - * short link_storage - * <=0: link storage is ignored. - * 1: link storage should be compact. - * >1: link storage should be dense. - - * unsigned int which - * The number of iterations for group creation - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the insert_links and link storage transit functions. - * For link storage, we test at both the writer and the reader. - *------------------------------------------------------------------------- -*/ - -static bool -insert_one_link(state_t *s, hid_t obj_id, const char *name, const char *newname, bool is_hard, - short link_storage, unsigned int which) -{ - - H5G_info_t group_info; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - /* For storage transit and insert_links cases, we - * create links in different style, just add a little - * variation of the tests.*/ - if (is_hard) { - if (link_storage > 0) { - if (H5Lcreate_hard(s->file, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Lcreate_hard failed\n"); - TEST_ERROR; - } - } - else { - if (H5Lcreate_hard(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Lcreate_hard failed\n"); - TEST_ERROR; - } - } - } - else { - if (link_storage > 0) { - if (H5Lcreate_soft("/", obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Lcreate_soft failed\n"); - TEST_ERROR; - } - } - else { - if (H5Lcreate_soft(name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { - printf("H5Lcreate_soft failed.\n"); - TEST_ERROR; - } - } - } - - if (link_storage > 0) { - - if (s->old_style_grp) { - printf("Old style group doesn't support dense or compact storage.\n"); - TEST_ERROR; - } - - if (H5Gget_info(obj_id, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (link_storage == 1) { - if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { - printf("The group link storage should be compact. \n"); - TEST_ERROR; - } - } - else { - if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { - printf("The group link storage should be dense. \n"); - TEST_ERROR; - } - } - } - - return true; - -error: - return false; -} - -/*------------------------------------------------------------------------- - * Function: insert_links - * - * Purpose: create links with a group. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations - * used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -insert_links(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char hd_name[sizeof("/hd-group-9999999999")]; - char st_name[sizeof("/st-group-9999999999")]; - - bool ret_value = create_group(s, which); - if (ret_value == true) { - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); - esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); - ret_value = insert_one_link(s, s->file, name, hd_name, true, 0, which); - if (ret_value == true) - ret_value = insert_one_link(s, s->file, name, st_name, false, 0, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: delete_links - * - * Purpose: create links with a group and then delete them successfully. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations - * used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -delete_links(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char hd_name[sizeof("/hd-group-9999999999")]; - char st_name[sizeof("/st-group-9999999999")]; - - bool ret_value = insert_links(s, which); - if (ret_value == true) { - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); - esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); - ret_value = delete_one_link(s, s->file, hd_name, 0, which); - if (ret_value == true) - ret_value = delete_one_link(s, s->file, st_name, 0, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: transit_storage_compact_to_dense - * - * Purpose: Add links so that the link storage transits from - * compact to dense. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -transit_storage_compact_to_dense(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char hd_name[sizeof("/hd-group-9999999999")]; - char st_name[sizeof("/st-group-9999999999")]; - - hid_t g = create_group_id(s, which, false); - if (g < 0) { - printf("create_group_id failed\n"); - TEST_ERROR; - } - - /* First insert a hard link, compact storage. */ - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); - if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { - printf("insert_one_link for compact storage failed\n"); - TEST_ERROR; - } - - /* Then insert a soft link, the storage becomes dense. */ - esnprintf(st_name, sizeof(st_name), "st-group-%u", which); - if (insert_one_link(s, g, name, st_name, false, 2, which) == false) { - printf("insert_one_link for dense storage failed\n"); - TEST_ERROR; - } - - if (close_group_id(s, g) == false) { - printf("insert_one_link for dense storage failed\n"); - TEST_ERROR; - } - - return true; - -error: - H5E_BEGIN_TRY - { - H5Gclose(g); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: transit_storage_dense_to_compact - * - * Purpose: Add or delete links so that the link storage transits from - * compact to dense then to compact. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe - * and some VFD SWMR configuration parameters - * - * unsigned int which - * The number of iterations used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -transit_storage_dense_to_compact(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - char hd_name[sizeof("/hd-group-9999999999")]; - char st_name[sizeof("st-group-9999999999")]; - char st2_name[sizeof("st2-group-9999999999")]; - - hid_t g = create_group_id(s, which, true); - if (g < 0) { - printf("create_group_id failed\n"); - TEST_ERROR; - } - - /* Insert a link, storage is compact. */ - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); - if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { - printf("insert_one_link for compact storage failed\n"); - TEST_ERROR; - } - - /* Insert a link, storage is still compact. */ - esnprintf(st_name, sizeof(st_name), "st-group-%u", which); - if (insert_one_link(s, g, name, st_name, false, 1, which) == false) { - printf("insert_one_link for compact storage failed\n"); - TEST_ERROR; - } - - /* Insert a link, storage becomes dense. */ - esnprintf(st2_name, sizeof(st2_name), "st2-group-%u", which); - if (insert_one_link(s, g, name, st2_name, false, 2, which) == false) { - printf("insert_one_link for dense storage failed\n"); - TEST_ERROR; - } - - /* Delete a link, storage is still dense */ - if (delete_one_link(s, g, st_name, 2, which) == false) { - printf("delete_one_link for dense storage failed\n"); - TEST_ERROR; - } - - /* Delete another link, storage becomes compact */ - if (delete_one_link(s, g, st2_name, 1, which) == false) { - printf("delete_one_link for compact storage failed\n"); - TEST_ERROR; - } - - if (close_group_id(s, g) == false) { - printf("insert_one_link for dense storage failed\n"); - TEST_ERROR; - } - - return true; - -error: - H5E_BEGIN_TRY - { - H5Gclose(g); - } - H5E_END_TRY; - - return false; -} - -/*------------------------------------------------------------------------- - * Function: group_operations - * - * Purpose: Carry out group and attribute operations(add,delete etc.) - * according to the group operation and attribute test patterns. - * - * Parameters: state_t *s - * The struct that stores information of HDF5 file, 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. The check of attribute - * operations is inside the write_group() function. - *------------------------------------------------------------------------- - */ -static bool -group_operations(state_t *s, unsigned int which) -{ - - bool ret_value = false; - char test_pattern = s->grp_op_pattern; - - switch (test_pattern) { - case 'c': - ret_value = create_group(s, which); - break; - case 'd': - ret_value = delete_group(s, which); - break; - case 'm': - ret_value = move_group(s, which); - break; - case 'i': - ret_value = insert_links(s, which); - break; - case 'D': - ret_value = delete_links(s, which); - break; - case 't': - ret_value = transit_storage_compact_to_dense(s, which); - break; - case 'T': - ret_value = transit_storage_dense_to_compact(s, which); - break; - case ' ': - default: - ret_value = write_group(s, which); - break; - } - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: vrfy_create_group - * - * Purpose: Verify if a group can be created successfully. - * - * 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 - * used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the verify_group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -vrfy_create_group(state_t *s, unsigned int which) -{ - - char name[sizeof("/group-9999999999")]; - hid_t g = H5I_INVALID_HID; - H5G_info_t group_info; - - if (which >= s->nsteps) { - printf("Number of created groups is out of bounds\n"); - TEST_ERROR; - } - - esnprintf(name, sizeof(name), "/group-%u", which); - - if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) { - printf("H5Gopen failed\n"); + esnprintf(name, sizeof(name), "/group-%u", which); + if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + printf("H5Gcreate2 failed\n"); TEST_ERROR; } @@ -3591,20 +1842,19 @@ vrfy_create_group(state_t *s, unsigned int which) TEST_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) { - printf("Reader - Old-styled group: but the group is not in old-style. \n"); + printf("Old-styled group test: but the group is not in old-style. \n"); TEST_ERROR; } - dbgf(2, "Reader: verify that the group is created with the old-style.\n"); + dbgf(2, "Writer: group is created with the old-style.\n"); } else { if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("Reader - The created group should NOT be in old-style . \n"); + printf("The created group should NOT be in old-style . \n"); TEST_ERROR; } - dbgf(2, "Reader: verify that the group is created with the new-style.\n"); + dbgf(2, "Writer: group is created with the new-style.\n"); } if (H5Gclose(g) < 0) { @@ -3626,251 +1876,176 @@ error: } /*------------------------------------------------------------------------- - * Function: vrfy_create_group_id + * Function: delete_one_link * - * Purpose: Verify if a group is created successfully and return the group - * ID. + * Purpose: Delete a link(either hard/soft) in group operation tests. + * according to the group test pattern. * * Parameters: state_t *s * The struct that stores information of HDF5 file, named pipe * and some VFD SWMR configuration parameters * + * hid_t obj_id + * The HDF5 object ID that the deleted link is attached to. + * + * const char *name + * The name of the link to be deleted. + * + * short link_storage + * <=0: link storage is ignored. + * 1: link storage should be compact after link deletion.. + * >1: link storage should be dense after link deletion. + * * unsigned int which * The number of iterations for group creation - * used to generate the group name. * - * bool dense_to_compact - * true if this function is used to test the transition from dense to - * compact, false if the test is from compact to dense. * - * Return: Success: the group ID - * Failure: -1 + * Return: Success: true + * Failure: false * - * Note: This function is used by the link storage transit functions. + * Note: This is used by delete_groups() and delete_links() functions. *------------------------------------------------------------------------- */ -static hid_t -vrfy_create_group_id(state_t *s, unsigned int which, bool dense_to_compact) +static bool +delete_one_link(state_t *s, hid_t obj_id, const char *name, short link_storage, unsigned int which) { - char name[sizeof("/group-9999999999")]; - hid_t g = H5I_INVALID_HID; - hid_t gcpl = H5I_INVALID_HID; H5G_info_t group_info; - unsigned max_compact = 0; - unsigned min_dense = 0; if (which >= s->nsteps) { - printf("Number of the created groups is out of bounds\n"); - TEST_ERROR; - } - - esnprintf(name, sizeof(name), "/group-%u", which); - - if ((g = H5Gopen(s->file, name, H5P_DEFAULT)) < 0) { - printf("H5Gopen failed\n"); + printf("Number of created groups is out of bounds\n"); TEST_ERROR; } - if ((gcpl = H5Gget_create_plist(g)) < 0) { - printf("H5Gget_create_plist failed\n"); + if (H5Ldelete(obj_id, name, H5P_DEFAULT) < 0) { + printf("H5Ldelete failed\n"); TEST_ERROR; } - if (H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) { - printf("H5Pget_link_phase_change failed\n"); - TEST_ERROR; - } + if (link_storage > 0) { - if (dense_to_compact) { - if (max_compact != 2) { - printf("For storage check from dense to compact:\n"); - printf(" The max_compact should be 2.\n"); - printf(" But the actual value is %d.\n", max_compact); - TEST_ERROR; - } - else if (min_dense != 2) { - printf("For storage check from dense to compact:\n"); - printf(" The min_dense should be 2.\n"); - printf(" But the actual value is %d.\n", min_dense); - TEST_ERROR; - } - } - else { - if (max_compact != 1) { - printf("For storage check from dense to compact:\n"); - printf(" The max_compact should be 1.\n"); - printf(" But the actual value is %d.\n", max_compact); + if (s->old_style_grp) { + printf("Old style group doesn't support the indexed storage.\n"); TEST_ERROR; } - else if (min_dense != 1) { - printf("For storage check from dense to compact:\n"); - printf(" The min_dense should be 1.\n"); - printf(" But the actual value is %d.\n", min_dense); + + if (H5Gget_info(obj_id, &group_info) < 0) { + printf("H5Gget_info failed\n"); TEST_ERROR; } - } - if (H5Pclose(gcpl) < 0) { - printf("H5Pclose failed\n"); - TEST_ERROR; - } + if (link_storage == 1) { - if (H5Gget_info(g, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("The group link storage should be compact. \n"); + TEST_ERROR; + } + } + else { - /* When the group is created, the storage type is always compact. */ - if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { - printf("Old-styled group test: but the group is not in old-style. \n"); - TEST_ERROR; + if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { + printf("The group link storage should be dense. \n"); + TEST_ERROR; + } + } } - dbgf(2, "Storage info is %d\n", group_info.storage_type); - - return g; + return true; error: - - H5E_BEGIN_TRY - { - H5Gclose(g); - H5Pclose(gcpl); - } - H5E_END_TRY; - - return -1; + return false; } /*------------------------------------------------------------------------- - * Function: vrfy_close_group_id + * Function: delete_group * - * Purpose: Verify if a group is closed successfully. + * Purpose: Delete a group and carry out group operations(add,delete etc.) + * according to the group operation test pattern. * * Parameters: state_t *s * The struct that stores information of HDF5 file, named pipe * and some VFD SWMR configuration parameters * - * hid_t g - * The ID of the group to be closed. + * unsigned int which + * The number of iterations for group creation + * This is used to generate the group name + * * * Return: Success: true * Failure: false * - * Note: This is used by the link storage transit functions. + * Note: This is called by the group_operations() function. *------------------------------------------------------------------------- */ static bool -vrfy_close_group_id(state_t *s, hid_t g) +delete_group(state_t *s, unsigned int which) { - if (H5Gclose(g) < 0) { - printf("H5Gclose failed\n"); - TEST_ERROR; + char name[sizeof("/group-9999999999")]; + bool ret_value = create_group(s, which); + if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); + ret_value = delete_one_link(s, s->file, name, 0, which); } - return true; - -error: - - return false; + return ret_value; } /*------------------------------------------------------------------------- - * Function: vrfy_one_link_exist + * Function: move_one_group * - * Purpose: Verify if a link exists or not. The link storage is - * also checked. + * Purpose: A helper function used by the move_group operation. * * Parameters: state_t *s * The struct that stores information of HDF5 file, named pipe * and some VFD SWMR configuration parameters * * hid_t obj_id - * The ID of the object the link is attached to + * ID of the object this group is attached to + * + * const char *name + * The original group name + * + * const char *newname + * The new group name * - * bool expect_exist - * A flag that indicates if this link is expected to exist + * unsigned int which + * The number of iterations for group creation * - * short link_storage - * <=0: link storage check is ignored. - * 1: link storage is expected to be compact. - * >1: link storage is expected to be dense. * * Return: Success: true * Failure: false * - * Note: Helper function to check if links are inserted or deleted. - * The link storage is also checked. + * Note: This is called by the move_group() function. *------------------------------------------------------------------------- */ static bool -vrfy_one_link_exist(state_t *s, hid_t obj_id, const char *name, bool expect_exist, short link_storage) +move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, unsigned int which) { - int link_exists = 0; - H5G_info_t group_info; - - link_exists = H5Lexists(obj_id, name, H5P_DEFAULT); - - if (link_exists < 0) { - printf("H5Lexists error\n"); - TEST_ERROR; - } - else if (link_exists == 1) { - if (expect_exist == false) { - printf("This link should be moved or deleted but it still exists.\n"); - TEST_ERROR; - } - } - else if (link_exists == 0) { - if (expect_exist == true) { - printf("This link should exist but it is moved or deleted.\n"); - TEST_ERROR; - } - } - - if (link_storage > 0) { - - if (s->old_style_grp) { - printf("Old style group doesn't support the indexed storage.\n"); - TEST_ERROR; - } - - if (H5Gget_info(obj_id, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (link_storage == 1) { - if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { - printf("The group link storage should be compact. \n"); - TEST_ERROR; - } - } - else { - if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { - printf("The group link storage should be dense. \n"); - TEST_ERROR; - } - } + if (which >= s->nsteps) { + printf("Number of created groups is out of bounds\n"); + TEST_ERROR; + } + + if (H5Lmove(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Ldelete failed\n"); + TEST_ERROR; } return true; error: - return false; } /*------------------------------------------------------------------------- - * Function: vrfy_delete_group + * Function: move_group * - * Purpose: Verify if a group can be deleted successfully. + * Purpose: Move a group to another group. * * Parameters: state_t *s * The struct that stores information of HDF5 file, named pipe @@ -3883,245 +2058,226 @@ error: * Return: Success: true * Failure: false * - * Note: This is called by the verify_group_operations() function. + * Note: This is called by the group_operations() function. *------------------------------------------------------------------------- */ static bool -vrfy_delete_group(state_t *s, unsigned int which) +move_group(state_t *s, unsigned int which) { - bool ret_value = false; char name[sizeof("/group-9999999999")]; - - ret_value = vrfy_create_group(s, which); + char new_name[sizeof("/new-group-9999999999")]; + bool ret_value = create_group(s, which); if (ret_value == true) { esnprintf(name, sizeof(name), "/group-%u", which); - ret_value = vrfy_one_link_exist(s, s->file, name, false, 0); + esnprintf(new_name, sizeof(new_name), "/new-group-%u", which); + ret_value = move_one_group(s, s->file, name, new_name, which); } return ret_value; } /*------------------------------------------------------------------------- - * Function: vrfy_move_one_group + * Function: insert_one_link * - * Purpose: A helper function to verify the move_group operation successfully. + * Purpose: A helper function used to attach a link 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 obj_id - * ID of the object this group is attached to + * ID of the object this link is attached to * * const char *name - * The original group name + * The name of the target object used by creating links * * const char *newname - * The new group name + * The name of the linked objects + * + * bool is_hard + * true if inserting a hard link + * false if inserting a soft link * + * short link_storage + * <=0: link storage is ignored. + * 1: link storage should be compact. + * >1: link storage should be dense. + * unsigned int which * The number of iterations for group creation * * Return: Success: true * Failure: false * - * Note: This is called by the verify_move_group() function. + * Note: This is called by the insert_links and link storage transit functions. + * For link storage, we test at both the writer and the reader. *------------------------------------------------------------------------- - */ +*/ static bool -vrfy_move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, unsigned int which) +insert_one_link(state_t *s, hid_t obj_id, const char *name, const char *newname, bool is_hard, + short link_storage, unsigned int which) { - hid_t g = H5I_INVALID_HID; H5G_info_t group_info; - int link_exists = 0; if (which >= s->nsteps) { printf("Number of created groups is out of bounds\n"); TEST_ERROR; } - link_exists = H5Lexists(obj_id, name, H5P_DEFAULT); - if (link_exists < 0) { - printf("H5Lexists error\n"); - TEST_ERROR; - } - else if (link_exists == 1) { - printf("This link should be moved but it still exists.\n"); - TEST_ERROR; + /* For storage transit and insert_links cases, we + * create links in different style, just add a little + * variation of the tests.*/ + if (is_hard) { + if (link_storage > 0) { + if (H5Lcreate_hard(s->file, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_hard failed\n"); + TEST_ERROR; + } + } + else { + if (H5Lcreate_hard(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_hard failed\n"); + TEST_ERROR; + } + } } - - if ((g = H5Gopen(obj_id, newname, H5P_DEFAULT)) < 0) { - printf("H5Gopen failed\n"); - TEST_ERROR; + else { + if (link_storage > 0) { + if (H5Lcreate_soft("/", obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_soft failed\n"); + TEST_ERROR; + } + } + else { + if (H5Lcreate_soft(name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) { + printf("H5Lcreate_soft failed.\n"); + TEST_ERROR; + } + } } - if (H5Gget_info(g, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } + if (link_storage > 0) { - 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) { - printf("Reader - Old-styled group: but the group is not in old-style. \n"); + if (s->old_style_grp) { + printf("Old style group doesn't support dense or compact storage.\n"); TEST_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) { - printf("Reader - The created group should NOT be in old-style . \n"); + + if (H5Gget_info(obj_id, &group_info) < 0) { + printf("H5Gget_info failed\n"); TEST_ERROR; } - dbgf(2, "Reader: verify that the group is created with the new-style.\n"); - } - if (H5Gclose(g) < 0) { - printf("H5Gclose failed\n"); - TEST_ERROR; + if (link_storage == 1) { + if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) { + printf("The group link storage should be compact. \n"); + TEST_ERROR; + } + } + else { + if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) { + printf("The group link storage should be dense. \n"); + TEST_ERROR; + } + } } return true; error: - - H5E_BEGIN_TRY - { - H5Gclose(g); - } - H5E_END_TRY; - return false; } /*------------------------------------------------------------------------- - * Function: vrfy_move_group + * Function: insert_links * - * Purpose: Verify if a group can be moved successfully. + * Purpose: create links with a group. * * 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 + * The number of iterations * used to generate the group name. * * Return: Success: true * Failure: false * - * Note: This is called by the verify_group_operations() function. + * Note: This is called by the group_operations() function. *------------------------------------------------------------------------- */ static bool -vrfy_move_group(state_t *s, unsigned int which) +insert_links(state_t *s, unsigned int which) { char name[sizeof("/group-9999999999")]; - char new_name[sizeof("/new-group-9999999999")]; - bool ret_value = vrfy_create_group(s, which); - if (ret_value == true) { - esnprintf(name, sizeof(name), "/group-%u", which); - esnprintf(new_name, sizeof(new_name), "/new-group-%u", which); - ret_value = vrfy_move_one_group(s, s->file, name, new_name, which); - } - - return ret_value; -} - -/*------------------------------------------------------------------------- - * Function: vrfy_insert_links - * - * Purpose: Verify if the links are inserted successfully. - * - * 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 - * used to generate the group name. - * - * Return: Success: true - * Failure: false - * - * Note: This is called by the verify_group_operations() function. - *------------------------------------------------------------------------- - */ - -static bool -vrfy_insert_links(state_t *s, unsigned int which) -{ - - bool ret_value = false; char hd_name[sizeof("/hd-group-9999999999")]; char st_name[sizeof("/st-group-9999999999")]; - ret_value = vrfy_create_group(s, which); - + bool ret_value = create_group(s, which); if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); - ret_value = vrfy_one_link_exist(s, s->file, hd_name, true, 0); + ret_value = insert_one_link(s, s->file, name, hd_name, true, 0, which); if (ret_value == true) - ret_value = vrfy_one_link_exist(s, s->file, st_name, true, 0); + ret_value = insert_one_link(s, s->file, name, st_name, false, 0, which); } return ret_value; } /*------------------------------------------------------------------------- - * Function: vrfy_delete_links + * Function: delete_links * - * Purpose: Verify if the links created with a group are deleted successfully. + * Purpose: create links with a group and then delete them successfully. * * 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 + * The number of iterations * used to generate the group name. * * Return: Success: true * Failure: false * - * Note: This is called by the verify_group_operations() function. + * Note: This is called by the group_operations() function. *------------------------------------------------------------------------- */ static bool -vrfy_delete_links(state_t *s, unsigned int which) +delete_links(state_t *s, unsigned int which) { - bool ret_value = false; + char name[sizeof("/group-9999999999")]; char hd_name[sizeof("/hd-group-9999999999")]; char st_name[sizeof("/st-group-9999999999")]; - /* First verify if the links are inserted correctly */ - ret_value = vrfy_insert_links(s, which); - - /* Then if these links are deleted correctly. */ + bool ret_value = insert_links(s, which); if (ret_value == true) { + esnprintf(name, sizeof(name), "/group-%u", which); esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which); esnprintf(st_name, sizeof(st_name), "/st-group-%u", which); - ret_value = vrfy_one_link_exist(s, s->file, hd_name, false, 0); + ret_value = delete_one_link(s, s->file, hd_name, 0, which); if (ret_value == true) - ret_value = vrfy_one_link_exist(s, s->file, st_name, false, 0); + ret_value = delete_one_link(s, s->file, st_name, 0, which); } return ret_value; } /*------------------------------------------------------------------------- - * Function: vrfy_transit_storage_compact_to_dense + * Function: transit_storage_compact_to_dense * - * Purpose: Verify if the link storage successfully transits from + * Purpose: Add links so that the link storage transits from * compact to dense. * * Parameters: state_t *s @@ -4129,46 +2285,49 @@ vrfy_delete_links(state_t *s, unsigned int which) * and some VFD SWMR configuration parameters * * unsigned int which - * The number of iterations for group creation - * used to generate the group name. + * The number of iterations used to generate the group name. * * Return: Success: true * Failure: false * - * Note: This is called by the verify_group_operations() function. + * Note: This is called by the group_operations() function. *------------------------------------------------------------------------- */ static bool -vrfy_transit_storage_compact_to_dense(state_t *s, unsigned int which) +transit_storage_compact_to_dense(state_t *s, unsigned int which) { - hid_t g = H5I_INVALID_HID; - char hd_name[sizeof("hd-group-9999999999")]; - char st_name[sizeof("st-group-9999999999")]; + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("/st-group-9999999999")]; - g = vrfy_create_group_id(s, which, false); + hid_t g = create_group_id(s, which, false); if (g < 0) { - printf("verify create_group_id failed\n"); + printf("create_group_id failed\n"); TEST_ERROR; } + /* First insert a hard link, compact storage. */ + esnprintf(name, sizeof(name), "/group-%u", which); esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); - if (vrfy_one_link_exist(s, g, hd_name, true, 1) == false) { - printf("verify the compact storage failed for 'link compact to dense' test\n"); + if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { + printf("insert_one_link for compact storage failed\n"); TEST_ERROR; } + /* Then insert a soft link, the storage becomes dense. */ esnprintf(st_name, sizeof(st_name), "st-group-%u", which); - if (vrfy_one_link_exist(s, g, st_name, true, 2) == false) { - printf("verify the dense link storage failed for 'link compact to dense' test\n"); + if (insert_one_link(s, g, name, st_name, false, 2, which) == false) { + printf("insert_one_link for dense storage failed\n"); TEST_ERROR; } - if (vrfy_close_group_id(s, g) == false) { - printf("verify the group close for 'link compact to dense' test\n"); + if (close_group_id(g) == false) { + printf("insert_one_link for dense storage failed\n"); TEST_ERROR; } + return true; error: @@ -4177,13 +2336,14 @@ error: H5Gclose(g); } H5E_END_TRY; + return false; } /*------------------------------------------------------------------------- - * Function: vrfy_transit_storage_dense_to_compact + * Function: transit_storage_dense_to_compact * - * Purpose: Verify if the link storage successfully transits from + * Purpose: Add or delete links so that the link storage transits from * compact to dense then to compact. * * Parameters: state_t *s @@ -4191,68 +2351,69 @@ error: * and some VFD SWMR configuration parameters * * unsigned int which - * The number of iterations for group creation - * used to generate the group name. + * The number of iterations used to generate the group name. * * Return: Success: true * Failure: false * - * Note: This is called by the verify_group_operations() function. + * Note: This is called by the group_operations() function. *------------------------------------------------------------------------- */ static bool -vrfy_transit_storage_dense_to_compact(state_t *s, unsigned int which) +transit_storage_dense_to_compact(state_t *s, unsigned int which) { - hid_t g = H5I_INVALID_HID; - char hd_name[sizeof("hd-group-9999999999")]; - char st_name[sizeof("st-group-9999999999")]; - char st2_name[sizeof("st2-group-9999999999")]; + char name[sizeof("/group-9999999999")]; + char hd_name[sizeof("/hd-group-9999999999")]; + char st_name[sizeof("st-group-9999999999")]; + char st2_name[sizeof("st2-group-9999999999")]; - g = vrfy_create_group_id(s, which, true); + hid_t g = create_group_id(s, which, true); if (g < 0) { - printf("verify create_group_id failed\n"); + printf("create_group_id failed\n"); TEST_ERROR; } - /* Add a link, verify it is still the compact storage */ + /* Insert a link, storage is compact. */ + esnprintf(name, sizeof(name), "/group-%u", which); esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which); - if (vrfy_one_link_exist(s, g, hd_name, true, 1) == false) { - printf("verify the compact storage failed for 'link compact to dense' test\n"); + if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) { + printf("insert_one_link for compact storage failed\n"); TEST_ERROR; } - /* Add another link, verify it is still the compact storage */ + /* Insert a link, storage is still compact. */ esnprintf(st_name, sizeof(st_name), "st-group-%u", which); - if (vrfy_one_link_exist(s, g, st_name, true, 1) == false) { - printf("verify the compact link storage failed for 'link compact to dense' test\n"); + if (insert_one_link(s, g, name, st_name, false, 1, which) == false) { + printf("insert_one_link for compact storage failed\n"); TEST_ERROR; } - /* Add the third link, verify it becomes the dense storage */ + /* Insert a link, storage becomes dense. */ esnprintf(st2_name, sizeof(st2_name), "st2-group-%u", which); - if (vrfy_one_link_exist(s, g, st2_name, true, 2) == false) { - printf("verify the dense link storage failed for 'link compact to dense' test\n"); + if (insert_one_link(s, g, name, st2_name, false, 2, which) == false) { + printf("insert_one_link for dense storage failed\n"); TEST_ERROR; } - /* Remove a link, verify the link doesn't exist and still dense storage */ - if (vrfy_one_link_exist(s, g, st_name, false, 2) == false) { - printf("verify the dense link storage failed for 'link compact to dense' test\n"); + /* Delete a link, storage is still dense */ + if (delete_one_link(s, g, st_name, 2, which) == false) { + printf("delete_one_link for dense storage failed\n"); TEST_ERROR; } - /* Remove a link, verify the link doesn't exist and it becomes compact storage */ - if (vrfy_one_link_exist(s, g, st2_name, false, 1) == false) { - printf("verify the compact link storage failed for 'link compact to dense' test\n"); + /* Delete another link, storage becomes compact */ + if (delete_one_link(s, g, st2_name, 1, which) == false) { + printf("delete_one_link for compact storage failed\n"); TEST_ERROR; } - if (vrfy_close_group_id(s, g) == false) { - printf("verify the group close for 'link compact to dense' test\n"); + if (close_group_id(g) == false) { + printf("insert_one_link for dense storage failed\n"); TEST_ERROR; } + return true; error: @@ -4261,15 +2422,15 @@ error: H5Gclose(g); } H5E_END_TRY; + return false; } /*------------------------------------------------------------------------- - * Function: verify_group_operations + * Function: group_operations * - * Purpose: verify the success of group creation and - * carry out the test for attribute operations(add,delete etc.) - * according to the attribute test pattern. + * Purpose: Carry out group and attribute operations(add,delete etc.) + * according to the group operation and attribute test patterns. * * Parameters: state_t *s * The struct that stores information of HDF5 file, named pipe @@ -4282,41 +2443,42 @@ error: * Return: Success: true * Failure: false * - * Note: This is called by the main() function. + * Note: This is called by the main() function. The check of attribute + * operations is inside the write_group() function. *------------------------------------------------------------------------- */ - static bool -verify_group_operations(state_t *s, unsigned int which) +group_operations(state_t *s, unsigned int which) { + bool ret_value = false; char test_pattern = s->grp_op_pattern; switch (test_pattern) { case 'c': - ret_value = vrfy_create_group(s, which); + ret_value = create_group(s, which); break; case 'd': - ret_value = vrfy_delete_group(s, which); + ret_value = delete_group(s, which); break; case 'm': - ret_value = vrfy_move_group(s, which); + ret_value = move_group(s, which); break; case 'i': - ret_value = vrfy_insert_links(s, which); + ret_value = insert_links(s, which); break; case 'D': - ret_value = vrfy_delete_links(s, which); + ret_value = delete_links(s, which); break; case 't': - ret_value = vrfy_transit_storage_compact_to_dense(s, which); + ret_value = transit_storage_compact_to_dense(s, which); break; case 'T': - ret_value = vrfy_transit_storage_dense_to_compact(s, which); + ret_value = transit_storage_dense_to_compact(s, which); break; case ' ': default: - ret_value = verify_group(s, which); + ret_value = write_group(s, which); break; } return ret_value; @@ -4452,7 +2614,6 @@ main(int argc, char **argv) const char * personality; H5F_vfd_swmr_config_t config; bool wg_ret = false; - bool vg_ret = false; struct timespec start_time, end_time; unsigned int num_elems_per_level; @@ -4472,8 +2633,12 @@ main(int argc, char **argv) TEST_ERROR; } + if(writer == false) { + printf("Reader is skipped for the performance tests.\n"); + return EXIT_SUCCESS; + } + /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */ - // init_vfd_swmr_config(&config, 4, 7, writer, FALSE, 128, "./group-shadow"); init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow"); /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST) @@ -4559,7 +2724,6 @@ main(int argc, char **argv) if (s.nglevels > 0) { num_elems_per_level = obtain_tree_level_elems(s.nsteps, s.nglevels); - // wg_ret = gen_tree_struct(&s,s.nsteps,s.nglevels,num_elems_per_level,s.file); /* for the recursive call, the groups under the root is treated as one level */ wg_ret = gen_tree_struct(&s, s.nglevels + 1, num_elems_per_level, s.file); if (wg_ret == false) { @@ -4593,30 +2757,9 @@ main(int argc, char **argv) fprintf(stdout, "group creation +5 attrs mean time = %lf\n", s.mean_time); } } - else { - - if (s.nglevels > 0) { - printf("Reader: The nested group creation test is not implemented. Stop!\n"); - TEST_ERROR; - } - if (s.num_attrs > 1) { - printf("Reader: number of attribute must be 1 for the default group test. Stop!\n"); - printf("The current number of attributes per group is %u\n", s.num_attrs); - TEST_ERROR; - } - - for (step = 0; step < s.nsteps; step++) { - dbgf(1, "reader: step %d\n", step); - - vg_ret = verify_group_operations(&s, step); - - if (vg_ret == false) { - - printf("verify_group_operations failed\n"); - TEST_ERROR; - } - } - } + else + printf("Reader is skipped for the performance tests.\n"); + if (H5Pclose(fapl) < 0) { printf("H5Pclose failed\n"); -- cgit v0.12 From ee86255610d4db64921ab18cc21fc16c94859067 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Aug 2021 21:09:46 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_gperf_writer.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index 15f9522..a64af45 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -99,7 +99,7 @@ usage(const char *progname) "-b: write data in big-endian byte order\n" "-n ngroups: the number of groups\n" "-N num_attrs: the number of attributes \n" - "-V vlstr attrs: Use variable length string attribute in the performance test. \n" + "-V vlstr attrs: Use variable length string attribute in the performance test. \n" "-l ng_levels: the number of level of nested groups. \n" " If all the groups are under the root group, \n" " this number should be 0.\n" @@ -598,8 +598,6 @@ error: return false; } - - /*------------------------------------------------------------------------- * Function: add_vlstr_attrs * @@ -630,18 +628,16 @@ static bool add_vlstr_attrs(state_t *s, hid_t g, unsigned int which, unsigned int num_attrs) { unsigned u; - bool ret_value = true; + bool ret_value = true; for (u = 0; u < num_attrs; u++) { - ret_value = add_vlstr_attr(s, g, u+which); - if(ret_value == false) + ret_value = add_vlstr_attr(s, g, u + which); + if (ret_value == false) break; } return ret_value; } - - /*------------------------------------------------------------------------- * Function: add_default_group_attr * @@ -680,13 +676,12 @@ add_default_group_attr(state_t *s, hid_t g, unsigned int which) * the default number of attribute is 1. */ /* If the vl string attribute type is chosen. */ - if(s->vlstr_test == true) + if (s->vlstr_test == true) return add_vlstr_attrs(s, g, which, s->num_attrs); - else + else return add_attr(s, g, which, s->num_attrs, aname_format, which); } - /*------------------------------------------------------------------------- * Function: del_one_attr * @@ -887,7 +882,7 @@ error: * * Purpose: Modify the value of an VL string attribute in a group. * - * Parameters: + * Parameters: * hid_t g * HDF5 object ID (in this file: means group ID) * @@ -2633,7 +2628,7 @@ main(int argc, char **argv) TEST_ERROR; } - if(writer == false) { + if (writer == false) { printf("Reader is skipped for the performance tests.\n"); return EXIT_SUCCESS; } @@ -2757,9 +2752,8 @@ main(int argc, char **argv) fprintf(stdout, "group creation +5 attrs mean time = %lf\n", s.mean_time); } } - else + else printf("Reader is skipped for the performance tests.\n"); - if (H5Pclose(fapl) < 0) { printf("H5Pclose failed\n"); -- cgit v0.12 From 49c9cea3a89232d4cc94bc72de4f54b4d2998cd7 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Thu, 19 Aug 2021 15:45:55 -0500 Subject: Add statistics information, comments. Also clean up code a bit. --- test/vfd_swmr_gperf_writer.c | 334 ++++++++++++++++++++++++++++++------------- 1 file changed, 238 insertions(+), 96 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index 15f9522..61b9217 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -54,10 +54,12 @@ typedef struct { uint32_t max_lag; uint32_t tick_len; bool gperf; - double min_time; - double max_time; - double mean_time; + double min_gc_time; + double max_gc_time; + double mean_gc_time; + double total_gc_time; double total_time; + double mean_time; double fo_total_time; double fc_total_time; unsigned int num_attrs; @@ -71,38 +73,41 @@ typedef struct { (state_t) \ { \ .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ - .filetype = H5T_NATIVE_UINT32, .asteps = 10, .nsteps = 100, .use_vfd_swmr = true, \ + .filetype = H5T_NATIVE_UINT32, .asteps = 1, .nsteps = 100, .use_vfd_swmr = true, \ .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ - .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_time = 100., .max_time = 0., \ - .mean_time = 0., .total_time = 0., .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, \ - .vlstr_test = false, .ps = 4096, .pbs = 4096, .nglevels = 0 \ + .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_gc_time = 100., \ + .max_gc_time = 0., .mean_gc_time = 0., .total_gc_time = 0., .total_time = 0., .mean_time = 0., \ + .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, .vlstr_test = false, \ + .ps = 4096, .pbs = 4096, .nglevels =0 \ } static void usage(const char *progname) { fprintf(stderr, - "usage: %s [-P] [-S] [-G] [-a steps] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" - " [-b] [-n ngroups]\n" - " [-N num_attrs] [-l ng_levels] [-q] [-A at_pattern] [-O grp_op_pattern]\n" + "usage: ./%s -P -n 1000 -N 5 -q (create 1000 groups, each group has 5 attributes)\n" + "Options: \n" + " [-P] [-S] [-G] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n" + " [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n" + " [-N num_attrs] [-V] [-b] [-A at_pattern] [-a steps] [-q]\n" "\n" "-P: carry out the performance test\n" "-S: do not use VFD SWMR\n" "-G: old-style type of group\n" - "-a steps: `steps` between adding attributes\n" "-t tick_len: length of a tick in tenths of a second.\n" "-m max_lag: maximum expected lag(in ticks) between writer and readers\n" - "-B pbs: Page Buffer Size in bytes:\n" + "-B pbs: page Buffer Size in bytes:\n" " The default value is 4K(4096).\n" - "-s ps: Page size used by page aggregation, page buffer and \n" + "-s ps: page size used by page aggregation, page buffer and \n" " the metadata file. \n" - "-b: write data in big-endian byte order\n" "-n ngroups: the number of groups\n" - "-N num_attrs: the number of attributes \n" - "-V vlstr attrs: Use variable length string attribute in the performance test. \n" "-l ng_levels: the number of level of nested groups. \n" " If all the groups are under the root group, \n" " this number should be 0.\n" + "-N num_attrs: the number of attributes \n" + "-V use variable length string attributes for performance test\n" + "-b: write data in big-endian byte order\n" + " (For the performance test, -V overwrites -b)\n" "-A at_pattern: `at_pattern' for different attribute tests\n" " The value of `at_pattern` is one of the following:\n" " `compact` - Attributes added in compact storage\n" @@ -156,6 +161,8 @@ usage(const char *progname) " dense to compact again. \n" " The links include both hard and\n" " soft links. \n" + "-a steps: `steps` between adding attributes\n" + " (Don't recommend to use this option for performance test.)\n" "-q: silence printouts, few messages\n" "\n", progname); @@ -1592,11 +1599,11 @@ write_group(state_t *s, unsigned int which) } temp_time = TIME_PASSED(start_time, end_time); - if (temp_time < s->min_time) - s->min_time = temp_time; - if (temp_time > s->max_time) - s->max_time = temp_time; - s->total_time += temp_time; + if (temp_time < s->min_gc_time) + s->min_gc_time = temp_time; + if (temp_time > s->max_gc_time) + s->max_gc_time = temp_time; + s->total_gc_time += temp_time; } /* We need to create a dummy dataset for the object header continuation block test. */ @@ -1607,24 +1614,27 @@ write_group(state_t *s, unsigned int which) TEST_ERROR; } } - if (H5Gget_info(g, &group_info) < 0) { - printf("H5Gget_info failed\n"); - TEST_ERROR; - } - - if (s->old_style_grp) { - if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("Old-styled group test: but the group is not in old-style. \n"); + /* We only need to check the first group */ + if(which == 0) { + if (H5Gget_info(g, &group_info) < 0) { + printf("H5Gget_info failed\n"); TEST_ERROR; } - dbgf(2, "Writer: group is created with the old-style.\n"); - } - else { - if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { - printf("The created group should NOT be in old-style . \n"); - TEST_ERROR; + + if (s->old_style_grp) { + if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("Old-styled group test: but the group is not in old-style. \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the old-style.\n"); + } + else { + if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) { + printf("The created group should NOT be in old-style . \n"); + TEST_ERROR; + } + dbgf(2, "Writer: group is created with the new-style.\n"); } - dbgf(2, "Writer: group is created with the new-style.\n"); } /* If coming to an "object header continuation block" test, @@ -2485,6 +2495,24 @@ group_operations(state_t *s, unsigned int which) } static unsigned int grp_counter = 0; + +/*------------------------------------------------------------------------- + * Function: UI_Pow + * + * Purpose: Helper function to obtain the power 'n' of + * an unsigned integer 'x' + * Similar to pow(x,y) but for an unsigned integer. + * + * Parameters: unsigned int x + * unsigned int n + * + * Return: Return an unsigned integer of value of pow(x,n) + * Note: If the returned value is > 2^32-1, an overflow + * may occur. For our testing purpose, this may never happen. + * + *------------------------------------------------------------------------- + */ + static unsigned int UI_Pow(unsigned int x, unsigned int n) { @@ -2497,17 +2525,55 @@ UI_Pow(unsigned int x, unsigned int n) return (number); } +/*------------------------------------------------------------------------- + * Function: obtain_tree_level_elems + * + * Purpose: Helper function to obtain the maximum number of elements + * at one level. + * + * Parameters: unsigned int total_ele + * The total number of elements of a tree(excluding the root) + * + * unsigned int level + * The number of nested levels + * (If every element of the tree is under the root, + * the level is 0.) + * + * Return: Return the maximum number of elements at one level + * + * Example: If the total number of elements is 6 and level is 1, + * the maximum number of elements is 2.The tree is + * a perfectly balanced tree. + * Such as: + * 0 + * 1 2 + * 3 4 5 6 + * + * If the total number of elements is 5 and level is 1, + * the maximum number of elements is still 2. The + * tree is not balanced, there is no element on the + * right-most leaf but the level is still 1. + * Such as: + * 0 + * 1 2 + * 3 4 5 + * + *------------------------------------------------------------------------- + */ + static unsigned int obtain_tree_level_elems(unsigned int total_ele, unsigned int level) { assert(level <= total_ele); + /* if every element is under the root, just return the total number of elements. */ if (level == 0) return total_ele; else { unsigned int test_elems_level = 0; unsigned total = 0; unsigned int i = 1; + /* Obtain the maximum number of elements for a level with the brutal force way. */ while (total < total_ele) { test_elems_level++; total = 0; @@ -2515,11 +2581,32 @@ obtain_tree_level_elems(unsigned int total_ele, unsigned int level) total += UI_Pow(test_elems_level, i); } if (total == total_ele) - printf("Perfectly match: Number of elements per level is %u\n", test_elems_level); + dbgf(2, "Perfectly match: Number of elements per level is %u\n", test_elems_level); return test_elems_level; } } +/*------------------------------------------------------------------------- + * Function: gen_tree_struct + * + * Purpose: Generate the nested groups + * + * Parameters: state_t *s + * The struct that stores information of HDF5 file, named pipe + * and some VFD SWMR configuration parameters + * + * unsigned int level + * The number of nested levels +1 + * (Note: If every element of the tree is under the root, + * the level is 1 in this function.) + * unsigned num_elems_per_level + * The maximum number of element in a level + * hid_t group_id + * The ID of the parent group + * + * Return: Success: true + * Failure: false + */ static bool gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgrp_id) { @@ -2529,6 +2616,9 @@ gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgr hid_t grp_id; bool result = true; H5G_info_t group_info; + struct timespec start_time, end_time; + double temp_time; + if (level > 0 && grp_counter < s->nsteps) { @@ -2536,6 +2626,16 @@ gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgr esnprintf(name, sizeof(name), "group-%u", grp_counter); if (grp_counter == s->nsteps) break; + + dbgf(2, "writer in nested group: step %d\n", grp_counter); + if (s->gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; + } + } + /* For each i a group is created. Use grp_counter to generate the group name. printf("id: %u,level: %u, index: %u\n",id,level,i); @@ -2545,6 +2645,23 @@ gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgr TEST_ERROR; } + if (s->gperf) { + + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + + fprintf(stderr, "HDclock_gettime failed"); + + TEST_ERROR; + } + + temp_time = TIME_PASSED(start_time, end_time); + if (temp_time < s->min_gc_time) + s->min_gc_time = temp_time; + if (temp_time > s->max_gc_time) + s->max_gc_time = temp_time; + s->total_gc_time += temp_time; + } + /* Just check the first group information. */ if (grp_counter == 0) { if (H5Gget_info(grp_id, &group_info) < 0) { @@ -2645,24 +2762,12 @@ main(int argc, char **argv) * 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().*/ + * Also pass the use_vfd_swmr, only_meta_page, page buffer size, config to vfd_swmr_create_fapl().*/ if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, s.pbs, &config)) < 0) { printf("vfd_swmr_create_fapl failed\n"); TEST_ERROR; } -#if 0 - if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { - printf("H5Pcreate failed\n"); - TEST_ERROR; - } - - if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, false, 1) < 0) { - printf("H5Pset_file_space_strategy failed\n"); - TEST_ERROR; - } -#endif - /* Set fs_strategy (file space strategy) and fs_page_size (file space page size) */ if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s.ps)) < 0) { HDprintf("vfd_swmr_create_fcpl() failed"); @@ -2680,87 +2785,76 @@ main(int argc, char **argv) if (s.gperf) { if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; } } - if (writer) - s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl); - else - s.file = H5Fopen(s.filename, H5F_ACC_RDONLY, fapl); + s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl); if (s.gperf) { if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; } s.fo_total_time = TIME_PASSED(start_time, end_time); - fprintf(stdout, "H5Fopen time = %lf\n", s.fo_total_time); } - if (s.file < 0) { - printf("H5Fcreate/open failed\n"); + printf("H5Fcreate failed\n"); TEST_ERROR; } - if (writer) { - if (s.gperf) { + /* If generating nested groups, calculate the maximum number of + elements per level. */ + if (s.nglevels > 0) + num_elems_per_level = obtain_tree_level_elems(s.nsteps, s.nglevels); - if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { - fprintf(stderr, "HDclock_gettime failed"); + if (s.gperf) { - TEST_ERROR; - } + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; } + } - if (s.nglevels > 0) { + /* If generating nested groups */ + if (s.nglevels > 0) { - num_elems_per_level = obtain_tree_level_elems(s.nsteps, s.nglevels); - /* for the recursive call, the groups under the root is treated as one level */ - wg_ret = gen_tree_struct(&s, s.nglevels + 1, num_elems_per_level, s.file); - if (wg_ret == false) { - printf("write nested group failed at group counter %u\n", grp_counter); - TEST_ERROR; - } + /* for the recursive call, the groups under the root is treated as one level */ + wg_ret = gen_tree_struct(&s, s.nglevels + 1, num_elems_per_level, s.file); + if (wg_ret == false) { + printf("write nested group failed at group counter %u\n", grp_counter); + TEST_ERROR; } - else { - for (step = 0; step < s.nsteps; step++) { + } + else { + for (step = 0; step < s.nsteps; step++) { - dbgf(2, "writer: step %d\n", step); - wg_ret = group_operations(&s, step); - if (wg_ret == false) { - printf("write_group failed at step %d\n", step); - TEST_ERROR; - } + dbgf(2, "writer: step %d\n", step); + wg_ret = group_operations(&s, step); + if (wg_ret == false) { + printf("write_group failed at step %d\n", step); + TEST_ERROR; } } + } - if (s.gperf) { - - if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { + if (s.gperf) { - fprintf(stderr, "HDclock_gettime failed"); - TEST_ERROR; - } + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - s.total_time = TIME_PASSED(start_time, end_time); - s.mean_time = s.total_time / s.nsteps; - fprintf(stdout, "group creation +5 attrs total time = %lf\n", s.total_time); - fprintf(stdout, "group creation +5 attrs mean time = %lf\n", s.mean_time); + fprintf(stderr, "HDclock_gettime failed"); + TEST_ERROR; } + + s.total_time = TIME_PASSED(start_time, end_time); + s.mean_time = s.total_time / s.nsteps; + s.mean_gc_time = s.total_gc_time/s.nsteps; } - else - printf("Reader is skipped for the performance tests.\n"); - if (H5Pclose(fapl) < 0) { printf("H5Pclose failed\n"); TEST_ERROR; @@ -2801,7 +2895,55 @@ main(int argc, char **argv) } s.fc_total_time = TIME_PASSED(start_time, end_time); + } + + /* Performance statistics summary */ + if(s.gperf) { + + if (verbosity !=0) { + + fprintf(stdout, "\nPerformance Test Configuration: "); + if(s.use_vfd_swmr) + fprintf(stdout, " Using VFD SWMR \n"); + else + fprintf(stdout, " Not using VFD SWMR \n"); + + if(s.old_style_grp) + fprintf(stdout, " Groups: Created via the earlist file format(old-style) \n"); + else + fprintf(stdout, " Groups: Created via the latest file format(new-style) \n"); + + fprintf(stdout, "\n"); + + fprintf(stdout, "The length of a tick = %u\n",s.tick_len); + fprintf(stdout, "The maximum expected log(in ticks)= %u\n",s.max_lag); + fprintf(stdout, "The page size(in bytes) = %u\n",s.ps); + fprintf(stdout, "The page buffer size(in bytes) = %u\n",s.pbs); + fprintf(stdout, "\n"); + fprintf(stdout, "Number of groups = %u\n" ,s.nsteps); + fprintf(stdout, "Group Nested levels = %u\n", s.nglevels); + fprintf(stdout, "Number of attributes = %u\n", s.num_attrs); + fprintf(stdout, "Number of element per attribute = 1\n"); + if(s.vlstr_test) + fprintf(stdout, "Attribute datatype is variable length string. \n"); + else if(s.filetype == H5T_STD_U32BE) + fprintf(stdout, "Attribute datatype is big-endian unsigned 32-bit integer.\n"); + else + fprintf(stdout, "Attribute datatype is native unsigned 32-bit integer.\n"); + + fprintf(stdout, "\n"); + fprintf(stdout, "(If the nested level is 0, all the groups are created directly under the root.)\n\n"); + fprintf(stdout, "group creation maximum time =%lf\n", s.max_gc_time); + fprintf(stdout, "group creation minimum time =%lf\n", s.min_gc_time); + } + + fprintf(stdout, "group creation total time = %lf\n", s.total_gc_time); + fprintf(stdout, "group creation mean time(per group) = %lf\n", s.mean_gc_time); + fprintf(stdout, "group creation and attributes generation total time = %lf\n", s.total_time); + fprintf(stdout, "group creation and attributes generation mean time(per group) = %lf\n",s.mean_time); + fprintf(stdout, "H5Fcreate time = %lf\n", s.fo_total_time); fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); + } return EXIT_SUCCESS; -- cgit v0.12 From 55caf37315100c76193c1e49d94cb85d9eecec96 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Aug 2021 20:54:04 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_gperf_writer.c | 114 +++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 58 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index e0a9b43..d0dd4d9 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -73,12 +73,12 @@ typedef struct { (state_t) \ { \ .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \ - .filetype = H5T_NATIVE_UINT32, .asteps = 1, .nsteps = 100, .use_vfd_swmr = true, \ + .filetype = H5T_NATIVE_UINT32, .asteps = 1, .nsteps = 100, .use_vfd_swmr = true, \ .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \ .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_gc_time = 100., \ .max_gc_time = 0., .mean_gc_time = 0., .total_gc_time = 0., .total_time = 0., .mean_time = 0., \ - .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, .vlstr_test = false, \ - .ps = 4096, .pbs = 4096, .nglevels =0 \ + .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, .vlstr_test = false, .ps = 4096, \ + .pbs = 4096, .nglevels = 0 \ } static void @@ -105,7 +105,7 @@ usage(const char *progname) " If all the groups are under the root group, \n" " this number should be 0.\n" "-N num_attrs: the number of attributes \n" - "-V use variable length string attributes for performance test\n" + "-V use variable length string attributes for performance test\n" "-b: write data in big-endian byte order\n" " (For the performance test, -V overwrites -b)\n" "-A at_pattern: `at_pattern' for different attribute tests\n" @@ -1610,12 +1610,12 @@ write_group(state_t *s, unsigned int which) } } /* We only need to check the first group */ - if(which == 0) { + if (which == 0) { if (H5Gget_info(g, &group_info) < 0) { printf("H5Gget_info failed\n"); TEST_ERROR; } - + if (s->old_style_grp) { if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) { printf("Old-styled group test: but the group is not in old-style. \n"); @@ -2494,11 +2494,11 @@ static unsigned int grp_counter = 0; /*------------------------------------------------------------------------- * Function: UI_Pow * - * Purpose: Helper function to obtain the power 'n' of + * Purpose: Helper function to obtain the power 'n' of * an unsigned integer 'x' * Similar to pow(x,y) but for an unsigned integer. * - * Parameters: unsigned int x + * Parameters: unsigned int x * unsigned int n * * Return: Return an unsigned integer of value of pow(x,n) @@ -2523,35 +2523,35 @@ UI_Pow(unsigned int x, unsigned int n) /*------------------------------------------------------------------------- * Function: obtain_tree_level_elems * - * Purpose: Helper function to obtain the maximum number of elements + * Purpose: Helper function to obtain the maximum number of elements * at one level. * - * Parameters: unsigned int total_ele + * Parameters: unsigned int total_ele * The total number of elements of a tree(excluding the root) * * unsigned int level * The number of nested levels - * (If every element of the tree is under the root, + * (If every element of the tree is under the root, * the level is 0.) * * Return: Return the maximum number of elements at one level * * Example: If the total number of elements is 6 and level is 1, * the maximum number of elements is 2.The tree is - * a perfectly balanced tree. - * Such as: + * a perfectly balanced tree. + * Such as: * 0 - * 1 2 + * 1 2 * 3 4 5 6 * * If the total number of elements is 5 and level is 1, - * the maximum number of elements is still 2. The - * tree is not balanced, there is no element on the - * right-most leaf but the level is still 1. - * Such as: + * the maximum number of elements is still 2. The + * tree is not balanced, there is no element on the + * right-most leaf but the level is still 1. + * Such as: * 0 - * 1 2 - * 3 4 5 + * 1 2 + * 3 4 5 * *------------------------------------------------------------------------- */ @@ -2584,7 +2584,7 @@ obtain_tree_level_elems(unsigned int total_ele, unsigned int level) /*------------------------------------------------------------------------- * Function: gen_tree_struct * - * Purpose: Generate the nested groups + * Purpose: Generate the nested groups * * Parameters: state_t *s * The struct that stores information of HDF5 file, named pipe @@ -2592,7 +2592,7 @@ obtain_tree_level_elems(unsigned int total_ele, unsigned int level) * * unsigned int level * The number of nested levels +1 - * (Note: If every element of the tree is under the root, + * (Note: If every element of the tree is under the root, * the level is 1 in this function.) * unsigned num_elems_per_level * The maximum number of element in a level @@ -2606,15 +2606,14 @@ static bool gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgrp_id) { - char name[sizeof("group-9999999999")]; - unsigned int i; - hid_t grp_id; - bool result = true; - H5G_info_t group_info; + char name[sizeof("group-9999999999")]; + unsigned int i; + hid_t grp_id; + bool result = true; + H5G_info_t group_info; struct timespec start_time, end_time; double temp_time; - if (level > 0 && grp_counter < s->nsteps) { for (i = 0; i < ne_per_level; i++) { @@ -2624,7 +2623,7 @@ gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgr dbgf(2, "writer in nested group: step %d\n", grp_counter); if (s->gperf) { - + if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { fprintf(stderr, "HDclock_gettime failed"); TEST_ERROR; @@ -2641,14 +2640,14 @@ gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgr } if (s->gperf) { - + if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) { - + fprintf(stderr, "HDclock_gettime failed"); - + TEST_ERROR; } - + temp_time = TIME_PASSED(start_time, end_time); if (temp_time < s->min_gc_time) s->min_gc_time = temp_time; @@ -2801,12 +2800,11 @@ main(int argc, char **argv) TEST_ERROR; } - /* If generating nested groups, calculate the maximum number of + /* If generating nested groups, calculate the maximum number of elements per level. */ - if (s.nglevels > 0) + if (s.nglevels > 0) num_elems_per_level = obtain_tree_level_elems(s.nsteps, s.nglevels); - if (s.gperf) { if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) { @@ -2845,11 +2843,11 @@ main(int argc, char **argv) TEST_ERROR; } - s.total_time = TIME_PASSED(start_time, end_time); - s.mean_time = s.total_time / s.nsteps; - s.mean_gc_time = s.total_gc_time/s.nsteps; + s.total_time = TIME_PASSED(start_time, end_time); + s.mean_time = s.total_time / s.nsteps; + s.mean_gc_time = s.total_gc_time / s.nsteps; } - + if (H5Pclose(fapl) < 0) { printf("H5Pclose failed\n"); TEST_ERROR; @@ -2893,41 +2891,42 @@ main(int argc, char **argv) } /* Performance statistics summary */ - if(s.gperf) { + if (s.gperf) { - if (verbosity !=0) { + if (verbosity != 0) { fprintf(stdout, "\nPerformance Test Configuration: "); - if(s.use_vfd_swmr) + if (s.use_vfd_swmr) fprintf(stdout, " Using VFD SWMR \n"); - else + else fprintf(stdout, " Not using VFD SWMR \n"); - if(s.old_style_grp) + if (s.old_style_grp) fprintf(stdout, " Groups: Created via the earlist file format(old-style) \n"); else fprintf(stdout, " Groups: Created via the latest file format(new-style) \n"); fprintf(stdout, "\n"); - - fprintf(stdout, "The length of a tick = %u\n",s.tick_len); - fprintf(stdout, "The maximum expected log(in ticks)= %u\n",s.max_lag); - fprintf(stdout, "The page size(in bytes) = %u\n",s.ps); - fprintf(stdout, "The page buffer size(in bytes) = %u\n",s.pbs); + + fprintf(stdout, "The length of a tick = %u\n", s.tick_len); + fprintf(stdout, "The maximum expected log(in ticks)= %u\n", s.max_lag); + fprintf(stdout, "The page size(in bytes) = %u\n", s.ps); + fprintf(stdout, "The page buffer size(in bytes) = %u\n", s.pbs); fprintf(stdout, "\n"); - fprintf(stdout, "Number of groups = %u\n" ,s.nsteps); + fprintf(stdout, "Number of groups = %u\n", s.nsteps); fprintf(stdout, "Group Nested levels = %u\n", s.nglevels); fprintf(stdout, "Number of attributes = %u\n", s.num_attrs); fprintf(stdout, "Number of element per attribute = 1\n"); - if(s.vlstr_test) + if (s.vlstr_test) fprintf(stdout, "Attribute datatype is variable length string. \n"); - else if(s.filetype == H5T_STD_U32BE) + else if (s.filetype == H5T_STD_U32BE) fprintf(stdout, "Attribute datatype is big-endian unsigned 32-bit integer.\n"); - else + else fprintf(stdout, "Attribute datatype is native unsigned 32-bit integer.\n"); - + fprintf(stdout, "\n"); - fprintf(stdout, "(If the nested level is 0, all the groups are created directly under the root.)\n\n"); + fprintf(stdout, + "(If the nested level is 0, all the groups are created directly under the root.)\n\n"); fprintf(stdout, "group creation maximum time =%lf\n", s.max_gc_time); fprintf(stdout, "group creation minimum time =%lf\n", s.min_gc_time); } @@ -2935,10 +2934,9 @@ main(int argc, char **argv) fprintf(stdout, "group creation total time = %lf\n", s.total_gc_time); fprintf(stdout, "group creation mean time(per group) = %lf\n", s.mean_gc_time); fprintf(stdout, "group creation and attributes generation total time = %lf\n", s.total_time); - fprintf(stdout, "group creation and attributes generation mean time(per group) = %lf\n",s.mean_time); + fprintf(stdout, "group creation and attributes generation mean time(per group) = %lf\n", s.mean_time); fprintf(stdout, "H5Fcreate time = %lf\n", s.fo_total_time); fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); - } return EXIT_SUCCESS; -- cgit v0.12 From 404784189cd069f3eaad0884b73c862318a156ff Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Fri, 20 Aug 2021 13:51:25 -0500 Subject: Add more description. --- test/vfd_swmr_gperf_writer.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index d0dd4d9..bb0a98c 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -14,12 +14,21 @@ * This program checks the performance of group creations for VFD SWMR. * Currently the group creation time, H5Fopen and H5Fclose time are measured. * After compiling the program, - * ./vfd_swmr_gperf_writer -n 1000 -P -N 5 -a 1 -q + * ./vfd_swmr_gperf_writer -n 1000 -P -N 5 -q * will generate 1000 groups, each group has 5 attributes. * ./vfd_swmr_gperf_writer -n 1000 -P -N 0 -q * will generate 1000 empty groups. - * ./vfd_swmr_gperf_writer -n 1000 -P -q - * will generate 1000 groups,for every ten groups, an attribute is generated. + * ./vfd_swmr_gperf_writer -n 1000 -P -l 1 -q + * will generate 1000 groups with 1 level of nested groups,(like /g1/g2) + * each group has one attribute. + * ./vfd_swmr_gperf_writer -n 1000 -P -S -G -V -N 5 -l 1 -m 8 -t 4 -B 16384 -s 8192 + * will generate 1000 groups with 1 level of nested groups,(like /g1/g2) + * each group has 5 attributes and the attribute type is variable length string. + * The groups is created without using VFD SWMR; + * The groups are created with the earliest file format(old-styled) + * The program is run with max_lag = 8, tick_len = 4; + * The page buffer size is 16384 bytes. The page size is 8192 bytes. + * */ #define H5F_FRIEND /*suppress error about including H5Fpkg */ @@ -2617,6 +2626,11 @@ gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgr if (level > 0 && grp_counter < s->nsteps) { for (i = 0; i < ne_per_level; i++) { + + /* For each i a group is created. + Use grp_counter to generate the group name. + printf("id: %u,level: %u, index: %u\n",id,level,i); + */ esnprintf(name, sizeof(name), "group-%u", grp_counter); if (grp_counter == s->nsteps) break; @@ -2630,10 +2644,6 @@ gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgr } } - /* For each i a group is created. - Use grp_counter to generate the group name. - printf("id: %u,level: %u, index: %u\n",id,level,i); - */ if ((grp_id = H5Gcreate2(pgrp_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { printf("H5Gcreate2 failed\n"); TEST_ERROR; @@ -2688,6 +2698,8 @@ gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgr TEST_ERROR; } grp_counter++; + + /* Generate groups in the next level */ result = gen_tree_struct(s, level - 1, ne_per_level, grp_id); if (result == false) { printf("Cannot create nested groups. \n"); @@ -2795,6 +2807,7 @@ main(int argc, char **argv) s.fo_total_time = TIME_PASSED(start_time, end_time); } + if (s.file < 0) { printf("H5Fcreate failed\n"); TEST_ERROR; @@ -2936,7 +2949,7 @@ main(int argc, char **argv) fprintf(stdout, "group creation and attributes generation total time = %lf\n", s.total_time); fprintf(stdout, "group creation and attributes generation mean time(per group) = %lf\n", s.mean_time); fprintf(stdout, "H5Fcreate time = %lf\n", s.fo_total_time); - fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); + fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time); } return EXIT_SUCCESS; -- cgit v0.12 From 25c8ea101aabb70e92b46297d401caf7a0d7cc2a Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 20 Aug 2021 18:55:19 +0000 Subject: Committing clang-format changes --- test/vfd_swmr_gperf_writer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index bb0a98c..15b52c1 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -19,11 +19,11 @@ * ./vfd_swmr_gperf_writer -n 1000 -P -N 0 -q * will generate 1000 empty groups. * ./vfd_swmr_gperf_writer -n 1000 -P -l 1 -q - * will generate 1000 groups with 1 level of nested groups,(like /g1/g2) - * each group has one attribute. + * will generate 1000 groups with 1 level of nested groups,(like /g1/g2) + * each group has one attribute. * ./vfd_swmr_gperf_writer -n 1000 -P -S -G -V -N 5 -l 1 -m 8 -t 4 -B 16384 -s 8192 * will generate 1000 groups with 1 level of nested groups,(like /g1/g2) - * each group has 5 attributes and the attribute type is variable length string. + * each group has 5 attributes and the attribute type is variable length string. * The groups is created without using VFD SWMR; * The groups are created with the earliest file format(old-styled) * The program is run with max_lag = 8, tick_len = 4; @@ -2698,7 +2698,7 @@ gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgr TEST_ERROR; } grp_counter++; - + /* Generate groups in the next level */ result = gen_tree_struct(s, level - 1, ne_per_level, grp_id); if (result == false) { -- cgit v0.12 From 8555ac9f1958ab7d20adefd5e378294226055693 Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Fri, 20 Aug 2021 14:19:55 -0500 Subject: Add vfd_gperf_writer.c to MANIFEST. --- MANIFEST | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST b/MANIFEST index a183dc5..328d35d 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1420,6 +1420,7 @@ ./test/vfd_swmr_common.h ./test/vfd_swmr_generator.c ./test/vfd_swmr_group_writer.c +./test/vfd_swmr_gperf_writer.c ./test/vfd_swmr_reader.c ./test/vfd_swmr_remove_reader.c ./test/vfd_swmr_remove_writer.c -- cgit v0.12 From 6e2a2fed3a68085fca170065a3d191f4f946ba1e Mon Sep 17 00:00:00 2001 From: Muqun Yang Date: Thu, 26 Aug 2021 12:59:04 -0500 Subject: fixed comment issues. --- test/vfd_swmr_gperf_writer.c | 64 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c index 15b52c1..e21f931 100644 --- a/test/vfd_swmr_gperf_writer.c +++ b/test/vfd_swmr_gperf_writer.c @@ -416,7 +416,7 @@ error: * Purpose: Add attributes to a group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t oid @@ -522,7 +522,7 @@ error: * Purpose: Add a variable length string attribute to a group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -620,7 +620,7 @@ error: * Purpose: Add variable length string attributes to a group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -660,7 +660,7 @@ add_vlstr_attrs(state_t *s, hid_t g, unsigned int which, unsigned int num_attrs) * Purpose: Add an attribute to a group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -704,7 +704,7 @@ add_default_group_attr(state_t *s, hid_t g, unsigned int which) * Purpose: delete one attribute in a group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t obj_id @@ -785,7 +785,7 @@ error: * then delete this attribute in this a group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -825,7 +825,7 @@ add_del_vlstr_attr(state_t *s, hid_t g, unsigned int which) * Purpose: Modify the value of an attribute in a group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -990,10 +990,10 @@ error: * Function: add_modify_vlstr_attr * * Purpose: Add a variable length string attribute - * then modify this attribute in this a group. + * then modify this attribute in the group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -1033,7 +1033,7 @@ add_modify_vlstr_attr(state_t *s, hid_t g, unsigned int which) * attributes that the compact storage can hold * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -1095,7 +1095,7 @@ error: * Then, add another atribute, the storage becomes dense. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -1231,7 +1231,7 @@ error: * Then, delete one atribute, the storage is still compact. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -1277,7 +1277,7 @@ add_del_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which) * Then, delete one atribute, the storage is still dense. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -1333,7 +1333,7 @@ error: * dense to compact again. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -1373,7 +1373,7 @@ add_del_attrs_compact_dense_compact(state_t *s, hid_t g, hid_t gcpl, unsigned in * 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 + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -1413,7 +1413,7 @@ add_modify_default_group_attr(state_t *s, hid_t g, unsigned int which) * the object header continuation block * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -1451,7 +1451,7 @@ del_ohr_block_attr(state_t *s, hid_t g, unsigned int which) * correponding test function.. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t g @@ -1527,7 +1527,7 @@ add_group_attribute(state_t *s, hid_t g, hid_t gcpl, unsigned int which) * according to the attribute test pattern. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -1695,7 +1695,7 @@ error: * Purpose: Create a group and return the group ID. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -1818,7 +1818,7 @@ error: * Purpose: Create a group * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -1896,7 +1896,7 @@ error: * according to the group test pattern. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t obj_id @@ -1978,7 +1978,7 @@ error: * according to the group operation test pattern. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -2013,7 +2013,7 @@ delete_group(state_t *s, unsigned int which) * Purpose: A helper function used by the move_group operation. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t obj_id @@ -2062,7 +2062,7 @@ error: * Purpose: Move a group to another group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -2098,7 +2098,7 @@ move_group(state_t *s, unsigned int which) * Purpose: A helper function used to attach a link to a group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * hid_t obj_id @@ -2212,7 +2212,7 @@ error: * Purpose: create links with a group. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -2253,7 +2253,7 @@ insert_links(state_t *s, unsigned int which) * Purpose: create links with a group and then delete them successfully. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -2295,7 +2295,7 @@ delete_links(state_t *s, unsigned int which) * compact to dense. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -2361,7 +2361,7 @@ error: * compact to dense then to compact. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -2447,7 +2447,7 @@ error: * according to the group operation and attribute test patterns. * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int which @@ -2596,7 +2596,7 @@ obtain_tree_level_elems(unsigned int total_ele, unsigned int level) * Purpose: Generate the nested groups * * Parameters: state_t *s - * The struct that stores information of HDF5 file, named pipe + * The struct that stores information of HDF5 file * and some VFD SWMR configuration parameters * * unsigned int level @@ -2922,7 +2922,7 @@ main(int argc, char **argv) fprintf(stdout, "\n"); fprintf(stdout, "The length of a tick = %u\n", s.tick_len); - fprintf(stdout, "The maximum expected log(in ticks)= %u\n", s.max_lag); + fprintf(stdout, "The maximum expected lag(in ticks)= %u\n", s.max_lag); fprintf(stdout, "The page size(in bytes) = %u\n", s.ps); fprintf(stdout, "The page buffer size(in bytes) = %u\n", s.pbs); fprintf(stdout, "\n"); -- cgit v0.12