summaryrefslogtreecommitdiffstats
path: root/test/links.c
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2009-01-08 18:16:31 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2009-01-08 18:16:31 (GMT)
commitd6da56adb76db4d8f4394e5d812697dd5b25909c (patch)
treeb4b91c7578bddde67d39f7ebb87d15ca0417a8f8 /test/links.c
parent634c7c5a93abb49a56336eec9e842a0bd694f828 (diff)
downloadhdf5-d6da56adb76db4d8f4394e5d812697dd5b25909c.zip
hdf5-d6da56adb76db4d8f4394e5d812697dd5b25909c.tar.gz
hdf5-d6da56adb76db4d8f4394e5d812697dd5b25909c.tar.bz2
[svn-r16281] 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, linew, smirom (h5committest)
Diffstat (limited to 'test/links.c')
-rw-r--r--test/links.c278
1 files changed, 278 insertions, 0 deletions
diff --git a/test/links.c b/test/links.c
index 433e9f8..cab5f6e 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
/*-------------------------------------------------------------------------
@@ -12342,6 +12618,8 @@ main(void)
nerrors += external_set_elink_fapl1(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += external_set_elink_fapl2(my_fapl, new_format) < 0 ? 1 : 0;
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;