summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2011-04-15 22:05:23 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2011-04-15 22:05:23 (GMT)
commit7610dd20af382ba6d784c95f6436bb56ff895e07 (patch)
tree4cd64207ed16a5ea96dc3669e2efa6a645c89f67 /src
parente1ed6bb771ad03d584b465036dba79cbad2254c5 (diff)
downloadhdf5-7610dd20af382ba6d784c95f6436bb56ff895e07.zip
hdf5-7610dd20af382ba6d784c95f6436bb56ff895e07.tar.gz
hdf5-7610dd20af382ba6d784c95f6436bb56ff895e07.tar.bz2
[svn-r20529] Purpose: Add testing for bug 1864
Description: Added internal tesitng routines to traverse a file and verify that symbol table information is *always* cached, whenever possible. Added this check to the end of many tests to check all the test files, right before the call to h5_cleanup. Tested: jam, amani, heiwa (h5committest)
Diffstat (limited to 'src')
-rw-r--r--src/H5Gpkg.h1
-rw-r--r--src/H5Gtest.c164
2 files changed, 165 insertions, 0 deletions
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index dfaf112..c966e16 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -608,6 +608,7 @@ H5_DLL herr_t H5G_new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *c
H5_DLL herr_t H5G_lheap_size_test(hid_t gid, size_t *lheap_size);
H5_DLL herr_t H5G_user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsigned *user_path_hidden);
H5_DLL herr_t H5G_verify_cached_stab_test(H5O_loc_t *grp_oloc, H5G_entry_t *ent);
+H5_DLL herr_t H5G_verify_cached_stabs_test(hid_t gid);
#endif /* H5G_TESTING */
#endif /* _H5Gpkg_H */
diff --git a/src/H5Gtest.c b/src/H5Gtest.c
index 96ecfda..ec55e47 100644
--- a/src/H5Gtest.c
+++ b/src/H5Gtest.c
@@ -641,3 +641,167 @@ done:
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5G_verify_cached_stab_test() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_verify_cached_stabs_test_cb
+ *
+ * Purpose: Verify that all entries in this node contain cached symbol
+ * table information if and only if the entry refers to a
+ * group with a symbol table, and that that information is
+ * correct.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Apr 8, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5G_verify_cached_stabs_test_cb(H5F_t *f, hid_t dxpl_id,
+ const void UNUSED *_lt_key, haddr_t addr, const void UNUSED *_rt_key,
+ void UNUSED *udata)
+{
+ H5G_node_t *sn = NULL;
+ H5O_loc_t targ_oloc;
+ H5O_t *targ_oh = NULL;
+ htri_t stab_exists;
+ H5O_stab_t stab;
+ unsigned i;
+ int ret_value = H5_ITER_CONT;
+
+ FUNC_ENTER_NOAPI(H5G_verify_cached_stabs_test_cb, H5_ITER_ERROR)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Load the node */
+ if(NULL == (sn = (H5G_node_t *)H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, f, H5AC_READ)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load symbol table node")
+
+ /* Check each target object to see if its stab message (if present) matches
+ * the cached stab (if present). If one exists, both must exist. */
+ /* Initialize constant fields in target oloc */
+ targ_oloc.file = f;
+ targ_oloc.holding_file = FALSE;
+
+ /* Iterate over entries */
+ for(i=0; i<sn->nsyms; i++) {
+ /* Update oloc address */
+ targ_oloc.addr = sn->entry[i].header;
+
+ /* Load target object header */
+ if(NULL == (targ_oh = H5O_protect(&targ_oloc, dxpl_id, H5AC_READ)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTPROTECT, H5_ITER_ERROR, "unable to protect target object header")
+
+ /* Check if a symbol table message exists */
+ if((stab_exists = H5O_msg_exists_oh(targ_oh, H5O_STAB_ID)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5_ITER_ERROR, "unable to check for STAB message")
+
+ if(stab_exists) {
+ /* Read symbol table message */
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, targ_oh, H5O_STAB_ID, &stab))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5_ITER_ERROR, "unable to read STAB message")
+
+ /* Check if the stab matches the cached stab info */
+ if(sn->entry[i].type != H5G_CACHED_STAB)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, H5_ITER_ERROR, "STAB message is not cached in group node")
+
+ if((sn->entry[i].cache.stab.btree_addr != stab.btree_addr)
+ || (sn->entry[i].cache.stab.heap_addr != stab.heap_addr))
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, H5_ITER_ERROR, "cached symbol table information is incorrect")
+ } /* end if */
+ else if(sn->entry[i].type == H5G_CACHED_STAB)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, H5_ITER_ERROR, "nonexistent STAB message is cached")
+
+ /* Unprotect target object */
+ if(H5O_unprotect(&targ_oloc, dxpl_id, targ_oh, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTUNPROTECT, H5_ITER_ERROR, "unable to release object header");
+ targ_oh = NULL;
+ } /* end for */
+
+done:
+ if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5_ITER_ERROR, "unable to release object header")
+
+ if(targ_oh) {
+ HDassert(ret_value == H5_ITER_ERROR);
+ if(H5O_unprotect(&targ_oloc, dxpl_id, targ_oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTUNPROTECT, H5_ITER_ERROR, "unable to release object header");
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_verify_cached_stabs_test_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_verify_cached_stabs_test
+ *
+ * Purpose: If the provided group contains a symbol table, verifies
+ * that all links in the group contain cached symbol table
+ * information if and only if the link points to a group
+ * with a symbol table, and that that information is correct.
+ * If the provided group does not contain a symbol table,
+ * does nothing.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * nfortne2@hdfgroup.org
+ * April 6 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_verify_cached_stabs_test(hid_t gid)
+{
+ H5G_t *grp = NULL; /* Group */
+ htri_t stab_exists;
+ H5O_stab_t stab; /* Symbol table message */
+ H5G_bt_common_t udata = {NULL, NULL}; /* Dummy udata so H5B_iterate doesn't freak out */
+ haddr_t prev_tag = HADDR_UNDEF; /* Previous metadata tag */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_verify_cached_stabs_test, FAIL)
+
+ /* check args */
+ HDassert(gid >= 0);
+
+ /* Check args */
+ if(NULL == (grp = (H5G_t *)H5I_object_verify(gid, H5I_GROUP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+
+ /* Set up metadata tagging */
+ if(H5AC_tag(H5AC_ind_dxpl_id, grp->oloc.addr, &prev_tag) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag")
+
+ /* Check for group having a symbol table message */
+ /* Check for the group having a group info message */
+ if((stab_exists = H5O_msg_exists(&(grp->oloc), H5O_STAB_ID,
+ H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+
+ /* No need to check anything if the symbol table doesn't exist */
+ if(!stab_exists)
+ HGOTO_DONE(SUCCEED);
+
+ /* Read the stab */
+ if(NULL == H5O_msg_read(&(grp->oloc), H5O_STAB_ID, &stab, H5AC_ind_dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get symbol table info")
+
+ /* Iterate over the b-tree, checking validity of cached information */
+ if((ret_value = H5B_iterate(grp->oloc.file, H5AC_ind_dxpl_id, H5B_SNODE,
+ stab.btree_addr, H5G_verify_cached_stabs_test_cb, &udata)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "iteration operator failed");
+
+ /* Reset metadata tagging */
+ if(H5AC_tag(H5AC_ind_dxpl_id, prev_tag, NULL) < 0)
+ HDONE_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_verify_cached_stabs_test() */
+