summaryrefslogtreecommitdiffstats
path: root/test/links.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/links.c')
-rw-r--r--test/links.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/test/links.c b/test/links.c
index 433e9f8..d807352 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
};
@@ -112,6 +116,8 @@ const char *FILENAME[] = {
#define LE_FILENAME "le_extlink1.h5"
#define BE_FILENAME "be_extlink1.h5"
+#define ELINK_CB_FAM_SIZE (hsize_t) 100
+
#define H5L_DIM1 100
#define H5L_DIM2 100
@@ -3947,6 +3953,284 @@ 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:
+ *
+ *-------------------------------------------------------------------------
+ */
+ /* User data structure for callback function */
+typedef struct {
+ const char *parent_file; /* Expected parent file name */
+ const char *target_file; /* Expected target file name */
+ hid_t base_fapl; /* Base fapl for family driver */
+ hsize_t fam_size; /* Size of family files */
+ int code; /* Code to control the actions taken by the callback */
+} 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;
+
+ /* 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;
+
+ /* Set family file driver on fapl */
+ if (H5Pset_fapl_family(fapl, op_data->fam_size, op_data->base_fapl) < 0) return FAIL;
+
+ /* Codes to cause an invalid condition (and verify that an error is issued */
+ if (op_data->code == 1)
+ return FAIL;
+ if (op_data->code == 2)
+ *flags = H5F_ACC_DEFAULT;
+
+ 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, base_driver;
+ 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()")
+
+ /* Build user data for callback */
+ op_data.parent_file = filename1;
+ op_data.target_file = filename2;
+ /* Core file driver has issues when used as the member file driver for a family file */
+ /* Family file driver cannot be used with family or multi drivers for member files */
+ /* Also disable parellel member drivers, because IS_H5FD_MPI whould report FALSE, causing problems */
+ base_driver = H5Pget_driver(fapl);
+ op_data.base_fapl = (base_driver == H5FD_FAMILY || base_driver == H5FD_MULTI
+ || base_driver == H5FD_MPIO || base_driver == H5FD_MPIPOSIX
+ || base_driver == H5FD_CORE) ? H5P_DEFAULT : fapl;
+ op_data.fam_size = ELINK_CB_FAM_SIZE;
+ op_data.code = 0;
+
+ /* Create family fapl */
+ if ((fam_fapl = H5Pcopy(fapl)) < 0) TEST_ERROR
+ if (H5Pset_fapl_family(fam_fapl, op_data.fam_size, op_data.base_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
+
+ /* 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.code = 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.code = 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 +12626,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;