diff options
Diffstat (limited to 'c++/test')
-rw-r--r-- | c++/test/CMakeLists.txt | 3 | ||||
-rw-r--r-- | c++/test/CMakeTests.cmake | 2 | ||||
-rw-r--r-- | c++/test/Makefile.in | 78 | ||||
-rw-r--r-- | c++/test/dsets.cpp | 19 | ||||
-rw-r--r-- | c++/test/tattr.cpp | 12 | ||||
-rw-r--r-- | c++/test/tfile.cpp | 27 | ||||
-rw-r--r-- | c++/test/tlinks.cpp | 380 | ||||
-rw-r--r-- | c++/test/tobject.cpp | 51 |
8 files changed, 511 insertions, 61 deletions
diff --git a/c++/test/CMakeLists.txt b/c++/test/CMakeLists.txt index c6f76c9..665a49f 100644 --- a/c++/test/CMakeLists.txt +++ b/c++/test/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.2.2) +cmake_minimum_required (VERSION 3.10) PROJECT (HDF5_CPP_TEST) # -------------------------------------------------------------------- # Notes: When creating unit test executables they should be prefixed @@ -36,7 +36,6 @@ set (srcdir ${CMAKE_CURRENT_SOURCE_DIR}) configure_file (${HDF5_CPP_TEST_SOURCE_DIR}/H5srcdir_str.h.in H5srcdir_str.h @ONLY) add_executable (cpp_testhdf5 ${CPP_TEST_SRCS} ) -TARGET_NAMING (cpp_testhdf5 STATIC) TARGET_C_PROPERTIES (cpp_testhdf5 STATIC " " " ") target_link_libraries (cpp_testhdf5 ${HDF5_CPP_LIB_TARGET} diff --git a/c++/test/CMakeTests.cmake b/c++/test/CMakeTests.cmake index 4f5ba94..11463a0 100644 --- a/c++/test/CMakeTests.cmake +++ b/c++/test/CMakeTests.cmake @@ -8,7 +8,7 @@ # 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. - +# HDFTEST_COPY_FILE("${HDF5_CPP_TEST_SOURCE_DIR}/th5s.h5" "${PROJECT_BINARY_DIR}/th5s.h5" "cpp_testhdf5_files") add_custom_target(cpp_testhdf5_files ALL COMMENT "Copying files needed by cpp_testhdf5 tests" DEPENDS ${cpp_testhdf5_files_list}) diff --git a/c++/test/Makefile.in b/c++/test/Makefile.in index 841a797..4ea9261 100644 --- a/c++/test/Makefile.in +++ b/c++/test/Makefile.in @@ -701,6 +701,7 @@ chk_TESTS = $(check_PROGRAMS) $(check_SCRIPTS) $(EXTRA_TEST) TEST_EXTENSIONS = .sh SH_LOG_COMPILER = $(SHELL) AM_SH_LOG_FLAGS = +REALTIMEOUTPUT = $(realtimeOutput) TEST_PROG_CHKEXE = $(TEST_PROG:=.chkexe_) TEST_PROG_PARA_CHKEXE = $(TEST_PROG_PARA:=.chkexe_) TEST_SCRIPT_CHKSH = $(TEST_SCRIPT:=.chkexe_) @@ -1185,7 +1186,6 @@ mostlyclean-local: @if test -d ii_files; then \ $(RM) -rf ii_files; \ fi - # lib/progs/tests targets recurse into subdirectories. build-* targets # build files in this directory. build-lib: $(LIB) @@ -1273,28 +1273,62 @@ $(TEST_PROG_CHKEXE) $(TEST_PROG_PARA_CHKEXE) dummy.chkexe_: if $(top_srcdir)/bin/newer $(@:.chkexe_=.chkexe) $${tname}; then \ echo "No need to test $${tname} again."; \ else \ - echo "============================" > $${log}; \ - if test "X$(FORTRAN_API)" = "Xyes"; then \ - echo "Fortran API: Testing $(HDF5_DRIVER) $${tname} $(TEST_FLAGS)"; \ - echo "Fortran API: $(HDF5_DRIVER) $${tname} $(TEST_FLAGS) Test Log" >> $${log}; \ - elif test "X$(CXX_API)" = "Xyes"; then \ - echo "C++ API: Testing $(HDF5_DRIVER) $${tname} $(TEST_FLAGS)"; \ - echo "C++ API: $(HDF5_DRIVER) $${tname} $(TEST_FLAGS) Test Log" >> $${log};\ - else \ - echo "Testing $(HDF5_DRIVER) $${tname} $(TEST_FLAGS)"; \ - echo "$(HDF5_DRIVER) $${tname} $(TEST_FLAGS) Test Log" >> $${log}; \ - fi; \ - echo "============================" >> $${log}; \ - srcdir="$(srcdir)" \ - $(TIME) $(RUNEXEC) ./$${tname} $(TEST_FLAGS) >> $${log} 2>&1 \ - && touch $(@:.chkexe_=.chkexe) || \ - (test $$HDF5_Make_Ignore && echo "*** Error ignored") || \ - (cat $${log} && false) || exit 1; \ + if test -n "$(REALTIMEOUTPUT)"; then \ + echo "============================" | tee $${log}; \ + else \ + echo "============================" > $${log}; \ + fi; \ + if test "X$(FORTRAN_API)" = "Xyes"; then \ + echo "Fortran API: Testing $(HDF5_DRIVER) $${tname} $(TEST_FLAGS)"; \ + if test -n "$(REALTIMEOUTPUT)"; then \ + echo "Fortran API: $(HDF5_DRIVER) $${tname} $(TEST_FLAGS) Test Log" | tee -a $${log}; \ + else \ + echo "Fortran API: $(HDF5_DRIVER) $${tname} $(TEST_FLAGS) Test Log" >> $${log}; \ + fi; \ + elif test "X$(CXX_API)" = "Xyes"; then \ + echo "C++ API: Testing $(HDF5_DRIVER) $${tname} $(TEST_FLAGS)"; \ + if test -n "$(REALTIMEOUTPUT)"; then \ + echo "C++ API: $(HDF5_DRIVER) $${tname} $(TEST_FLAGS) Test Log" | tee -a $${log};\ + else \ + echo "C++ API: $(HDF5_DRIVER) $${tname} $(TEST_FLAGS) Test Log" >> $${log};\ + fi; \ + else \ + echo "Testing $(HDF5_DRIVER) $${tname} $(TEST_FLAGS)"; \ + if test -n "$(REALTIMEOUTPUT)"; then \ + echo "$(HDF5_DRIVER) $${tname} $(TEST_FLAGS) Test Log" | tee -a $${log}; \ + else \ + echo "$(HDF5_DRIVER) $${tname} $(TEST_FLAGS) Test Log" >> $${log}; \ + fi; \ + fi; \ + if test -n "$(REALTIMEOUTPUT)"; then \ + echo "============================" | tee -a $${log}; \ + else \ + echo "============================" >> $${log}; \ + fi; \ + if test -n "$(REALTIMEOUTPUT)"; then \ + srcdir="$(srcdir)" \ + $(TIME) $(RUNEXEC) ./$${tname} $(TEST_FLAGS) | tee -a $${log} 2>&1 \ + && touch $(@:.chkexe_=.chkexe) || \ + (test $$HDF5_Make_Ignore && echo "*** Error ignored") || \ + (cat $${log} && false) || exit 1; \ + else \ + srcdir="$(srcdir)" \ + $(TIME) $(RUNEXEC) ./$${tname} $(TEST_FLAGS) >> $${log} 2>&1 \ + && touch $(@:.chkexe_=.chkexe) || \ + (test $$HDF5_Make_Ignore && echo "*** Error ignored") || \ + (cat $${log} && false) || exit 1; \ + fi; \ echo "" >> $${log}; \ - echo "Finished testing $${tname} $(TEST_FLAGS)" >> $${log}; \ - echo "============================" >> $${log}; \ - echo "Finished testing $${tname} $(TEST_FLAGS)"; \ - cat $${log}; \ + if test -n "$(REALTIMEOUTPUT)"; then \ + echo "Finished testing $${tname} $(TEST_FLAGS)" | tee -a $${log}; \ + echo "============================" | tee -a $${log}; \ + else \ + echo "Finished testing $${tname} $(TEST_FLAGS)" >> $${log}; \ + echo "============================" >> $${log}; \ + fi; \ + if test -z "$(REALTIMEOUTPUT)"; then \ + cat $${log}; \ + fi; \ fi; \ fi diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp index 8d2618b..0a187ef 100644 --- a/c++/test/dsets.cpp +++ b/c++/test/dsets.cpp @@ -68,6 +68,8 @@ static size_t filter_bogus(unsigned int flags, size_t cd_nelmts, * *------------------------------------------------------------------------- */ +const H5std_string DSET_COMMENT ("This is a dataset"); +const H5std_string NON_EXISTING_DSET ("does_not_exist"); static herr_t test_create( H5File& file) { @@ -83,13 +85,12 @@ test_create( H5File& file) DataSpace space (2, dims, NULL); // Create a dataset using the default dataset creation properties. - // We're not sure what they are, so we won't check. dataset = new DataSet (file.createDataSet (DSET_DEFAULT_NAME, PredType::NATIVE_DOUBLE, space)); // Add a comment to the dataset - file.setComment (DSET_DEFAULT_NAME, "This is a dataset"); + file.setComment (DSET_DEFAULT_NAME, DSET_COMMENT); // Close the dataset delete dataset; @@ -120,7 +121,7 @@ test_create( H5File& file) // Get and verify the comment from this dataset, using // H5std_string getComment(const H5std_string& name, <buf_size=0, by default>) H5std_string comment = file.getComment(DSET_DEFAULT_NAME); - verify_val(comment, "This is a dataset", "DataSet::getComment", __LINE__, __FILE__); + verify_val(comment, DSET_COMMENT, "DataSet::getComment", __LINE__, __FILE__); // Close the dataset when accessing is completed delete dataset; @@ -132,24 +133,24 @@ test_create( H5File& file) // exception is not thrown for this action by openDataSet, then // display failure information and throw an exception. try { - dataset = new DataSet (file.openDataSet( "does_not_exist" )); + dataset = new DataSet (file.openDataSet(NON_EXISTING_DSET)); // continuation here, that means no exception has been thrown throw InvalidActionException("H5File::openDataSet", "Attempted to open a non-existent dataset"); } - catch (FileIException& E ) // catching creating non-existent dataset + catch (FileIException& E ) // catching opening non-existent dataset {} // do nothing, exception expected - // Create a new dataset that uses chunked storage instead of the default - // layout. + // Create a new dataset that uses chunked storage instead of the + // default layout. DSetCreatPropList create_parms; - hsize_t csize[2]; + hsize_t csize[2]; csize[0] = 5; csize[1] = 100; create_parms.setChunk( 2, csize ); dataset = new DataSet (file.createDataSet - (DSET_CHUNKED_NAME, PredType::NATIVE_DOUBLE, space, create_parms)); + (DSET_CHUNKED_NAME, PredType::NATIVE_DOUBLE, space, create_parms)); // Note: this one has no error message in C when failure occurs? // clean up and return with success diff --git a/c++/test/tattr.cpp b/c++/test/tattr.cpp index d97d478..25b5ff8 100644 --- a/c++/test/tattr.cpp +++ b/c++/test/tattr.cpp @@ -653,7 +653,8 @@ static void test_attr_compound_read() verify_val((long)dims[1], (long)ATTR4_DIM2, "DataSpace::getSimpleExtentDims",__LINE__, __FILE__); // Get the class of the datatype that is used by attr - H5T_class_t type_class = attr.getTypeClass(); + H5T_class_t type_class; + type_class = attr.getTypeClass(); // Verify that the type is of compound datatype verify_val(type_class, H5T_COMPOUND, "Attribute::getTypeClass", __LINE__, __FILE__); @@ -1289,6 +1290,7 @@ static void test_attr_dtype_shared() // Retrieve and verify information about the type H5O_info_t oinfo; + dtype.getObjectInfo(TYPE1_NAME, &oinfo); fid1.getObjectInfo(TYPE1_NAME, &oinfo); if (oinfo.type != H5O_TYPE_NAMED_DATATYPE) TestErrPrintf("Line %d: object type wrong!\n", __LINE__); @@ -1402,6 +1404,14 @@ static void test_attr_dtype_shared() PASSED(); } // end try block + catch (DataTypeIException& E) + { + issue_fail_msg("test_attr_dtype_shared()", __LINE__, __FILE__, E.getCDetailMsg()); + } + catch (FileIException& E) + { + issue_fail_msg("test_attr_dtype_shared()", __LINE__, __FILE__, E.getCDetailMsg()); + } catch (Exception& E) { issue_fail_msg("test_attr_dtype_shared()", __LINE__, __FILE__, E.getCDetailMsg()); diff --git a/c++/test/tfile.cpp b/c++/test/tfile.cpp index 059c548..d5278d5 100644 --- a/c++/test/tfile.cpp +++ b/c++/test/tfile.cpp @@ -336,9 +336,12 @@ static void test_file_open() // Truncating should succeed now. H5File file3(FILE2, H5F_ACC_TRUNC); - // Opening another file to file3 object, FILE2 should be closed, so - // the next attempt to truncate FILE2 should succeed. + // Opening another file to file3 object. file3.openFile(FILE1, H5F_ACC_RDONLY); + + // In the previous statement, openFile closes FILE2 first before + // opening FILE1, so when H5File constructs file4 with an + // attempt to truncate FILE2, it should succeed. H5File file4(FILE2, H5F_ACC_TRUNC); PASSED(); @@ -493,6 +496,12 @@ static void test_file_name() // Get and verify file name via a committed datatype. comp_type.getFileName(); verify_val(file_name, FILE4, "CompType::getFileName", __LINE__, __FILE__); + + // Get the file's version information. + H5F_info_t finfo; + file4.getFileInfo(finfo); + verify_val(finfo.sohm.hdr_size, 0, "H5File::getFileInfo", __LINE__, __FILE__); + PASSED(); } // end of try block @@ -503,6 +512,15 @@ static void test_file_name() } // test_file_name() +/*------------------------------------------------------------------------- + * + * Function: test_file_attribute + * + * Purpose Test file attributes + * + * Return None + *------------------------------------------------------------------------- + */ const int RANK1 = 1; const int ATTR1_DIM1 = 3; const H5std_string FILE5("tfattrs.h5"); @@ -619,6 +637,11 @@ static void test_file_attribute() PASSED(); } // end of try block + // Catch creating existing attribute + catch (AttributeIException& E) + {} // do nothing, exception expected + + // Catch all other exceptions catch (Exception& E) { issue_fail_msg("test_file_attribute()", __LINE__, __FILE__, E.getCDetailMsg()); diff --git a/c++/test/tlinks.cpp b/c++/test/tlinks.cpp index b38ed39..ae0d53a 100644 --- a/c++/test/tlinks.cpp +++ b/c++/test/tlinks.cpp @@ -326,11 +326,9 @@ static const char *FILENAME[] = { * Purpose: Test building a file with assorted links. * * Return: Success: 0 - * * Failure: -1 * - * Programmer: Binh-Minh Ribler - * October 16, 2009 + * October, 2009 * *------------------------------------------------------------------------- */ @@ -369,7 +367,6 @@ static void test_basic_links(hid_t fapl_id, hbool_t new_format) // Because these are not implemented in the C++ API yet, they are // used so CommonFG::getLinkval can be tested. - // Create a hard link if(H5Lcreate_hard( file_id, "dset1", H5L_SAME_LOC, "grp1/hard1", H5P_DEFAULT, H5P_DEFAULT) < 0) @@ -433,7 +430,367 @@ static void test_basic_links(hid_t fapl_id, hbool_t new_format) { issue_fail_msg("test_basic_links()", __LINE__, __FILE__, E.getCDetailMsg()); } -} +} // test_basic_links + +/*------------------------------------------------------------------------- + * Function: test_lcpl + * + * Purpose: Tests link creation property lists, specifically, the + * character encoding property. + * + * Return: Success: 0 + * Failure: number of errors + * May 2018 + *------------------------------------------------------------------------- + */ +const H5std_string GROUP1NAME("First_group"); +const H5std_string GROUP2NAME("Second_group"); +static void +test_lcpl(hid_t fapl_id, hbool_t new_format) +{ + H5L_info_t linfo; + char filename[1024]; + hsize_t dims[2]; + + if(new_format) + SUBTEST("Link creation property lists (w/new group format)") + else + SUBTEST("Link creation property lists") + + try + { + FileAccPropList fapl(fapl_id); + + // Create a new file. + h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); + H5File file(filename, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl); + + // Create and link a group with the default LCPL. + Group grp_1(file.createGroup(GROUP1NAME)); + grp_1.close(); + + // Check that its character encoding is the default. + linfo = file.getLinkInfo(GROUP1NAME); + if(linfo.cset != H5T_CSET_ASCII) + throw InvalidActionException("H5Lget_info", "Character encoding is not default"); + + // Create and commit a datatype with the default LCPL. + IntType dtype(PredType::NATIVE_INT); + dtype.commit(file, "/type"); + dtype.close(); + + // Check that its character encoding is the default. + linfo = file.getLinkInfo("/type"); + verify_val(linfo.cset, H5T_CSET_ASCII, "Character encoding is not default", __LINE__, __FILE__); + + // Create a simple dataspace. + dims[0] = H5L_DIM1; + dims[1] = H5L_DIM2; + DataSpace dspace(2 ,dims); + + // Create a dataset using the default LCPL. + DataSet dset(file.createDataSet("/dataset", PredType::NATIVE_INT, dspace)); + dset.close(); + + // Check that its character encoding is the default. + linfo = file.getLinkInfo("/dataset"); + verify_val(linfo.cset, H5T_CSET_ASCII, "Character encoding is not default", __LINE__, __FILE__); + + // Create a link creation property list with the UTF-8 character encoding. + LinkCreatPropList lcpl; + lcpl.setCharEncoding(H5T_CSET_UTF8); + + // Create and link a group with the new LCPL. + Group grp_2(file.createGroup(GROUP2NAME, 0, lcpl)); + grp_2.close(); + + // Check that its character encoding is UTF-8. + linfo = file.getLinkInfo(GROUP2NAME); + verify_val(linfo.cset, H5T_CSET_UTF8, "Character encoding is not UTF-8", __LINE__, __FILE__); + + PASSED(); + } // end of try block + catch (Exception& E) + { + issue_fail_msg("test_lcpl()", __LINE__, __FILE__, E.getCDetailMsg()); + } +} // end test_lcpl() + +/*------------------------------------------------------------------------- + * Function: test_move + * + * Purpose: Tests wrappers of H5Lmove() + * + * Return: Success: 0 + * Failure: number of errors + * May 2018 + *------------------------------------------------------------------------- + */ +static void +test_move(hid_t fapl_id, hbool_t new_format) +{ + char filename[1024]; + + if(new_format) + SUBTEST("Group::moveLink (w/new group format)") + else + SUBTEST("Group::moveLink") + + try + { + FileAccPropList fapl(fapl_id); + + // Create two new files + h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); + H5File file_a(filename, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl); + h5_fixname(FILENAME[1], fapl_id, filename, sizeof filename); + H5File file_b(filename, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl); + + // Create groups in first file + Group grp_1(file_a.createGroup(GROUP1NAME)); + Group grp_2(file_a.createGroup(GROUP2NAME)); + Group grp_move(grp_1.createGroup("group_move")); + + // Create hard and soft links + grp_1.link(H5L_TYPE_HARD, "group_move", "hard"); + grp_2.link(H5L_TYPE_SOFT, "/First_group/group_copy", "soft"); + + // Move a group across files, should fail + try { + grp_1.moveLink("group_move", file_b, "group_new_name"); + + // Should throw an exception but didn't + H5_FAILED(); + cerr << " Group group_move should not be moved across files" << endl; + } catch (Exception& E) { + // expected + } + + // Move a soft link across files, should succeed + grp_2.moveLink("soft", file_b, "soft_new_name"); + if(file_b.nameExists("soft_new_name") != TRUE) + throw InvalidActionException("H5File::nameExists", "grp1/soft doesn't exist"); + + // Move a group across groups in the same file while renaming it + grp_1.moveLink("group_move", grp_2, "group_new_name"); + + // Open the group just moved to the new location. */ + Group moved_grp = grp_2.openGroup("group_new_name"); + moved_grp.close(); + + // Verify that the group is no longer in the original location + try { + moved_grp = grp_1.openGroup("group_move"); + + // Should throw an exception but didn't + H5_FAILED(); + cerr << " Group group_move should not be in original location" << endl; + } catch (Exception& E) { + // expected + } + + // Use H5Lmove to rename a group without moving it + H5std_string new_name("group_new_name"); + H5std_string newer_name("group_newer_name"); + grp_2.moveLink(new_name, newer_name); + + // Open the group + moved_grp = grp_2.openGroup("group_newer_name"); + moved_grp.close(); + + // Use H5Lmove to move a group without renaming it + grp_2.moveLink(newer_name, grp_1, newer_name); + + // Open the group + moved_grp = grp_1.openGroup("group_newer_name"); + moved_grp.close(); + + // Move the group while giving long paths + file_a.moveLink("/First_group/group_newer_name", grp_2, "/Second_group/group_newest_name"); + + // Open the group just moved to the new location + moved_grp = grp_2.openGroup("group_newest_name"); + moved_grp.close(); + + // Verify that the groups are not in previous locations + try { + moved_grp = grp_1.openGroup("group_newer_name"); + moved_grp.close(); + + H5_FAILED(); // Should throw an exception but didn't + cerr << " Group group_newer_name should not be in GROUP1NAME" << endl; + } catch (Exception& E) { + // expected + } + try { + moved_grp = grp_2.openGroup("group_newer_name"); + moved_grp.close(); + + H5_FAILED(); // Should throw an exception but didn't + cerr << " Group group_newer_name should not be in GROUP2NAME" << endl; + } catch (Exception& E) { + // expected + } + try { + moved_grp = grp_2.openGroup("group_new_name"); + moved_grp.close(); + + H5_FAILED(); // Should throw an exception but didn't + cerr << " Group group_new_name should not be in GROUP2NAME" << endl; + } catch (Exception& E) { + // expected + } + try { + moved_grp = grp_1.openGroup("group_copy"); + moved_grp.close(); + + H5_FAILED(); // Should throw an exception but didn't + cerr << " Group group_copy should not be in GROUP1NAME" << endl; + } catch (Exception& E) { + // expected + } + PASSED(); + } // end of try block + catch (Exception& E) + { + issue_fail_msg("test_move()", __LINE__, __FILE__, E.getCDetailMsg()); + } +} // test_move + +/*------------------------------------------------------------------------- + * Function: test_copy + * + * Purpose: Tests wrappers of H5Lcopy() and H5Ldelete() + * + * Return: Success: 0 + * Failure: number of errors + * May 2018 + *------------------------------------------------------------------------- + */ +static void test_copy(hid_t fapl_id, hbool_t new_format) +{ + char filename[1024]; + + if(new_format) + SUBTEST("Group::copyLink (w/new group format)") + else + SUBTEST("Group::copyLink") + + try + { + // Create two new files + h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); + H5File file_a(filename, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl_id); + h5_fixname(FILENAME[1], fapl_id, filename, sizeof filename); + H5File file_b(filename, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, fapl_id); + + // Create groups in first file + Group grp_1(file_a.createGroup(GROUP1NAME)); + Group grp_2(file_a.createGroup(GROUP2NAME)); + Group grp_move(grp_1.createGroup("group_copy")); + + // Create hard and soft links + grp_1.link("group_copy", H5L_SAME_LOC, "hard"); + grp_2.link("/First_group/group_copy", "soft"); + + // Copy a group across files, should fail + try { + grp_1.copyLink("group_copy", file_b, "group_new_name"); + } catch (Exception& E) { + // expected + } + + // Copy a soft link across files, should succeed + grp_2.copyLink("soft", file_b, "soft_new_name"); + if (file_b.nameExists("soft_new_name") != TRUE) + throw InvalidActionException("H5File::nameExists", "soft_new_name doesn't exist"); + + // Move a group across groups in the same file while renaming it + H5std_string copy_name("group_copy"); + H5std_string new_name("group_new_name"); + grp_1.copyLink(copy_name, grp_2, new_name); + + // Open the group just moved to the new location. + Group moved_grp(grp_2.openGroup("group_new_name")); + moved_grp.close(); + + // Verify that the group is also in the original location + moved_grp = grp_1.openGroup("group_copy"); + moved_grp.close(); + + // Create a group in the same location with a different name + grp_2.copyLink("group_new_name", "group_newer_name"); + + // Open the group + moved_grp = grp_2.openGroup("group_newer_name"); + moved_grp.close(); + + // Verify that the group is also in the original location + moved_grp = grp_2.openGroup("group_new_name"); + moved_grp.close(); + + // Use H5Lcopy to copy to a different location with the same name + grp_2.copyLink("group_newer_name", grp_1, "group_newer_name"); + + // Open the group + moved_grp = grp_1.openGroup("group_newer_name"); + moved_grp.close(); + + // Verify that the group is still in the previous location + moved_grp = grp_2.openGroup("group_new_name"); + moved_grp.close(); + + // Copy the group while giving long paths + file_a.copyLink("/First_group/group_newer_name", grp_2, "/Second_group/group_newest_name"); + + // Open the newest group just moved to the new location + moved_grp = grp_2.openGroup("group_newest_name"); + moved_grp.close(); + + // Verify that the group is still in all previous original locations + moved_grp = grp_1.openGroup("group_newer_name"); + moved_grp.close(); + + moved_grp = grp_2.openGroup("group_newer_name"); + moved_grp.close(); + + moved_grp = grp_2.openGroup("group_new_name"); + moved_grp.close(); + + moved_grp = grp_1.openGroup("group_copy"); + moved_grp.close(); + + // Delete "group_newer_name" from group 2, then try to open it. + grp_2.unlink("group_newer_name"); + try { + moved_grp = grp_2.openGroup("group_newer_name"); + moved_grp.close(); + + H5_FAILED(); // Should throw an exception but didn't + cerr << " Group group_newer_name should not be in GROUP2NAME" << endl; + } catch (Exception& E) { + // expected + } + + // Delete "group_copy" from group 1, then try to open it. + grp_1.unlink("group_copy"); + try { + moved_grp = grp_1.openGroup("group_copy"); + moved_grp.close(); + + H5_FAILED(); // Should throw an exception but didn't + cerr << " Group group_copy should not be in GROUP1NAME" << endl; + } catch (Exception& E) { + // expected + } + + PASSED(); + } // end of try block + catch (Exception& E) + { + issue_fail_msg("test_copy()", __LINE__, __FILE__, E.getCDetailMsg()); + } +} // test_copy /*------------------------------------------------------------------------- * Function: test_num_links @@ -441,12 +798,9 @@ static void test_basic_links(hid_t fapl_id, hbool_t new_format) * Purpose: Test setting and getting limit of number of links * * Return: Success: 0 - * * Failure: -1 * - * Programmer: Binh-Minh Ribler - * Mar, 2017 - * + * March, 2017 *------------------------------------------------------------------------- */ static void test_num_links(hid_t fapl_id, hbool_t new_format) @@ -534,10 +888,13 @@ void test_links() // FileAccPropList may be passed in instead of fapl id test_basic_links(my_fapl_id, new_format); test_num_links(my_fapl_id, new_format); + test_lcpl(my_fapl_id, new_format); + test_move(my_fapl_id, new_format); + test_copy(my_fapl_id, new_format); #if 0 + // these tests are from the C test links.c and left here for future // implementation of H5L API - nerrors += test_basic_links(fapl_id, new_format) < 0 ? 1 : 0; nerrors += cklinks(my_fapl, new_format) < 0 ? 1 : 0; nerrors += new_links(my_fapl, new_format) < 0 ? 1 : 0; nerrors += ck_new_links(my_fapl, new_format) < 0 ? 1 : 0; @@ -545,9 +902,6 @@ void test_links() nerrors += toomany(my_fapl, new_format) < 0 ? 1 : 0; /* Test new H5L link creation routine */ - nerrors += test_lcpl(my_fapl, new_format); - nerrors += test_move(my_fapl, new_format); - nerrors += test_copy(my_fapl, new_format); nerrors += test_move_preserves(my_fapl, new_format); #ifndef H5_NO_DEPRECATED_SYMBOLS nerrors += test_deprec(my_fapl, new_format); diff --git a/c++/test/tobject.cpp b/c++/test/tobject.cpp index c053604..b5e9ff0 100644 --- a/c++/test/tobject.cpp +++ b/c++/test/tobject.cpp @@ -73,6 +73,19 @@ static void test_get_objname() Group grp1_1 = grp1.createGroup(GROUP1_1, 0); Group grp1_2 = grp1.createGroup(GROUP1_2, 0); + // Attempted to create a same group to generate a failure, which should + // be caught with sub-class exception clause, if available. + try { + Group grp1_2 = grp1.createGroup(GROUP1_2, 0); + } + catch (GroupIException& E) + {} // do nothing, exception expected + catch (Exception& E) + { + cerr << "Exception should have been caught by the previous catch" << endl; + issue_fail_msg("test_get_objname", __LINE__, __FILE__); + } + // Get part of the group's name, random length using // ssize_t getObjName(char* comment, size_t buf_size) @@ -302,6 +315,7 @@ static void test_get_objtype() *------------------------------------------------------------------------- */ const H5std_string GROUPNAME("group"); +const H5std_string NOGROUPNAME("non-existent-group"); const H5std_string DTYPENAME("group/datatype"); const H5std_string DTYPENAME_INGRP("datatype"); const H5std_string DSETNAME("dataset"); @@ -323,22 +337,25 @@ static void test_open_object_header() // Create a group in the root group Group grp(file1.createGroup(GROUPNAME)); - grp.close(); // Commit the type inside the file IntType dtype(PredType::NATIVE_INT); dtype.commit(file1, DTYPENAME); dtype.close(); - // Create a new dataset + // Create a new dataset in the file dims[0] = DIM0; dims[1] = DIM1; DataSpace dspace(RANK, dims); DataSet dset(file1.createDataSet(DSETNAME, PredType::NATIVE_INT, dspace)); - // Close dataset and dataspace + // Create a dataset in the group + DataSet dsingrp(grp.createDataSet(DSET_IN_GRP1, PredType::NATIVE_INT, dspace)); + + // Close dataset, dataspace, and group dset.close(); dspace.close(); + grp.close(); // Now make sure that openObjId can open all three types of objects hid_t obj_grp = file1.openObjId(GROUPNAME); @@ -357,12 +374,12 @@ static void test_open_object_header() Group grp2(obj_grp); hsize_t num_objs = grp2.getNumObjs(); - verify_val(num_objs, 1, "H5Gget_info", __LINE__, __FILE__); - // There should be one object, the datatype + verify_val(num_objs, 2, "H5Gget_info", __LINE__, __FILE__); // Close datatype object opened from the file - file1.closeObjId(obj_dtype); + H5Location::closeObjId(obj_dtype); + // Do a few things using the dset object identifier dset.setId(obj_dset); dspace = dset.getSpace(); bool is_simple = dspace.isSimple(); @@ -371,24 +388,38 @@ static void test_open_object_header() // Open datatype object from the group obj_dtype = grp2.openObjId(DTYPENAME_INGRP); + // Do a few things using the datatype object identifier dtype.setId(obj_dtype); H5T_class_t type_class = dtype.getClass(); verify_val(type_class, H5T_INTEGER, "H5Tget_class", __LINE__, __FILE__); dtype.close(); // Close datatype object - grp2.closeObjId(obj_dtype); + H5Location::closeObjId(obj_dtype); // Close the group object - file1.closeObjId(obj_grp); + H5Location::closeObjId(obj_grp); // Try doing something with group, the ID should still work num_objs = grp2.getNumObjs(); - verify_val(num_objs, 1, "H5Gget_info", __LINE__, __FILE__); + verify_val(num_objs, 2, "H5Gget_info", __LINE__, __FILE__); // Close the cloned group grp2.close(); + // Attempted to open a non-existing group, which should + // be caught with sub-class exception clause, if available. + try { + Group grp3 = dsingrp.openObjId(NOGROUPNAME); + } + catch (DataSetIException& E) + {} // do nothing, exception expected and caught correctly + catch (Exception& E) + { + cerr << "Exception should have been caught by the previous catch" << endl; + issue_fail_msg("test_get_objname", __LINE__, __FILE__); + } + PASSED(); } // end of try block // catch invalid action exception @@ -401,7 +432,6 @@ static void test_open_object_header() // catch all other exceptions catch (Exception& E) { - cerr << " in Exception" << endl; issue_fail_msg("test_file_name()", __LINE__, __FILE__, E.getCDetailMsg()); } } /* test_open_object_header() */ @@ -454,7 +484,6 @@ static void test_is_valid() // catch all other exceptions catch (Exception& E) { - cerr << " in catch " << endl; issue_fail_msg("test_get_objtype", __LINE__, __FILE__, E.getCDetailMsg()); } } // test_is_valid |