diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2011-04-15 22:05:23 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2011-04-15 22:05:23 (GMT) |
commit | 7610dd20af382ba6d784c95f6436bb56ff895e07 (patch) | |
tree | 4cd64207ed16a5ea96dc3669e2efa6a645c89f67 /src | |
parent | e1ed6bb771ad03d584b465036dba79cbad2254c5 (diff) | |
download | hdf5-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.h | 1 | ||||
-rw-r--r-- | src/H5Gtest.c | 164 |
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() */ + |