From 99030cf45c9f6a804e4a22b1af38b872f06396cb Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Mon, 6 Jun 2011 17:15:24 -0500 Subject: [svn-r20936] Issue 4278 - When reading data fails, the error message should say which filter isn't registered. The fix is simple. Most of the effort is on the test. The file with filter enabled is created in gen_filter.c. The verification of the error message is in test_error.c. The output is compared against the standard output. Tested on jam, koala, and heiwa. --- MANIFEST | 1 + release_docs/RELEASE.txt | 5 +- src/H5Z.c | 12 ++- test/error_test.c | 77 ++++++++++++++++++-- test/filter_error.h5 | Bin 0 -> 3576 bytes test/gen_filters.c | 157 +++++++++++++++++++++++++++++++++++++--- test/testfiles/error_test_1 | 24 +++++- tools/testfiles/filter_fail.ddl | 2 +- 8 files changed, 249 insertions(+), 29 deletions(-) create mode 100644 test/filter_error.h5 diff --git a/MANIFEST b/MANIFEST index 3e59e71..a456228 100644 --- a/MANIFEST +++ b/MANIFEST @@ -812,6 +812,7 @@ ./test/external.c ./test/error_test.c ./test/err_compat.c +./test/filter_error.h5 ./test/links_env.c ./test/family_v16_00000.h5 ./test/family_v16_00001.h5 diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 055a360..ec6f11d 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -105,8 +105,9 @@ Bug Fixes since HDF5-1.8.7 Library ------- - - None - + - When a dataset had filters and reading data failed, the error message + didn't say which filter isn't registered. It's fixed now. (SLU - 2011/6/3) + Parallel Library ---------------- - None diff --git a/src/H5Z.c b/src/H5Z.c index b22863e..c083641 100644 --- a/src/H5Z.c +++ b/src/H5Z.c @@ -96,9 +96,6 @@ H5Z_init_interface (void) HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register fletcher32 filter") #endif /* H5_HAVE_FILTER_FLETCHER32 */ #ifdef H5_HAVE_FILTER_SZIP - H5Z_SZIP->encoder_present = SZ_encoder_enabled(); - if (H5Z_SZIP->encoder_present < 0) - HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "szip filter reports bad status") if (H5Z_register (H5Z_SZIP)<0) HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register szip filter") #endif /* H5_HAVE_FILTER_SZIP */ @@ -1091,7 +1088,14 @@ H5Z_pipeline(const H5O_pline_t *pline, unsigned flags, continue;/*filter excluded*/ } if ((fclass_idx=H5Z_find_idx(pline->filter[idx].id))<0) { - HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter is not registered") + /* Print out the filter name to give more info. But the name is optional for + * the filter */ + if(pline->filter[idx].name) + HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter '%s' is not registered", + pline->filter[idx].name) + else + HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter (name unavailable) is not registered") + } fclass=&H5Z_table_g[fclass_idx]; #ifdef H5Z_DEBUG diff --git a/test/error_test.c b/test/error_test.c index 52dcc0c..760351d 100644 --- a/test/error_test.c +++ b/test/error_test.c @@ -20,17 +20,19 @@ * Purpose: Tests the error API routines. */ #include "h5test.h" +#include "H5srcdir.h" #ifdef H5_USE_16_API int main(void) { - printf("Test skipped because backward compatbility with v1.6 is configured in\n"); + fprintf(stderr, "Test skipped because backward compatbility with v1.6 is configured in\n"); return 0; } #else /* H5_USE_16_API */ const char *FILENAME[] = { "errors", + "filter_error", NULL }; @@ -74,6 +76,8 @@ hid_t ERR_MIN_GETNUM; #define MSG_SIZE 64 #define LONG_DESC_SIZE 8192 +#define DSET_FILTER_NAME "dataset_with_filter" + static herr_t custom_print_cb(unsigned n, const H5E_error2_t *err_desc, void *client_data); @@ -102,8 +106,7 @@ test_error(hid_t file) H5E_auto2_t old_func; void *old_data; - TESTING("error API based on data I/O"); - printf("\n"); + fprintf(stderr, "\nTesting error API based on data I/O\n"); /* Create the data space */ dims[0] = DIM0; @@ -360,7 +363,7 @@ test_long_desc(void) if(H5Epush(H5E_DEFAULT, __FILE__, test_FUNC, __LINE__, ERR_CLS, ERR_MAJ_TEST, ERR_MIN_SUBROUTINE, format, long_desc) < 0) TEST_ERROR; /* Create the string that should be in the description */ - HDsnprintf(full_desc, LONG_DESC_SIZE + 128, format, long_desc); + snprintf(full_desc, (size_t)(LONG_DESC_SIZE + 128), format, long_desc); /* Make certain that the description is correct */ if(H5Ewalk2(H5E_DEFAULT, H5E_WALK_UPWARD, long_desc_cb, full_desc) < 0) TEST_ERROR; @@ -534,7 +537,6 @@ test_copy(void) const char *err_func = "test_copy"; /* Function name for pushing error */ const char *err_msg = "Error message"; /* Error message for pushing error */ int err_num; /* Number of errors on stack */ - int err_num_copy; /* Number of errors on stack copy */ hid_t estack_id; /* Error stack ID */ herr_t ret; /* Generic return value */ @@ -618,6 +620,57 @@ error: /*------------------------------------------------------------------------- + * Function: test_filter_error + * + * Purpose: Make sure the error message prints out the filter name + * when the existent file is opened but the filter isn't + * registered. The existent file was created with + * gen_filters.c. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Raymond Lu + * 2 June 2011 + * + *------------------------------------------------------------------------- + */ +static herr_t +test_filter_error(const char *fname) +{ + const char *pathname = H5_get_srcdir_filename(fname); /* Corrected test file name */ + hid_t file, dataset; /* handles */ + int buf[20]; + + fprintf(stderr, "\nTesting error message during data reading when filter isn't registered\n"); + + /* Open the file */ + if((file = H5Fopen(pathname, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + TEST_ERROR; + + /* Open the regular dataset */ + if((dataset = H5Dopen2(file, DSET_FILTER_NAME, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) >= 0) + TEST_ERROR; + + /* Close/release resources */ + if(H5Dclose(dataset) < 0) + TEST_ERROR + + if(H5Fclose(file) < 0) + TEST_ERROR + + return 0; + +error: + return -1; +} + + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Test error API. @@ -689,17 +742,25 @@ main(void) if(test_copy() < 0) TEST_ERROR; if(H5Fclose(file) < 0) TEST_ERROR; - h5_cleanup(FILENAME, fapl); /* Close error information */ if(close_error() < 0) TEST_ERROR; - printf("All error API tests passed.\n"); + /* Test error message during data reading when filter isn't registered + * Use default FAPL to avoid some VFD drivers by the check-vfd test because + * the test file was pre-generated. */ + h5_fixname(FILENAME[1], H5P_DEFAULT, filename, sizeof filename); + if(test_filter_error(filename) < 0) + TEST_ERROR; + + h5_cleanup(FILENAME, fapl); + + fprintf(stderr, "\nAll error API tests passed.\n"); return 0; error: - printf("***** ERROR TEST FAILED! *****\n"); + fprintf(stderr, "\n***** ERROR TEST FAILED (real problem)! *****\n"); return 1; } #endif /* H5_USE_16_API */ diff --git a/test/filter_error.h5 b/test/filter_error.h5 new file mode 100644 index 0000000..370cc1c Binary files /dev/null and b/test/filter_error.h5 differ diff --git a/test/gen_filters.c b/test/gen_filters.c index 6d24fb3..58400d5 100644 --- a/test/gen_filters.c +++ b/test/gen_filters.c @@ -13,20 +13,38 @@ * access to either file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* +#include "h5test.h" + +#define TESTFILE1 "test_filters.h5" +#define TESTFILE2 "filter_error.h5" +#define DSETNAME "dataset_with_filter" + +/* Temporary filter IDs used for testing */ +#define H5Z_FILTER_BOGUS 305 + +/* Local prototypes for filter functions */ +static size_t filter_bogus(unsigned int flags, size_t cd_nelmts, + const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf); + + +/*------------------------------------------------------------------------- + * Function: create_file_with_bogus_filter + * + * Purpose: Create a dataset with the fletcher filter. + * This function is used to create the test file `test_filters.h5' + * which has a dataset with the "fletcher" I/O filter. This dataset + * will be used to verify the correct behavior of the library in + * the test "dsets" + * + * Return: Success: 0 + * + * Failure: -1 + * * Programmer: Pedro Vicente * Thursday, March 25, 2004 * - * Purpose: Create a dataset with the fletcher filter. - * This program is used to create the test file `test_filters.h5' which has - * a dataset with the "fletcher" I/O filter. This dataset will - * be used to verify the correct behavior of the library in the test "dsets" + *------------------------------------------------------------------------- */ -#include "hdf5.h" - -#define TESTFILE "test_filters.h5" - - static herr_t test_filters_endianess(void) { @@ -45,7 +63,7 @@ test_filters_endianess(void) buf[i] = 1; /* create a file using default properties */ - if((fid = H5Fcreate(TESTFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error; + if((fid = H5Fcreate(TESTFILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error; /* create a data space */ if((sid = H5Screate_simple(rank, dims, NULL)) < 0) goto error; @@ -82,7 +100,109 @@ error: #endif /* H5_HAVE_FILTER_FLETCHER32 */ } /* end test_filters_endianess() */ +/* This message derives from H5Z */ +const H5Z_class2_t H5Z_BOGUS[1] = {{ + H5Z_CLASS_T_VERS, /* H5Z_class_t version */ + H5Z_FILTER_BOGUS, /* Filter id number */ + 1, 1, /* Encoding and decoding enabled */ + "bogus", /* Filter name for debugging */ + NULL, /* The "can apply" callback */ + NULL, /* The "set local" callback */ + filter_bogus, /* The actual filter function */ +}}; + +/*------------------------------------------------------------------------- + * Function: filter_bogus + * + * Purpose: A bogus compression method that doesn't do anything. + * + * Return: Success: Data chunk size + * + * Failure: 0 + * + * Programmer: Raymond Lu + * 2 June 2011 + * + *------------------------------------------------------------------------- + */ +static size_t +filter_bogus(unsigned int UNUSED flags, size_t UNUSED cd_nelmts, + const unsigned int UNUSED *cd_values, size_t nbytes, + size_t UNUSED *buf_size, void UNUSED **buf) +{ + return nbytes; +} + + +/*------------------------------------------------------------------------- + * Function: create_file_with_bogus_filter + * + * Purpose: Create a file and a dataset with a bogus filter enabled + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Raymond Lu + * 2 June 2011 + * + *------------------------------------------------------------------------- + */ +static herr_t +create_file_with_bogus_filter(void) +{ + hid_t fid = -1; /* file ID */ + hid_t dsid = -1; /* dataset ID */ + hid_t sid = -1; /* dataspace ID */ + hid_t dcpl = -1; /* dataset creation property list ID */ + hsize_t dims[1] = {20}; /* dataspace dimensions */ + hsize_t chunk_dims[1] = {10}; /* chunk dimensions */ + int buf[20]; + int rank = 1; + int i; + + for(i = 0; i < 20; i++) + buf[i] = 1; + + /* create a file using default properties */ + if((fid = H5Fcreate(TESTFILE2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error; + + /* create a data space */ + if((sid = H5Screate_simple(rank, dims, NULL)) < 0) goto error; + + /* create dcpl */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error; + + /* create chunking */ + if(H5Pset_chunk(dcpl, rank, chunk_dims) < 0) goto error; + + /* register bogus filter */ + if(H5Zregister (H5Z_BOGUS) < 0) goto error; + if(H5Pset_filter(dcpl, H5Z_FILTER_BOGUS, 0, (size_t)0, NULL) < 0) goto error; + + /* create a dataset */ + if((dsid = H5Dcreate2(fid, DSETNAME, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) goto error; + + if(H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) goto error; + + /* close */ + if(H5Pclose(dcpl) < 0) goto error; + if(H5Dclose(dsid) < 0) goto error; + if(H5Sclose(sid) < 0) goto error; + if(H5Fclose(fid) < 0) goto error; + + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(dcpl); + H5Dclose(dsid); + H5Sclose(sid); + H5Fclose(fid); + } H5E_END_TRY; + return -1; +} /*------------------------------------------------------------------------- @@ -99,7 +219,20 @@ error: int main(void) { - test_filters_endianess(); + int nerrors = 0; + + nerrors += test_filters_endianess() < 0 ? 1 : 0; + nerrors += create_file_with_bogus_filter() < 0 ? 1 : 0; + + if(nerrors) + goto error; + printf("All tests passed.\n"); + return 0; + +error: + nerrors = MAX(1, nerrors); + printf("***** %d GEN_FILTERS FAILURES *****\n", nerrors); + return 1; } diff --git a/test/testfiles/error_test_1 b/test/testfiles/error_test_1 index 308ca07..8d6e208 100644 --- a/test/testfiles/error_test_1 +++ b/test/testfiles/error_test_1 @@ -1,8 +1,6 @@ ############################# Expected output for error_test ############################# -Testing error API based on data I/O -All error API tests passed. This program tests the Error API. There're supposed to be some error messages ********* Print error stack in HDF5 default way ********* Second Test-DIAG: Error detected in Second Program (1.0) thread (IDs): @@ -23,6 +21,8 @@ Error Test-DIAG: Error detected in Error Program (1.0) thread (IDs): class: Second Test major: Error in test minor: Error in error stack + +Testing error API based on data I/O HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #000: (file name) line (number) in H5Dwrite(): not a dataset major: Invalid arguments to routine @@ -38,3 +38,23 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #002: (file name) line (number) in H5Dwrite(): not a dataset major: Invalid arguments to routine minor: Inappropriate type + +Testing error message during data reading when filter isn't registered +HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): + #000: (file name) line (number) in H5Dread(): can't read data + major: Dataset + minor: Read failed + #001: (file name) line (number) in H5D_read(): can't read data + major: Dataset + minor: Read failed + #002: (file name) line (number) in H5D_chunk_read(): unable to read raw data chunk + major: Low-level I/O + minor: Read failed + #003: (file name) line (number) in H5D_chunk_lock(): data pipeline read failed + major: Data filters + minor: Filter operation failed + #004: (file name) line (number) in H5Z_pipeline(): required filter 'bogus' is not registered + major: Data filters + minor: Read failed + +All error API tests passed. diff --git a/tools/testfiles/filter_fail.ddl b/tools/testfiles/filter_fail.ddl index 9ee1da8..1bb65ba 100644 --- a/tools/testfiles/filter_fail.ddl +++ b/tools/testfiles/filter_fail.ddl @@ -21,7 +21,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #003: (file name) line (number) in H5D_chunk_lock(): data pipeline read failed major: Data filters minor: Filter operation failed - #004: (file name) line (number) in H5Z_pipeline(): required filter is not registered + #004: (file name) line (number) in H5Z_pipeline(): required filter 'filter_fail_test' is not registered major: Data filters minor: Read failed h5dump error: unable to print data -- cgit v0.12