Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test and document path handling of H5Lcreate_* API #3829

Merged
merged 5 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions src/H5Lpublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,13 @@ H5_DLL herr_t H5Lcopy(hid_t src_loc, const char *src_name, hid_t dst_loc, const
* location and name, respectively, of the new hard link.
*
* \p cur_name and \p dst_name are interpreted relative to \p cur_loc
* and \p dst_loc, respectively. If \p cur_loc and \p dst_loc are the
* same location, the HDF5 macro #H5L_SAME_LOC can be used for either
* parameter (but not both).
* and \p dst_loc, respectively. If a given name begins with \c /,
* then it will be interpreted as absolute path in the file.
* The names of the created links will be the last element of
* each provided path. Prior elements in each path are used to
* locate the parent groups of each new link. If \p cur_loc and
* \p dst_loc are the same location, the HDF5 macro
* #H5L_SAME_LOC can be used for either parameter (but not both).
*
* \p lcpl_id and \p lapl_id are the link creation and access property
* lists associated with the new link.
Expand Down Expand Up @@ -321,8 +325,10 @@ H5_DLL herr_t H5Lcreate_hard_async(hid_t cur_loc_id, const char *cur_name, hid_t
*
* \p link_loc_id and \p link_name specify the location and name,
* respectively, of the new soft link. \p link_name is interpreted
* relative to \p link_loc_id and must contain only the name of the soft
* link; \p link_name may not contain any additional path elements.
* as a path relative to \p link_loc_id, or an absolute path if it
* begins with \c /. The name of the created link will be the last
* element of the provided path. Prior elements in the path are
* used to locate the parent group of the new link.
*
* If \p link_loc_id is a group identifier, the object pointed to by
* \p link_name will be accessed as a member of that group. If
Expand Down Expand Up @@ -1190,7 +1196,11 @@ H5_DLL herr_t H5Lvisit_by_name2(hid_t loc_id, const char *group_name, H5_index_t
* named \p link_name at the location specified in \p link_loc_id with
* user-specified data \p udata.
*
* \p link_name is interpreted relative to \p link_loc_id.
* \p link_name is interpreted relative to \p link_loc_id. If
* \p link_name begins with \c /, then it will be interpreted as
* an absolute path in the file. The name of the created link
* will be the last element of the provided path. Prior elements
* in the path are used to locate the parent group of the new link.
*
* Valid values for the link class of the new link, \p link_type,
* include #H5L_TYPE_EXTERNAL and any user-defined link classes that
Expand Down Expand Up @@ -1307,7 +1317,10 @@ H5_DLL herr_t H5Lunpack_elink_val(const void *ext_linkval /*in*/, size_t link_si
*
* \p link_loc_id and \p link_name specify the location and name,
* respectively, of the new link. \p link_name is interpreted relative
* to \p link_loc_id.
* to \p link_loc_id. If \p link_name begins with \c /, then it is
* interpreted as an absolute path in the file. The name of the created
* link will be the last element of the provided path. Prior elements in
* the path are used to locate the parent group of the new link.
*
* \p lcpl_id is the link creation property list used in creating the
* new link.
Expand Down
250 changes: 250 additions & 0 deletions test/links.c
Original file line number Diff line number Diff line change
Expand Up @@ -22623,6 +22623,253 @@ timestamps(hid_t fapl)
return FAIL;
} /* end timestamps() */

/*-------------------------------------------------------------------------
* Function: link_path_handling
*
* Purpose: Create hard and soft links by relative and absolute paths
*
* Return: Success: 0
* Failure: -1
*-------------------------------------------------------------------------
*/
static int
link_path_handling(hid_t fapl, bool new_format)
{

hid_t file_id = (H5I_INVALID_HID);
hid_t grp1 = (H5I_INVALID_HID), grp2 = (H5I_INVALID_HID);
char filename[NAME_BUF_SIZE];

if (new_format)
TESTING("H5Lcreate path handling (w/new group format)");
else
TESTING("H5Lcreate path handling");

/* Create file */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));

if ((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
TEST_ERROR;

/* Create two groups */
if ((grp1 = H5Gcreate2(file_id, "grp1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;
if ((grp2 = H5Gcreate2(grp1, "grp2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;

/* Create hard link to grp1 that resides in grp2 by relative path */
if (H5Lcreate_hard(file_id, "grp1", grp1, "grp2/relative_hard_link", H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR;

if (H5Lexists(grp2, "relative_hard_link", H5P_DEFAULT) <= 0)
TEST_ERROR;

/* Create soft link to grp1 that resides in grp2 by relative path */
if (H5Lcreate_soft("/grp1", grp1, "grp2/relative_soft_link", H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR;

if (H5Lexists(grp2, "relative_soft_link", H5P_DEFAULT) <= 0)
TEST_ERROR;

/* Create hard link to grp1 that resides in grp2 by absolute path */
if (H5Lcreate_hard(file_id, "grp1", grp1, "/grp1/grp2/absolute_hard_link", H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR;

if (H5Lexists(grp2, "absolute_hard_link", H5P_DEFAULT) <= 0)
TEST_ERROR;

/* Create soft link to grp1 that resides in grp2 by absolute path */
if (H5Lcreate_soft("/grp1", grp1, "/grp1/grp2/absolute_soft_link", H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR;

if (H5Lexists(grp2, "absolute_soft_link", H5P_DEFAULT) <= 0)
TEST_ERROR;

/* Close groups and file */
if (H5Gclose(grp1) < 0)
TEST_ERROR;
if (H5Gclose(grp2) < 0)
TEST_ERROR;
if (H5Fclose(file_id) < 0)
TEST_ERROR;

PASSED();
return SUCCEED;

error:
H5E_BEGIN_TRY
{
H5Gclose(grp1);
H5Gclose(grp2);
H5Fclose(file_id);
}
H5E_END_TRY
return FAIL;
}

/*-------------------------------------------------------------------------
* Function: ext_link_path_handling
*
* Purpose: Create external links by relative and absolute paths
*
* Return: Success: 0
* Failure: -1
*-------------------------------------------------------------------------
*/
static int
ext_link_path_handling(hid_t fapl, bool new_format)
{

hid_t file_id = (H5I_INVALID_HID);
hid_t grp1 = (H5I_INVALID_HID), grp2 = (H5I_INVALID_HID);
char filename[NAME_BUF_SIZE];

if (new_format)
TESTING("H5Lcreate external link path handling (w/new group format)");
else
TESTING("H5Lcreate external link path handling");

/* Create file */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));

if ((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
TEST_ERROR;

/* Create two groups */
if ((grp1 = H5Gcreate2(file_id, "grp1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;
if ((grp2 = H5Gcreate2(grp1, "grp2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;

/* Create external link to nonexistent object by relative path */
if (H5Lcreate_external("nonexistent_file", "nonexistent_object", grp1, "grp2/relative_ext_link",
H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR;

if (H5Lexists(grp2, "relative_ext_link", H5P_DEFAULT) <= 0)
TEST_ERROR;

/* Create external link to nonexistent object by absolute path */
if (H5Lcreate_external("nonexistent_file", "nonexistent_object", grp1, "/grp1/grp2/relative_soft_link",
H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR;

if (H5Lexists(grp2, "relative_soft_link", H5P_DEFAULT) <= 0)
TEST_ERROR;

/* Close groups and file */
if (H5Gclose(grp1) < 0)
TEST_ERROR;
if (H5Gclose(grp2) < 0)
TEST_ERROR;
if (H5Fclose(file_id) < 0)
TEST_ERROR;

PASSED();
return SUCCEED;

error:
H5E_BEGIN_TRY
{
H5Gclose(grp1);
H5Gclose(grp2);
H5Fclose(file_id);
}
H5E_END_TRY
return FAIL;
}

/*-------------------------------------------------------------------------
* Function: ud_link_path_handling
*
* Purpose: Create user-defined links by relative and absolute paths
*
* Return: Success: 0
* Failure: -1
*-------------------------------------------------------------------------
*/
static int
ud_link_path_handling(hid_t fapl, bool new_format)
{

hid_t file_id = (H5I_INVALID_HID);
hid_t grp1 = (H5I_INVALID_HID), grp2 = (H5I_INVALID_HID);
char filename[NAME_BUF_SIZE];
H5L_info2_t li;

if (new_format)
TESTING("H5Lcreate ud link path handling (w/new group format)");
else
TESTING("H5Lcreate ud link path handling");

/* Create file */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));

if ((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
TEST_ERROR;

/* Create two groups */
if ((grp1 = H5Gcreate2(file_id, "grp1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;
if ((grp2 = H5Gcreate2(grp1, "grp2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
TEST_ERROR;

/* Check that UD hard links are not registered */
if (H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != false)
TEST_ERROR;

/* Register "user-defined hard links" with the library */
if (H5Lregister(UD_hard_class) < 0)
TEST_ERROR;

/* Check that UD hard links are registered */
if (H5Lis_registered((H5L_type_t)UD_HARD_TYPE) != true)
TEST_ERROR;

if (H5Lget_info2(file_id, "grp1", &li, H5P_DEFAULT) < 0)
TEST_ERROR;

/* Create user-defined (hard) link to grp1 by relative path */
if (H5Lcreate_ud(grp1, "grp2/relative_ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.token),
sizeof(li.u.token), H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR;

if (H5Lexists(grp2, "relative_ud_link", H5P_DEFAULT) <= 0)
TEST_ERROR;

/* Create user-defined (hard) link to grp1 by absolute path */
if (H5Lcreate_ud(grp1, "/grp1/grp2/absolute_ud_link", (H5L_type_t)UD_HARD_TYPE, &(li.u.token),
sizeof(li.u.token), H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR;

if (H5Lexists(grp2, "absolute_ud_link", H5P_DEFAULT) <= 0)
TEST_ERROR;

/* Close groups and file */
if (H5Gclose(grp1) < 0)
TEST_ERROR;
if (H5Gclose(grp2) < 0)
TEST_ERROR;
if (H5Fclose(file_id) < 0)
TEST_ERROR;
if (H5Lunregister((H5L_type_t)UD_HARD_TYPE) < 0)
TEST_ERROR;

PASSED();
return SUCCEED;

error:
H5E_BEGIN_TRY
{
H5Gclose(grp1);
H5Gclose(grp2);
H5Fclose(file_id);
H5Lunregister((H5L_type_t)UD_HARD_TYPE);
}
H5E_END_TRY
return FAIL;
}

/*-------------------------------------------------------------------------
* Function: main
*
Expand Down Expand Up @@ -22697,6 +22944,7 @@ main(void)
nerrors += ck_new_links(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += long_links(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += toomany(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += link_path_handling(my_fapl, new_format) < 0 ? 1 : 0;

/* Test new H5L link creation routine */
nerrors += test_lcpl(my_fapl, new_format);
Expand Down Expand Up @@ -22804,6 +23052,7 @@ main(void)
nerrors += external_open_twice(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += external_link_with_committed_datatype(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += external_link_public_macros(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += ext_link_path_handling(my_fapl, new_format) < 0 ? 1 : 0;
} /* with/without external file cache */
}

Expand All @@ -22826,6 +23075,7 @@ main(void)
nerrors += ud_callbacks_deprec(my_fapl, new_format) < 0 ? 1 : 0;
#endif /* H5_NO_DEPRECATED_SYMBOLS */
nerrors += ud_link_errors(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += ud_link_path_handling(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += lapl_udata(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += lapl_nlinks(my_fapl, new_format) < 0 ? 1 : 0;
#ifndef H5_NO_DEPRECATED_SYMBOLS
Expand Down