diff options
Diffstat (limited to 'test/h5test.c')
-rw-r--r-- | test/h5test.c | 409 |
1 files changed, 293 insertions, 116 deletions
diff --git a/test/h5test.c b/test/h5test.c index e370c6d..6ed14d3 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -102,7 +102,6 @@ static char *h5_fixname_real(const char *base_name, hid_t fapl, const char *suff char *fullname, size_t size); - /*------------------------------------------------------------------------- * Function: h5_errors * @@ -127,7 +126,7 @@ h5_errors(hid_t estack, void H5_ATTR_UNUSED *client_data) return 0; } - + /*------------------------------------------------------------------------- * Function: h5_clean_files * @@ -156,7 +155,7 @@ h5_clean_files(const char *base_name[], hid_t fapl) return; } /* end h5_clean_files() */ - + /*------------------------------------------------------------------------- * Function: h5_delete_test_file * @@ -233,7 +232,7 @@ h5_delete_test_file(const char *base_name, hid_t fapl) } /* end h5_delete_test_file() */ #pragma GCC diagnostic pop - + /*------------------------------------------------------------------------- * Function: h5_delete_all_test_files * @@ -266,7 +265,7 @@ h5_delete_all_test_files(const char *base_name[], hid_t fapl) return; } /* end h5_delete_all_test_files() */ - + /*------------------------------------------------------------------------- * Function: h5_cleanup * @@ -299,7 +298,7 @@ h5_cleanup(const char *base_name[], hid_t fapl) return retval; } /* end h5_cleanup() */ - + /*------------------------------------------------------------------------- * Function: h5_test_shutdown * @@ -328,7 +327,7 @@ h5_test_shutdown(void) return; } /* end h5_test_shutdown() */ - + /*------------------------------------------------------------------------- * Function: h5_restore_err * @@ -350,7 +349,7 @@ h5_restore_err(void) err_func = NULL; } - + /*------------------------------------------------------------------------- * Function: h5_reset * @@ -392,7 +391,7 @@ h5_reset(void) * Cause the library to emit some diagnostics early so they don't * interfere with other formatted output. */ - sprintf(filename, "/tmp/h5emit-%05d.h5", HDgetpid()); + HDsprintf(filename, "/tmp/h5emit-%05d.h5", HDgetpid()); H5E_BEGIN_TRY { hid_t file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); @@ -405,7 +404,7 @@ h5_reset(void) #endif /* OLD_WAY */ } - + /*------------------------------------------------------------------------- * Function: h5_test_init * @@ -438,7 +437,7 @@ h5_test_init(void) return; } /* end h5_test_init() */ - + /*------------------------------------------------------------------------- * Function: h5_fixname * @@ -468,7 +467,6 @@ h5_fixname(const char *base_name, hid_t fapl, char *fullname, size_t size) } - /*------------------------------------------------------------------------- * Function: h5_fixname_no_suffix * @@ -489,7 +487,32 @@ h5_fixname_no_suffix(const char *base_name, hid_t fapl, char *fullname, size_t s } - +/*------------------------------------------------------------------------- + * Function: h5_fixname_printf + * + * Purpose: Same as h5_fixname but returns a filename that can be passed + * through a printf-style function once before being passed to the file + * driver. Basically, replaces all % characters used by the file + * driver with %%. + * + * Return: Success: The FULLNAME pointer. + * + * Failure: NULL if BASENAME or FULLNAME is the null + * pointer or if FULLNAME isn't large enough for + * the result. + * + * Programmer: Neil Fortner + * Wednesday, July 15, 2015 + * + *------------------------------------------------------------------------- + */ +char * +h5_fixname_printf(const char *base_name, hid_t fapl, char *fullname, size_t size) +{ + return (h5_fixname_real(base_name, fapl, ".h5", fullname, size)); +} + + /*------------------------------------------------------------------------- * Function: h5_fixname_real * @@ -585,7 +608,7 @@ h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); if (mpi_rank == 0) - printf("*** Hint ***\n" + HDprintf("*** Hint ***\n" "You can use environment variable HDF5_PARAPREFIX to " "run parallel test files in a\n" "different directory or to add file type prefix. e.g.,\n" @@ -701,7 +724,7 @@ h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, return fullname; } - + /*------------------------------------------------------------------------- * Function: h5_rmprefix * @@ -732,13 +755,13 @@ h5_rmprefix(const char *filename) return(ret_ptr); } - + /*------------------------------------------------------------------------- * Function: h5_fileaccess * * Purpose: Returns a file access template which is the default template - * but with a file driver set according to the constant or - * environment variable HDF5_DRIVER + * but with a file driver set + * according to a constant or environment variable HDF5_DRIVER * * Return: Success: A file access property list * Failure: H5I_INVALID_HID @@ -760,10 +783,6 @@ h5_fileaccess(void) if(h5_get_vfd_fapl(fapl_id) < 0) goto error; - /* Finally, check for libver bounds */ - if(h5_get_libver_fapl(fapl_id) < 0) - goto error; - return fapl_id; error: @@ -772,7 +791,7 @@ error: return H5I_INVALID_HID; } /* end h5_fileaccess() */ - + /*------------------------------------------------------------------------- * Function: h5_fileaccess_flags * @@ -800,10 +819,6 @@ h5_fileaccess_flags(unsigned flags) if((flags & H5_FILEACCESS_VFD) && h5_get_vfd_fapl(fapl_id) < 0) goto error; - /* Finally, check for libver bounds */ - if((flags & H5_FILEACCESS_LIBVER) && h5_get_libver_fapl(fapl_id) < 0) - goto error; - return fapl_id; error: @@ -812,7 +827,7 @@ error: return H5I_INVALID_HID; } /* end h5_fileaccess_flags() */ - + /*------------------------------------------------------------------------- * Function: h5_get_vfd_fapl * @@ -936,12 +951,7 @@ h5_get_vfd_fapl(hid_t fapl) if(H5Pset_fapl_direct(fapl, 1024, 4096, 8 * 4096) < 0) goto error; #endif - } else if(!HDstrcmp(tok, "latest")) { - /* use the latest format */ - if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) - goto error; - } - else { + } else { /* Unknown driver */ goto error; } /* end if */ @@ -955,69 +965,6 @@ error: /*------------------------------------------------------------------------- - * Function: h5_get_libver_fapl - * - * Purpose: Sets the library version bounds for a FAPL according to the - * value in the constant or environment variable "HDF5_LIBVER_BOUNDS". - * - * Return: Success: 0 - * Failure: -1 - * - * Programmer: Quincey Koziol - * November 2018 - * - *------------------------------------------------------------------------- - */ -herr_t -h5_get_libver_fapl(hid_t fapl) -{ - const char *env = NULL; /* HDF5_DRIVER environment variable */ - const char *tok = NULL; /* strtok pointer */ - char *lasts = NULL; /* Context pointer for strtok_r() call */ - char buf[1024]; /* buffer for tokenizing HDF5_DRIVER */ - - /* Get the environment variable, if it exists */ - env = HDgetenv("HDF5_LIBVER_BOUNDS"); -#ifdef HDF5_LIBVER_BOUNDS - /* Use the environment variable, then the compile-time constant */ - if(!env) - env = HDF5_LIBVER_BOUNDS; -#endif - - /* If the environment variable was not set, just return - * without modifying the FAPL. - */ - if(!env || !*env) - goto done; - - /* 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)); - buf[sizeof(buf) - 1] = '\0'; - if(NULL == (tok = HDstrtok_r(buf, " \t\n\r", &lasts))) - goto done; - - if(!HDstrcmp(tok, "latest")) { - /* use the latest format */ - if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) - goto error; - } /* end if */ - else { - /* Unknown setting */ - goto error; - } /* end else */ - -done: - return 0; - -error: - return -1; -} /* end h5_get_libver_fapl() */ - - -/*------------------------------------------------------------------------- * Function: h5_no_hwconv * * Purpose: Turn off hardware data type conversions. @@ -1037,7 +984,7 @@ h5_no_hwconv(void) H5Tunregister(H5T_PERS_HARD, NULL, (hid_t)-1, (hid_t)-1, NULL); } - + /*------------------------------------------------------------------------- * Function: h5_show_hostname * @@ -1071,15 +1018,15 @@ h5_show_hostname(void) if(mpi_initialized && !mpi_finalized) { MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank); - printf("MPI-process %d.", mpi_rank); + HDprintf("MPI-process %d.", mpi_rank); } else - printf("thread 0."); + HDprintf("thread 0."); } #elif defined(H5_HAVE_THREADSAFE) - printf("thread %lu.", HDpthread_self_ulong()); + HDprintf("thread %lu.", HDpthread_self_ulong()); #else - printf("thread 0."); + HDprintf("thread 0."); #endif #ifdef H5_HAVE_WIN32_API @@ -1105,18 +1052,18 @@ h5_show_hostname(void) #endif #ifdef H5_HAVE_GETHOSTNAME if (gethostname(hostname, (size_t)80) < 0) - printf(" gethostname failed\n"); + HDprintf(" gethostname failed\n"); else - printf(" hostname=%s\n", hostname); + HDprintf(" hostname=%s\n", hostname); #else - printf(" gethostname not supported\n"); + HDprintf(" gethostname not supported\n"); #endif #ifdef H5_HAVE_WIN32_API WSACleanup(); #endif } - + #ifdef H5_HAVE_PARALLEL /* * Function: h5_set_info_object @@ -1215,7 +1162,7 @@ h5_set_info_object(void) return ret_value; } - + /* * Function: h5_dump_info_object * Purpose: Display content of an MPI Info object @@ -1231,25 +1178,25 @@ h5_dump_info_object(MPI_Info info) int flag; int i, nkeys; - printf("Dumping MPI Info Object(%d) (up to %d bytes per item):\n", (int)info, + HDprintf("Dumping MPI Info Object(%d) (up to %d bytes per item):\n", (int)info, MPI_MAX_INFO_VAL); if (info==MPI_INFO_NULL){ - printf("object is MPI_INFO_NULL\n"); + HDprintf("object is MPI_INFO_NULL\n"); } else { MPI_Info_get_nkeys(info, &nkeys); - printf("object has %d items\n", nkeys); + HDprintf("object has %d items\n", nkeys); for (i=0; i<nkeys; i++){ MPI_Info_get_nthkey(info, i, key); MPI_Info_get(info, key, MPI_MAX_INFO_VAL, value, &flag); - printf("%s=%s\n", key, value); + HDprintf("%s=%s\n", key, value); } } } #endif /* H5_HAVE_PARALLEL */ - + /*------------------------------------------------------------------------- * Function: h5_get_file_size * @@ -1386,14 +1333,14 @@ print_func(const char *format, ...) int ret_value; HDva_start(arglist, format); - ret_value = vprintf(format, arglist); + ret_value = HDvprintf(format, arglist); HDva_end(arglist); return ret_value; } #ifdef H5_HAVE_FILTER_SZIP - + /*------------------------------------------------------------------------- * Function: h5_szip_can_encode * @@ -1592,7 +1539,7 @@ error: return -1; } /* end h5_make_local_copy() */ - + /*------------------------------------------------------------------------- * Function: h5_verify_cached_stabs_cb * @@ -1615,7 +1562,7 @@ h5_verify_cached_stabs_cb(hid_t oid, const char H5_ATTR_UNUSED *name, return SUCCEED; } /* end h5_verify_cached_stabs_cb() */ - + /*------------------------------------------------------------------------- * Function: h5_verify_cached_stabs * @@ -1676,3 +1623,233 @@ error: return -1; } +/*------------------------------------------------------------------------- + * Function: h5_send_message + * + * Purpose: Sends the specified signal. + * + * In terms of this test framework, a signal consists of a file + * on disk. Since there are multiple processes that need to + * communicate with each other, they do so by writing and + * reading signal files on disk, the names and contents of + * which are used to inform a process about when it can + * proceed and what it should do next. + * + * This function writes a signal file. The first argument is + * the name of the signal file, and the second and third + * arguments are the contents of the first two lines of the + * signal file. The last two arguments may be NULL. + * + * Return: void + * + * Programmer: Mike McGreevy + * August 18, 2010 + * + *------------------------------------------------------------------------- + */ +void +h5_send_message(const char *send, const char *arg1, const char *arg2) +{ + FILE *signalfile = NULL; + + /* Create signal file (which will send signal to some other process) */ + signalfile = HDfopen(TMP_SIGNAL_FILE, "w+"); + + /* Write messages to signal file, if provided */ + if(arg2 != NULL) { + HDassert(arg1); + HDfprintf(signalfile, "%s\n%s\n", arg1, arg2); + } /* end if */ + else if(arg1 != NULL) { + HDassert(arg2 == NULL); + HDfprintf(signalfile, "%s\n", arg1); + } /* end if */ + else { + HDassert(arg1 == NULL); + HDassert(arg2 == NULL); + }/* end else */ + + HDfclose(signalfile); + + HDrename(TMP_SIGNAL_FILE, send); +} /* h5_send_message() */ + +/*------------------------------------------------------------------------- + * Function: h5_wait_message + * + * Purpose: Waits for the specified signal. + * + * In terms of this test framework, a signal consists of a file + * on disk. Since there are multiple processes that need to + * communicate with each other, they do so by writing and + * reading signal files on disk, the names and contents of + * which are used to inform a process about when it can + * proceed and what it should do next. + * + * This function continuously attempts to read the specified + * signal file from disk, and only continues once it has + * successfully done so (i.e., only after another process has + * called the "h5_send_message" function to write the signal file). + * This functon will then immediately remove the file (i.e., + * to indicate that it has been received and can be reused), + * and then exits, allowing the calling function to continue. + * + * Return: void + * + * Programmer: Mike McGreevy + * August 18, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +h5_wait_message(const char *waitfor) +{ + FILE *returnfile; + time_t t0,t1; + + /* Start timer. If this function runs for too long (i.e., + expected signal is never received), it will + return failure */ + HDtime(&t0); + + /* Wait for return signal from some other process */ + while ((returnfile = HDfopen(waitfor, "r")) == NULL) { + + /* make note of current time. */ + HDtime(&t1); + + /* If we've been waiting for a signal for too long, then + it was likely never sent and we should fail rather + than loop infinitely */ + if(HDdifftime(t1, t0) > MESSAGE_TIMEOUT) { + HDfprintf(stdout, "Error communicating between processes. Make sure test script is running.\n"); + TEST_ERROR; + } /* end if */ + } /* end while */ + + HDfclose(returnfile); + HDunlink(waitfor); + + return SUCCEED; + +error: + return FAIL; +} /* h5_wait_message() */ + +/* Functions for the dummy VFD class (see below). + * + * Useful for testing things like ID handling where we shouldn't mess with the + * real VFDs. + */ +static H5FD_t *dummy_vfd_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); +static H5FD_t *dummy_vfd_open(const char H5_ATTR_UNUSED *name, unsigned H5_ATTR_UNUSED flags, hid_t H5_ATTR_UNUSED fapl_id, haddr_t H5_ATTR_UNUSED maxaddr) { return NULL; } + +static herr_t dummy_vfd_close(H5FD_t *_file); +static herr_t dummy_vfd_close(H5FD_t H5_ATTR_UNUSED *_file) { return FAIL; } + +static haddr_t dummy_vfd_get_eoa(const H5FD_t *file, H5FD_mem_t type); +static haddr_t dummy_vfd_get_eoa(const H5FD_t H5_ATTR_UNUSED *file, H5FD_mem_t H5_ATTR_UNUSED type) { return HADDR_UNDEF; } + +static herr_t dummy_vfd_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); +static herr_t dummy_vfd_set_eoa(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t H5_ATTR_UNUSED addr) { return FAIL; } + +static haddr_t dummy_vfd_get_eof(const H5FD_t *file, H5FD_mem_t type); +static haddr_t dummy_vfd_get_eof(const H5FD_t H5_ATTR_UNUSED *file, H5FD_mem_t H5_ATTR_UNUSED type) { return HADDR_UNDEF; } + +static herr_t dummy_vfd_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, void *buf); +static herr_t dummy_vfd_read(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUSED fapl_id, haddr_t H5_ATTR_UNUSED addr, size_t H5_ATTR_UNUSED size, void H5_ATTR_UNUSED *buf) { return FAIL; } + +static herr_t dummy_vfd_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, const void *buf); +static herr_t dummy_vfd_write(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUSED fapl_id, haddr_t H5_ATTR_UNUSED addr, size_t H5_ATTR_UNUSED size, const void H5_ATTR_UNUSED *buf) { return FAIL; } + +/* Dummy VFD with the minimum parameters to make a VFD that can be registered */ +static const H5FD_class_t H5FD_dummy_g = { + "dummy", /* name */ + 1, /* maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ + NULL, /* terminate */ + NULL, /* sb_size */ + NULL, /* sb_encode */ + NULL, /* sb_decode */ + 0, /* fapl_size */ + NULL, /* fapl_get */ + NULL, /* fapl_copy */ + NULL, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + dummy_vfd_open, /* open */ + dummy_vfd_close, /* close */ + NULL, /* cmp */ + NULL, /* query */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ + dummy_vfd_get_eoa, /* get_eoa */ + dummy_vfd_set_eoa, /* set_eoa */ + dummy_vfd_get_eof, /* get_eof */ + NULL, /* get_handle */ + dummy_vfd_read, /* read */ + dummy_vfd_write, /* write */ + NULL, /* flush */ + NULL, /* truncate */ + NULL, /* lock */ + NULL, /* unlock */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ +}; + + +/*------------------------------------------------------------------------- + * Function: h5_get_dummy_vfd_class() + * + * Purpose: Returns a disposable, generally non-functional, + * VFD class struct. + * + * In some of the test code, we need a disposable VFD but + * we don't want to mess with the real VFDs and we also + * don't have access to the internals of the real VFDs (which + * use static globals and functions) to easily duplicate + * them (e.g.: for testing VFD ID handling). + * + * This API call will return a pointer to a VFD class that + * can be used to construct a test VFD using H5FDregister(). + * + * Return: Success: A pointer to a VFD class struct + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +H5FD_class_t * +h5_get_dummy_vfd_class(void) +{ + H5FD_class_t *vfd_class = NULL; /* Dummy VFD that will be returned */ + + /* Create the class and initialize everything to zero/NULL */ + if(NULL == (vfd_class = (H5FD_class_t *)HDmalloc(sizeof(H5FD_class_t)))) + TEST_ERROR; + + /* Copy the dummy VFD */ + HDmemcpy(vfd_class, &H5FD_dummy_g, sizeof(H5FD_class_t)); + + return vfd_class; + +error: + if(vfd_class) + HDfree(vfd_class); + return NULL; +} /* h5_get_dummy_vfd_class */ + +/*------------------------------------------------------------------------- + * Function: h5_get_version_string + * + * Purpose: Get the string that corresponds to the libvery version bound. + * + * Return: The string + * + *------------------------------------------------------------------------- + */ +char * +h5_get_version_string(H5F_libver_t libver) +{ + return(LIBVER_NAMES[libver]); +} /* end of h5_get_version_string */ |