summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDana Robinson <derobins@hdfgroup.org>2016-02-17 04:30:49 (GMT)
committerDana Robinson <derobins@hdfgroup.org>2016-02-17 04:30:49 (GMT)
commite43c97fdb2459bfe605b7cb1a88624804b100232 (patch)
treeee1c279a339d2c25e4d22f9251a6c4c18011c7ec
parent77f2f1c132a852eb8e0893f051b128cf8f42a9ef (diff)
downloadhdf5-e43c97fdb2459bfe605b7cb1a88624804b100232.zip
hdf5-e43c97fdb2459bfe605b7cb1a88624804b100232.tar.gz
hdf5-e43c97fdb2459bfe605b7cb1a88624804b100232.tar.bz2
[svn-r29132] Added new single-responsibility functions to h5test.c/h that can
replace functions like h5_clean_files() that also do things like reset the error handler and close fapls. Existing tests have not yet been updated to use these new functions. Tested on: 64-bit Ubuntu 15.10 (Linux 4.2.0 x86_64) gcc 5.2.1 autotools serial
-rw-r--r--test/h5test.c294
-rw-r--r--test/h5test.h17
2 files changed, 311 insertions, 0 deletions
diff --git a/test/h5test.c b/test/h5test.c
index 843ec35..c010adc 100644
--- a/test/h5test.c
+++ b/test/h5test.c
@@ -193,6 +193,107 @@ h5_clean_files(const char *base_name[], hid_t fapl)
/*-------------------------------------------------------------------------
+ * Function: h5_delete_test_file
+ *
+ * Purpose Clean up temporary test files.
+ *
+ * When a test calls h5_fixname() get a VFD-dependent
+ * test file name, this function can be used to clean it up.
+ *
+ * Return: void
+ *
+ * Since this is a cleanup file, we don't care if it fails.
+ *
+ * Programmer: Dana Robinson
+ * February 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+h5_delete_test_file(const char *base_name, hid_t fapl)
+{
+ char filename[1024]; /* VFD-dependent filename to delete */
+ char sub_filename[2048]; /* sub-files in multi & family VFDs */
+ hid_t driver = -1; /* VFD ID */
+
+ /* Get the VFD-dependent filename */
+ if(NULL == h5_fixname(base_name, fapl, filename, sizeof(filename)))
+ return;
+
+ driver = H5Pget_driver(fapl);
+
+ if(driver == H5FD_FAMILY) {
+ int j;
+ for(j = 0; /*void*/; j++) {
+ HDsnprintf(sub_filename, sizeof(sub_filename), filename, j);
+
+ /* If we can't access the file, it probably doesn't exist
+ * and we are done deleting the sub-files.
+ */
+ if(HDaccess(sub_filename, F_OK) < 0)
+ break;
+
+ HDremove(sub_filename);
+ } /* end for */
+ } else if(driver == H5FD_CORE) {
+ hbool_t backing; /* Whether the core file has backing store */
+
+ H5Pget_fapl_core(fapl, NULL, &backing);
+
+ /* If the file was stored to disk with bacing store, remove it */
+ if(backing)
+ HDremove(filename);
+ } else if (driver == H5FD_MULTI) {
+ H5FD_mem_t mt;
+
+ HDassert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES);
+
+ for(mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,mt)) {
+ HDsnprintf(sub_filename, sizeof(sub_filename), "%s-%c.h5", filename, multi_letters[mt]);
+ HDremove(sub_filename);
+ } /* end for */
+ } else {
+ HDremove(filename);
+ } /* end if */
+
+ return;
+} /* end h5_delete_test_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5_delete_all_test_files
+ *
+ * Purpose Clean up temporary test files.
+ *
+ * When a test calls h5_fixname() get a VFD-dependent
+ * test file name, this function can be used to clean it up.
+ *
+ * This function takes an array of filenames that ends with
+ * a NULL string and cleans them all.
+ *
+ * Return: void
+ *
+ * Since this is a cleanup file, we don't care if it fails.
+ *
+ * Programmer: Dana Robinson
+ * February 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+h5_delete_all_test_files(const char *base_name[], hid_t fapl)
+{
+ int i; /* iterator */
+
+ for(i = 0; base_name[i]; i++) {
+ h5_delete_test_file(base_name[i], fapl);
+ } /* end for */
+
+ return;
+} /* end h5_delete_all_test_files() */
+
+
+/*-------------------------------------------------------------------------
* Function: h5_cleanup
*
* Purpose: Cleanup temporary test files.
@@ -226,6 +327,35 @@ h5_cleanup(const char *base_name[], hid_t fapl)
/*-------------------------------------------------------------------------
+ * Function: h5_test_shutdown
+ *
+ * Purpose: Performs any special test cleanup required before the test
+ * ends.
+ *
+ * NOTE: This function should normally only be called once
+ * in a given test, usually just before leaving main(). It
+ * is intended for use in the single-file unit tests, not
+ * testhdf5.
+ *
+ * Return: void
+ *
+ * Programmer: Dana Robinson
+ * February 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+h5_test_shutdown(void)
+{
+
+ /* Restore the original error reporting routine */
+ h5_restore_err();
+
+ return;
+} /* end h5_test_shutdown() */
+
+
+/*-------------------------------------------------------------------------
* Function: h5_restore_err
*
* Purpose: Restore the default error handler.
@@ -303,6 +433,39 @@ h5_reset(void)
/*-------------------------------------------------------------------------
+ * Function: h5_test_init
+ *
+ * Purpose: Performs any special actions before the test begins.
+ *
+ * NOTE: This function should normally only be called once
+ * in a given test, usually at the beginning of main(). It
+ * is intended for use in the single-file unit tests, not
+ * testhdf5.
+ *
+ * Return: void
+ *
+ * Programmer: Dana Robinson
+ * February 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+h5_test_init(void)
+{
+ HDfflush(stdout);
+ HDfflush(stderr);
+ H5close();
+
+ /* Save current error stack reporting routine and redirect to our local one */
+ HDassert(err_func == NULL);
+ H5Eget_auto2(H5E_DEFAULT, &err_func, NULL);
+ H5Eset_auto2(H5E_DEFAULT, h5_errors, NULL);
+
+ return;
+} /* end h5_test_init() */
+
+
+/*-------------------------------------------------------------------------
* Function: h5_fixname
*
* Purpose: Create a file name from a file base name like `test' and
@@ -744,6 +907,137 @@ h5_fileaccess(void)
/*-------------------------------------------------------------------------
+ * Function: h5_get_vfd_fapl
+ *
+ * Purpose: Returns a file access property list which is the default
+ * fapl but with a file driver set according to the constant or
+ * environment variable HDF5_DRIVER.
+ *
+ * Return: Success: A file access property list ID
+ * Failure: -1
+ *
+ * Programmer: Dana Robinson
+ * February 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+h5_get_vfd_fapl(void)
+{
+ const char *env = NULL; /* HDF5_DRIVER environment variable */
+ const char *tok = NULL; /* strtok pointer */
+ char buf[1024]; /* buffer for tokenizing HDF5_DRIVER */
+ hid_t fapl = -1; /* fapl to be returned */
+
+ /* Get the environment variable, if it exists */
+ env = HDgetenv("HDF5_DRIVER");
+
+ /* Create a default fapl */
+ if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+ return -1;
+
+ /* If the environment variable was not set, just return
+ * the default fapl.
+ */
+ if(!env || !*env)
+ return fapl;
+
+ /* Get the first 'word' of the environment variable.
+ * If it's nothing (environment variable was whitespace)
+ * just return the default fapl.
+ */
+ HDstrncpy(buf, env, sizeof(buf));
+ HDmemset(buf, 0, sizeof(buf));
+ if(NULL == (tok = HDstrtok(buf, " \t\n\r")))
+ return fapl;
+
+ if(!HDstrcmp(tok, "sec2")) {
+ /* POSIX (section 2) read() and write() system calls */
+ if(H5Pset_fapl_sec2(fapl) < 0)
+ return -1;
+ } else if(!HDstrcmp(tok, "stdio")) {
+ /* Standard C fread() and fwrite() system calls */
+ if(H5Pset_fapl_stdio(fapl) < 0)
+ return -1;
+ } else if(!HDstrcmp(tok, "core")) {
+ /* In-memory driver settings (backing store on, 1 MB increment) */
+ if(H5Pset_fapl_core(fapl, (size_t)1, TRUE) < 0)
+ return -1;
+ } else if(!HDstrcmp(tok, "core_paged")) {
+ /* In-memory driver with write tracking and paging on */
+ if(H5Pset_fapl_core(fapl, (size_t)1, TRUE) < 0)
+ return -1;
+ if(H5Pset_core_write_tracking(fapl, TRUE, (size_t)4096) < 0)
+ return -1;
+ } else if(!HDstrcmp(tok, "split")) {
+ /* Split meta data and raw data each using default driver */
+ if(H5Pset_fapl_split(fapl,
+ "-m.h5", H5P_DEFAULT,
+ "-r.h5", H5P_DEFAULT) < 0)
+ return -1;
+ } else if(!HDstrcmp(tok, "multi")) {
+ /* Multi-file driver, general case of the split driver */
+ H5FD_mem_t memb_map[H5FD_MEM_NTYPES];
+ hid_t memb_fapl[H5FD_MEM_NTYPES];
+ const char *memb_name[H5FD_MEM_NTYPES];
+ char sv[H5FD_MEM_NTYPES][1024];
+ haddr_t memb_addr[H5FD_MEM_NTYPES];
+ H5FD_mem_t mt;
+
+ HDmemset(memb_map, 0, sizeof(memb_map));
+ HDmemset(memb_fapl, 0, sizeof(memb_fapl));
+ HDmemset(memb_name, 0, sizeof(memb_name));
+ HDmemset(memb_addr, 0, sizeof(memb_addr));
+
+ HDassert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES);
+ for(mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, mt)) {
+ memb_fapl[mt] = H5P_DEFAULT;
+ HDsprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]);
+ memb_name[mt] = sv[mt];
+ memb_addr[mt] = (haddr_t)MAX(mt - 1, 0) * (HADDR_MAX / 10);
+ } /* end for */
+
+ if(H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name,
+ memb_addr, FALSE) < 0) {
+ return -1;
+ } /* end if */
+ } else if(!HDstrcmp(tok, "family")) {
+ /* Family of files, each 1MB and using the default driver */
+ hsize_t fam_size = 100*1024*1024; /*100 MB*/
+
+ /* Was a family size specified in the environment variable? */
+ if((tok = HDstrtok(NULL, " \t\n\r")))
+ fam_size = (hsize_t)(HDstrtod(tok, NULL) * 1024*1024);
+ if(H5Pset_fapl_family(fapl, fam_size, H5P_DEFAULT) < 0)
+ return -1;
+ } else if(!HDstrcmp(tok, "log")) {
+ /* Log file access */
+ unsigned log_flags = H5FD_LOG_LOC_IO | H5FD_LOG_ALLOC;
+
+ /* Were special log file flags specified in the environment variable? */
+ if((tok = HDstrtok(NULL, " \t\n\r")))
+ log_flags = (unsigned)HDstrtol(tok, NULL, 0);
+
+ if(H5Pset_fapl_log(fapl, NULL, log_flags, (size_t)0) < 0)
+ return -1;
+#ifdef H5_HAVE_DIRECT
+ } else if(!HDstrcmp(tok, "direct")) {
+ /* Linux direct read() and write() system calls. Set memory boundary,
+ * file block size, and copy buffer size to the default values.
+ */
+ if(H5Pset_fapl_direct(fapl, 1024, 4096, 8*4096)<0)
+ return -1;
+#endif
+ } else {
+ /* Unknown driver */
+ return -1;
+ } /* end if */
+
+ return fapl;
+} /* end h5_get_vfd_fapl() */
+
+
+/*-------------------------------------------------------------------------
* Function: h5_no_hwconv
*
* Purpose: Turn off hardware data type conversions.
diff --git a/test/h5test.h b/test/h5test.h
index ca0eead..575497b 100644
--- a/test/h5test.h
+++ b/test/h5test.h
@@ -139,6 +139,23 @@ H5TEST_DLL int print_func(const char *format, ...);
H5TEST_DLL int h5_make_local_copy(const char *origfilename, const char *local_copy_name);
H5TEST_DLL herr_t h5_verify_cached_stabs(const char *base_name[], hid_t fapl);
+/* Functions that will replace VFD-dependent functions that violate
+ * the single responsibility principle. Unlike their predecessors,
+ * these new functions do not have hidden side effects.
+ */
+/* h5_fileaccess() replacement */
+H5TEST_DLL hid_t h5_get_vfd_fapl(void);
+
+/* h5_clean_files() replacements */
+H5TEST_DLL void h5_delete_test_file(const char *base_name, hid_t fapl);
+H5TEST_DLL void h5_delete_all_test_files(const char *base_name[], hid_t fapl);
+
+/* h5_reset() replacement */
+H5TEST_DLL void h5_test_init(void);
+
+/* h5_cleanup() replacement */
+H5TEST_DLL void h5_test_shutdown(void);
+
/* Routines for operating on the list of tests (for the "all in one" tests) */
H5TEST_DLL void TestUsage(void);
H5TEST_DLL void AddTest(const char *TheName, void (*TheCall) (void),