diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2009-01-08 18:24:09 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2009-01-08 18:24:09 (GMT) |
commit | 50d88ec142fc41ba5588980cde79c6bb9c2e276a (patch) | |
tree | 0a848b0ff0ef7fe06554a902d186dc34e153134a /test/links.c | |
parent | ab2ff6eda496173e038d97685f96dd2de9e3df29 (diff) | |
download | hdf5-50d88ec142fc41ba5588980cde79c6bb9c2e276a.zip hdf5-50d88ec142fc41ba5588980cde79c6bb9c2e276a.tar.gz hdf5-50d88ec142fc41ba5588980cde79c6bb9c2e276a.tar.bz2 |
[svn-r16282] Purpose: Add functions to allow more flexible traversal of external links.
Description: Added H5Pset/get_elink_cb to allow the user to specify a callback
function to be called whenever an external link is traversed. Added
H5Pset/get_elink_acc_flags to allow the user to specify the file access flags
to use to open the target file of an external link. All these properties are set on a LAPL.
Tested: jam (trunk version tested with h5committest)
Diffstat (limited to 'test/links.c')
-rw-r--r-- | test/links.c | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/test/links.c b/test/links.c index 85d8816..8a4274c 100644 --- a/test/links.c +++ b/test/links.c @@ -76,6 +76,10 @@ const char *FILENAME[] = { "extlinks16A", /* 37: */ /* TESTS for H5P_set_elink_fapl */ "extlinks16B", /* 38: */ "extlinks17", /* 39: */ + "extlinks18A", /* 40: */ + "extlinks18B", /* 41: */ + "extlinks19A", /* 42: */ + "extlinks19B", /* 43: */ NULL }; @@ -3947,6 +3951,278 @@ external_set_elink_fapl3(hbool_t new_format) } /* end external_set_elink_fapl3() */ +/*------------------------------------------------------------------------- + * Function: external_set_elink_acc_flags + * + * Purpose: Verify functionality of H5P_set/get_elink_acc_flags + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * Jan. 5, 2009 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +external_set_elink_acc_flags(hid_t fapl, hbool_t new_format) +{ + hid_t file1, file2, group, subgroup, gapl; + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE]; + unsigned flags; + + if(new_format) + TESTING("H5Pset/get_elink_acc_flags() (w/new group format)") + else + TESTING("H5Pset/get_elink_acc_flags()") + + /* Create parent and target files, and external link */ + h5_fixname(FILENAME[40], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[41], fapl, filename2, sizeof filename2); + if ((file1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if ((file2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if (H5Lcreate_external(filename2, "/", file1, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close file2, leave file1 open (should be read-write) */ + if (H5Fclose(file2) < 0) TEST_ERROR + + /* Create new gapl, and set elink access flags to be H5F_ACC_RDONLY */ + if ((gapl = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR + if (H5Pset_elink_acc_flags(gapl, H5F_ACC_RDONLY) < 0) TEST_ERROR + + /* Verify "get" routine functionality */ + if (H5Pget_elink_acc_flags(gapl, &flags) < 0) TEST_ERROR + if (flags != H5F_ACC_RDONLY) TEST_ERROR + + /* Attempt to create a group through the external link using gapl (should fail) */ + H5E_BEGIN_TRY { + group = H5Gcreate2(file1, "/ext_link/group", H5P_DEFAULT, H5P_DEFAULT, gapl); + } H5E_END_TRY; + if (group != FAIL) TEST_ERROR + + /* Close file1 and reopen with read only access */ + if (H5Fclose(file1) < 0) TEST_ERROR + if ((file1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Set elink access flags on gapl to be H5F_ACC_RDWR */ + if (H5Pset_elink_acc_flags(gapl, H5F_ACC_RDWR) < 0) TEST_ERROR + + /* Create a group through the external link using gapl (should succeed) */ + if ((group = H5Gcreate2(file1, "/ext_link/group", H5P_DEFAULT, H5P_DEFAULT, gapl)) < 0) TEST_ERROR + + /* Unset elink access flags on gapl */ + if (H5Pset_elink_acc_flags(gapl, H5F_ACC_DEFAULT) < 0) TEST_ERROR + + /* Attempt to create a group through the external link using gapl (should fail) */ + H5E_BEGIN_TRY { + subgroup = H5Gcreate2(file1, "/ext_link/group/subgroup", H5P_DEFAULT, H5P_DEFAULT, gapl); + } H5E_END_TRY; + if (subgroup != FAIL) TEST_ERROR + + /* Close file1 and group */ + if (H5Gclose(group) < 0) TEST_ERROR + if (H5Fclose(file1) < 0) TEST_ERROR + + /* Verify that H5Fcreate and H5Fopen reject H5F_ACC_DEFAULT */ + H5E_BEGIN_TRY { + file1 = H5Fcreate(filename1, H5F_ACC_DEFAULT, H5P_DEFAULT, fapl); + } H5E_END_TRY; + if (file1 != FAIL) TEST_ERROR + H5E_BEGIN_TRY { + file1 = H5Fcreate(filename1, H5F_ACC_TRUNC | H5F_ACC_DEFAULT, H5P_DEFAULT, fapl); + } H5E_END_TRY; + if (file1 != FAIL) TEST_ERROR + H5E_BEGIN_TRY { + file1 = H5Fopen(filename1, H5F_ACC_DEFAULT, fapl); + } H5E_END_TRY; + if (file1 != FAIL) TEST_ERROR + H5E_BEGIN_TRY { + file1 = H5Fopen(filename1, H5F_ACC_RDWR | H5F_ACC_DEFAULT, fapl); + } H5E_END_TRY; + if (file1 != FAIL) TEST_ERROR + + /* Close gapl */ + if (H5Pclose(gapl) < 0) TEST_ERROR + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose(group); + H5Gclose(subgroup); + H5Fclose(file1); + H5Fclose(file2); + H5Pclose(gapl); + } H5E_END_TRY; + return -1; +} /* end external_set_elink_acc_flags() */ + + +/*------------------------------------------------------------------------- + * Function: external_set_elink_cb + * + * Purpose: Verify functionality of H5P_set/get_elink_cb + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * Jan. 5, 2009 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +typedef struct { + const char *parent_file; + const char *target_file; + hid_t fapl; +} set_elink_cb_t; + +/* Callback function */ +static herr_t +external_set_elink_cb_cb(const char *parent_file, const char *parent_group, + const char *target_file, const char *target_obj, unsigned *flags, + hid_t fapl, void *_op_data) +{ + set_elink_cb_t *op_data = (set_elink_cb_t *)_op_data; + hid_t driver; + const void *driver_info; + + /* Codes to cause an invalid condition (and verify that an error is issued */ + if (op_data->fapl == -1) return FAIL; + if (op_data->fapl == -2) { + *flags = H5F_ACC_DEFAULT; + return 0; + } /* end if */ + + /* Verify file and object names are correct */ + if (HDstrcmp(parent_file, op_data->parent_file)) return FAIL; + if (HDstrcmp(parent_group, "/group1")) return FAIL; + if (HDstrcmp(target_file, op_data->target_file)) return FAIL; + if (HDstrcmp(target_obj, "/")) return FAIL; + + /* Set flags to be read-write */ + *flags = (*flags & ~H5F_ACC_RDONLY) | H5F_ACC_RDWR; + + /* Copy driver info from op_data->fapl to fapl */ + driver = H5Pget_driver(op_data->fapl); + driver_info = H5Pget_driver_info(op_data->fapl); + if (H5Pset_driver(fapl, driver, driver_info) < 0) return FAIL; + + return 0; +} + +/* Main test function */ +static int +external_set_elink_cb(hid_t fapl, hbool_t new_format) +{ + hid_t file1, file2, group, gapl, fam_fapl, ret_fapl; + set_elink_cb_t op_data, + *op_data_p; + H5L_elink_traverse_t cb; + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE]; + unsigned flags; + + if(new_format) + TESTING("H5Pset/get_elink_cb() (w/new group format)") + else + TESTING("H5Pset/get_elink_cb()") + + /* Create family fapl */ + if ((fam_fapl = H5Pcopy(fapl)) < 0) TEST_ERROR + if (H5Pset_fapl_family(fam_fapl, (hsize_t) 100, fapl) < 0) TEST_ERROR + + /* Create parent and target files, group, and external link */ + h5_fixname(FILENAME[40], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[41], fam_fapl, filename2, sizeof filename2); + if ((file1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + if ((file2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fam_fapl)) < 0) TEST_ERROR + if ((group = H5Gcreate2(file1, "group1",H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if (H5Lcreate_external(filename2, "/", group, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close files and group */ + if (H5Fclose(file1) < 0) TEST_ERROR + if (H5Fclose(file2) < 0) TEST_ERROR + if (H5Gclose(group) < 0) TEST_ERROR + + /* Build user data for callback */ + op_data.parent_file = filename1; + op_data.target_file = filename2; + op_data.fapl = fam_fapl; + + /* Create new gapl, and set elink callback */ + if ((gapl = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR + if (H5Pset_elink_cb(gapl, external_set_elink_cb_cb, &op_data) < 0) TEST_ERROR + + /* Verify "get" routine functionality */ + if (H5Pget_elink_cb(gapl, &cb, (void **) &op_data_p) < 0) TEST_ERROR + if (cb != external_set_elink_cb_cb) TEST_ERROR + if (op_data_p != &op_data) TEST_ERROR + + /* Open file1 with read only access */ + if ((file1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Create a group through the external link using gapl */ + if ((group = H5Gcreate2(file1, "/group1/ext_link/group2", H5P_DEFAULT, H5P_DEFAULT, gapl)) < 0) TEST_ERROR + + /* Verify that the correct parameters have been set on file2 (somewhat + * redundant as the library would be unable to create the group otherwise) + */ + if ((file2 = H5Iget_file_id(group)) < 0) TEST_ERROR + if (H5Fget_intent(file2, &flags) < 0) TEST_ERROR + if (!(flags & H5F_ACC_RDWR)) TEST_ERROR + if ((ret_fapl = H5Fget_access_plist(file2)) < 0) TEST_ERROR + if (H5FD_FAMILY != H5Pget_driver(ret_fapl)) TEST_ERROR + + if (H5Gclose(group) < 0) TEST_ERROR + if (H5Fclose(file2) < 0) TEST_ERROR + if (H5Pclose(ret_fapl) < 0) TEST_ERROR + if (H5Pclose(fam_fapl) < 0) TEST_ERROR + + /* Modify the user data structure to cause the callback to fail next time */ + op_data.fapl = -1; + + /* Attempt to reopen group2 (should fail) */ + H5E_BEGIN_TRY { + group = H5Gopen2(file1, "/group1/ext_link/group2", gapl); + } H5E_END_TRY; + if (group != FAIL) TEST_ERROR + + /* Modify the user data structure to cause the callback to return invalid flags */ + op_data.fapl = -2; + + /* Attempt to reopen group2 (should fail) */ + H5E_BEGIN_TRY { + group = H5Gopen2(file1, "/group1/ext_link/group2", gapl); + } H5E_END_TRY; + if (group != FAIL) TEST_ERROR + + /* Close */ + if (H5Fclose(file1) < 0) TEST_ERROR + if (H5Pclose(gapl) < 0) TEST_ERROR + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose(group); + H5Fclose(file1); + H5Fclose(file2); + H5Pclose(gapl); + H5Pclose(ret_fapl); + H5Pclose(fam_fapl); + } H5E_END_TRY; + return -1; +} /* end external_set_elink_cb() */ + + #ifdef H5_HAVE_WINDOW_PATH /*------------------------------------------------------------------------- @@ -12346,6 +12622,8 @@ main(void) nerrors += external_set_elink_fapl2(my_fapl, new_format) < 0 ? 1 : 0; #endif nerrors += external_set_elink_fapl3(new_format) < 0 ? 1 : 0; + nerrors += external_set_elink_acc_flags(my_fapl, new_format) < 0 ? 1 : 0; + nerrors += external_set_elink_cb(my_fapl, new_format) < 0 ? 1 : 0; #ifdef H5_HAVE_WINDOW_PATH nerrors += external_link_win1(my_fapl, new_format) < 0 ? 1 : 0; |