diff options
Diffstat (limited to 'test/links.c')
-rw-r--r-- | test/links.c | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/test/links.c b/test/links.c index 3619c27..8ee16a6 100644 --- a/test/links.c +++ b/test/links.c @@ -176,6 +176,8 @@ const char *FILENAME[] = { #define H5L_DIM1 100 #define H5L_DIM2 100 +#define FILTER_FILESIZE_MAX_FRACTION .9 + /* Creation order macros */ #define CORDER_GROUP_NAME "corder_group" #define CORDER_SOFT_GROUP_NAME "corder_soft_group" @@ -8520,6 +8522,386 @@ error: /*------------------------------------------------------------------------- + * Function: link_filters + * + * Purpose: Tests adding filters to group link storage. Also tests + * copying these groups. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * Tuesday, June 16, 2009 + * + *------------------------------------------------------------------------- + */ +static enum { + LFS_INIT, + LFS_CAN_APPLY_CALLED, + LFS_SET_LOCAL_CALLED, + LFS_ENCODED, + LFS_DECODED +} link_filter_state; + +static herr_t link_filter_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id) +{ + if(dcpl_id >= 0 || type_id >= 0 || space_id >= 0) + return -1; + + if(link_filter_state >= LFS_ENCODED) + return 1; + + if(link_filter_state != LFS_INIT) + return -1; + + link_filter_state = LFS_CAN_APPLY_CALLED; + + return 1; +} /* end link_fitler_can_apply */ + +static herr_t link_filter_set_local(hid_t dcpl_id, hid_t type_id, hid_t space_id) +{ + if(dcpl_id >= 0 || type_id >= 0 || space_id >= 0) + return -1; + + if(link_filter_state >= LFS_ENCODED) + return 0; + + if(link_filter_state != LFS_CAN_APPLY_CALLED) + return -1; + + link_filter_state = LFS_SET_LOCAL_CALLED; + + return 0; +} /* end link_filter_set_local */ + +static size_t link_filter_filter(unsigned int flags, size_t cd_nelmts, + const unsigned int cd_values[], size_t nbytes, size_t UNUSED *buf_size, + void UNUSED **buf) +{ + if(flags & H5Z_FLAG_OPTIONAL || cd_nelmts != 1 || cd_values[0] != 2112) + return 0; + + if(link_filter_state == LFS_DECODED) + return nbytes; + + if(flags & H5Z_FLAG_REVERSE) { + if(link_filter_state != LFS_ENCODED) + return 0; + link_filter_state = LFS_DECODED; + } else { + if(link_filter_state < LFS_SET_LOCAL_CALLED) + return 0; + link_filter_state = LFS_ENCODED; + } /* end else */ + + return nbytes; +} /* end link_filter_filter */ + +static int +link_filters(hid_t fapl, hbool_t new_format) +{ + hid_t fid = -1, fcpl = -1; + hid_t gid1 = -1, gid2 = -1, gcpl1 = -1, gcpl2 = -1; + hid_t lcpl = -1; + size_t cd_nelmts = 1; + unsigned cd_value = 2112; + unsigned cd_value_out; + unsigned flags_out; + unsigned filter_config_out; + int nfilters = 0; + H5Z_class2_t filter_class; + char name_out[24]; + char filename[NAME_BUF_SIZE]; + htri_t tri_ret; + herr_t status; + + /* This test actually always uses the new group format for the main group. + * The new format flag affects the version of object header messages, + * etc., which are important for this test. */ + if(new_format) + TESTING("group link filters (w/new group format)") + else + TESTING("group link filters") + + /* Initialize link filter state global */ + link_filter_state = LFS_INIT; + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create gcpl, force use of dense storage */ + if((gcpl1 = H5Pcreate(H5P_GROUP_CREATE)) < 0) TEST_ERROR + if(H5Pset_link_phase_change(gcpl1, 2, 2) < 0) TEST_ERROR + + /* Add deflate and checksum filters, if available */ + if((tri_ret = H5Zfilter_avail(H5Z_FILTER_DEFLATE)) < 0) TEST_ERROR + if(tri_ret) { + if(H5Pset_deflate(gcpl1, 6) < 0) TEST_ERROR + nfilters++; + } /* end if */ + if((tri_ret = H5Zfilter_avail(H5Z_FILTER_FLETCHER32)) < 0) TEST_ERROR + if(tri_ret) { + if(H5Pset_fletcher32(gcpl1) < 0) TEST_ERROR + nfilters++; + } /* end if */ + + /* Register and add custom filter */ + filter_class.version = H5Z_CLASS_T_VERS; + filter_class.id = H5Z_FILTER_RESERVED + 42; + filter_class.encoder_present = TRUE; + filter_class.decoder_present = TRUE; + filter_class.name = "custom_link_filter"; + filter_class.can_apply = link_filter_can_apply; + filter_class.set_local = link_filter_set_local; + filter_class.filter = link_filter_filter; + if(H5Zregister(&filter_class) < 0) TEST_ERROR + if(H5Pset_filter(gcpl1, H5Z_FILTER_RESERVED + 42, 0, (size_t)1, &cd_value) < 0) + TEST_ERROR + nfilters++; + + /* Test various other filter functions for use on gcpl's */ + if(H5Pget_nfilters(gcpl1) != nfilters) TEST_ERROR + if(H5Pall_filters_avail(gcpl1) != TRUE) TEST_ERROR + + /* Create a group using this filter, add some soft links to it */ + if((gid1 = H5Gcreate2(fid, "group1", H5P_DEFAULT, gcpl1, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close file and group */ + if(H5Gclose(gid1) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Verify the filter has been applied */ + if(link_filter_state != LFS_ENCODED) TEST_ERROR + + /* Reopen file and group */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + if((gid1 = H5Gopen2(fid, "group1", H5P_DEFAULT)) < 0) TEST_ERROR + + /* Retrieve gcpl, verify number of filters */ + if((gcpl2 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl2) != nfilters) TEST_ERROR + if(H5Pclose(gcpl2) < 0) TEST_ERROR + + /* Now try copying gcpl1, and verify number of filters */ + if((gcpl2 = H5Pcopy(gcpl1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl2) != nfilters) TEST_ERROR + if(H5Pclose(gcpl2) < 0) TEST_ERROR + + /* Add another soft link */ + if(H5Lcreate_soft("/", gid1, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Copy the group */ + if(H5Ocopy(fid, "group1", fid, "group2", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if((gid2 = H5Gopen2(fid, "group2", H5P_DEFAULT)) <0) TEST_ERROR + + /* Verify that all links have been copied */ + if(H5Lexists(gid2, "link1", H5P_DEFAULT) != TRUE) TEST_ERROR + if(H5Lexists(gid2, "link2", H5P_DEFAULT) != TRUE) TEST_ERROR + if(H5Lexists(gid2, "link3", H5P_DEFAULT) != TRUE) TEST_ERROR + if(H5Lexists(gid2, "link4", H5P_DEFAULT) != TRUE) TEST_ERROR + + /* Retrieve gcpl, verify number of filters */ + if((gcpl2 = H5Gget_create_plist(gid2)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl2) != nfilters) TEST_ERROR + + /* Delete 3 links to force the group back into compact mode */ + if(H5Ldelete(gid1, "link2", H5P_DEFAULT) < 0) TEST_ERROR + if(H5Ldelete(gid1, "link3", H5P_DEFAULT) < 0) TEST_ERROR + if(H5Ldelete(gid1, "link4", H5P_DEFAULT) < 0) TEST_ERROR + + /* Close file and groups */ + if(H5Gclose(gid1) < 0) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Reset link filter state */ + link_filter_state = LFS_INIT; + + /* Reopen file and group, add 2 links */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + if((gid1 = H5Gopen2(fid, "group1", H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", gid1, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close file and group */ + if(H5Gclose(gid1) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Verify that the filter was reapplied */ + if(link_filter_state != LFS_ENCODED) TEST_ERROR + + /* Test H5Pget_filter_by_id2 and H5Pget_filter2 */ + if(H5Pget_filter_by_id2(gcpl2, H5Z_FILTER_RESERVED + 42, &flags_out, + &cd_nelmts, &cd_value_out, (size_t)24, name_out, &filter_config_out) < 0) + TEST_ERROR + if(flags_out != 0 || cd_value_out != cd_value + || HDstrcmp(filter_class.name, name_out) + || filter_config_out != (H5Z_FILTER_CONFIG_ENCODE_ENABLED + | H5Z_FILTER_CONFIG_DECODE_ENABLED)) + TEST_ERROR + if(H5Pget_filter2(gcpl2, 2, &flags_out, &cd_nelmts, &cd_value_out, (size_t)24, + name_out, &filter_config_out) < 0) + TEST_ERROR + if(flags_out != 0 || cd_value_out != cd_value + || HDstrcmp(filter_class.name, name_out) + || filter_config_out != (H5Z_FILTER_CONFIG_ENCODE_ENABLED + | H5Z_FILTER_CONFIG_DECODE_ENABLED)) + TEST_ERROR + + /* Test H5Pmodify_filter */ + cd_value++; + if(H5Pmodify_filter(gcpl2, H5Z_FILTER_RESERVED + 42, 0, (size_t)1, &cd_value) < 0) + TEST_ERROR + if(H5Pget_filter_by_id2(gcpl2, H5Z_FILTER_RESERVED + 42, &flags_out, + &cd_nelmts, &cd_value_out, (size_t)24, name_out, &filter_config_out) < 0) + TEST_ERROR + if(flags_out != 0 || cd_value_out != cd_value + || HDstrcmp(filter_class.name, name_out) + || filter_config_out != (H5Z_FILTER_CONFIG_ENCODE_ENABLED + | H5Z_FILTER_CONFIG_DECODE_ENABLED)) + TEST_ERROR + + /* Test H5Premove_filter */ + if(H5Premove_filter(gcpl2, H5Z_FILTER_RESERVED + 42) < 0) TEST_ERROR + H5E_BEGIN_TRY { + status = H5Pget_filter_by_id2(gcpl2, H5Z_FILTER_RESERVED + 42, + &flags_out, &cd_nelmts, &cd_value_out, (size_t)24, name_out, + &filter_config_out); + } H5E_END_TRY + if(status >= 0) TEST_ERROR + + /* Close remaining ids */ + if(H5Pclose(gcpl1) < 0) TEST_ERROR + if(H5Pclose(gcpl2) < 0) TEST_ERROR + + /* Now create an object in the compressed group, creating intermediate + * groups, to verify that the filter pipeline is inherited for the groups + * that are created along the way */ + /* Reopen file */ + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Create lcpl, setting the "create intermediate groups" flag */ + if((lcpl = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR + if(H5Pset_create_intermediate_group(lcpl, (unsigned)TRUE) < 0) TEST_ERROR + + /* Create new group, with missing intermediate groups, in compressed group */ + if((gid1 = H5Gcreate2(fid, "group1/group2/group3/group4", lcpl, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Close LCPL ID */ + if(H5Pclose(lcpl) < 0) TEST_ERROR + + /* Verify that new group doesn't have filters */ + if((gcpl1 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl1) != 0) TEST_ERROR + + /* Close group & GCPL IDs */ + if(H5Pclose(gcpl1) < 0) TEST_ERROR + if(H5Gclose(gid1) < 0) TEST_ERROR + + /* Open intermediate groups that were created and verify that they have filters */ + if((gid1 = H5Gopen2(fid, "group1/group2", H5P_DEFAULT)) < 0) TEST_ERROR + if((gcpl1 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl1) != nfilters) TEST_ERROR + if(H5Pclose(gcpl1) < 0) TEST_ERROR + if(H5Gclose(gid1) < 0) TEST_ERROR + if((gid1 = H5Gopen2(fid, "group1/group2/group3", H5P_DEFAULT)) < 0) TEST_ERROR + if((gcpl1 = H5Gget_create_plist(gid1)) < 0) TEST_ERROR + if(H5Pget_nfilters(gcpl1) != nfilters) TEST_ERROR + if(H5Pclose(gcpl1) < 0) TEST_ERROR + if(H5Gclose(gid1) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + + /* Now create the same file with and without deflate, and verify that the + * file size is smaller with deflate */ + /* But only if the deflate filter is available */ + if((tri_ret = H5Zfilter_avail(H5Z_FILTER_DEFLATE)) < 0) TEST_ERROR + if(tri_ret) { + h5_stat_size_t filesize_filtered; + h5_stat_size_t filesize_unfiltered; + + /* Create gcpl, force use of dense storage */ + if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) TEST_ERROR + if(H5Pset_link_phase_change(fcpl, 2, 2) < 0) TEST_ERROR + + /* Create file */ + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + TEST_ERROR + + /* Create links in file */ + if(H5Lcreate_soft("/", fid, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close file, get file size */ + if(H5Fclose(fid) < 0) TEST_ERROR + filesize_unfiltered = h5_get_file_size(filename, fapl); + + /* Set deflate fitler */ + if(H5Pset_deflate(fcpl, 6) < 0) TEST_ERROR + + /* Recreate the same file with the deflate filter */ + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + if(H5Lcreate_soft("/", fid, "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR + + /* Close file, get file size */ + if(H5Fclose(fid) < 0) TEST_ERROR + filesize_filtered = h5_get_file_size(filename, fapl); + + /* Check that the file size is smaller with the filter */ + if((double)filesize_filtered + > (filesize_unfiltered * FILTER_FILESIZE_MAX_FRACTION)) + TEST_ERROR + + /* Close */ + if(H5Pclose(fcpl) < 0) TEST_ERROR + } /* end if */ + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid1); + H5Gclose(gid2); + H5Fclose(fid); + H5Pclose(lcpl); + H5Pclose(gcpl1); + H5Pclose(gcpl2); + H5Pclose(fcpl); + } H5E_END_TRY; + return -1; +} /* end link_filters() */ + + +/*------------------------------------------------------------------------- * Function: corder_create_empty * * Purpose: Create an empty group with creation order indices @@ -13056,6 +13438,7 @@ main(void) nerrors += obj_visit(my_fapl, new_format) < 0 ? 1 : 0; nerrors += obj_visit_by_name(my_fapl, new_format) < 0 ? 1 : 0; nerrors += obj_visit_stop(my_fapl, new_format) < 0 ? 1 : 0; + nerrors += link_filters(my_fapl, new_format) < 0 ? 1 : 0; /* Keep this test last, it's testing files that are used above */ /* do not do this for files used by external link tests */ |