diff options
Diffstat (limited to 'test/API/H5_api_object_test.c')
-rw-r--r-- | test/API/H5_api_object_test.c | 7172 |
1 files changed, 7172 insertions, 0 deletions
diff --git a/test/API/H5_api_object_test.c b/test/API/H5_api_object_test.c new file mode 100644 index 0000000..e054356 --- /dev/null +++ b/test/API/H5_api_object_test.c @@ -0,0 +1,7172 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "H5_api_object_test.h" + +static int test_open_object(void); +static int test_open_object_invalid_params(void); +static int test_object_exists(void); +static int test_object_exists_invalid_params(void); +static int test_get_object_info(void); +static int test_get_object_info_invalid_params(void); +static int test_link_object(void); +static int test_link_object_invalid_params(void); +static int test_incr_decr_object_refcount(void); +static int test_incr_decr_object_refcount_invalid_params(void); +static int test_object_copy_basic(void); +static int test_object_copy_already_existing(void); +static int test_object_copy_shallow_group_copy(void); +static int test_object_copy_no_attributes(void); +static int test_object_copy_by_soft_link(void); +static int test_object_copy_group_with_soft_links(void); +static int test_object_copy_between_files(void); +static int test_object_copy_invalid_params(void); +static int test_object_comments(void); +static int test_object_comments_invalid_params(void); +static int test_object_visit(void); +static int test_object_visit_soft_link(void); +static int test_object_visit_invalid_params(void); +static int test_close_object(void); +static int test_close_object_invalid_params(void); +static int test_close_invalid_objects(void); +static int test_flush_object(void); +static int test_flush_object_invalid_params(void); +static int test_refresh_object(void); +static int test_refresh_object_invalid_params(void); + +static herr_t object_copy_attribute_iter_callback(hid_t location_id, const char *attr_name, + const H5A_info_t *ainfo, void *op_data); +static herr_t object_copy_soft_link_non_expand_callback(hid_t group, const char *name, + const H5L_info2_t *info, void *op_data); +static herr_t object_copy_soft_link_expand_callback(hid_t group, const char *name, const H5L_info2_t *info, + void *op_data); +static herr_t object_visit_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, + void *op_data); +static herr_t object_visit_dset_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, + void *op_data); +static herr_t object_visit_dtype_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, + void *op_data); +static herr_t object_visit_soft_link_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, + void *op_data); +static herr_t object_visit_noop_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, + void *op_data); + +/* + * The array of object tests to be performed. + */ +static int (*object_tests[])(void) = { + test_open_object, + test_open_object_invalid_params, + test_object_exists, + test_object_exists_invalid_params, + test_get_object_info, + test_get_object_info_invalid_params, + test_link_object, + test_link_object_invalid_params, + test_incr_decr_object_refcount, + test_incr_decr_object_refcount_invalid_params, + test_object_copy_basic, + test_object_copy_already_existing, + test_object_copy_shallow_group_copy, + test_object_copy_no_attributes, + test_object_copy_by_soft_link, + test_object_copy_group_with_soft_links, + test_object_copy_between_files, + test_object_copy_invalid_params, + test_object_comments, + test_object_comments_invalid_params, + test_object_visit, + test_object_visit_soft_link, + test_object_visit_invalid_params, + test_close_object, + test_close_object_invalid_params, + test_close_invalid_objects, + test_flush_object, + test_flush_object_invalid_params, + test_refresh_object, + test_refresh_object_invalid_params, +}; + +/* + * A test to check that various objects (group, dataset, datatype) + * can be opened by using H5Oopen, H5Oopen_by_idx and H5Oopen_by_addr. + * + * XXX: create separate objects for each test part. + * + * XXX: Add more open by idx tests + * + * XXX: test opening through dangling and resolving soft links. + */ +static int +test_open_object(void) +{ + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + hid_t type_id = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + + TESTING_MULTIPART("object opening"); + + TESTING_2("test setup"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, dataset, or stored datatype aren't " + "supported with this connector\n"); + return 0; + } + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_OPEN_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container sub-group '%s'\n", OBJECT_OPEN_TEST_GROUP_NAME); + goto error; + } + + if ((fspace_id = generate_random_dataspace(OBJECT_OPEN_TEST_SPACE_RANK, NULL, NULL, FALSE)) < 0) + TEST_ERROR; + + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Oopen_group) + { + TESTING_2("H5Oopen on a group"); + + if ((group_id2 = H5Gcreate2(group_id, OBJECT_OPEN_TEST_GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_OPEN_TEST_GRP_NAME); + PART_ERROR(H5Oopen_group); + } + + H5E_BEGIN_TRY + { + H5Gclose(group_id2); + } + H5E_END_TRY; + + if ((group_id2 = H5Oopen(group_id, OBJECT_OPEN_TEST_GRP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open group '%s' with H5Oopen\n", OBJECT_OPEN_TEST_GRP_NAME); + PART_ERROR(H5Oopen_group); + } + + if (H5Iget_type(group_id2) != H5I_GROUP) { + H5_FAILED(); + HDprintf(" ID is not a group\n"); + PART_ERROR(H5Oopen_group); + } + + if (H5Gclose(group_id2) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group opened with H5Oopen\n"); + PART_ERROR(H5Oopen_group); + } + + PASSED(); + } + PART_END(H5Oopen_group); + + PART_BEGIN(H5Oopen_dset) + { + TESTING_2("H5Oopen on a dataset"); + + if ((dset_id = H5Dcreate2(group_id, OBJECT_OPEN_TEST_DSET_NAME, dset_dtype, fspace_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset '%s'\n", OBJECT_OPEN_TEST_DSET_NAME); + PART_ERROR(H5Oopen_dset); + } + + H5E_BEGIN_TRY + { + H5Dclose(dset_id); + } + H5E_END_TRY; + + if ((dset_id = H5Oopen(group_id, OBJECT_OPEN_TEST_DSET_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open dataset '%s' with H5Oopen\n", OBJECT_OPEN_TEST_DSET_NAME); + PART_ERROR(H5Oopen_dset); + } + + if (H5Iget_type(dset_id) != H5I_DATASET) { + H5_FAILED(); + HDprintf(" ID is not a dataset\n"); + PART_ERROR(H5Oopen_dset); + } + + if (H5Dclose(dset_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close dataset opened with H5Oopen\n"); + PART_ERROR(H5Oopen_dset); + } + + PASSED(); + } + PART_END(H5Oopen_dset); + + PART_BEGIN(H5Oopen_dtype) + { + TESTING_2("H5Oopen on a committed datatype"); + + if ((type_id = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create datatype '%s'\n", OBJECT_OPEN_TEST_TYPE_NAME); + PART_ERROR(H5Oopen_dtype); + } + + if (H5Tcommit2(group_id, OBJECT_OPEN_TEST_TYPE_NAME, type_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't commit datatype '%s'\n", OBJECT_OPEN_TEST_TYPE_NAME); + PART_ERROR(H5Oopen_dtype); + } + + H5E_BEGIN_TRY + { + H5Tclose(type_id); + } + H5E_END_TRY; + + if ((type_id = H5Oopen(group_id, OBJECT_OPEN_TEST_TYPE_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open datatype '%s' with H5Oopen\n", OBJECT_OPEN_TEST_TYPE_NAME); + PART_ERROR(H5Oopen_dtype); + } + + if (H5Iget_type(type_id) != H5I_DATATYPE) { + H5_FAILED(); + HDprintf(" ID is not a dataset\n"); + PART_ERROR(H5Oopen_dtype); + } + + if (H5Tclose(type_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close committed datatype opened with H5Oopen\n"); + PART_ERROR(H5Oopen_dtype); + } + + PASSED(); + } + PART_END(H5Oopen_dtype); + + if (group_id2 >= 0) { + H5E_BEGIN_TRY + { + H5Gclose(group_id2); + } + H5E_END_TRY; + group_id2 = H5I_INVALID_HID; + } + if (dset_id >= 0) { + H5E_BEGIN_TRY + { + H5Dclose(dset_id); + } + H5E_END_TRY; + dset_id = H5I_INVALID_HID; + } + if (type_id >= 0) { + H5E_BEGIN_TRY + { + H5Tclose(type_id); + } + H5E_END_TRY; + type_id = H5I_INVALID_HID; + } + + PART_BEGIN(H5Oopen_by_idx_group) + { + TESTING_2("H5Oopen_by_idx on a group"); + + if ((group_id2 = H5Oopen_by_idx(container_group, OBJECT_OPEN_TEST_GROUP_NAME, H5_INDEX_NAME, + H5_ITER_INC, 1, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open group '%s' with H5Oopen_by_idx\n", OBJECT_OPEN_TEST_GRP_NAME); + PART_ERROR(H5Oopen_by_idx_group); + } + + PASSED(); + } + PART_END(H5Oopen_by_idx_group); + + PART_BEGIN(H5Oopen_by_idx_dset) + { + TESTING_2("H5Oopen_by_idx on a dataset"); + + if ((dset_id = H5Oopen_by_idx(container_group, OBJECT_OPEN_TEST_GROUP_NAME, H5_INDEX_NAME, + H5_ITER_INC, 0, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open dataset '%s' with H5Oopen_by_idx\n", OBJECT_OPEN_TEST_DSET_NAME); + PART_ERROR(H5Oopen_by_idx_dset); + } + + PASSED(); + } + PART_END(H5Oopen_by_idx_dset); + + PART_BEGIN(H5Oopen_by_idx_dtype) + { + TESTING_2("H5Oopen_by_idx on a committed datatype"); + + if ((type_id = H5Oopen_by_idx(container_group, OBJECT_OPEN_TEST_GROUP_NAME, H5_INDEX_NAME, + H5_ITER_INC, 2, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open committed datatype '%s' with H5Oopen_by_idx\n", + OBJECT_OPEN_TEST_TYPE_NAME); + PART_ERROR(H5Oopen_by_idx_dtype); + } + + PASSED(); + } + PART_END(H5Oopen_by_idx_dtype); + + if (group_id2 >= 0) { + H5E_BEGIN_TRY + { + H5Gclose(group_id2); + } + H5E_END_TRY; + group_id2 = H5I_INVALID_HID; + } + if (dset_id >= 0) { + H5E_BEGIN_TRY + { + H5Dclose(dset_id); + } + H5E_END_TRY; + dset_id = H5I_INVALID_HID; + } + if (type_id >= 0) { + H5E_BEGIN_TRY + { + H5Tclose(type_id); + } + H5E_END_TRY; + type_id = H5I_INVALID_HID; + } + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(fspace_id) < 0) + TEST_ERROR; + if (H5Tclose(dset_dtype) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(fspace_id); + H5Tclose(dset_dtype); + H5Tclose(type_id); + H5Dclose(dset_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test to check that various objects (group, dataset, datatype) + * can't be opened when H5Oopen, H5Oopen_by_idx and H5Oopen_by_addr + * are passed invalid parameters. + */ +static int +test_open_object_invalid_params(void) +{ + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t gcpl_id = H5I_INVALID_HID; + + TESTING_MULTIPART("object opening with invalid parameters"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, or creation order aren't supported with " + "this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create a GCPL\n"); + goto error; + } + + if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) { + H5_FAILED(); + HDprintf(" couldn't enable link creation order tracking and indexing on GCPL\n"); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_OPEN_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT, + gcpl_id, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container sub-group '%s'\n", + OBJECT_OPEN_INVALID_PARAMS_TEST_GROUP_NAME); + goto error; + } + + if ((group_id2 = H5Gcreate2(group_id, OBJECT_OPEN_INVALID_PARAMS_TEST_GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_OPEN_INVALID_PARAMS_TEST_GRP_NAME); + goto error; + } + + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Oopen_invalid_loc_id) + { + TESTING_2("H5Oopen with an invalid location ID"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen(H5I_INVALID_HID, OBJECT_OPEN_INVALID_PARAMS_TEST_GRP_NAME, H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen succeeded with an invalid location ID!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_invalid_loc_id); + } + + PASSED(); + } + PART_END(H5Oopen_invalid_loc_id); + + PART_BEGIN(H5Oopen_invalid_obj_name) + { + TESTING_2("H5Oopen with an invalid object name"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen(group_id, NULL, H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen succeeded with a NULL object name!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_invalid_obj_name); + } + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen(group_id, "", H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen succeeded with an invalid object name of ''!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_invalid_obj_name); + } + + PASSED(); + } + PART_END(H5Oopen_invalid_obj_name); + + PART_BEGIN(H5Oopen_invalid_lapl) + { + TESTING_2("H5Oopen with an invalid LAPL"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen(group_id, OBJECT_OPEN_INVALID_PARAMS_TEST_GRP_NAME, H5I_INVALID_HID); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen succeeded with an invalid LAPL!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_invalid_lapl); + } + + PASSED(); + } + PART_END(H5Oopen_invalid_lapl); + + PART_BEGIN(H5Oopen_by_idx_invalid_loc_id) + { + TESTING_2("H5Oopen_by_idx with an invalid location ID"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_idx(H5I_INVALID_HID, OBJECT_OPEN_INVALID_PARAMS_TEST_GROUP_NAME, + H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen_by_idx succeeded with an invalid location ID!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_idx_invalid_loc_id); + } + + PASSED(); + } + PART_END(H5Oopen_by_idx_invalid_loc_id); + + PART_BEGIN(H5Oopen_by_idx_invalid_grp_name) + { + TESTING_2("H5Oopen_by_idx with an invalid group name"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_idx(container_group, NULL, H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen_by_idx succeeded with a NULL group name!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_idx_invalid_grp_name); + } + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_idx(container_group, "", H5_INDEX_NAME, H5_ITER_INC, 0, H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen_by_idx succeeded with an invalid group name of ''!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_idx_invalid_grp_name); + } + + PASSED(); + } + PART_END(H5Oopen_by_idx_invalid_grp_name); + + PART_BEGIN(H5Oopen_by_idx_invalid_index_type) + { + TESTING_2("H5Oopen_by_idx with an invalid index type"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_idx(container_group, OBJECT_OPEN_INVALID_PARAMS_TEST_GROUP_NAME, + H5_INDEX_UNKNOWN, H5_ITER_INC, 0, H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen_by_idx succeeded with invalid index type H5_INDEX_UNKNOWN!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_idx_invalid_index_type); + } + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_idx(container_group, OBJECT_OPEN_INVALID_PARAMS_TEST_GROUP_NAME, + H5_INDEX_N, H5_ITER_INC, 0, H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen_by_idx succeeded with invalid index type H5_INDEX_N!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_idx_invalid_index_type); + } + + PASSED(); + } + PART_END(H5Oopen_by_idx_invalid_index_type); + + PART_BEGIN(H5Oopen_by_idx_invalid_iter_order) + { + TESTING_2("H5Oopen_by_idx with an invalid iteration order"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_idx(container_group, OBJECT_OPEN_INVALID_PARAMS_TEST_GROUP_NAME, + H5_INDEX_NAME, H5_ITER_UNKNOWN, 0, H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf( + " H5Oopen_by_idx succeeded with an invalid iteration ordering H5_ITER_UNKNOWN!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_idx_invalid_iter_order); + } + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_idx(container_group, OBJECT_OPEN_INVALID_PARAMS_TEST_GROUP_NAME, + H5_INDEX_NAME, H5_ITER_N, 0, H5P_DEFAULT); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen_by_idx succeeded with an invalid iteration ordering H5_ITER_N!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_idx_invalid_iter_order); + } + + PASSED(); + } + PART_END(H5Oopen_by_idx_invalid_iter_order); + + PART_BEGIN(H5Oopen_by_idx_invalid_lapl) + { + TESTING_2("H5Oopen_by_idx with an invalid LAPL"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_idx(container_group, OBJECT_OPEN_INVALID_PARAMS_TEST_GROUP_NAME, + H5_INDEX_NAME, H5_ITER_INC, 0, H5I_INVALID_HID); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen_by_idx succeeded with an invalid LAPL!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_idx_invalid_lapl); + } + + PASSED(); + } + PART_END(H5Oopen_by_idx_invalid_lapl); + + PART_BEGIN(H5Oopen_by_token_invalid_loc_id) + { + TESTING_2("H5Oopen_by_token with an invalid location ID"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_token(H5I_INVALID_HID, H5O_TOKEN_UNDEF); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen_by_token succeeded with an invalid location ID!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_token_invalid_loc_id); + } + + PASSED(); + } + PART_END(H5Oopen_by_token_invalid_loc_id); + + PART_BEGIN(H5Oopen_by_token_invalid_token) + { + TESTING_2("H5Oopen_by_token with an invalid token"); + + H5E_BEGIN_TRY + { + group_id2 = H5Oopen_by_token(file_id, H5O_TOKEN_UNDEF); + } + H5E_END_TRY; + + if (group_id2 >= 0) { + H5_FAILED(); + HDprintf(" H5Oopen_by_token succeeded with an invalid token!\n"); + H5Gclose(group_id2); + PART_ERROR(H5Oopen_by_token_invalid_token); + } + + PASSED(); + } + PART_END(H5Oopen_by_token_invalid_token); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Pclose(gcpl_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(gcpl_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test for H5Oexists_by_name. + */ +static int +test_object_exists(void) +{ + htri_t object_exists; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t dtype_id = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + + TESTING_MULTIPART("object existence"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, dataset, stored datatype or soft link " + "aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_EXISTS_TEST_SUBGROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", OBJECT_EXISTS_TEST_SUBGROUP_NAME); + goto error; + } + + if ((fspace_id = generate_random_dataspace(OBJECT_EXISTS_TEST_DSET_SPACE_RANK, NULL, NULL, FALSE)) < 0) + TEST_ERROR; + + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + PASSED(); + + /* + * NOTE: H5Oexists_by_name for hard links should always succeed. + * H5Oexists_by_name for a soft link may fail if the link doesn't resolve. + */ + BEGIN_MULTIPART + { + PART_BEGIN(H5Oexists_by_name_group) + { + TESTING_2("H5Oexists_by_name on a group"); + + if ((group_id2 = H5Gcreate2(group_id, OBJECT_EXISTS_TEST_GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_EXISTS_TEST_GRP_NAME); + PART_ERROR(H5Oexists_by_name_group); + } + + if ((object_exists = H5Oexists_by_name(group_id, OBJECT_EXISTS_TEST_GRP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if object '%s' exists\n", OBJECT_EXISTS_TEST_GRP_NAME); + PART_ERROR(H5Oexists_by_name_group); + } + + if (!object_exists) { + H5_FAILED(); + HDprintf(" object '%s' didn't exist!\n", OBJECT_EXISTS_TEST_GRP_NAME); + PART_ERROR(H5Oexists_by_name_group); + } + + if (H5Gclose(group_id2) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group\n"); + PART_ERROR(H5Oexists_by_name_group); + } + + PASSED(); + } + PART_END(H5Oexists_by_name_group); + + PART_BEGIN(H5Oexists_by_name_dset) + { + TESTING_2("H5Oexists_by_name on a dataset"); + + if ((dset_id = H5Dcreate2(group_id, OBJECT_EXISTS_TEST_DSET_NAME, dset_dtype, fspace_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset '%s'\n", OBJECT_EXISTS_TEST_DSET_NAME); + PART_ERROR(H5Oexists_by_name_dset); + } + + if ((object_exists = H5Oexists_by_name(group_id, OBJECT_EXISTS_TEST_DSET_NAME, H5P_DEFAULT)) < + 0) { + H5_FAILED(); + HDprintf(" couldn't determine if object '%s' exists\n", OBJECT_EXISTS_TEST_DSET_NAME); + PART_ERROR(H5Oexists_by_name_dset); + } + + if (!object_exists) { + H5_FAILED(); + HDprintf(" object '%s' didn't exist!\n", OBJECT_EXISTS_TEST_DSET_NAME); + PART_ERROR(H5Oexists_by_name_dset); + } + + if (H5Dclose(dset_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close dataset\n"); + PART_ERROR(H5Oexists_by_name_dset); + } + + PASSED(); + } + PART_END(H5Oexists_by_name_dset); + + PART_BEGIN(H5Oexists_by_name_dtype) + { + TESTING_2("H5Oexists_by_name on a committed datatype"); + + if ((dtype_id = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create datatype '%s'\n", OBJECT_EXISTS_TEST_TYPE_NAME); + PART_ERROR(H5Oexists_by_name_dtype); + } + + if (H5Tcommit2(group_id, OBJECT_EXISTS_TEST_TYPE_NAME, dtype_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't commit datatype '%s'\n", OBJECT_EXISTS_TEST_TYPE_NAME); + PART_ERROR(H5Oexists_by_name_dtype); + } + + if ((object_exists = H5Oexists_by_name(group_id, OBJECT_EXISTS_TEST_TYPE_NAME, H5P_DEFAULT)) < + 0) { + H5_FAILED(); + HDprintf(" couldn't determine if object '%s' exists\n", OBJECT_EXISTS_TEST_TYPE_NAME); + PART_ERROR(H5Oexists_by_name_dtype); + } + + if (!object_exists) { + H5_FAILED(); + HDprintf(" object '%s' didn't exist!\n", OBJECT_EXISTS_TEST_TYPE_NAME); + PART_ERROR(H5Oexists_by_name_dtype); + } + + if (H5Tclose(dtype_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close datatype\n"); + PART_ERROR(H5Oexists_by_name_dtype); + } + + PASSED(); + } + PART_END(H5Oexists_by_name_dtype); + + PART_BEGIN(H5Oexists_by_name_soft_link) + { + TESTING_2("H5Oexists_by_name for a soft link"); + + if (H5Lcreate_soft("/" OBJECT_TEST_GROUP_NAME "/" OBJECT_EXISTS_TEST_SUBGROUP_NAME, group_id, + OBJECT_EXISTS_TEST_SOFT_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't create soft link '%s'\n", OBJECT_EXISTS_TEST_SOFT_LINK_NAME); + PART_ERROR(H5Oexists_by_name_soft_link); + } + + if ((object_exists = + H5Oexists_by_name(group_id, OBJECT_EXISTS_TEST_SOFT_LINK_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if object '%s' exists\n", OBJECT_EXISTS_TEST_SOFT_LINK_NAME); + PART_ERROR(H5Oexists_by_name_soft_link); + } + + if (!object_exists) { + H5_FAILED(); + HDprintf(" object '%s' didn't exist!\n", OBJECT_EXISTS_TEST_SOFT_LINK_NAME); + PART_ERROR(H5Oexists_by_name_soft_link); + } + + PASSED(); + } + PART_END(H5Oexists_by_name_soft_link); + + PART_BEGIN(H5Oexists_by_name_dangling_soft_link) + { + TESTING_2("H5Oexists_by_name for a dangling soft link"); + + if (H5Lcreate_soft( + "/" OBJECT_TEST_GROUP_NAME "/" OBJECT_EXISTS_TEST_SUBGROUP_NAME "/non_existent_object", + group_id, OBJECT_EXISTS_TEST_DANGLING_LINK_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't create soft link '%s'\n", OBJECT_EXISTS_TEST_DANGLING_LINK_NAME); + PART_ERROR(H5Oexists_by_name_dangling_soft_link); + } + + if ((object_exists = + H5Oexists_by_name(group_id, OBJECT_EXISTS_TEST_DANGLING_LINK_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if object '%s' exists\n", + "/" OBJECT_TEST_GROUP_NAME "/" OBJECT_EXISTS_TEST_SUBGROUP_NAME + "/non_existent_object"); + PART_ERROR(H5Oexists_by_name_dangling_soft_link); + } + + if (object_exists) { + H5_FAILED(); + HDprintf(" object pointed to by dangling soft link should not have existed!\n"); + PART_ERROR(H5Oexists_by_name_dangling_soft_link); + } + + PASSED(); + } + PART_END(H5Oexists_by_name_dangling_soft_link); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(fspace_id) < 0) + TEST_ERROR; + if (H5Tclose(dset_dtype) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(fspace_id); + H5Tclose(dset_dtype); + H5Tclose(dtype_id); + H5Dclose(dset_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test to check that H5Oexists_by_name fails + * when it is passed invalid parameters. + */ +static int +test_object_exists_invalid_params(void) +{ + htri_t object_exists; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + + TESTING_MULTIPART("object existence with invalid parameters"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, or object aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_EXISTS_INVALID_PARAMS_TEST_SUBGROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", + OBJECT_EXISTS_INVALID_PARAMS_TEST_SUBGROUP_NAME); + goto error; + } + + if ((group_id2 = H5Gcreate2(group_id, OBJECT_EXISTS_INVALID_PARAMS_TEST_GRP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_EXISTS_INVALID_PARAMS_TEST_GRP_NAME); + goto error; + } + + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Oexists_by_name_invalid_loc_id) + { + TESTING_2("H5Oexists_by_name with an invalid location ID"); + + H5E_BEGIN_TRY + { + object_exists = H5Oexists_by_name(H5I_INVALID_HID, OBJECT_EXISTS_INVALID_PARAMS_TEST_GRP_NAME, + H5P_DEFAULT); + } + H5E_END_TRY; + + if (object_exists >= 0) { + H5_FAILED(); + HDprintf(" H5Oexists_by_name succeeded with an invalid location ID!\n"); + PART_ERROR(H5Oexists_by_name_invalid_loc_id); + } + + PASSED(); + } + PART_END(H5Oexists_by_name_invalid_loc_id); + + PART_BEGIN(H5Oexists_by_name_invalid_obj_name) + { + TESTING_2("H5Oexists_by_name with an invalid object name"); + + H5E_BEGIN_TRY + { + object_exists = H5Oexists_by_name(group_id, NULL, H5P_DEFAULT); + } + H5E_END_TRY; + + if (object_exists >= 0) { + H5_FAILED(); + HDprintf(" H5Oexists_by_name succeeded with a NULL object name!\n"); + PART_ERROR(H5Oexists_by_name_invalid_obj_name); + } + + H5E_BEGIN_TRY + { + object_exists = H5Oexists_by_name(group_id, "", H5P_DEFAULT); + } + H5E_END_TRY; + + if (object_exists >= 0) { + H5_FAILED(); + HDprintf(" H5Oexists_by_name succeeded with an invalid object name of ''!\n"); + PART_ERROR(H5Oexists_by_name_invalid_obj_name); + } + + PASSED(); + } + PART_END(H5Oexists_by_name_invalid_obj_name); + + PART_BEGIN(H5Oexists_by_name_invalid_lapl) + { + TESTING_2("H5Oexists_by_name with an invalid LAPL"); + + H5E_BEGIN_TRY + { + object_exists = + H5Oexists_by_name(group_id, OBJECT_EXISTS_INVALID_PARAMS_TEST_GRP_NAME, H5I_INVALID_HID); + } + H5E_END_TRY; + + if (object_exists >= 0) { + H5_FAILED(); + HDprintf(" H5Oexists_by_name succeeded with an invalid LAPL!\n"); + PART_ERROR(H5Oexists_by_name_invalid_lapl); + } + + PASSED(); + } + PART_END(H5Oexists_by_name_invalid_lapl); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test for H5Oget_info(_by_name/_by_idx). + */ +static int +test_get_object_info(void) +{ + TESTING("object info retrieval"); + + SKIPPED(); + + return 0; +} + +/* + * A test to check that an object's info can't be retrieved + * when H5Oget_info(_by_name/_by_idx) are passed invalid + * parameters. + */ +static int +test_get_object_info_invalid_params(void) +{ + TESTING("object info retrieval with invalid parameters"); + + SKIPPED(); + + return 0; +} + +/* + * A test for H5Olink. + */ +static int +test_link_object(void) +{ + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + hid_t type_id = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + + TESTING_MULTIPART("object linking"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, dataset, or stored datatype aren't " + "supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_LINK_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container sub-group '%s'\n", OBJECT_LINK_TEST_GROUP_NAME); + goto error; + } + + if ((fspace_id = generate_random_dataspace(OBJECT_LINK_TEST_SPACE_RANK, NULL, NULL, FALSE)) < 0) + TEST_ERROR; + + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Olink_group) + { + TESTING_2("H5Olink an anonymous group"); + + if ((group_id2 = H5Gcreate_anon(group_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create an anonymous group\n"); + PART_ERROR(H5Olink_group); + } + + if (H5Olink(group_id2, group_id, OBJECT_LINK_TEST_GROUP_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't link the anonymous group\n"); + PART_ERROR(H5Olink_group); + } + + PASSED(); + } + PART_END(H5Olink_group); + + PART_BEGIN(H5Olink_dataset) + { + TESTING_2("H5Olink an anonymous dataset"); + + if ((dset_id = H5Dcreate_anon(group_id, dset_dtype, fspace_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create an anonymous dataset\n"); + PART_ERROR(H5Olink_dataset); + } + + if (H5Olink(dset_id, group_id, OBJECT_LINK_TEST_DSET_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't link the anonymous dataset\n"); + PART_ERROR(H5Olink_dataset); + } + + PASSED(); + } + PART_END(H5Olink_dataset); + + PART_BEGIN(H5Olink_datatype) + { + TESTING_2("H5Olink an anonymous datatype"); + + if (H5Tcommit_anon(group_id, dset_dtype, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't create an anonymous datatype\n"); + PART_ERROR(H5Olink_datatype); + } + + if (H5Olink(dset_dtype, group_id, OBJECT_LINK_TEST_DTYPE_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't link the anonymous datatype\n"); + PART_ERROR(H5Olink_datatype); + } + + PASSED(); + } + PART_END(H5Olink_datatype); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(fspace_id) < 0) + TEST_ERROR; + if (H5Tclose(dset_dtype) < 0) + TEST_ERROR; + if (H5Dclose(dset_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(fspace_id); + H5Tclose(dset_dtype); + H5Tclose(type_id); + H5Dclose(dset_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test to check that an object can't be linked into + * the file structure when H5Olink is passed invalid + * parameters. + */ +static int +test_link_object_invalid_params(void) +{ + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + herr_t status; + + TESTING_MULTIPART("object linking with invalid parameters"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, or object aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_LINK_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container sub-group '%s'\n", OBJECT_LINK_TEST_GROUP_NAME); + goto error; + } + + if ((group_id2 = H5Gcreate_anon(group_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create an anonymous group\n"); + goto error; + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Olink_invalid_object_id) + { + TESTING_2("H5Olink with an invalid object ID"); + + H5E_BEGIN_TRY + { + status = H5Olink(H5I_INVALID_HID, group_id, OBJECT_LINK_TEST_GROUP_NAME2, H5P_DEFAULT, + H5P_DEFAULT); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Olink succeeded with an invalid object ID!\n"); + PART_ERROR(H5Olink_invalid_object_id); + } + + PASSED(); + } + PART_END(H5Olink_invalid_object_id); + + PART_BEGIN(H5Olink_invalid_location) + { + TESTING_2("H5Olink with an invalid location ID"); + + H5E_BEGIN_TRY + { + status = H5Olink(group_id2, H5I_INVALID_HID, OBJECT_LINK_TEST_GROUP_NAME2, H5P_DEFAULT, + H5P_DEFAULT); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Olink succeeded with an invalid location ID!\n"); + PART_ERROR(H5Olink_invalid_location); + } + + PASSED(); + } + PART_END(H5Olink_invalid_location); + + PART_BEGIN(H5Olink_invalid_name) + { + TESTING_2("H5Olink with an invalid name"); + + H5E_BEGIN_TRY + { + status = H5Olink(group_id2, group_id, NULL, H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Olink succeeded with NULL as the object name!\n"); + PART_ERROR(H5Olink_invalid_name); + } + + H5E_BEGIN_TRY + { + status = H5Olink(group_id2, group_id, "", H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Olink succeeded with an invalid object name of ''!\n"); + PART_ERROR(H5Olink_invalid_name); + } + + PASSED(); + } + PART_END(H5Olink_invalid_name); + + PART_BEGIN(H5Olink_invalid_lcpl) + { + TESTING_2("H5Olink with an invalid LCPL"); + + H5E_BEGIN_TRY + { + status = + H5Olink(group_id2, group_id, OBJECT_LINK_TEST_GROUP_NAME2, H5I_INVALID_HID, H5P_DEFAULT); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Olink succeeded with an invalid LCPL!\n"); + PART_ERROR(H5Olink_invalid_lcpl); + } + + PASSED(); + } + PART_END(H5Olink_invalid_lcpl); + + PART_BEGIN(H5Olink_invalid_lapl) + { + TESTING_2("H5Olink with an invalid LAPL"); +#ifndef NO_INVALID_PROPERTY_LIST_TESTS + H5E_BEGIN_TRY + { + status = + H5Olink(group_id2, group_id, OBJECT_LINK_TEST_GROUP_NAME2, H5P_DEFAULT, H5I_INVALID_HID); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Olink succeeded with an invalid LAPL!\n"); + PART_ERROR(H5Olink_invalid_lapl); + } + + PASSED(); +#else + SKIPPED(); + PART_EMPTY(H5Olink_invalid_lapl); +#endif + } + PART_END(H5Olink_invalid_lapl); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test for H5Oincr_refcount/H5Odecr_refcount. + */ +static int +test_incr_decr_object_refcount(void) +{ + H5O_info2_t oinfo; /* Object info struct */ + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + + TESTING_MULTIPART("increment/decrement the reference count of object"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, dataset, stored datatype, basic or more object " + "aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_REF_COUNT_TEST_SUBGROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", OBJECT_REF_COUNT_TEST_SUBGROUP_NAME); + goto error; + } + + if ((fspace_id = generate_random_dataspace(OBJECT_REF_COUNT_TEST_DSET_SPACE_RANK, NULL, NULL, FALSE)) < 0) + TEST_ERROR; + + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Oincr_decr_refcount_group) + { + TESTING_2("H5Oincr_refcount/H5Odecr_refcount on a group"); + + if ((group_id2 = H5Gcreate2(group_id, OBJECT_REF_COUNT_TEST_GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_REF_COUNT_TEST_GRP_NAME); + PART_ERROR(H5Oincr_decr_refcount_group); + } + + /* Increment the reference count */ + if (H5Oincr_refcount(group_id2) < 0) { + H5_FAILED(); + HDprintf(" couldn't increment reference count for the group '%s' \n", + OBJECT_REF_COUNT_TEST_GRP_NAME); + PART_ERROR(H5Oincr_decr_refcount_group); + } + + /* Verify that reference count is 2 now */ + if (H5Oget_info_by_name3(group_id, OBJECT_REF_COUNT_TEST_GRP_NAME, &oinfo, H5O_INFO_BASIC, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't get reference count for the group '%s' \n", + OBJECT_REF_COUNT_TEST_GRP_NAME); + PART_ERROR(H5Oincr_decr_refcount_group); + } + + if (oinfo.rc != 2) { + H5_FAILED(); + HDprintf(" the reference count for the group '%s' isn't 2: %d\n", + OBJECT_REF_COUNT_TEST_GRP_NAME, oinfo.rc); + PART_ERROR(H5Oincr_decr_refcount_group); + } + + /* Decrement the reference count */ + if (H5Odecr_refcount(group_id2) < 0) { + H5_FAILED(); + HDprintf(" couldn't decrement reference count for the group '%s' \n", + OBJECT_REF_COUNT_TEST_GRP_NAME); + PART_ERROR(H5Oincr_decr_refcount_group); + } + + /* Verify that reference count is 1 now */ + if (H5Oget_info_by_name3(group_id, OBJECT_REF_COUNT_TEST_GRP_NAME, &oinfo, H5O_INFO_BASIC, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't get reference count for the group '%s' \n", + OBJECT_REF_COUNT_TEST_GRP_NAME); + PART_ERROR(H5Oincr_decr_refcount_group); + } + + if (oinfo.rc != 1) { + H5_FAILED(); + HDprintf(" the reference count for the group '%s' isn't 1: %d\n", + OBJECT_REF_COUNT_TEST_GRP_NAME, oinfo.rc); + PART_ERROR(H5Oincr_decr_refcount_group); + } + + if (H5Gclose(group_id2) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group\n"); + PART_ERROR(H5Oincr_decr_refcount_group); + } + + PASSED(); + } + PART_END(H5Oincr_decr_refcount_group); + + PART_BEGIN(H5Oincr_decr_refcount_dset) + { + TESTING_2("H5Oincr_refcount/H5Odecr_refcount on a dataset"); + + if ((dset_id = H5Dcreate2(group_id, OBJECT_REF_COUNT_TEST_DSET_NAME, dset_dtype, fspace_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset '%s'\n", OBJECT_REF_COUNT_TEST_DSET_NAME); + PART_ERROR(H5Oincr_decr_refcount_dset); + } + + /* Increment the reference count */ + if (H5Oincr_refcount(dset_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't increment reference count for the dataset '%s' \n", + OBJECT_REF_COUNT_TEST_DSET_NAME); + PART_ERROR(H5Oincr_decr_refcount_dset); + } + + /* Verify that reference count is 2 now */ + if (H5Oget_info_by_name3(group_id, OBJECT_REF_COUNT_TEST_DSET_NAME, &oinfo, H5O_INFO_BASIC, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't get reference count for the dataset '%s' \n", + OBJECT_REF_COUNT_TEST_DSET_NAME); + PART_ERROR(H5Oincr_decr_refcount_dset); + } + + if (oinfo.rc != 2) { + H5_FAILED(); + HDprintf(" the reference count for the dataset '%s' isn't 2: %d\n", + OBJECT_REF_COUNT_TEST_DSET_NAME, oinfo.rc); + PART_ERROR(H5Oincr_decr_refcount_dset); + } + + /* Decrement the reference count */ + if (H5Odecr_refcount(dset_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't decrement reference count for the dataset '%s' \n", + OBJECT_REF_COUNT_TEST_DSET_NAME); + PART_ERROR(H5Oincr_decr_refcount_dset); + } + + /* Verify that reference count is 1 now */ + if (H5Oget_info_by_name3(group_id, OBJECT_REF_COUNT_TEST_DSET_NAME, &oinfo, H5O_INFO_BASIC, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't get reference count for the dataset '%s' \n", + OBJECT_REF_COUNT_TEST_DSET_NAME); + PART_ERROR(H5Oincr_decr_refcount_dset); + } + + if (oinfo.rc != 1) { + H5_FAILED(); + HDprintf(" the reference count for the dataset '%s' isn't 1: %d\n", + OBJECT_REF_COUNT_TEST_DSET_NAME, oinfo.rc); + PART_ERROR(H5Oincr_decr_refcount_dset); + } + + if (H5Dclose(dset_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close dataset\n"); + PART_ERROR(H5Oincr_decr_refcount_dset); + } + + PASSED(); + } + PART_END(H5Oincr_decr_refcount_dset); + + PART_BEGIN(H5Oincr / decr_refcount_dtype) + { + TESTING_2("H5Oincr_refcount/H5Odecr_refcount on a committed datatype"); + + if (H5Tcommit2(group_id, OBJECT_REF_COUNT_TEST_TYPE_NAME, dset_dtype, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't commit datatype '%s'\n", OBJECT_REF_COUNT_TEST_TYPE_NAME); + PART_ERROR(H5Oincr_decr_refcount_dtype); + } + + /* Increment the reference count */ + if (H5Oincr_refcount(dset_dtype) < 0) { + H5_FAILED(); + HDprintf(" couldn't increment reference count for the datatype '%s' \n", + OBJECT_REF_COUNT_TEST_TYPE_NAME); + PART_ERROR(H5Oincr_decr_refcount_dtype); + } + + /* Verify that reference count is 2 now */ + if (H5Oget_info_by_name3(group_id, OBJECT_REF_COUNT_TEST_TYPE_NAME, &oinfo, H5O_INFO_BASIC, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't get reference count for the datatype '%s' \n", + OBJECT_REF_COUNT_TEST_TYPE_NAME); + PART_ERROR(H5Oincr_decr_refcount_dtype); + } + + if (oinfo.rc != 2) { + H5_FAILED(); + HDprintf(" the reference count for the datatype '%s' isn't 2: %d\n", + OBJECT_REF_COUNT_TEST_TYPE_NAME, oinfo.rc); + PART_ERROR(H5Oincr_decr_refcount_dtype); + } + + /* Decrement the reference count */ + if (H5Odecr_refcount(dset_dtype) < 0) { + H5_FAILED(); + HDprintf(" couldn't decrement reference count for the datatype '%s' \n", + OBJECT_REF_COUNT_TEST_TYPE_NAME); + PART_ERROR(H5Oincr_decr_refcount_dtype); + } + + /* Verify that reference count is 1 now */ + if (H5Oget_info_by_name3(group_id, OBJECT_REF_COUNT_TEST_TYPE_NAME, &oinfo, H5O_INFO_BASIC, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't get reference count for the datatype '%s' \n", + OBJECT_REF_COUNT_TEST_TYPE_NAME); + PART_ERROR(H5Oincr_decr_refcount_dtype); + } + + if (oinfo.rc != 1) { + H5_FAILED(); + HDprintf(" the reference count for the datatype '%s' isn't 1: %d\n", + OBJECT_REF_COUNT_TEST_TYPE_NAME, oinfo.rc); + PART_ERROR(H5Oincr_decr_refcount_dtype); + } + + if (H5Tclose(dset_dtype) < 0) { + H5_FAILED(); + HDprintf(" couldn't close datatype\n"); + PART_ERROR(H5Oincr_decr_refcount_dtype); + } + + PASSED(); + } + PART_END(H5Oincr_decr_refcount_dtype); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(fspace_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(fspace_id); + H5Tclose(dset_dtype); + H5Dclose(dset_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} /* test_incr_decr_object_refcount */ + +/* + * A test to check that H5Oincr_refcount/H5Odecr_refcount + * fail when passed invalid parameters. + */ +static int +test_incr_decr_object_refcount_invalid_params(void) +{ + herr_t status; + + TESTING_MULTIPART("object reference count incr./decr. with an invalid parameter"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE)) { + SKIPPED(); + HDprintf(" API functions for more object aren't supported with this connector\n"); + return 0; + } + + BEGIN_MULTIPART + { + PART_BEGIN(H5Oincr_refcount_invalid_param) + { + TESTING_2("H5Oincr_refcount with invalid object ID"); + + H5E_BEGIN_TRY + { + status = H5Oincr_refcount(H5I_INVALID_HID); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" incremented the reference count for an invalid object ID\n"); + PART_ERROR(H5Oincr_refcount_invalid_param); + } + + PASSED(); + } + PART_END(H5Oincr_refcount_invalid_param); + + PART_BEGIN(H5Odecr_refcount_invalid_param) + { + TESTING_2("H5Odecr_refcount with invalid object ID"); + + H5E_BEGIN_TRY + { + status = H5Odecr_refcount(H5I_INVALID_HID); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" decremented the reference count for an invalid object ID\n"); + PART_ERROR(H5Odecr_refcount_invalid_param); + } + + PASSED(); + } + PART_END(H5Odecr_refcount_invalid_param); + } + END_MULTIPART; + + return 0; + +error: + return 1; +} + +/* + * Basic tests for H5Ocopy. + */ +static int +test_object_copy_basic(void) +{ + H5O_info2_t object_info; + H5G_info_t group_info; + htri_t object_link_exists; + size_t i; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID; + hid_t group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t tmp_group_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t tmp_dset_id = H5I_INVALID_HID; + hid_t dtype_id = H5I_INVALID_HID; + hid_t tmp_dtype_id = H5I_INVALID_HID; + hid_t tmp_attr_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + hid_t attr_space_id = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + + TESTING_MULTIPART("basic object copying"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, link, dataset, attribute, iterate, or " + "stored datatype aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_COPY_BASIC_TEST_SUBGROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", OBJECT_COPY_BASIC_TEST_SUBGROUP_NAME); + goto error; + } + + if ((space_id = generate_random_dataspace(OBJECT_COPY_BASIC_TEST_SPACE_RANK, NULL, NULL, FALSE)) < 0) + TEST_ERROR; + if ((attr_space_id = generate_random_dataspace(OBJECT_COPY_BASIC_TEST_SPACE_RANK, NULL, NULL, TRUE)) < 0) + TEST_ERROR; + + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + /* Create the test group object, along with its nested members and the attributes attached to it. */ + if ((group_id2 = H5Gcreate2(group_id, OBJECT_COPY_BASIC_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_COPY_BASIC_TEST_GROUP_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_BASIC_TEST_NUM_NESTED_OBJS; i++) { + char grp_name[OBJECT_COPY_BASIC_TEST_BUF_SIZE]; + + snprintf(grp_name, OBJECT_COPY_BASIC_TEST_BUF_SIZE, "grp%d", (int)i); + + if ((tmp_group_id = H5Gcreate2(group_id2, grp_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s' under group '%s'\n", grp_name, + OBJECT_COPY_BASIC_TEST_GROUP_NAME); + goto error; + } + + /* Create a further nested group under the last group added */ + if (i == (OBJECT_COPY_BASIC_TEST_NUM_NESTED_OBJS - 1)) { + if (H5Gclose(H5Gcreate2(tmp_group_id, OBJECT_COPY_BASIC_TEST_DEEP_NESTED_GROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create nested group '%s' under group '%s'\n", + OBJECT_COPY_BASIC_TEST_DEEP_NESTED_GROUP_NAME, grp_name); + goto error; + } + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s'\n", grp_name); + goto error; + } + } + + for (i = 0; i < (size_t)OBJECT_COPY_BASIC_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_BASIC_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_BASIC_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((tmp_attr_id = H5Acreate2(group_id2, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on group '%s'\n", attr_name, + OBJECT_COPY_BASIC_TEST_GROUP_NAME); + goto error; + } + + if (H5Aclose(tmp_attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + /* Create the test dataset object, along with the attributes attached to it. */ + if ((dset_id = H5Dcreate2(group_id, OBJECT_COPY_BASIC_TEST_DSET_NAME, dset_dtype, space_id, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset '%s'\n", OBJECT_COPY_BASIC_TEST_DSET_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_BASIC_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_BASIC_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_BASIC_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((tmp_attr_id = H5Acreate2(dset_id, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on dataset '%s'\n", attr_name, + OBJECT_COPY_BASIC_TEST_DSET_NAME); + goto error; + } + + if (H5Aclose(tmp_attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + /* Create the test committed datatype object, along with the attributes attached to it. */ + if ((dtype_id = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create datatype\n"); + goto error; + } + + if (H5Tcommit2(group_id, OBJECT_COPY_BASIC_TEST_DTYPE_NAME, dtype_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't commit datatype '%s'\n", OBJECT_COPY_BASIC_TEST_DTYPE_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_BASIC_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_BASIC_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_BASIC_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((tmp_attr_id = H5Acreate2(dtype_id, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on committed datatype '%s'\n", attr_name, + OBJECT_COPY_BASIC_TEST_DTYPE_NAME); + goto error; + } + + if (H5Aclose(tmp_attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Ocopy_group) + { + TESTING_2("H5Ocopy on a group (default copy options)"); + + if (H5Ocopy(group_id, OBJECT_COPY_BASIC_TEST_GROUP_NAME, group_id, + OBJECT_COPY_BASIC_TEST_NEW_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy group '%s' to '%s'\n", OBJECT_COPY_BASIC_TEST_GROUP_NAME, + OBJECT_COPY_BASIC_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group); + } + + if ((object_link_exists = + H5Lexists(group_id, OBJECT_COPY_BASIC_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied group exists\n", + OBJECT_COPY_BASIC_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied group didn't exist!\n", + OBJECT_COPY_BASIC_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group); + } + + /* Ensure that the new group has all the members of the copied group, and all its attributes */ + if ((tmp_group_id = H5Gopen2(group_id, OBJECT_COPY_BASIC_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open group copy '%s'\n", OBJECT_COPY_BASIC_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group); + } + + memset(&group_info, 0, sizeof(group_info)); + + /* + * Set link count to zero in case the connector doesn't support + * retrieval of group info. + */ + group_info.nlinks = 0; + + if (H5Gget_info(tmp_group_id, &group_info) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve group info\n"); + PART_ERROR(H5Ocopy_group); + } + + if (group_info.nlinks != OBJECT_COPY_BASIC_TEST_NUM_NESTED_OBJS) { + H5_FAILED(); + HDprintf(" copied group contained %d members instead of %d members after a deep copy!\n", + (int)group_info.nlinks, OBJECT_COPY_BASIC_TEST_NUM_NESTED_OBJS); + PART_ERROR(H5Ocopy_group); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 0; + + if (H5Oget_info3(tmp_group_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_group); + } + + if (object_info.num_attrs == 0) { + H5_FAILED(); + HDprintf(" copied group didn't contain any attributes after copy operation!\n"); + PART_ERROR(H5Ocopy_group); + } + + /* Check the attribute names, types, etc. */ + i = 0; + if (H5Aiterate2(tmp_group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, + object_copy_attribute_iter_callback, &i) < 0) { + H5_FAILED(); + HDprintf(" failed to iterate over copied group's attributes\n"); + PART_ERROR(H5Ocopy_group); + } + + if (i != OBJECT_COPY_BASIC_TEST_NUM_ATTRS) { + H5_FAILED(); + HDprintf( + " number of attributes on copied group (%llu) didn't match expected number (%llu)!\n", + (unsigned long long)i, (unsigned long long)OBJECT_COPY_BASIC_TEST_NUM_ATTRS); + PART_ERROR(H5Ocopy_group); + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close group copy\n"); + PART_ERROR(H5Ocopy_group); + } + + /* + * Ensure that the last immediate member of the copied group + * contains its single member after the deep copy. + */ + { + char grp_name[OBJECT_COPY_BASIC_TEST_BUF_SIZE]; + + snprintf(grp_name, OBJECT_COPY_BASIC_TEST_BUF_SIZE, + OBJECT_COPY_BASIC_TEST_NEW_GROUP_NAME "/grp%d", + OBJECT_COPY_BASIC_TEST_NUM_NESTED_OBJS - 1); + + if ((tmp_group_id = H5Gopen2(group_id, grp_name, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open group '%s'\n", + OBJECT_COPY_BASIC_TEST_DEEP_NESTED_GROUP_NAME); + PART_ERROR(H5Ocopy_group); + } + + memset(&group_info, 0, sizeof(group_info)); + + /* + * Set link count to zero in case the connector doesn't support + * retrieval of group info. + */ + group_info.nlinks = 0; + + if (H5Gget_info(tmp_group_id, &group_info) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve group info\n"); + PART_ERROR(H5Ocopy_group); + } + + if (group_info.nlinks != 1) { + H5_FAILED(); + HDprintf(" copied group's immediate members didn't contain nested members after a " + "deep copy!\n"); + PART_ERROR(H5Ocopy_group); + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close group '%s'\n", + OBJECT_COPY_BASIC_TEST_DEEP_NESTED_GROUP_NAME); + PART_ERROR(H5Ocopy_group); + } + } + + PASSED(); + } + PART_END(H5Ocopy_group); + + if (tmp_group_id >= 0) { + H5E_BEGIN_TRY + { + H5Gclose(tmp_group_id); + } + H5E_END_TRY; + tmp_group_id = H5I_INVALID_HID; + } + + PART_BEGIN(H5Ocopy_dset) + { + TESTING_2("H5Ocopy on a dataset (default copy options)"); + + if (H5Ocopy(group_id, OBJECT_COPY_BASIC_TEST_DSET_NAME, group_id, + OBJECT_COPY_BASIC_TEST_NEW_DSET_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy dataset '%s' to '%s'\n", OBJECT_COPY_BASIC_TEST_DSET_NAME, + OBJECT_COPY_BASIC_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset); + } + + if ((object_link_exists = + H5Lexists(group_id, OBJECT_COPY_BASIC_TEST_NEW_DSET_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied dataset exists\n", + OBJECT_COPY_BASIC_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied dataset didn't exist!\n", + OBJECT_COPY_BASIC_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset); + } + + /* Ensure that the new dataset has all of the attributes of the copied dataset */ + if ((tmp_dset_id = H5Dopen2(group_id, OBJECT_COPY_BASIC_TEST_NEW_DSET_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open dataset copy '%s'\n", OBJECT_COPY_BASIC_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 0; + + if (H5Oget_info3(tmp_dset_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_dset); + } + + if (object_info.num_attrs == 0) { + H5_FAILED(); + HDprintf(" copied dataset didn't contain any attributes after copy operation!\n"); + PART_ERROR(H5Ocopy_dset); + } + + /* Check the attribute names, types, etc. */ + i = 0; + if (H5Aiterate2(tmp_dset_id, H5_INDEX_NAME, H5_ITER_INC, NULL, + object_copy_attribute_iter_callback, &i) < 0) { + H5_FAILED(); + HDprintf(" failed to iterate over copied dataset's attributes\n"); + PART_ERROR(H5Ocopy_dset); + } + + if (i != OBJECT_COPY_BASIC_TEST_NUM_ATTRS) { + H5_FAILED(); + HDprintf(" number of attributes on copied dataset (%llu) didn't match expected number " + "(%llu)!\n", + (unsigned long long)i, (unsigned long long)OBJECT_COPY_BASIC_TEST_NUM_ATTRS); + PART_ERROR(H5Ocopy_dset); + } + + if (H5Dclose(tmp_dset_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close dataset copy\n"); + PART_ERROR(H5Ocopy_dset); + } + + PASSED(); + } + PART_END(H5Ocopy_dset); + + if (tmp_dset_id >= 0) { + H5E_BEGIN_TRY + { + H5Dclose(tmp_dset_id); + } + H5E_END_TRY; + tmp_dset_id = H5I_INVALID_HID; + } + + PART_BEGIN(H5Ocopy_dtype) + { + TESTING_2("H5Ocopy on a committed datatype (default copy options)"); + + if (H5Ocopy(group_id, OBJECT_COPY_BASIC_TEST_DTYPE_NAME, group_id, + OBJECT_COPY_BASIC_TEST_NEW_DTYPE_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy datatype '%s' to '%s'\n", OBJECT_COPY_BASIC_TEST_DTYPE_NAME, + OBJECT_COPY_BASIC_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype); + } + + if ((object_link_exists = + H5Lexists(group_id, OBJECT_COPY_BASIC_TEST_NEW_DTYPE_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied datatype exists\n", + OBJECT_COPY_BASIC_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied datatype didn't exist!\n", + OBJECT_COPY_BASIC_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype); + } + + /* Ensure that the new committed datatype has all the attributes of the copied datatype */ + if ((tmp_dtype_id = H5Topen2(group_id, OBJECT_COPY_BASIC_TEST_NEW_DTYPE_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open datatype copy '%s'\n", OBJECT_COPY_BASIC_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 0; + + if (H5Oget_info3(tmp_dtype_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_dtype); + } + + if (object_info.num_attrs == 0) { + H5_FAILED(); + HDprintf( + " copied committed datatype didn't contain any attributes after copy operation!\n"); + PART_ERROR(H5Ocopy_dtype); + } + + /* Check the attribute names, types, etc. */ + i = 0; + if (H5Aiterate2(tmp_dtype_id, H5_INDEX_NAME, H5_ITER_INC, NULL, + object_copy_attribute_iter_callback, &i) < 0) { + H5_FAILED(); + HDprintf(" failed to iterate over copied datatype's attributes\n"); + PART_ERROR(H5Ocopy_dtype); + } + + if (i != OBJECT_COPY_BASIC_TEST_NUM_ATTRS) { + H5_FAILED(); + HDprintf(" number of attributes on copied datatype (%llu) didn't match expected number " + "(%llu)!\n", + (unsigned long long)i, (unsigned long long)OBJECT_COPY_BASIC_TEST_NUM_ATTRS); + PART_ERROR(H5Ocopy_dtype); + } + + if (H5Tclose(tmp_dtype_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close datatype copy\n"); + PART_ERROR(H5Ocopy_dtype); + } + + PASSED(); + } + PART_END(H5Ocopy_dtype); + + if (tmp_dtype_id >= 0) { + H5E_BEGIN_TRY + { + H5Tclose(tmp_dtype_id); + } + H5E_END_TRY; + tmp_dtype_id = H5I_INVALID_HID; + } + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(attr_space_id) < 0) + TEST_ERROR; + if (H5Sclose(space_id) < 0) + TEST_ERROR; + if (H5Tclose(dset_dtype) < 0) + TEST_ERROR; + if (H5Tclose(dtype_id) < 0) + TEST_ERROR; + if (H5Dclose(dset_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(attr_space_id); + H5Sclose(space_id); + H5Aclose(tmp_attr_id); + H5Tclose(dset_dtype); + H5Tclose(tmp_dtype_id); + H5Tclose(dtype_id); + H5Dclose(tmp_dset_id); + H5Dclose(dset_id); + H5Gclose(tmp_group_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * Tests to ensure that H5Ocopy fails when attempting to copy + * an object to a destination where the object already exists. + */ +static int +test_object_copy_already_existing(void) +{ + herr_t err_ret; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID; + hid_t group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t dtype_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + + TESTING_MULTIPART("object copying to location where objects already exist"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, dataset, or stored datatype aren't " + "supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_COPY_ALREADY_EXISTING_TEST_SUBGROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", + OBJECT_COPY_ALREADY_EXISTING_TEST_SUBGROUP_NAME); + goto error; + } + + if ((space_id = + generate_random_dataspace(OBJECT_COPY_ALREADY_EXISTING_TEST_SPACE_RANK, NULL, NULL, FALSE)) < 0) + TEST_ERROR; + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + /* Create the test group object */ + if ((group_id2 = H5Gcreate2(group_id, OBJECT_COPY_ALREADY_EXISTING_TEST_GROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_COPY_ALREADY_EXISTING_TEST_GROUP_NAME); + goto error; + } + + /* Create the test dataset object */ + if ((dset_id = H5Dcreate2(group_id, OBJECT_COPY_ALREADY_EXISTING_TEST_DSET_NAME, dset_dtype, space_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset '%s'\n", OBJECT_COPY_ALREADY_EXISTING_TEST_DSET_NAME); + goto error; + } + + /* Create the test committed datatype object */ + if ((dtype_id = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create datatype\n"); + goto error; + } + + if (H5Tcommit2(group_id, OBJECT_COPY_ALREADY_EXISTING_TEST_DTYPE_NAME, dtype_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't commit datatype '%s'\n", OBJECT_COPY_ALREADY_EXISTING_TEST_DTYPE_NAME); + goto error; + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Ocopy_already_existing_group) + { + TESTING_2("H5Ocopy group to location where group already exists"); + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, OBJECT_COPY_ALREADY_EXISTING_TEST_GROUP_NAME, group_id, + OBJECT_COPY_ALREADY_EXISTING_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" group copy succeeded in location where group already exists!\n"); + PART_ERROR(H5Ocopy_already_existing_group); + } + + PASSED(); + } + PART_END(H5Ocopy_already_existing_group); + + PART_BEGIN(H5Ocopy_already_existing_dset) + { + TESTING_2("H5Ocopy dataset to location where dataset already exists"); + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, OBJECT_COPY_ALREADY_EXISTING_TEST_DSET_NAME, group_id, + OBJECT_COPY_ALREADY_EXISTING_TEST_DSET_NAME, H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" dataset copy succeeded in location where dataset already exists!\n"); + PART_ERROR(H5Ocopy_already_existing_dset); + } + + PASSED(); + } + PART_END(H5Ocopy_already_existing_dset); + + PART_BEGIN(H5Ocopy_already_existing_dtype) + { + TESTING_2("H5Ocopy committed datatype to location where committed datatype already exists"); + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, OBJECT_COPY_ALREADY_EXISTING_TEST_DTYPE_NAME, group_id, + OBJECT_COPY_ALREADY_EXISTING_TEST_DTYPE_NAME, H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" committed datatype copy succeeded in location where committed datatype already " + "exists!\n"); + PART_ERROR(H5Ocopy_already_existing_dtype); + } + + PASSED(); + } + PART_END(H5Ocopy_already_existing_dtype); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(space_id) < 0) + TEST_ERROR; + if (H5Tclose(dset_dtype) < 0) + TEST_ERROR; + if (H5Tclose(dtype_id) < 0) + TEST_ERROR; + if (H5Dclose(dset_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(space_id); + H5Tclose(dset_dtype); + H5Tclose(dtype_id); + H5Dclose(dset_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test to exercise the H5O_COPY_SHALLOW_HIERARCHY_FLAG flag + * for H5Ocopy. + */ +static int +test_object_copy_shallow_group_copy(void) +{ + H5G_info_t group_info; + htri_t object_link_exists; + size_t i; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID; + hid_t group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t tmp_group_id = H5I_INVALID_HID; + hid_t ocpypl_id = H5I_INVALID_HID; + + TESTING("object copying with H5O_COPY_SHALLOW_HIERARCHY_FLAG flag"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_MORE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, or link aren't supported with this " + "connector\n"); + return 0; + } + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_COPY_SHALLOW_TEST_SUBGROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", OBJECT_COPY_SHALLOW_TEST_SUBGROUP_NAME); + goto error; + } + + /* Create the test group object, along with its nested members. */ + if ((group_id2 = H5Gcreate2(group_id, OBJECT_COPY_SHALLOW_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_COPY_SHALLOW_TEST_GROUP_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_SHALLOW_TEST_NUM_NESTED_OBJS; i++) { + char grp_name[OBJECT_COPY_SHALLOW_TEST_BUF_SIZE]; + + snprintf(grp_name, OBJECT_COPY_SHALLOW_TEST_BUF_SIZE, "grp%d", (int)i); + + if ((tmp_group_id = H5Gcreate2(group_id2, grp_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s' under group '%s'\n", grp_name, + OBJECT_COPY_SHALLOW_TEST_GROUP_NAME); + goto error; + } + + /* Create a further nested group under the last group added */ + if (i == (OBJECT_COPY_SHALLOW_TEST_NUM_NESTED_OBJS - 1)) { + if (H5Gclose(H5Gcreate2(tmp_group_id, OBJECT_COPY_SHALLOW_TEST_DEEP_NESTED_GROUP_NAME, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create nested group '%s' under group '%s'\n", + OBJECT_COPY_SHALLOW_TEST_DEEP_NESTED_GROUP_NAME, grp_name); + goto error; + } + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s'\n", grp_name); + goto error; + } + } + + if ((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create OCopyPL\n"); + goto error; + } + + if (H5Pset_copy_object(ocpypl_id, H5O_COPY_SHALLOW_HIERARCHY_FLAG) < 0) { + H5_FAILED(); + HDprintf(" couldn't set object copying options\n"); + goto error; + } + + if (H5Ocopy(group_id, OBJECT_COPY_SHALLOW_TEST_GROUP_NAME, group_id, + OBJECT_COPY_SHALLOW_TEST_NEW_GROUP_NAME, ocpypl_id, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy group '%s' to '%s'\n", OBJECT_COPY_SHALLOW_TEST_GROUP_NAME, + OBJECT_COPY_SHALLOW_TEST_NEW_GROUP_NAME); + goto error; + } + + if ((object_link_exists = H5Lexists(group_id, OBJECT_COPY_SHALLOW_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < + 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied group exists\n", + OBJECT_COPY_SHALLOW_TEST_NEW_GROUP_NAME); + goto error; + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied group didn't exist!\n", OBJECT_COPY_SHALLOW_TEST_NEW_GROUP_NAME); + goto error; + } + + /* + * Ensure that the new group has only the immediate members of the copied group. + */ + if ((tmp_group_id = H5Gopen2(group_id, OBJECT_COPY_SHALLOW_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open group copy '%s'\n", OBJECT_COPY_SHALLOW_TEST_NEW_GROUP_NAME); + goto error; + } + + memset(&group_info, 0, sizeof(group_info)); + + /* + * Set link count to zero in case the connector doesn't support + * retrieval of group info. + */ + group_info.nlinks = 0; + + if (H5Gget_info(tmp_group_id, &group_info) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve group info\n"); + goto error; + } + + if (group_info.nlinks != OBJECT_COPY_SHALLOW_TEST_NUM_NESTED_OBJS) { + H5_FAILED(); + HDprintf(" copied group contained %d members instead of %d members after a shallow copy!\n", + (int)group_info.nlinks, OBJECT_COPY_SHALLOW_TEST_NUM_NESTED_OBJS); + goto error; + } + + if (H5Gclose(tmp_group_id) < 0) + TEST_ERROR; + + /* + * Ensure that the last immediate member of the copied group doesn't + * contain any members after the shallow copy. + */ + { + char grp_name[OBJECT_COPY_SHALLOW_TEST_BUF_SIZE]; + + snprintf(grp_name, OBJECT_COPY_SHALLOW_TEST_BUF_SIZE, + OBJECT_COPY_SHALLOW_TEST_NEW_GROUP_NAME "/grp%d", + OBJECT_COPY_SHALLOW_TEST_NUM_NESTED_OBJS - 1); + + if ((tmp_group_id = H5Gopen2(group_id, grp_name, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open group '%s'\n", grp_name); + goto error; + } + + memset(&group_info, 0, sizeof(group_info)); + + /* + * Set link count to non-zero in case the connector doesn't support + * retrieval of group info. + */ + group_info.nlinks = 1; + + if (H5Gget_info(tmp_group_id, &group_info) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve group info\n"); + goto error; + } + + if (group_info.nlinks != 0) { + H5_FAILED(); + HDprintf(" copied group's immediate members contained nested members after a shallow copy!\n"); + goto error; + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close group '%s'\n", grp_name); + goto error; + } + } + + if (H5Pclose(ocpypl_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(ocpypl_id); + H5Gclose(tmp_group_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * Tests to exercise the H5O_COPY_WITHOUT_ATTR_FLAG flag + * of H5Ocopy. + */ +static int +test_object_copy_no_attributes(void) +{ + H5O_info2_t object_info; + htri_t object_link_exists; + size_t i; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID; + hid_t group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t tmp_group_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t tmp_dset_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + hid_t dtype_id = H5I_INVALID_HID; + hid_t tmp_dtype_id = H5I_INVALID_HID; + hid_t attr_id = H5I_INVALID_HID; + hid_t attr_space_id = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + hid_t ocpypl_id = H5I_INVALID_HID; + + TESTING_MULTIPART("object copying with H5O_COPY_WITHOUT_ATTR_FLAG flag"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, link, dataset, attribute, or stored " + "datatype aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_COPY_NO_ATTRS_TEST_SUBGROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_SUBGROUP_NAME); + goto error; + } + + if ((space_id = generate_random_dataspace(OBJECT_COPY_NO_ATTRS_TEST_SPACE_RANK, NULL, NULL, FALSE)) < 0) + TEST_ERROR; + if ((attr_space_id = generate_random_dataspace(OBJECT_COPY_NO_ATTRS_TEST_SPACE_RANK, NULL, NULL, TRUE)) < + 0) + TEST_ERROR; + + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + /* Create the test group object, along with the attributes attached to it. */ + if ((group_id2 = H5Gcreate2(group_id, OBJECT_COPY_NO_ATTRS_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_GROUP_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_NO_ATTRS_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_NO_ATTRS_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_NO_ATTRS_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((attr_id = H5Acreate2(group_id2, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on group '%s'\n", attr_name, + OBJECT_COPY_NO_ATTRS_TEST_GROUP_NAME); + goto error; + } + + if (H5Aclose(attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + /* Create the test dataset object, along with the attributes attached to it. */ + if ((dset_id = H5Dcreate2(group_id, OBJECT_COPY_NO_ATTRS_TEST_DSET_NAME, dset_dtype, space_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_DSET_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_NO_ATTRS_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_NO_ATTRS_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_NO_ATTRS_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((attr_id = H5Acreate2(dset_id, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on dataset '%s'\n", attr_name, + OBJECT_COPY_NO_ATTRS_TEST_DSET_NAME); + goto error; + } + + if (H5Aclose(attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + /* Create the test committed datatype object, along with the attributes attached to it. */ + if ((dtype_id = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create datatype\n"); + goto error; + } + + if (H5Tcommit2(group_id, OBJECT_COPY_NO_ATTRS_TEST_DTYPE_NAME, dtype_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't commit datatype '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_DTYPE_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_NO_ATTRS_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_NO_ATTRS_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_NO_ATTRS_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((attr_id = H5Acreate2(dtype_id, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on committed datatype '%s'\n", attr_name, + OBJECT_COPY_NO_ATTRS_TEST_DTYPE_NAME); + goto error; + } + + if (H5Aclose(attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Ocopy_group_no_attributes) + { + TESTING_2("H5Ocopy on a group (without attributes)"); + + if ((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create OCopyPL\n"); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + if (H5Pset_copy_object(ocpypl_id, H5O_COPY_WITHOUT_ATTR_FLAG) < 0) { + H5_FAILED(); + HDprintf(" couldn't set object copying options\n"); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + if (H5Ocopy(group_id, OBJECT_COPY_NO_ATTRS_TEST_GROUP_NAME, group_id, + OBJECT_COPY_NO_ATTRS_TEST_NEW_GROUP_NAME, ocpypl_id, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy group '%s' to '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_GROUP_NAME, + OBJECT_COPY_NO_ATTRS_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + if ((object_link_exists = + H5Lexists(group_id, OBJECT_COPY_NO_ATTRS_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied group exists\n", + OBJECT_COPY_NO_ATTRS_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied group didn't exist!\n", + OBJECT_COPY_NO_ATTRS_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + /* Ensure that the new group has no attributes */ + if ((tmp_group_id = H5Gopen2(group_id, OBJECT_COPY_NO_ATTRS_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < + 0) { + H5_FAILED(); + HDprintf(" failed to open group copy '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to non-zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 1; + + if (H5Oget_info3(tmp_group_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + if (object_info.num_attrs != 0) { + H5_FAILED(); + HDprintf(" copied group contained attributes after a non-attribute copy!\n"); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + if (H5Pclose(ocpypl_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close OCopyPL\n"); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close group copy\n"); + PART_ERROR(H5Ocopy_group_no_attributes); + } + + PASSED(); + } + PART_END(H5Ocopy_group_no_attributes); + + if (ocpypl_id >= 0) { + H5E_BEGIN_TRY + { + H5Pclose(ocpypl_id); + } + H5E_END_TRY; + ocpypl_id = H5I_INVALID_HID; + } + if (tmp_group_id >= 0) { + H5E_BEGIN_TRY + { + H5Gclose(tmp_group_id); + } + H5E_END_TRY; + tmp_group_id = H5I_INVALID_HID; + } + + PART_BEGIN(H5Ocopy_dset_no_attributes) + { + TESTING_2("H5Ocopy on a dataset (without attributes)"); + + if ((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create OCopyPL\n"); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + if (H5Pset_copy_object(ocpypl_id, H5O_COPY_WITHOUT_ATTR_FLAG) < 0) { + H5_FAILED(); + HDprintf(" couldn't set object copying options\n"); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + if (H5Ocopy(group_id, OBJECT_COPY_NO_ATTRS_TEST_DSET_NAME, group_id, + OBJECT_COPY_NO_ATTRS_TEST_NEW_DSET_NAME, ocpypl_id, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy dataset '%s' to '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_DSET_NAME, + OBJECT_COPY_NO_ATTRS_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + if ((object_link_exists = + H5Lexists(group_id, OBJECT_COPY_NO_ATTRS_TEST_NEW_DSET_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied dataset exists\n", + OBJECT_COPY_NO_ATTRS_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied dataset didn't exist!\n", + OBJECT_COPY_NO_ATTRS_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + /* Ensure that the new dataset doesn't have any attributes */ + if ((tmp_dset_id = H5Dopen2(group_id, OBJECT_COPY_NO_ATTRS_TEST_NEW_DSET_NAME, H5P_DEFAULT)) < + 0) { + H5_FAILED(); + HDprintf(" failed to open dataset copy '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to non-zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 1; + + if (H5Oget_info3(tmp_dset_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + if (object_info.num_attrs != 0) { + H5_FAILED(); + HDprintf(" copied dataset contained attributes after a non-attribute copy!\n"); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + if (H5Pclose(ocpypl_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close OCopyPL\n"); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + if (H5Dclose(tmp_dset_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close dataset copy\n"); + PART_ERROR(H5Ocopy_dset_no_attributes); + } + + PASSED(); + } + PART_END(H5Ocopy_dset_no_attributes); + + if (ocpypl_id >= 0) { + H5E_BEGIN_TRY + { + H5Pclose(ocpypl_id); + } + H5E_END_TRY; + ocpypl_id = H5I_INVALID_HID; + } + if (tmp_dset_id >= 0) { + H5E_BEGIN_TRY + { + H5Dclose(tmp_dset_id); + } + H5E_END_TRY; + tmp_dset_id = H5I_INVALID_HID; + } + + PART_BEGIN(H5Ocopy_dtype_no_attributes) + { + TESTING_2("H5Ocopy on a committed datatype (without attributes)"); + + if ((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create OCopyPL\n"); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + if (H5Pset_copy_object(ocpypl_id, H5O_COPY_WITHOUT_ATTR_FLAG) < 0) { + H5_FAILED(); + HDprintf(" couldn't set object copying options\n"); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + if (H5Ocopy(group_id, OBJECT_COPY_NO_ATTRS_TEST_DTYPE_NAME, group_id, + OBJECT_COPY_NO_ATTRS_TEST_NEW_DTYPE_NAME, ocpypl_id, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy datatype '%s' to '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_DTYPE_NAME, + OBJECT_COPY_NO_ATTRS_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + if ((object_link_exists = + H5Lexists(group_id, OBJECT_COPY_NO_ATTRS_TEST_NEW_DTYPE_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied datatype exists\n", + OBJECT_COPY_NO_ATTRS_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied datatype didn't exist!\n", + OBJECT_COPY_NO_ATTRS_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + /* Ensure that the new committed datatype doesn't have any attributes */ + if ((tmp_dtype_id = H5Topen2(group_id, OBJECT_COPY_NO_ATTRS_TEST_NEW_DTYPE_NAME, H5P_DEFAULT)) < + 0) { + H5_FAILED(); + HDprintf(" failed to open dataset copy '%s'\n", OBJECT_COPY_NO_ATTRS_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to non-zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 1; + + if (H5Oget_info3(tmp_dtype_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + if (object_info.num_attrs != 0) { + H5_FAILED(); + HDprintf(" copied committed datatype contained attributes after a non-attribute copy!\n"); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + if (H5Pclose(ocpypl_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close OCopyPL\n"); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + if (H5Tclose(tmp_dtype_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close datatype copy\n"); + PART_ERROR(H5Ocopy_dtype_no_attributes); + } + + PASSED(); + } + PART_END(H5Ocopy_dtype_no_attributes); + + if (ocpypl_id >= 0) { + H5E_BEGIN_TRY + { + H5Pclose(ocpypl_id); + } + H5E_END_TRY; + ocpypl_id = H5I_INVALID_HID; + } + if (tmp_dtype_id >= 0) { + H5E_BEGIN_TRY + { + H5Tclose(tmp_dtype_id); + } + H5E_END_TRY; + tmp_dtype_id = H5I_INVALID_HID; + } + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(attr_space_id) < 0) + TEST_ERROR; + if (H5Sclose(space_id) < 0) + TEST_ERROR; + if (H5Tclose(dset_dtype) < 0) + TEST_ERROR; + if (H5Tclose(dtype_id) < 0) + TEST_ERROR; + if (H5Dclose(dset_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(ocpypl_id); + H5Sclose(attr_space_id); + H5Sclose(space_id); + H5Aclose(attr_id); + H5Tclose(dset_dtype); + H5Tclose(tmp_dtype_id); + H5Tclose(dtype_id); + H5Dclose(tmp_dset_id); + H5Dclose(dset_id); + H5Gclose(tmp_group_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * Tests to exercise the behavior of H5Ocopy when the source + * object specified is a soft link or dangling soft link. + */ +static int +test_object_copy_by_soft_link(void) +{ + H5O_info2_t object_info; + H5G_info_t group_info; + H5L_info2_t link_info; + htri_t object_link_exists; + size_t i; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID; + hid_t group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t tmp_group_id = H5I_INVALID_HID; + hid_t attr_id = H5I_INVALID_HID; + hid_t attr_space_id = H5I_INVALID_HID; + + TESTING_MULTIPART("object copying through use of soft links"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, link, dataset, attribute, iterate, or " + "soft link aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_COPY_SOFT_LINK_TEST_SUBGROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", OBJECT_COPY_SOFT_LINK_TEST_SUBGROUP_NAME); + goto error; + } + + if ((attr_space_id = generate_random_dataspace(OBJECT_COPY_SOFT_LINK_TEST_SPACE_RANK, NULL, NULL, TRUE)) < + 0) + TEST_ERROR; + + /* Create the test group object, along with its nested members and the attributes attached to it. */ + if ((group_id2 = H5Gcreate2(group_id, OBJECT_COPY_SOFT_LINK_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_COPY_SOFT_LINK_TEST_GROUP_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_SOFT_LINK_TEST_NUM_NESTED_OBJS; i++) { + char grp_name[OBJECT_COPY_SOFT_LINK_TEST_BUF_SIZE]; + + snprintf(grp_name, OBJECT_COPY_SOFT_LINK_TEST_BUF_SIZE, "grp%d", (int)i); + + if ((tmp_group_id = H5Gcreate2(group_id2, grp_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s' under group '%s'\n", grp_name, + OBJECT_COPY_SOFT_LINK_TEST_GROUP_NAME); + goto error; + } + + /* Create a further nested group under the last group added */ + if (i == (OBJECT_COPY_SOFT_LINK_TEST_NUM_NESTED_OBJS - 1)) { + if (H5Gclose(H5Gcreate2(tmp_group_id, OBJECT_COPY_SOFT_LINK_TEST_DEEP_NESTED_GROUP_NAME, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create nested group '%s' under group '%s'\n", + OBJECT_COPY_SOFT_LINK_TEST_DEEP_NESTED_GROUP_NAME, grp_name); + goto error; + } + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s'\n", grp_name); + goto error; + } + } + + for (i = 0; i < (size_t)OBJECT_COPY_SOFT_LINK_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_SOFT_LINK_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_SOFT_LINK_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((attr_id = H5Acreate2(group_id2, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on group '%s'\n", attr_name, + OBJECT_COPY_SOFT_LINK_TEST_GROUP_NAME); + goto error; + } + + if (H5Aclose(attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Ocopy_through_soft_link) + { + TESTING_2("H5Ocopy through use of a soft link"); + + if (H5Lcreate_soft("/" OBJECT_TEST_GROUP_NAME "/" OBJECT_COPY_SOFT_LINK_TEST_SUBGROUP_NAME + "/" OBJECT_COPY_SOFT_LINK_TEST_GROUP_NAME, + group_id, OBJECT_COPY_SOFT_LINK_TEST_SOFT_LINK_NAME, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to create soft link '%s' to group for copying\n", + OBJECT_COPY_SOFT_LINK_TEST_SOFT_LINK_NAME); + PART_ERROR(H5Ocopy_through_soft_link); + } + + if (H5Ocopy(group_id, OBJECT_COPY_SOFT_LINK_TEST_SOFT_LINK_NAME, group_id, + OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy group '%s' to '%s'\n", OBJECT_COPY_SOFT_LINK_TEST_GROUP_NAME, + OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_through_soft_link); + } + + if ((object_link_exists = + H5Lexists(group_id, OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied group exists\n", + OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_through_soft_link); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied group didn't exist!\n", + OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_through_soft_link); + } + + /* Make sure the new object is an actual group and not another soft link */ + memset(&link_info, 0, sizeof(link_info)); + if (H5Lget_info2(group_id, OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME, &link_info, H5P_DEFAULT) < + 0) { + H5_FAILED(); + HDprintf(" failed to retrieve info for link '%s'\n", + OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_through_soft_link); + } + + if (link_info.type != H5L_TYPE_HARD) { + H5_FAILED(); + HDprintf( + " after group copy through soft link, group's new link type wasn't H5L_TYPE_HARD!\n"); + PART_ERROR(H5Ocopy_through_soft_link); + } + + /* + * Ensure that the new group doesn't have any attributes and only the + * immediate members of the copied group. + */ + if ((tmp_group_id = H5Gopen2(group_id, OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < + 0) { + H5_FAILED(); + HDprintf(" failed to open group copy '%s'\n", OBJECT_COPY_SOFT_LINK_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_through_soft_link); + } + + memset(&group_info, 0, sizeof(group_info)); + + /* + * Set link count to zero in case the connector doesn't support + * retrieval of group info. + */ + group_info.nlinks = 0; + + if (H5Gget_info(tmp_group_id, &group_info) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve group info\n"); + PART_ERROR(H5Ocopy_through_soft_link); + } + + if (group_info.nlinks != OBJECT_COPY_SOFT_LINK_TEST_NUM_NESTED_OBJS) { + H5_FAILED(); + HDprintf( + " copied group contained %d members instead of %d members after a shallow copy!\n", + (int)group_info.nlinks, OBJECT_COPY_SOFT_LINK_TEST_NUM_NESTED_OBJS); + PART_ERROR(H5Ocopy_through_soft_link); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 0; + + if (H5Oget_info3(tmp_group_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_through_soft_link); + } + + if (object_info.num_attrs == 0) { + H5_FAILED(); + HDprintf(" copied group didn't contain any attributes after copy operation!\n"); + PART_ERROR(H5Ocopy_through_soft_link); + } + + /* Check the attribute names, types, etc. */ + i = 0; + if (H5Aiterate2(tmp_group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, + object_copy_attribute_iter_callback, &i) < 0) { + H5_FAILED(); + HDprintf(" failed to iterate over copied group's attributes\n"); + PART_ERROR(H5Ocopy_through_soft_link); + } + + if (i != OBJECT_COPY_SOFT_LINK_TEST_NUM_ATTRS) { + H5_FAILED(); + HDprintf( + " number of attributes on copied group (%llu) didn't match expected number (%llu)!\n", + (unsigned long long)i, (unsigned long long)OBJECT_COPY_SOFT_LINK_TEST_NUM_ATTRS); + PART_ERROR(H5Ocopy_through_soft_link); + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close group copy\n"); + PART_ERROR(H5Ocopy_through_soft_link); + } + + PASSED(); + } + PART_END(H5Ocopy_through_soft_link); + + if (tmp_group_id >= 0) { + H5E_BEGIN_TRY + { + H5Gclose(tmp_group_id); + } + H5E_END_TRY; + tmp_group_id = H5I_INVALID_HID; + } + + PART_BEGIN(H5Ocopy_through_dangling_soft_link) + { + herr_t err_ret; + + TESTING_2("H5Ocopy through use of a dangling soft link"); + + if (H5Lcreate_soft("/" OBJECT_TEST_GROUP_NAME "/" OBJECT_COPY_SOFT_LINK_TEST_SUBGROUP_NAME + "/nonexistent_object", + group_id, OBJECT_COPY_SOFT_LINK_TEST_DANGLING_LINK_NAME, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to create dangling soft link '%s'\n", + OBJECT_COPY_SOFT_LINK_TEST_DANGLING_LINK_NAME); + PART_ERROR(H5Ocopy_through_dangling_soft_link); + } + + H5E_BEGIN_TRY + { + err_ret = + H5Ocopy(group_id, OBJECT_COPY_SOFT_LINK_TEST_DANGLING_LINK_NAME, group_id, + OBJECT_COPY_SOFT_LINK_TEST_DANGLING_LINK_NAME "2", H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" copied non-existent object through use of a dangling soft link!\n"); + PART_ERROR(H5Ocopy_through_dangling_soft_link); + } + + PASSED(); + } + PART_END(H5Ocopy_through_dangling_soft_link); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(attr_space_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(attr_space_id); + H5Aclose(attr_id); + H5Gclose(tmp_group_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * Tests for copying groups that contain soft links with + * H5Ocopy. Also tested is the H5O_COPY_EXPAND_SOFT_LINK_FLAG + * flag. + */ +static int +test_object_copy_group_with_soft_links(void) +{ + H5G_info_t group_info; + htri_t object_link_exists; + size_t i; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID; + hid_t group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t tmp_group_id = H5I_INVALID_HID; + hid_t ocpypl_id = H5I_INVALID_HID; + + TESTING_MULTIPART("group copying when group contains soft links"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, link, or soft link aren't supported with " + "this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_SUBGROUP_NAME, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_SUBGROUP_NAME); + goto error; + } + + /* Create the test group object. */ + if ((group_id2 = H5Gcreate2(group_id, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_GROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_GROUP_NAME); + goto error; + } + + /* Create several groups at the root level and add soft links pointing to them inside + * the test group object. + */ + for (i = 0; i < (size_t)OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS; i++) { + char grp_name[OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE]; + char lnk_name[OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE]; + char lnk_target[2 * OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE]; + + snprintf(grp_name, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE, "grp%d", (int)i); + snprintf(lnk_name, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE, "link%d", (int)i); + snprintf(lnk_target, 2 * OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE, + "/" OBJECT_TEST_GROUP_NAME "/" OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_SUBGROUP_NAME "/%s", + grp_name); + + if ((tmp_group_id = H5Gcreate2(group_id, grp_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s' under group '%s'\n", grp_name, + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_SUBGROUP_NAME); + goto error; + } + + if (H5Lcreate_soft(lnk_target, group_id2, lnk_name, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to create soft link '%s'\n", lnk_name); + goto error; + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s'\n", grp_name); + goto error; + } + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Ocopy_dont_expand_soft_links) + { + TESTING_2("H5Ocopy on group with soft links (soft links not expanded)"); + + if (H5Ocopy(group_id, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_GROUP_NAME, group_id, + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NON_EXPAND_GROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy group '%s' to '%s'\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_GROUP_NAME, + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NON_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_dont_expand_soft_links); + } + + if ((object_link_exists = + H5Lexists(group_id, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NON_EXPAND_GROUP_NAME, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied group exists\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NON_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_dont_expand_soft_links); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied group didn't exist!\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NON_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_dont_expand_soft_links); + } + + /* Ensure that the number of links is the same */ + if ((tmp_group_id = + H5Gopen2(group_id, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NON_EXPAND_GROUP_NAME, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open group copy '%s'\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NON_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_dont_expand_soft_links); + } + + memset(&group_info, 0, sizeof(group_info)); + + /* + * Set link count to zero in case the connector doesn't support + * retrieval of group info. + */ + group_info.nlinks = 0; + + if (H5Gget_info(tmp_group_id, &group_info) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve group info\n"); + PART_ERROR(H5Ocopy_dont_expand_soft_links); + } + + if (group_info.nlinks != OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS) { + H5_FAILED(); + HDprintf(" copied group contained %d members instead of %d members after copy!\n", + (int)group_info.nlinks, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS); + PART_ERROR(H5Ocopy_dont_expand_soft_links); + } + + /* + * Iterate over the links in the copied group and ensure that they're all + * still soft links with their original values. + */ + i = 0; + if (H5Literate2(tmp_group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, + object_copy_soft_link_non_expand_callback, &i) < 0) { + H5_FAILED(); + HDprintf(" failed to iterate over links in group '%s'\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NON_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_dont_expand_soft_links); + } + + if (i != OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS) { + H5_FAILED(); + HDprintf(" number of links in copied group (%llu) didn't match expected number (%llu)!\n", + (unsigned long long)i, + (unsigned long long)OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS); + PART_ERROR(H5Ocopy_dont_expand_soft_links); + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close group copy\n"); + PART_ERROR(H5Ocopy_dont_expand_soft_links); + } + + PASSED(); + } + PART_END(H5Ocopy_dont_expand_soft_links); + + if (tmp_group_id >= 0) { + H5E_BEGIN_TRY + { + H5Gclose(tmp_group_id); + } + H5E_END_TRY; + tmp_group_id = H5I_INVALID_HID; + } + + PART_BEGIN(H5Ocopy_expand_soft_links) + { + TESTING_2("H5Ocopy on group with soft links (soft links expanded)"); + + if ((ocpypl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create OCopyPL\n"); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + if (H5Pset_copy_object(ocpypl_id, H5O_COPY_EXPAND_SOFT_LINK_FLAG) < 0) { + H5_FAILED(); + HDprintf(" couldn't set object copying options\n"); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + if (H5Ocopy(group_id, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_GROUP_NAME, group_id, + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_GROUP_NAME, ocpypl_id, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy group '%s' to '%s'\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_GROUP_NAME, + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + if ((object_link_exists = H5Lexists( + group_id, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied group exists\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied group didn't exist!\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + /* Ensure that the number of links is the same */ + if ((tmp_group_id = H5Gopen2(group_id, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_GROUP_NAME, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open group copy '%s'\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + memset(&group_info, 0, sizeof(group_info)); + + /* + * Set link count to zero in case the connector doesn't support + * retrieval of group info. + */ + group_info.nlinks = 0; + + if (H5Gget_info(tmp_group_id, &group_info) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve group info\n"); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + if (group_info.nlinks != OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS) { + H5_FAILED(); + HDprintf(" copied group contained %d members instead of %d members after copy!\n", + (int)group_info.nlinks, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + /* + * Iterate over the links in the copied group and ensure that they've all + * been expanded into hard links corresponding to the top-level groups + * created. + */ + i = 0; + if (H5Literate2(tmp_group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, + object_copy_soft_link_expand_callback, &i) < 0) { + H5_FAILED(); + HDprintf(" failed to iterate over links in group '%s'\n", + OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_EXPAND_GROUP_NAME); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + if (i != OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS) { + H5_FAILED(); + HDprintf(" number of links in copied group (%llu) didn't match expected number (%llu)!\n", + (unsigned long long)i, + (unsigned long long)OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_NUM_NESTED_OBJS); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + if (H5Pclose(ocpypl_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close OCopyPL\n"); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close group copy\n"); + PART_ERROR(H5Ocopy_expand_soft_links); + } + + PASSED(); + } + PART_END(H5Ocopy_expand_soft_links); + + if (ocpypl_id >= 0) { + H5E_BEGIN_TRY + { + H5Gclose(ocpypl_id); + } + H5E_END_TRY; + ocpypl_id = H5I_INVALID_HID; + } + if (tmp_group_id >= 0) { + H5E_BEGIN_TRY + { + H5Gclose(tmp_group_id); + } + H5E_END_TRY; + tmp_group_id = H5I_INVALID_HID; + } + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(ocpypl_id); + H5Gclose(tmp_group_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * Tests for copying objects between two different files using + * H5Ocopy. + */ +static int +test_object_copy_between_files(void) +{ + H5O_info2_t object_info; + H5G_info_t group_info; + htri_t object_link_exists; + size_t i; + hid_t file_id = H5I_INVALID_HID; + hid_t file_id2 = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID; + hid_t group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t tmp_group_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t tmp_dset_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + hid_t dtype_id = H5I_INVALID_HID; + hid_t tmp_dtype_id = H5I_INVALID_HID; + hid_t attr_id = H5I_INVALID_HID; + hid_t attr_space_id = H5I_INVALID_HID; + hid_t space_id = H5I_INVALID_HID; + hid_t ocpypl_id = H5I_INVALID_HID; + + TESTING_MULTIPART("object copying between files"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_LINK_MORE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_MORE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, link, dataset, attribute, stored " + "datatype, or iterate aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + /* + * Create the second file for the between file copying tests. + */ + if ((file_id2 = H5Fcreate(OBJECT_COPY_BETWEEN_FILES_TEST_FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_COPY_BETWEEN_FILES_TEST_SUBGROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", + OBJECT_COPY_BETWEEN_FILES_TEST_SUBGROUP_NAME); + goto error; + } + + if ((space_id = generate_random_dataspace(OBJECT_COPY_BETWEEN_FILES_TEST_SPACE_RANK, NULL, NULL, FALSE)) < + 0) + TEST_ERROR; + if ((attr_space_id = + generate_random_dataspace(OBJECT_COPY_BETWEEN_FILES_TEST_SPACE_RANK, NULL, NULL, TRUE)) < 0) + TEST_ERROR; + + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + /* Create the test group object, along with its nested members and the attributes attached to it. */ + if ((group_id2 = H5Gcreate2(group_id, OBJECT_COPY_BETWEEN_FILES_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_COPY_BETWEEN_FILES_TEST_GROUP_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_BETWEEN_FILES_TEST_NUM_NESTED_OBJS; i++) { + char grp_name[OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE]; + + snprintf(grp_name, OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE, "grp%d", (int)i); + + if ((tmp_group_id = H5Gcreate2(group_id2, grp_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s' under group '%s'\n", grp_name, + OBJECT_COPY_BETWEEN_FILES_TEST_GROUP_NAME); + goto error; + } + + /* Create a further nested group under the last group added */ + if (i == (OBJECT_COPY_BETWEEN_FILES_TEST_NUM_NESTED_OBJS - 1)) { + if (H5Gclose(H5Gcreate2(tmp_group_id, OBJECT_COPY_BETWEEN_FILES_TEST_DEEP_NESTED_GROUP_NAME, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create nested group '%s' under group '%s'\n", + OBJECT_COPY_BETWEEN_FILES_TEST_DEEP_NESTED_GROUP_NAME, grp_name); + goto error; + } + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s'\n", grp_name); + goto error; + } + } + + for (i = 0; i < (size_t)OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((attr_id = H5Acreate2(group_id2, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on group '%s'\n", attr_name, + OBJECT_COPY_BETWEEN_FILES_TEST_GROUP_NAME); + goto error; + } + + if (H5Aclose(attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + /* Create the test dataset object, along with the attributes attached to it. */ + if ((dset_id = H5Dcreate2(group_id, OBJECT_COPY_BETWEEN_FILES_TEST_DSET_NAME, dset_dtype, space_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset '%s'\n", OBJECT_COPY_BETWEEN_FILES_TEST_DSET_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((attr_id = H5Acreate2(dset_id, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on dataset '%s'\n", attr_name, + OBJECT_COPY_BETWEEN_FILES_TEST_DSET_NAME); + goto error; + } + + if (H5Aclose(attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + /* Create the test committed datatype object, along with the attributes attached to it. */ + if ((dtype_id = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create datatype\n"); + goto error; + } + + if (H5Tcommit2(group_id, OBJECT_COPY_BETWEEN_FILES_TEST_DTYPE_NAME, dtype_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't commit datatype '%s'\n", OBJECT_COPY_BETWEEN_FILES_TEST_DTYPE_NAME); + goto error; + } + + for (i = 0; i < (size_t)OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS; i++) { + char attr_name[OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE]; + + snprintf(attr_name, OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE, "attr%d", (int)i); + + if ((attr_id = H5Acreate2(dtype_id, attr_name, H5T_NATIVE_INT, attr_space_id, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create attribute '%s' on committed datatype '%s'\n", attr_name, + OBJECT_COPY_BETWEEN_FILES_TEST_DTYPE_NAME); + goto error; + } + + if (H5Aclose(attr_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close attribute '%s'\n", attr_name); + goto error; + } + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Ocopy_group_between_files) + { + TESTING_2("H5Ocopy on group between different files"); + + if (H5Ocopy(group_id, OBJECT_COPY_BETWEEN_FILES_TEST_GROUP_NAME, file_id2, + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy group '%s' to second file '%s'\n", + OBJECT_COPY_BETWEEN_FILES_TEST_GROUP_NAME, + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group_between_files); + } + + if ((object_link_exists = + H5Lexists(file_id2, OBJECT_COPY_BETWEEN_FILES_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied group exists\n", + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group_between_files); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied group in second file '%s' didn't exist!\n", + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_GROUP_NAME, + OBJECT_COPY_BETWEEN_FILES_TEST_FILE_NAME); + PART_ERROR(H5Ocopy_group_between_files); + } + + /* Ensure that the new group has all the members of the copied group, and all its attributes */ + if ((tmp_group_id = + H5Gopen2(file_id2, OBJECT_COPY_BETWEEN_FILES_TEST_NEW_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open group copy '%s'\n", + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_GROUP_NAME); + PART_ERROR(H5Ocopy_group_between_files); + } + + memset(&group_info, 0, sizeof(group_info)); + + /* + * Set link count to zero in case the connector doesn't support + * retrieval of group info. + */ + group_info.nlinks = 0; + + if (H5Gget_info(tmp_group_id, &group_info) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve group info\n"); + PART_ERROR(H5Ocopy_group_between_files); + } + + if (group_info.nlinks != OBJECT_COPY_BETWEEN_FILES_TEST_NUM_NESTED_OBJS) { + H5_FAILED(); + HDprintf(" copied group contained %d members instead of %d members after a deep copy!\n", + (int)group_info.nlinks, OBJECT_COPY_BETWEEN_FILES_TEST_NUM_NESTED_OBJS); + PART_ERROR(H5Ocopy_group_between_files); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 0; + + if (H5Oget_info3(tmp_group_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_group_between_files); + } + + if (object_info.num_attrs == 0) { + H5_FAILED(); + HDprintf(" copied group didn't contain any attributes after copy operation!\n"); + PART_ERROR(H5Ocopy_group_between_files); + } + + /* Check the attribute names, types, etc. */ + i = 0; + if (H5Aiterate2(tmp_group_id, H5_INDEX_NAME, H5_ITER_INC, NULL, + object_copy_attribute_iter_callback, &i) < 0) { + H5_FAILED(); + HDprintf(" failed to iterate over copied group's attributes\n"); + PART_ERROR(H5Ocopy_group_between_files); + } + + if (i != OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS) { + H5_FAILED(); + HDprintf( + " number of attributes on copied group (%llu) didn't match expected number (%llu)!\n", + (unsigned long long)i, (unsigned long long)OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS); + PART_ERROR(H5Ocopy_group_between_files); + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close group copy\n"); + PART_ERROR(H5Ocopy_group_between_files); + } + + /* + * Ensure that the last immediate member of the copied group + * contains its single member after the deep copy. + */ + { + char grp_name[OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE]; + + snprintf(grp_name, OBJECT_COPY_BETWEEN_FILES_TEST_BUF_SIZE, + "/" OBJECT_COPY_BETWEEN_FILES_TEST_NEW_GROUP_NAME "/grp%d", + OBJECT_COPY_BETWEEN_FILES_TEST_NUM_NESTED_OBJS - 1); + + if ((tmp_group_id = H5Gopen2(file_id2, grp_name, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open group '%s'\n", grp_name); + PART_ERROR(H5Ocopy_group_between_files); + } + + memset(&group_info, 0, sizeof(group_info)); + + /* + * Set link count to zero in case the connector doesn't support + * retrieval of group info. + */ + group_info.nlinks = 0; + + if (H5Gget_info(tmp_group_id, &group_info) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve group info\n"); + PART_ERROR(H5Ocopy_group_between_files); + } + + if (group_info.nlinks != 1) { + H5_FAILED(); + HDprintf(" copied group's immediate members didn't contain nested members after a " + "deep copy!\n"); + PART_ERROR(H5Ocopy_group_between_files); + } + + if (H5Gclose(tmp_group_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close group '%s'\n", grp_name); + PART_ERROR(H5Ocopy_group_between_files); + } + } + + PASSED(); + } + PART_END(H5Ocopy_group_between_files); + + if (tmp_group_id >= 0) { + H5E_BEGIN_TRY + { + H5Gclose(tmp_group_id); + } + H5E_END_TRY; + tmp_group_id = H5I_INVALID_HID; + } + + PART_BEGIN(H5Ocopy_dset_between_files) + { + TESTING_2("H5Ocopy on dataset between different files"); + + if (H5Ocopy(group_id, OBJECT_COPY_BETWEEN_FILES_TEST_DSET_NAME, file_id2, + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DSET_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy dataset '%s' to second file '%s'\n", + OBJECT_COPY_BETWEEN_FILES_TEST_DSET_NAME, + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset_between_files); + } + + if ((object_link_exists = + H5Lexists(file_id2, OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DSET_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied dataset exists\n", + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset_between_files); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied dataset in second file '%s' didn't exist!\n", + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DSET_NAME, + OBJECT_COPY_BETWEEN_FILES_TEST_FILE_NAME); + PART_ERROR(H5Ocopy_dset_between_files); + } + + /* Ensure that the new dataset has all the attributes of the copied dataset */ + if ((tmp_dset_id = + H5Dopen2(file_id2, OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DSET_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open dataset copy '%s'\n", + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DSET_NAME); + PART_ERROR(H5Ocopy_dset_between_files); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 0; + + if (H5Oget_info3(tmp_dset_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_dset_between_files); + } + + if (object_info.num_attrs == 0) { + H5_FAILED(); + HDprintf(" copied dataset didn't contain any attributes after copy operation!\n"); + PART_ERROR(H5Ocopy_dset_between_files); + } + + /* Check the attribute names, types, etc. */ + i = 0; + if (H5Aiterate2(tmp_dset_id, H5_INDEX_NAME, H5_ITER_INC, NULL, + object_copy_attribute_iter_callback, &i) < 0) { + H5_FAILED(); + HDprintf(" failed to iterate over copied dataset's attributes\n"); + PART_ERROR(H5Ocopy_dset_between_files); + } + + if (i != OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS) { + H5_FAILED(); + HDprintf(" number of attributes on copied dataset (%llu) didn't match expected number " + "(%llu)!\n", + (unsigned long long)i, (unsigned long long)OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS); + PART_ERROR(H5Ocopy_dset_between_files); + } + + if (H5Dclose(tmp_dset_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close dataset copy\n"); + PART_ERROR(H5Ocopy_dset_between_files); + } + + PASSED(); + } + PART_END(H5Ocopy_dset_between_files); + + if (tmp_dset_id >= 0) { + H5E_BEGIN_TRY + { + H5Dclose(tmp_dset_id); + } + H5E_END_TRY; + tmp_dset_id = H5I_INVALID_HID; + } + + PART_BEGIN(H5Ocopy_dtype_between_files) + { + TESTING_2("H5Ocopy on committed datatype between different files"); + + if (H5Ocopy(group_id, OBJECT_COPY_BETWEEN_FILES_TEST_DTYPE_NAME, file_id2, + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DTYPE_NAME, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" failed to copy committed datatype '%s' to second file '%s'\n", + OBJECT_COPY_BETWEEN_FILES_TEST_DTYPE_NAME, + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype_between_files); + } + + if ((object_link_exists = + H5Lexists(file_id2, OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DTYPE_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't determine if link '%s' to copied committed datatype exists\n", + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype_between_files); + } + + if (!object_link_exists) { + H5_FAILED(); + HDprintf(" link '%s' to copied committed datatype in second file '%s' didn't exist!\n", + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DTYPE_NAME, + OBJECT_COPY_BETWEEN_FILES_TEST_FILE_NAME); + PART_ERROR(H5Ocopy_dtype_between_files); + } + + /* Ensure that the new committed datatype has all the attributes of the copied committed datatype + */ + if ((tmp_dtype_id = + H5Topen2(file_id2, OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DTYPE_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" failed to open committed datatype copy '%s'\n", + OBJECT_COPY_BETWEEN_FILES_TEST_NEW_DTYPE_NAME); + PART_ERROR(H5Ocopy_dtype_between_files); + } + + memset(&object_info, 0, sizeof(object_info)); + + /* + * Set attribute count to zero in case the connector doesn't + * support retrieval of object info. + */ + object_info.num_attrs = 0; + + if (H5Oget_info3(tmp_dtype_id, &object_info, H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" failed to retrieve object info\n"); + PART_ERROR(H5Ocopy_dtype_between_files); + } + + if (object_info.num_attrs == 0) { + H5_FAILED(); + HDprintf( + " copied committed datatype didn't contain any attributes after copy operation!\n"); + PART_ERROR(H5Ocopy_dtype_between_files); + } + + /* Check the attribute names, types, etc. */ + i = 0; + if (H5Aiterate2(tmp_dtype_id, H5_INDEX_NAME, H5_ITER_INC, NULL, + object_copy_attribute_iter_callback, &i) < 0) { + H5_FAILED(); + HDprintf(" failed to iterate over copied datatype's attributes\n"); + PART_ERROR(H5Ocopy_dtype_between_files); + } + + if (i != OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS) { + H5_FAILED(); + HDprintf(" number of attributes on copied datatype (%llu) didn't match expected number " + "(%llu)!\n", + (unsigned long long)i, (unsigned long long)OBJECT_COPY_BETWEEN_FILES_TEST_NUM_ATTRS); + PART_ERROR(H5Ocopy_dtype_between_files); + } + + if (H5Tclose(tmp_dtype_id) < 0) { + H5_FAILED(); + HDprintf(" failed to close committed datatype copy\n"); + PART_ERROR(H5Ocopy_dtype_between_files); + } + + PASSED(); + } + PART_END(H5Ocopy_dtype_between_files); + + if (tmp_dtype_id >= 0) { + H5E_BEGIN_TRY + { + H5Tclose(tmp_dtype_id); + } + H5E_END_TRY; + tmp_dtype_id = H5I_INVALID_HID; + } + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(attr_space_id) < 0) + TEST_ERROR; + if (H5Sclose(space_id) < 0) + TEST_ERROR; + if (H5Tclose(dset_dtype) < 0) + TEST_ERROR; + if (H5Tclose(dtype_id) < 0) + TEST_ERROR; + if (H5Dclose(dset_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id2) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(ocpypl_id); + H5Sclose(attr_space_id); + H5Sclose(space_id); + H5Aclose(attr_id); + H5Tclose(dset_dtype); + H5Tclose(tmp_dtype_id); + H5Tclose(dtype_id); + H5Dclose(tmp_dset_id); + H5Dclose(dset_id); + H5Gclose(tmp_group_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id2); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test to check that H5Ocopy fails when it + * is passed invalid parameters. + */ +static int +test_object_copy_invalid_params(void) +{ + herr_t err_ret = -1; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + + TESTING_MULTIPART("object copying with invalid parameters"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_MORE)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, or object aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_COPY_INVALID_PARAMS_TEST_SUBGROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", + OBJECT_COPY_INVALID_PARAMS_TEST_SUBGROUP_NAME); + goto error; + } + + if ((group_id2 = H5Gcreate2(group_id, OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME); + goto error; + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Ocopy_invalid_src_loc_id) + { + TESTING_2("H5Ocopy with an invalid source location ID"); + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(H5I_INVALID_HID, OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME, group_id, + OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME2, H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ocopy succeeded with an invalid source location ID!\n"); + PART_ERROR(H5Ocopy_invalid_src_loc_id); + } + + PASSED(); + } + PART_END(H5Ocopy_invalid_src_loc_id); + + PART_BEGIN(H5Ocopy_invalid_src_obj_name) + { + TESTING_2("H5Ocopy with an invalid source object name"); + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, NULL, group_id, OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME2, + H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ocopy succeeded with a NULL source object name!\n"); + PART_ERROR(H5Ocopy_invalid_src_obj_name); + } + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, "", group_id, OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME2, + H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ocopy succeeded with an invalid source object name of ''!\n"); + PART_ERROR(H5Ocopy_invalid_src_obj_name); + } + + PASSED(); + } + PART_END(H5Ocopy_invalid_src_obj_name); + + PART_BEGIN(H5Ocopy_invalid_dst_loc_id) + { + TESTING_2("H5Ocopy with an invalid destination location ID"); + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME, H5I_INVALID_HID, + OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME2, H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ocopy succeeded with an invalid destination location ID!\n"); + PART_ERROR(H5Ocopy_invalid_dst_loc_id); + } + + PASSED(); + } + PART_END(H5Ocopy_invalid_dst_loc_id); + + PART_BEGIN(H5Ocopy_invalid_dst_obj_name) + { + TESTING_2("H5Ocopy with an invalid destination object name"); + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME, group_id, NULL, + H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ocopy succeeded with a NULL destination object name!\n"); + PART_ERROR(H5Ocopy_invalid_dst_obj_name); + } + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME, group_id, "", + H5P_DEFAULT, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ocopy succeeded with an invalid destination object name of ''!\n"); + PART_ERROR(H5Ocopy_invalid_dst_obj_name); + } + + PASSED(); + } + PART_END(H5Ocopy_invalid_dst_obj_name); + + PART_BEGIN(H5Ocopy_invalid_ocpypl) + { + TESTING_2("H5Ocopy with an invalid OcpyPL"); + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME, group_id, + OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME2, H5I_INVALID_HID, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ocopy succeeded with an invalid OcpyPL!\n"); + PART_ERROR(H5Ocopy_invalid_ocpypl); + } + + PASSED(); + } + PART_END(H5Ocopy_invalid_ocpypl); + + PART_BEGIN(H5Ocopy_invalid_lcpl) + { + TESTING_2("H5Ocopy with an invalid LCPL"); + + H5E_BEGIN_TRY + { + err_ret = H5Ocopy(group_id, OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME, group_id, + OBJECT_COPY_INVALID_PARAMS_TEST_GROUP_NAME2, H5P_DEFAULT, H5I_INVALID_HID); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ocopy succeeded with an invalid LCPL!\n"); + PART_ERROR(H5Ocopy_invalid_lcpl); + } + + PASSED(); + } + PART_END(H5Ocopy_invalid_lcpl); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test for H5Oset_comment(_by_name)/H5Oget_comment(_by_name). + */ +static int +test_object_comments(void) +{ + TESTING("object comments"); + + SKIPPED(); + + return 0; +} + +/* + * A test to check that H5Oset_comment(_by_name)/H5Oget_comment(_by_name) + * fail when passed invalid parameters. + */ +static int +test_object_comments_invalid_params(void) +{ + TESTING("object comment "); + + SKIPPED(); + + return 0; +} + +/* + * A test for H5Ovisit(_by_name). + * + * XXX: Should have test for checking nested object's names/paths. + */ +static int +test_object_visit(void) +{ + size_t i; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t gcpl_id = H5I_INVALID_HID; + hid_t type_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + + TESTING_MULTIPART("object visiting"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, dataset, attribute, stored datatype, " + "iterate, or creation order aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create a GCPL\n"); + goto error; + } + + if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) { + H5_FAILED(); + HDprintf(" couldn't enable link creation order tracking and indexing on GCPL\n"); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_VISIT_TEST_SUBGROUP_NAME, H5P_DEFAULT, gcpl_id, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container sub-group '%s'\n", OBJECT_VISIT_TEST_SUBGROUP_NAME); + goto error; + } + + if ((fspace_id = generate_random_dataspace(OBJECT_VISIT_TEST_SPACE_RANK, NULL, NULL, FALSE)) < 0) + TEST_ERROR; + + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + if ((type_id = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create datatype '%s'\n", OBJECT_VISIT_TEST_TYPE_NAME); + goto error; + } + + if ((group_id2 = H5Gcreate2(group_id, OBJECT_VISIT_TEST_GROUP_NAME, H5P_DEFAULT, gcpl_id, H5P_DEFAULT)) < + 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_VISIT_TEST_GROUP_NAME); + goto error; + } + + if ((dset_id = H5Dcreate2(group_id, OBJECT_VISIT_TEST_DSET_NAME, dset_dtype, fspace_id, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset '%s'\n", OBJECT_VISIT_TEST_DSET_NAME); + goto error; + } + + if (H5Tcommit2(group_id, OBJECT_VISIT_TEST_TYPE_NAME, type_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < + 0) { + H5_FAILED(); + HDprintf(" couldn't commit datatype '%s'\n", OBJECT_VISIT_TEST_TYPE_NAME); + goto error; + } + + PASSED(); + + BEGIN_MULTIPART + { + /* + * NOTE: A counter is passed to the iteration callback to try to match up + * the expected objects with a given step throughout all of the following + * iterations. This is to try and check that the objects are indeed being + * returned in the correct order. + */ + + PART_BEGIN(H5Ovisit_obj_name_increasing) + { + TESTING_2("H5Ovisit by object name in increasing order"); + + i = 0; + + if (H5Ovisit3(group_id, H5_INDEX_NAME, H5_ITER_INC, object_visit_callback, &i, H5O_INFO_ALL) < + 0) { + H5_FAILED(); + HDprintf(" H5Ovisit by object name in increasing order failed\n"); + PART_ERROR(H5Ovisit_obj_name_increasing); + } + + if (i != OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_obj_name_increasing); + } + + PASSED(); + } + PART_END(H5Ovisit_obj_name_increasing); + + PART_BEGIN(H5Ovisit_obj_name_decreasing) + { + TESTING_2("H5Ovisit by object name in decreasing order"); +#ifndef NO_DECREASING_ALPHA_ITER_ORDER + /* Reset the counter to the appropriate value for the next test */ + i = OBJECT_VISIT_TEST_NUM_OBJS_VISITED; + + if (H5Ovisit3(group_id, H5_INDEX_NAME, H5_ITER_DEC, object_visit_callback, &i, H5O_INFO_ALL) < + 0) { + H5_FAILED(); + HDprintf(" H5Ovisit by object name in decreasing order failed\n"); + PART_ERROR(H5Ovisit_obj_name_decreasing); + } + + if (i != 2 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_obj_name_decreasing); + } + + PASSED(); +#else + SKIPPED(); + PART_EMPTY(H5Ovisit_obj_name_decreasing); +#endif + } + PART_END(H5Ovisit_obj_name_decreasing); + + PART_BEGIN(H5Ovisit_create_order_increasing) + { + TESTING_2("H5Ovisit by creation order in increasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 2 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED; + + if (H5Ovisit3(group_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, object_visit_callback, &i, + H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit by creation order in increasing order failed\n"); + PART_ERROR(H5Ovisit_create_order_increasing); + } + + if (i != 3 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_create_order_increasing); + } + + PASSED(); + } + PART_END(H5Ovisit_create_order_increasing); + + PART_BEGIN(H5Ovisit_create_order_decreasing) + { + TESTING_2("H5Ovisit by creation order in decreasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 3 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED; + + if (H5Ovisit3(group_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, object_visit_callback, &i, + H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit by creation order in decreasing order failed\n"); + PART_ERROR(H5Ovisit_create_order_decreasing); + } + + if (i != 4 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_create_order_decreasing); + } + + PASSED(); + } + PART_END(H5Ovisit_create_order_decreasing); + + PART_BEGIN(H5Ovisit_file) + { + TESTING_2("H5Ovisit on a file ID"); + + /* + * XXX: + */ + + SKIPPED(); + PART_EMPTY(H5Ovisit_file); + } + PART_END(H5Ovisit_file); + + PART_BEGIN(H5Ovisit_dset) + { + TESTING_2("H5Ovisit on a dataset ID"); + + if (H5Ovisit3(dset_id, H5_INDEX_NAME, H5_ITER_INC, object_visit_dset_callback, NULL, + H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit failed\n"); + PART_ERROR(H5Ovisit_dset); + } + + PASSED(); + } + PART_END(H5Ovisit_dset); + + PART_BEGIN(H5Ovisit_dtype) + { + TESTING_2("H5Ovisit on a committed datatype ID"); + + if (H5Ovisit3(type_id, H5_INDEX_NAME, H5_ITER_INC, object_visit_dtype_callback, NULL, + H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit failed\n"); + PART_ERROR(H5Ovisit_dtype); + } + + PASSED(); + } + PART_END(H5Ovisit_dtype); + + PART_BEGIN(H5Ovisit_by_name_obj_name_increasing) + { + TESTING_2("H5Ovisit_by_name by object name in increasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 0; + + /* First, test visiting using "." for the object name */ + if (H5Ovisit_by_name3(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, object_visit_callback, &i, + H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by object name in increasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_increasing); + } + + if (i != OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_increasing); + } + + /* Reset the special counter and repeat the test using an indirect object name. */ + i = 0; + + if (H5Ovisit_by_name3(container_group, OBJECT_VISIT_TEST_SUBGROUP_NAME, H5_INDEX_NAME, + H5_ITER_INC, object_visit_callback, &i, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by object name in increasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_increasing); + } + + if (i != OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_increasing); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_obj_name_increasing); + + PART_BEGIN(H5Ovisit_by_name_obj_name_decreasing) + { + TESTING_2("H5Ovisit_by_name by object name in decreasing order"); +#ifndef NO_DECREASING_ALPHA_ITER_ORDER + /* Reset the counter to the appropriate value for the next test */ + i = OBJECT_VISIT_TEST_NUM_OBJS_VISITED; + + /* First, test visiting using "." for the object name */ + if (H5Ovisit_by_name3(group_id, ".", H5_INDEX_NAME, H5_ITER_DEC, object_visit_callback, &i, + H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by object name in decreasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_decreasing); + } + + if (i != 2 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_decreasing); + } + + /* Reset the special counter and repeat the test using an indirect object name. */ + i = OBJECT_VISIT_TEST_NUM_OBJS_VISITED; + + if (H5Ovisit_by_name3(container_group, OBJECT_VISIT_TEST_SUBGROUP_NAME, H5_INDEX_NAME, + H5_ITER_DEC, object_visit_callback, &i, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by object name in decreasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_decreasing); + } + + if (i != 2 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_decreasing); + } + + PASSED(); +#else + SKIPPED(); + PART_EMPTY(H5Ovisit_by_name_obj_name_decreasing); +#endif + } + PART_END(H5Ovisit_by_name_obj_name_decreasing); + + PART_BEGIN(H5Ovisit_by_name_create_order_increasing) + { + TESTING_2("H5Ovisit_by_name by creation order in increasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 2 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED; + + /* First, test visiting using "." for the object name */ + if (H5Ovisit_by_name3(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, object_visit_callback, &i, + H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by creation order in increasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_create_order_increasing); + } + + if (i != 3 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_create_order_increasing); + } + + /* Reset the special counter and repeat the test using an indirect object name. */ + i = 2 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED; + + if (H5Ovisit_by_name3(container_group, OBJECT_VISIT_TEST_SUBGROUP_NAME, H5_INDEX_CRT_ORDER, + H5_ITER_INC, object_visit_callback, &i, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by creation order in increasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_create_order_increasing); + } + + if (i != 3 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_create_order_increasing); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_create_order_increasing); + + PART_BEGIN(H5Ovisit_by_name_create_order_decreasing) + { + TESTING_2("H5Ovisit_by_name by creation order in decreasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 3 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED; + + /* First, test visiting using "." for the object name */ + if (H5Ovisit_by_name3(group_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, object_visit_callback, &i, + H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by creation order in decreasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_create_order_decreasing); + } + + if (i != 4 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_create_order_decreasing); + } + + /* Reset the special counter and repeat the test using an indirect object name. */ + i = 3 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED; + + if (H5Ovisit_by_name3(container_group, OBJECT_VISIT_TEST_SUBGROUP_NAME, H5_INDEX_CRT_ORDER, + H5_ITER_DEC, object_visit_callback, &i, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by creation order in decreasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_create_order_decreasing); + } + + if (i != 4 * OBJECT_VISIT_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_create_order_decreasing); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_create_order_decreasing); + + PART_BEGIN(H5Ovisit_by_name_file) + { + TESTING_2("H5Ovisit_by_name on a file ID"); + + /* + * XXX: + */ + + SKIPPED(); + PART_EMPTY(H5Ovisit_by_name_file); + } + PART_END(H5Ovisit_by_name_file); + + PART_BEGIN(H5Ovisit_by_name_dset) + { + TESTING_2("H5Ovisit_by_name on a dataset ID"); + + if (H5Ovisit_by_name3(group_id, OBJECT_VISIT_TEST_DSET_NAME, H5_INDEX_NAME, H5_ITER_INC, + object_visit_dset_callback, NULL, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name failed\n"); + PART_ERROR(H5Ovisit_by_name_dset); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_dset); + + PART_BEGIN(H5Ovisit_by_name_dtype) + { + TESTING_2("H5Ovisit_by_name on a committed datatype ID"); + + if (H5Ovisit_by_name3(group_id, OBJECT_VISIT_TEST_TYPE_NAME, H5_INDEX_NAME, H5_ITER_INC, + object_visit_dtype_callback, NULL, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name failed\n"); + PART_ERROR(H5Ovisit_by_name_dtype); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_dtype); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(fspace_id) < 0) + TEST_ERROR; + if (H5Tclose(dset_dtype) < 0) + TEST_ERROR; + if (H5Tclose(type_id) < 0) + TEST_ERROR; + if (H5Dclose(dset_id) < 0) + TEST_ERROR; + if (H5Pclose(gcpl_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(fspace_id); + H5Tclose(dset_dtype); + H5Tclose(type_id); + H5Dclose(dset_id); + H5Pclose(gcpl_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test for H5Ovisit(_by_name) on soft links. Since + * H5Ovisit(_by_name) ignores soft links, this test is + * meant to verify that behavior by placing objects and + * the soft links pointing to those objects in separate + * groups. Visiting is done only on the group containing + * the links to ensure that the objects in the other group + * do not get visited. + */ +static int +test_object_visit_soft_link(void) +{ + size_t i; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t subgroup_id = H5I_INVALID_HID, subgroup_id2 = H5I_INVALID_HID; + hid_t linked_group_id = H5I_INVALID_HID; + hid_t gcpl_id = H5I_INVALID_HID; + + TESTING_MULTIPART("object visiting with soft links"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_CREATION_ORDER) || !(vol_cap_flags_g & H5VL_CAP_FLAG_SOFT_LINKS)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, soft link, iterate, or creation order " + "aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((gcpl_id = H5Pcreate(H5P_GROUP_CREATE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create a GCPL\n"); + goto error; + } + + if (H5Pset_link_creation_order(gcpl_id, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED) < 0) { + H5_FAILED(); + HDprintf(" couldn't enable link creation order tracking and indexing on GCPL\n"); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_VISIT_SOFT_LINK_TEST_SUBGROUP_NAME, H5P_DEFAULT, + gcpl_id, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container sub-group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_SUBGROUP_NAME); + goto error; + } + + /* Create group to hold soft links */ + if ((subgroup_id = H5Gcreate2(group_id, OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME1, H5P_DEFAULT, gcpl_id, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME1); + goto error; + } + + /* Create group to hold objects pointed to by soft links */ + if ((subgroup_id2 = H5Gcreate2(group_id, OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME2, H5P_DEFAULT, gcpl_id, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME2); + goto error; + } + + /* Create objects under subgroup 2 */ + if ((linked_group_id = H5Gcreate2(subgroup_id2, OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME1, H5P_DEFAULT, + gcpl_id, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME1); + goto error; + } + + if (H5Gclose(linked_group_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME1); + goto error; + } + + if ((linked_group_id = H5Gcreate2(subgroup_id2, OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME2, H5P_DEFAULT, + gcpl_id, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME2); + goto error; + } + + if (H5Gclose(linked_group_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME2); + goto error; + } + + if ((linked_group_id = H5Gcreate2(subgroup_id2, OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME3, H5P_DEFAULT, + gcpl_id, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME3); + goto error; + } + + if (H5Gclose(linked_group_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME3); + goto error; + } + + if (H5Gclose(subgroup_id2) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME2); + goto error; + } + + /* Create soft links under subgroup 1 to point to the previously-created objects */ + if (H5Lcreate_soft("/" OBJECT_TEST_GROUP_NAME "/" OBJECT_VISIT_SOFT_LINK_TEST_SUBGROUP_NAME + "/" OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME2 "/" OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME1, + subgroup_id, OBJECT_VISIT_SOFT_LINK_TEST_LINK_NAME1, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't create soft link '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_LINK_NAME1); + goto error; + } + + if (H5Lcreate_soft("/" OBJECT_TEST_GROUP_NAME "/" OBJECT_VISIT_SOFT_LINK_TEST_SUBGROUP_NAME + "/" OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME2 "/" OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME2, + subgroup_id, OBJECT_VISIT_SOFT_LINK_TEST_LINK_NAME2, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't create soft link '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_LINK_NAME2); + goto error; + } + + if (H5Lcreate_soft("/" OBJECT_TEST_GROUP_NAME "/" OBJECT_VISIT_SOFT_LINK_TEST_SUBGROUP_NAME + "/" OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME2 "/" OBJECT_VISIT_SOFT_LINK_TEST_OBJ_NAME3, + subgroup_id, OBJECT_VISIT_SOFT_LINK_TEST_LINK_NAME3, H5P_DEFAULT, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't create soft link '%s'\n", OBJECT_VISIT_SOFT_LINK_TEST_LINK_NAME3); + goto error; + } + + PASSED(); + + BEGIN_MULTIPART + { + /* + * NOTE: A counter is passed to the iteration callback to try to match up + * the expected objects with a given step throughout all of the following + * iterations. This is to try and check that the objects are indeed being + * returned in the correct order. + */ + + PART_BEGIN(H5Ovisit_obj_name_increasing) + { + TESTING_2("H5Ovisit by object name in increasing order"); + + i = 0; + + if (H5Ovisit3(subgroup_id, H5_INDEX_NAME, H5_ITER_INC, object_visit_soft_link_callback, &i, + H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit by object name in increasing order failed\n"); + PART_ERROR(H5Ovisit_obj_name_increasing); + } + + if (i != OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_obj_name_increasing); + } + + PASSED(); + } + PART_END(H5Ovisit_obj_name_increasing); + + PART_BEGIN(H5Ovisit_obj_name_decreasing) + { + TESTING_2("H5Ovisit by object name in decreasing order"); +#ifndef NO_DECREASING_ALPHA_ITER_ORDER + /* Reset the counter to the appropriate value for the next test */ + i = OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED; + + if (H5Ovisit3(subgroup_id, H5_INDEX_NAME, H5_ITER_DEC, object_visit_soft_link_callback, &i, + H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit by object name in decreasing order failed\n"); + PART_ERROR(H5Ovisit_obj_name_decreasing); + } + + if (i != 2 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_obj_name_decreasing); + } + + PASSED(); +#else + SKIPPED(); + PART_EMPTY(H5Ovisit_obj_name_decreasing); +#endif + } + PART_END(H5Ovisit_obj_name_decreasing); + + PART_BEGIN(H5Ovisit_create_order_increasing) + { + TESTING_2("H5Ovisit by creation order in increasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 2 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED; + + if (H5Ovisit3(subgroup_id, H5_INDEX_CRT_ORDER, H5_ITER_INC, object_visit_soft_link_callback, &i, + H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit by creation order in increasing order failed\n"); + PART_ERROR(H5Ovisit_create_order_increasing); + } + + if (i != 3 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_create_order_increasing); + } + + PASSED(); + } + PART_END(H5Ovisit_create_order_increasing); + + PART_BEGIN(H5Ovisit_create_order_decreasing) + { + TESTING_2("H5Ovisit by creation order in decreasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 3 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED; + + if (H5Ovisit3(subgroup_id, H5_INDEX_CRT_ORDER, H5_ITER_DEC, object_visit_soft_link_callback, &i, + H5O_INFO_ALL) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit by creation order in decreasing order failed\n"); + PART_ERROR(H5Ovisit_create_order_decreasing); + } + + if (i != 4 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_create_order_decreasing); + } + + PASSED(); + } + PART_END(H5Ovisit_create_order_decreasing); + + PART_BEGIN(H5Ovisit_by_name_obj_name_increasing) + { + TESTING_2("H5Ovisit_by_name by object name in increasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 0; + + /* First, test visiting using "." for the object name */ + if (H5Ovisit_by_name3(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_INC, + object_visit_soft_link_callback, &i, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by object name in increasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_increasing); + } + + if (i != OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_increasing); + } + + /* Reset the special counter and repeat the test using an indirect object name. */ + i = 0; + + /* Repeat the test using an indirect object name */ + if (H5Ovisit_by_name3(group_id, OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME1, H5_INDEX_NAME, + H5_ITER_INC, object_visit_soft_link_callback, &i, H5O_INFO_ALL, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by object name in increasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_increasing); + } + + if (i != OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_increasing); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_obj_name_increasing); + + PART_BEGIN(H5Ovisit_by_name_obj_name_decreasing) + { + TESTING_2("H5Ovisit_by_name by object name in decreasing order"); +#ifndef NO_DECREASING_ALPHA_ITER_ORDER + /* Reset the counter to the appropriate value for the next test */ + i = OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED; + + /* First, test visiting using "." for the object name */ + if (H5Ovisit_by_name3(subgroup_id, ".", H5_INDEX_NAME, H5_ITER_DEC, + object_visit_soft_link_callback, &i, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by object name in decreasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_decreasing); + } + + if (i != 2 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_decreasing); + } + + /* Reset the special counter and repeat the test using an indirect object name. */ + i = OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED; + + /* Repeat the test using an indirect object name */ + if (H5Ovisit_by_name3(group_id, OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME1, H5_INDEX_NAME, + H5_ITER_DEC, object_visit_soft_link_callback, &i, H5O_INFO_ALL, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by object name in decreasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_decreasing); + } + + if (i != 2 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_obj_name_decreasing); + } + + PASSED(); +#else + SKIPPED(); + PART_EMPTY(H5Ovisit_by_name_obj_name_decreasing); +#endif + } + PART_END(H5Ovisit_by_name_obj_name_decreasing); + + PART_BEGIN(H5Ovisit_by_name_create_order_increasing) + { + TESTING_2("H5Ovisit_by_name by creation order in increasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 2 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED; + + /* First, test visiting using "." for the object name */ + if (H5Ovisit_by_name3(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, + object_visit_soft_link_callback, &i, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by creation order in increasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_create_order_increasing); + } + + if (i != 3 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_create_order_increasing); + } + + /* Reset the special counter and repeat the test using an indirect object name. */ + i = 2 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED; + + /* Repeat the test using an indirect object name */ + if (H5Ovisit_by_name3(group_id, OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME1, H5_INDEX_CRT_ORDER, + H5_ITER_INC, object_visit_soft_link_callback, &i, H5O_INFO_ALL, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by creation order in increasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_create_order_increasing); + } + + if (i != 3 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_create_order_increasing); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_create_order_increasing); + + PART_BEGIN(H5Ovisit_by_name_create_order_decreasing) + { + TESTING_2("H5Ovisit_by_name by creation order in decreasing order"); + + /* Reset the counter to the appropriate value for the next test */ + i = 3 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED; + + /* First, test visiting using "." for the object name */ + if (H5Ovisit_by_name3(subgroup_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_DEC, + object_visit_soft_link_callback, &i, H5O_INFO_ALL, H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by creation order in decreasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_create_order_decreasing); + } + + if (i != 4 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_create_order_decreasing); + } + + /* Reset the special counter and repeat the test using an indirect object name. */ + i = 3 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED; + + /* Repeat the test using an indirect object name */ + if (H5Ovisit_by_name3(group_id, OBJECT_VISIT_SOFT_LINK_TEST_GROUP_NAME1, H5_INDEX_CRT_ORDER, + H5_ITER_DEC, object_visit_soft_link_callback, &i, H5O_INFO_ALL, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name by creation order in decreasing order failed\n"); + PART_ERROR(H5Ovisit_by_name_create_order_decreasing); + } + + if (i != 4 * OBJECT_VISIT_SOFT_LINK_TEST_NUM_OBJS_VISITED) { + H5_FAILED(); + HDprintf(" some objects were not visited!\n"); + PART_ERROR(H5Ovisit_by_name_create_order_decreasing); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_create_order_decreasing); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Pclose(gcpl_id) < 0) + TEST_ERROR; + if (H5Gclose(subgroup_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Pclose(gcpl_id); + H5Gclose(linked_group_id); + H5Gclose(subgroup_id); + H5Gclose(subgroup_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test to check that H5Ovisit(_by_name) fails when + * it is passed invalid parameters. + */ +static int +test_object_visit_invalid_params(void) +{ + herr_t err_ret = -1; + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + + TESTING_MULTIPART("object visiting with invalid parameters"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & H5VL_CAP_FLAG_FILE_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_ITERATE)) { + SKIPPED(); + HDprintf( + " API functions for basic file, group, or iterate aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container sub-group '%s'\n", + OBJECT_VISIT_INVALID_PARAMS_TEST_SUBGROUP_NAME); + goto error; + } + + if ((group_id2 = H5Gcreate2(group_id, OBJECT_VISIT_INVALID_PARAMS_TEST_GROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_VISIT_INVALID_PARAMS_TEST_GROUP_NAME); + goto error; + } + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Ovisit_invalid_obj_id) + { + TESTING_2("H5Ovisit with an invalid object ID"); + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit3(H5I_INVALID_HID, H5_INDEX_NAME, H5_ITER_INC, object_visit_noop_callback, + NULL, H5O_INFO_ALL); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit succeeded with an invalid object ID!\n"); + PART_ERROR(H5Ovisit_invalid_obj_id); + } + + PASSED(); + } + PART_END(H5Ovisit_invalid_obj_id); + + PART_BEGIN(H5Ovisit_invalid_index_type) + { + TESTING_2("H5Ovisit with an invalid index type"); + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit3(group_id, H5_INDEX_UNKNOWN, H5_ITER_INC, object_visit_noop_callback, NULL, + H5O_INFO_ALL); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit succeeded with invalid index type H5_INDEX_UNKNOWN!\n"); + PART_ERROR(H5Ovisit_invalid_index_type); + } + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit3(group_id, H5_INDEX_N, H5_ITER_INC, object_visit_noop_callback, NULL, + H5O_INFO_ALL); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit succeeded with invalid index type H5_INDEX_N!\n"); + PART_ERROR(H5Ovisit_invalid_index_type); + } + + PASSED(); + } + PART_END(H5Ovisit_invalid_index_type); + + PART_BEGIN(H5Ovisit_invalid_iter_order) + { + TESTING_2("H5Ovisit with an invalid iteration ordering"); + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit3(group_id, H5_INDEX_NAME, H5_ITER_UNKNOWN, object_visit_noop_callback, + NULL, H5O_INFO_ALL); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n"); + PART_ERROR(H5Ovisit_invalid_iter_order); + } + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit3(group_id, H5_INDEX_NAME, H5_ITER_N, object_visit_noop_callback, NULL, + H5O_INFO_ALL); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit succeeded with invalid iteration ordering H5_ITER_N!\n"); + PART_ERROR(H5Ovisit_invalid_iter_order); + } + + PASSED(); + } + PART_END(H5Ovisit_invalid_iter_order); + + PART_BEGIN(H5Ovisit_by_name_invalid_loc_id) + { + TESTING_2("H5Ovisit_by_name with an invalid location ID"); + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit_by_name3(H5I_INVALID_HID, ".", H5_INDEX_NAME, H5_ITER_N, + object_visit_noop_callback, NULL, H5O_INFO_ALL, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name succeeded with an invalid location ID!\n"); + PART_ERROR(H5Ovisit_by_name_invalid_loc_id); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_invalid_loc_id); + + PART_BEGIN(H5Ovisit_by_name_invalid_obj_name) + { + TESTING_2("H5Ovisit_by_name with an invalid object name"); + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit_by_name3(group_id, NULL, H5_INDEX_NAME, H5_ITER_N, + object_visit_noop_callback, NULL, H5O_INFO_ALL, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name succeeded with a NULL object name!\n"); + PART_ERROR(H5Ovisit_by_name_invalid_obj_name); + } + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit_by_name3(group_id, "", H5_INDEX_NAME, H5_ITER_N, + object_visit_noop_callback, NULL, H5O_INFO_ALL, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name succeeded with an invalid object name of ''!\n"); + PART_ERROR(H5Ovisit_by_name_invalid_obj_name); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_invalid_obj_name); + + PART_BEGIN(H5Ovisit_by_name_invalid_index_type) + { + TESTING_2("H5Ovisit_by_name with an invalid index type"); + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit_by_name3(group_id, ".", H5_INDEX_UNKNOWN, H5_ITER_N, + object_visit_noop_callback, NULL, H5O_INFO_ALL, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name succeeded with invalid index type H5_INDEX_UNKNOWN!\n"); + PART_ERROR(H5Ovisit_by_name_invalid_index_type); + } + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit_by_name3(group_id, ".", H5_INDEX_N, H5_ITER_N, object_visit_noop_callback, + NULL, H5O_INFO_ALL, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name succeeded with invalid index type H5_INDEX_N!\n"); + PART_ERROR(H5Ovisit_by_name_invalid_index_type); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_invalid_index_type); + + PART_BEGIN(H5Ovisit_by_name_invalid_iter_order) + { + TESTING_2("H5Ovisit_by_name with an invalid iteration ordering"); + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit_by_name3(group_id, ".", H5_INDEX_NAME, H5_ITER_UNKNOWN, + object_visit_noop_callback, NULL, H5O_INFO_ALL, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name succeeded with invalid iteration ordering H5_ITER_UNKNOWN!\n"); + PART_ERROR(H5Ovisit_by_name_invalid_iter_order); + } + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit_by_name3(group_id, ".", H5_INDEX_NAME, H5_ITER_N, + object_visit_noop_callback, NULL, H5O_INFO_ALL, H5P_DEFAULT); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name succeeded with invalid iteration ordering H5_ITER_N!\n"); + PART_ERROR(H5Ovisit_by_name_invalid_iter_order); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_invalid_iter_order); + + PART_BEGIN(H5Ovisit_by_name_invalid_lapl) + { + TESTING_2("H5Ovisit_by_name with an invalid LAPL"); + + H5E_BEGIN_TRY + { + err_ret = H5Ovisit_by_name3(group_id, ".", H5_INDEX_NAME, H5_ITER_INC, + object_visit_noop_callback, NULL, H5O_INFO_ALL, H5I_INVALID_HID); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Ovisit_by_name succeeded with an invalid LAPL!\n"); + PART_ERROR(H5Ovisit_by_name_invalid_lapl); + } + + PASSED(); + } + PART_END(H5Ovisit_by_name_invalid_lapl); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Gclose(group_id2) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test for H5Oclose. + */ +static int +test_close_object(void) +{ + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t group_id2 = H5I_INVALID_HID; + hid_t dtype_id = H5I_INVALID_HID; + hid_t dset_id = H5I_INVALID_HID; + hid_t dset_dtype = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + + TESTING_MULTIPART("H5Oclose"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC) || !(vol_cap_flags_g & H5VL_CAP_FLAG_DATASET_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_ATTR_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_STORED_DATATYPES)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, dataset, attribute, or stored datatype " + "aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_CLOSE_TEST_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container subgroup '%s'\n", OBJECT_CLOSE_TEST_GROUP_NAME); + goto error; + } + + if ((fspace_id = generate_random_dataspace(OBJECT_CLOSE_TEST_SPACE_RANK, NULL, NULL, FALSE)) < 0) + TEST_ERROR; + + if ((dset_dtype = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) + TEST_ERROR; + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Oclose_group) + { + TESTING_2("H5Oclose on a group"); + + if ((group_id2 = H5Gcreate2(group_id, OBJECT_CLOSE_TEST_GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create group '%s'\n", OBJECT_CLOSE_TEST_GRP_NAME); + PART_ERROR(H5Oclose_group); + } + + H5E_BEGIN_TRY + { + H5Gclose(group_id2); + } + H5E_END_TRY; + + if ((group_id2 = H5Oopen(group_id, OBJECT_CLOSE_TEST_GRP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open group '%s' with H5Oopen\n", OBJECT_CLOSE_TEST_GRP_NAME); + PART_ERROR(H5Oclose_group); + } + + if (H5Oclose(group_id2) < 0) { + H5_FAILED(); + HDprintf(" couldn't close group '%s' with H5Oclose\n", OBJECT_CLOSE_TEST_GRP_NAME); + PART_ERROR(H5Oclose_group); + } + + PASSED(); + } + PART_END(H5Oclose_group); + + PART_BEGIN(H5Oclose_dset) + { + TESTING_2("H5Oclose on a dataset"); + + if ((dset_id = H5Dcreate2(group_id, OBJECT_CLOSE_TEST_DSET_NAME, dset_dtype, fspace_id, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create dataset '%s'\n", OBJECT_CLOSE_TEST_DSET_NAME); + PART_ERROR(H5Oclose_dset); + } + + H5E_BEGIN_TRY + { + H5Dclose(dset_id); + } + H5E_END_TRY; + + if ((dset_id = H5Oopen(group_id, OBJECT_CLOSE_TEST_DSET_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open dataset '%s' with H5Oopen\n", OBJECT_CLOSE_TEST_DSET_NAME); + PART_ERROR(H5Oclose_dset); + } + + if (H5Oclose(dset_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close dataset '%s' with H5Oclose\n", OBJECT_CLOSE_TEST_DSET_NAME); + PART_ERROR(H5Oclose_dset); + } + + PASSED(); + } + PART_END(H5Oclose_dset); + + PART_BEGIN(H5Oclose_dtype) + { + TESTING_2("H5Oclose on a committed datatype"); + + if ((dtype_id = generate_random_datatype(H5T_NO_CLASS, FALSE)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create datatype '%s'\n", OBJECT_CLOSE_TEST_TYPE_NAME); + PART_ERROR(H5Oclose_dtype); + } + + if (H5Tcommit2(group_id, OBJECT_CLOSE_TEST_TYPE_NAME, dtype_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT) < 0) { + H5_FAILED(); + HDprintf(" couldn't commit datatype '%s'\n", OBJECT_CLOSE_TEST_TYPE_NAME); + PART_ERROR(H5Oclose_dtype); + } + + H5E_BEGIN_TRY + { + H5Tclose(dtype_id); + } + H5E_END_TRY; + + if ((dtype_id = H5Oopen(group_id, OBJECT_CLOSE_TEST_TYPE_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open datatype '%s' with H5Oopen\n", OBJECT_CLOSE_TEST_TYPE_NAME); + PART_ERROR(H5Oclose_dtype); + } + + if (H5Oclose(dtype_id) < 0) { + H5_FAILED(); + HDprintf(" couldn't close datatype '%s' with H5Oclose\n", OBJECT_CLOSE_TEST_TYPE_NAME); + PART_ERROR(H5Oclose_dtype); + } + + PASSED(); + } + PART_END(H5Oclose_dtype); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Sclose(fspace_id) < 0) + TEST_ERROR; + if (H5Tclose(dset_dtype) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Sclose(fspace_id); + H5Tclose(dset_dtype); + H5Tclose(dtype_id); + H5Dclose(dset_id); + H5Gclose(group_id2); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test to check that H5Oclose fails when it + * is passed invalid parameters. + */ +static int +test_close_object_invalid_params(void) +{ + herr_t err_ret = -1; + hid_t file_id = H5I_INVALID_HID; + + TESTING("H5Oclose with an invalid object ID"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC)) { + SKIPPED(); + HDprintf(" API functions for basic file or object aren't supported with this connector\n"); + return 0; + } + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + H5E_BEGIN_TRY + { + err_ret = H5Oclose(H5I_INVALID_HID); + } + H5E_END_TRY; + + if (err_ret >= 0) { + H5_FAILED(); + HDprintf(" H5Oclose succeeded with an invalid object ID!\n"); + goto error; + } + + if (H5Fclose(file_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Fclose(file_id); + } + H5E_END_TRY; + + return 1; +} + +/* + * A test to check that various objects (file, dataspace, property list, + * and attribute) can't be closed with H5Oclose. + */ +static int +test_close_invalid_objects(void) +{ + hid_t file_id = H5I_INVALID_HID; + hid_t container_group = H5I_INVALID_HID, group_id = H5I_INVALID_HID; + hid_t attr_dtype = H5I_INVALID_HID; + hid_t attr_space_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + hid_t attr_id = H5I_INVALID_HID; + herr_t status; + + TESTING_MULTIPART("H5Oclose invalid objects"); + + /* Make sure the connector supports the API functions being tested */ + if (!(vol_cap_flags_g & (H5VL_CAP_FLAG_FILE_BASIC)) || !(vol_cap_flags_g & H5VL_CAP_FLAG_GROUP_BASIC) || + !(vol_cap_flags_g & H5VL_CAP_FLAG_OBJECT_BASIC)) { + SKIPPED(); + HDprintf(" API functions for basic file, group, object, dataset, attribute, or stored datatype " + "aren't supported with this connector\n"); + return 0; + } + + TESTING_2("test setup"); + + if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR; + + if ((file_id = H5Fopen(H5_api_test_filename, H5F_ACC_RDWR, fapl_id)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open file '%s'\n", H5_api_test_filename); + goto error; + } + + if ((container_group = H5Gopen2(file_id, OBJECT_TEST_GROUP_NAME, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't open container group '%s'\n", OBJECT_TEST_GROUP_NAME); + goto error; + } + + if ((group_id = H5Gcreate2(container_group, OBJECT_CLOSE_INVALID_TEST_GROUP_NAME, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT)) < 0) { + H5_FAILED(); + HDprintf(" couldn't create container sub-group '%s'\n", OBJECT_OPEN_TEST_GROUP_NAME); + goto error; + } + + if ((attr_space_id = generate_random_dataspace(OBJECT_CLOSE_INVALID_TEST_SPACE_RANK, NULL, NULL, TRUE)) < + 0) + TEST_ERROR; + + if ((attr_dtype = generate_random_datatype(H5T_NO_CLASS, TRUE)) < 0) + TEST_ERROR; + + if ((attr_id = H5Acreate2(group_id, OBJECT_CLOSE_INVALID_TEST_ATTRIBUTE_NAME, attr_dtype, attr_space_id, + H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + + PASSED(); + + BEGIN_MULTIPART + { + PART_BEGIN(H5Oclose_file) + { + TESTING_2("H5Oclose with an invalid object - file"); + + H5E_BEGIN_TRY + { + status = H5Oclose(file_id); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Oclose succeeded with an invalid object (file)!\n"); + PART_ERROR(H5Oclose_file); + } + + PASSED(); + } + PART_END(H5Oclose_file); + + PART_BEGIN(H5Oclose_plist) + { + TESTING_2("H5Oclose with an invalid object - property list"); + + H5E_BEGIN_TRY + { + status = H5Oclose(fapl_id); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Oclose succeeded with an invalid object (property list)!\n"); + PART_ERROR(H5Oclose_plist); + } + + PASSED(); + } + PART_END(H5Oclose_plist); + + PART_BEGIN(H5Oclose_dspace) + { + TESTING_2("H5Oclose with an invalid object - data space"); + + H5E_BEGIN_TRY + { + status = H5Oclose(attr_space_id); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Oclose succeeded with an invalid object (data space)!\n"); + PART_ERROR(H5Oclose_dspace); + } + + PASSED(); + } + PART_END(H5Oclose_dspace); + + PART_BEGIN(H5Oclose_attribute) + { + TESTING_2("H5Oclose with an invalid object - attribute"); + + H5E_BEGIN_TRY + { + status = H5Oclose(attr_id); + } + H5E_END_TRY; + + if (status >= 0) { + H5_FAILED(); + HDprintf(" H5Oclose succeeded with an invalid object (attribute)!\n"); + PART_ERROR(H5Oclose_attribute); + } + + PASSED(); + } + PART_END(H5Oclose_attribute); + } + END_MULTIPART; + + TESTING_2("test cleanup"); + + if (H5Tclose(attr_dtype) < 0) + TEST_ERROR; + if (H5Aclose(attr_id) < 0) + TEST_ERROR; + if (H5Sclose(attr_space_id) < 0) + TEST_ERROR; + if (H5Gclose(group_id) < 0) + TEST_ERROR; + if (H5Gclose(container_group) < 0) + TEST_ERROR; + if (H5Fclose(file_id) < 0) + TEST_ERROR; + if (H5Pclose(fapl_id) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Tclose(attr_dtype); + H5Sclose(attr_space_id); + H5Aclose(attr_id); + H5Gclose(group_id); + H5Gclose(container_group); + H5Fclose(file_id); + H5Pclose(fapl_id); + } + H5E_END_TRY; + + return 1; +} /* test_close_invalid_objects */ + +/* + * A test for H5Oflush. + */ +static int +test_flush_object(void) +{ + TESTING("H5Oflush"); + + SKIPPED(); + + return 0; +} + +/* + * A test to check that H5Oflush fails when + * it is passed invalid parameters. + */ +static int +test_flush_object_invalid_params(void) +{ + TESTING("H5Oflush with invalid parameters"); + + SKIPPED(); + + return 0; +} + +/* + * A test for H5Orefresh. + */ +static int +test_refresh_object(void) +{ + TESTING("H5Orefresh"); + + SKIPPED(); + + return 0; +} + +/* + * A test to check that H5Orefresh fails when + * it is passed invalid parameters. + */ +static int +test_refresh_object_invalid_params(void) +{ + TESTING("H5Orefresh with invalid parameters"); + + SKIPPED(); + + return 0; +} + +/* + * H5Ocopy test callback to check that an object's attributes got copied + * over successfully to the new object. + */ +static herr_t +object_copy_attribute_iter_callback(hid_t location_id, const char *attr_name, const H5A_info_t *ainfo, + void *op_data) +{ + size_t *counter = (size_t *)op_data; + htri_t types_equal; + char expected_name[256]; + hid_t attr_id = H5I_INVALID_HID; + hid_t attr_type = H5I_INVALID_HID; + herr_t ret_value = H5_ITER_CONT; + + UNUSED(ainfo); + UNUSED(op_data); + + snprintf(expected_name, 256, "attr%d", (int)(*counter)); + + if (HDstrncmp(attr_name, expected_name, 256)) { + HDprintf(" attribute name '%s' did not match expected name '%s'\n", attr_name, expected_name); + ret_value = H5_ITER_ERROR; + goto done; + } + + if ((attr_id = H5Aopen(location_id, attr_name, H5P_DEFAULT)) < 0) { + HDprintf(" failed to open attribute '%s'\n", attr_name); + ret_value = H5_ITER_ERROR; + goto done; + } + + if ((attr_type = H5Aget_type(attr_id)) < 0) { + HDprintf(" failed to retrieve attribute's datatype\n"); + ret_value = H5_ITER_ERROR; + goto done; + } + + if ((types_equal = H5Tequal(attr_type, H5T_NATIVE_INT)) < 0) { + HDprintf(" failed to determine if attribute's datatype matched what is expected\n"); + ret_value = H5_ITER_ERROR; + goto done; + } + + if (!types_equal) { + HDprintf(" attribute datatype did not match expected H5T_NATIVE_INT\n"); + ret_value = H5_ITER_ERROR; + goto done; + } + +done: + if (attr_type >= 0) + H5Tclose(attr_type); + if (attr_id >= 0) + H5Aclose(attr_id); + + (*counter)++; + + return ret_value; +} + +/* + * H5Ocopy callback to check that a copied group's soft links + * have not been expanded when the default copy options are + * used. + */ +static herr_t +object_copy_soft_link_non_expand_callback(hid_t group, const char *name, const H5L_info2_t *info, + void *op_data) +{ + size_t *counter = (size_t *)op_data; + void *link_val_buf = NULL; + char expected_link_val[OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE]; + herr_t ret_value = H5_ITER_CONT; + + /* Make sure the link type is soft */ + if (H5L_TYPE_SOFT != info->type) { + HDprintf(" link type was not H5L_TYPE_SOFT; link must have been expanded!\n"); + ret_value = H5_ITER_ERROR; + goto done; + } + + if (NULL == (link_val_buf = calloc(1, info->u.val_size))) { + HDprintf(" failed to allocate buffer for link value\n"); + ret_value = H5_ITER_ERROR; + goto done; + } + + /* Retrieve the link's value */ + if (H5Lget_val(group, name, link_val_buf, info->u.val_size, H5P_DEFAULT) < 0) { + HDprintf(" failed to retrieve value of link '%s'\n", name); + ret_value = H5_ITER_ERROR; + goto done; + } + + /* Make sure link's value matches what is expected */ + snprintf(expected_link_val, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE, + "/" OBJECT_TEST_GROUP_NAME "/" OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_SUBGROUP_NAME "/grp%d", + (int)(*counter)); + + if (strncmp(link_val_buf, expected_link_val, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE)) { + HDprintf(" value '%s' for link '%s' did not match expected value '%s'\n", (char *)link_val_buf, + name, expected_link_val); + ret_value = H5_ITER_ERROR; + goto done; + } + +done: + if (link_val_buf) + free(link_val_buf); + + (*counter)++; + + return ret_value; +} + +/* + * H5Ocopy callback to check that a copied group's soft links + * have been expanded when the H5O_COPY_EXPAND_SOFT_LINK_FLAG + * flag is specified. + */ +static herr_t +object_copy_soft_link_expand_callback(hid_t group, const char *name, const H5L_info2_t *info, void *op_data) +{ + size_t *counter = (size_t *)op_data; + char expected_link_name[OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE]; + herr_t ret_value = H5_ITER_CONT; + + UNUSED(group); + + /* Make sure the link type is hard */ + if (H5L_TYPE_HARD != info->type) { + HDprintf(" link type was not H5L_TYPE_HARD; link must not have been expanded!\n"); + ret_value = H5_ITER_ERROR; + goto done; + } + + /* Ensure that the link's name still follows the 'link1', 'link2', etc. pattern */ + snprintf(expected_link_name, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE, "link%d", (int)(*counter)); + + if (strncmp(name, expected_link_name, OBJECT_COPY_GROUP_WITH_SOFT_LINKS_TEST_BUF_SIZE)) { + HDprintf(" link name '%s' did not match expected name '%s'\n", name, expected_link_name); + ret_value = H5_ITER_ERROR; + goto done; + } + +done: + (*counter)++; + + return ret_value; +} + +/* + * H5Ovisit callback to simply iterate recursively through all of the objects in a + * group and check to make sure their names match what is expected. + */ +static herr_t +object_visit_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, void *op_data) +{ + size_t *i = (size_t *)op_data; + size_t counter_val = *((size_t *)op_data); + herr_t ret_val = 0; + + UNUSED(o_id); + + if (!HDstrncmp(name, ".", strlen(".") + 1) && + (counter_val == 0 || counter_val == 4 || counter_val == 8 || counter_val == 12)) { + if (H5O_TYPE_GROUP == object_info->type) + goto done; + else + HDprintf(" type for object '%s' was not H5O_TYPE_GROUP\n", name); + } + else if (!HDstrncmp(name, OBJECT_VISIT_TEST_GROUP_NAME, strlen(OBJECT_VISIT_TEST_GROUP_NAME) + 1) && + (counter_val == 2 || counter_val == 6 || counter_val == 9 || counter_val == 15)) { + if (H5O_TYPE_GROUP == object_info->type) + goto done; + else + HDprintf(" type for object '%s' was not H5O_TYPE_GROUP\n", name); + } + else if (!HDstrncmp(name, OBJECT_VISIT_TEST_DSET_NAME, strlen(OBJECT_VISIT_TEST_DSET_NAME) + 1) && + (counter_val == 1 || counter_val == 7 || counter_val == 10 || counter_val == 14)) { + if (H5O_TYPE_DATASET == object_info->type) + goto done; + else + HDprintf(" type for object '%s' was not H5O_TYPE_DATASET\n", name); + } + else if (!HDstrncmp(name, OBJECT_VISIT_TEST_TYPE_NAME, strlen(OBJECT_VISIT_TEST_TYPE_NAME) + 1) && + (counter_val == 3 || counter_val == 5 || counter_val == 11 || counter_val == 13)) { + if (H5O_TYPE_NAMED_DATATYPE == object_info->type) + goto done; + else + HDprintf(" type for object '%s' was not H5O_TYPE_NAMED_DATATYPE\n", name); + } + else + HDprintf(" object '%s' didn't match known names or came in an incorrect order\n", name); + + ret_val = -1; + +done: + (*i)++; + + return ret_val; +} + +/* + * H5Ovisit callback for visiting a singular dataset. + */ +static herr_t +object_visit_dset_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, void *op_data) +{ + herr_t ret_val = 0; + + UNUSED(o_id); + UNUSED(op_data); + + if (HDstrncmp(name, ".", strlen(".") + 1)) { + HDprintf(" object '%s' didn't match known names\n", name); + return -1; + } + + if (H5O_TYPE_DATASET != object_info->type) { + HDprintf(" object type was not H5O_TYPE_DATASET\n"); + return -1; + } + + return ret_val; +} + +/* + * H5Ovisit callback for visiting a singular committed datatype. + */ +static herr_t +object_visit_dtype_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, void *op_data) +{ + herr_t ret_val = 0; + + UNUSED(o_id); + UNUSED(op_data); + + if (HDstrncmp(name, ".", strlen(".") + 1)) { + HDprintf(" object '%s' didn't match known names\n", name); + return -1; + } + + if (H5O_TYPE_NAMED_DATATYPE != object_info->type) { + HDprintf(" object type was not H5O_TYPE_NAMED_DATATYPE\n"); + return -1; + } + + return ret_val; +} + +/* + * H5Ovisit callback for testing ignoring of + * soft links during object visiting. + */ +static herr_t +object_visit_soft_link_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, void *op_data) +{ + size_t *i = (size_t *)op_data; + size_t counter_val = *((size_t *)op_data); + herr_t ret_val = 0; + + UNUSED(o_id); + + if (!HDstrncmp(name, ".", strlen(".") + 1) && (counter_val <= 5)) { + if (H5O_TYPE_GROUP == object_info->type) + goto done; + else + HDprintf(" type for object '%s' was not H5O_TYPE_GROUP\n", name); + } + else + HDprintf(" object '%s' didn't match known names or came in an incorrect order\n", name); + + ret_val = -1; + +done: + (*i)++; + + return ret_val; +} + +/* + * H5Ovisit callback to simply iterate through all of the objects in a given + * group. + */ +static herr_t +object_visit_noop_callback(hid_t o_id, const char *name, const H5O_info2_t *object_info, void *op_data) +{ + UNUSED(o_id); + UNUSED(name); + UNUSED(object_info); + UNUSED(op_data); + + return 0; +} + +/* + * Cleanup temporary test files + */ +static void +cleanup_files(void) +{ + H5Fdelete(OBJECT_COPY_BETWEEN_FILES_TEST_FILE_NAME, H5P_DEFAULT); +} + +int +H5_api_object_test(void) +{ + size_t i; + int nerrors; + + HDprintf("**********************************************\n"); + HDprintf("* *\n"); + HDprintf("* API Object Tests *\n"); + HDprintf("* *\n"); + HDprintf("**********************************************\n\n"); + + for (i = 0, nerrors = 0; i < ARRAY_LENGTH(object_tests); i++) { + nerrors += (*object_tests[i])() ? 1 : 0; + } + + HDprintf("\n"); + + HDprintf("Cleaning up testing files\n"); + cleanup_files(); + + return nerrors; +} |