summaryrefslogtreecommitdiffstats
path: root/c++/test
diff options
context:
space:
mode:
Diffstat (limited to 'c++/test')
-rw-r--r--c++/test/CMakeLists.txt3
-rw-r--r--c++/test/CMakeTests.cmake2
-rw-r--r--c++/test/Makefile.in78
-rw-r--r--c++/test/dsets.cpp19
-rw-r--r--c++/test/tattr.cpp12
-rw-r--r--c++/test/tfile.cpp27
-rw-r--r--c++/test/tlinks.cpp380
-rw-r--r--c++/test/tobject.cpp51
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