Merge SWMR-oriented accumulator tests from revise_chunks to develop.

This commit is contained in:
Quincey Koziol 2016-12-18 00:41:13 -08:00
parent 700c6ae985
commit b772be716d
3 changed files with 227 additions and 2 deletions

View File

@ -884,6 +884,7 @@
./test/H5srcdir_str.h.in
./test/Makefile.am
./test/accum.c
./test/accum_swmr_reader.c
./test/app_ref.c
./test/bad_compound.h5
./test/be_data.h5

View File

@ -53,12 +53,13 @@ TEST_PROG= testhdf5 cache cache_api cache_tagging lheap ohdr stab gheap \
# List programs to be built when testing here.
# error_test and err_compat are built at the same time as the other tests, but executed by testerror.sh.
# tcheck_version is used by testcheck_version.sh.
# accum_swmr_reader is used by accum.c.
# links_env is used by testlinks_env.sh
# 'make check' doesn't run them directly, so they are not included in TEST_PROG.
# Also build testmeta, which is used for timings test. It builds quickly,
# and this lets automake keep all its test programs in one place.
check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version \
testmeta \
testmeta accum_swmr_reader \
links_env
if HAVE_SHARED_CONDITIONAL
check_PROGRAMS+= plugin
@ -162,6 +163,7 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse
split_get_file_image_test-m.h5 split_get_file_image_test-r.h5 \
file_image_core_test.h5.copy unregister_filter_1.h5 unregister_filter_2.h5 \
vds_virt.h5 vds_dapl.h5 vds_src_[0-1].h5 \
accum_swmr_big.h5 \
cache_logging.h5 cache_logging.out \
swmr[0-2].h5
# Sources for testhdf5 executable

View File

@ -18,13 +18,20 @@
#include "h5test.h"
#define H5F_FRIEND /*suppress error about including H5Fpkg */
#define H5FD_FRIEND /*suppress error about including H5FDpkg */
#define H5FD_TESTING
#include "H5Fpkg.h"
#include "H5FDprivate.h"
#include "H5FDpkg.h"
#include "H5Iprivate.h"
/* Filename */
#define FILENAME "accum.h5"
/* The file name is the same as the define in accum_swmr_reader.c */
#define SWMR_FILENAME "accum_swmr_big.h5"
/* The reader forked by test_swmr_write_big() */
#define SWMR_READER "accum_swmr_reader"
/* "big" I/O test values */
#define BIG_BUF_SIZE (6 * 1024 * 1024)
@ -50,6 +57,7 @@ unsigned test_read_after(const H5F_io_info_t *fio_info);
unsigned test_free(const H5F_io_info_t *fio_info);
unsigned test_big(const H5F_io_info_t *fio_info);
unsigned test_random_write(const H5F_io_info_t *fio_info);
unsigned test_swmr_write_big(hbool_t newest_format);
/* Helper Function Prototypes */
void accum_printf(void);
@ -124,6 +132,10 @@ main(void)
if(H5Fclose(fid) < 0) TEST_ERROR
HDremove(FILENAME);
/* This test uses a different file */
nerrors += test_swmr_write_big(TRUE);
nerrors += test_swmr_write_big(FALSE);
if(nerrors)
goto error;
puts("All metadata accumulator tests passed.");
@ -1777,6 +1789,216 @@ error:
return 1;
} /* end test_random_write() */
/*-------------------------------------------------------------------------
* Function: test_swmr_write_big
*
* Purpose: A SWMR test: verifies that writing "large" metadata to a file
* opened with SWMR_WRITE will flush the existing metadata in the
* accumulator to disk first before writing the "large" metadata
* to disk.
* This test will fork and exec a reader "accum_swmr_reader" which
* opens the same file with SWMR_READ and verifies that the correct
* metadata is read from disk.
*
* Return: Success: 0
* Failure: 1
*
* Programmer: Vailin Choi; April 2013
*
*-------------------------------------------------------------------------
*/
unsigned
test_swmr_write_big(hbool_t newest_format)
{
hid_t fid = -1; /* File ID */
hid_t fapl = -1; /* File access property list */
H5F_t *rf = NULL; /* File pointer */
uint8_t *wbuf2 = NULL, *rbuf = NULL; /* Buffers for reading & writing */
uint8_t wbuf[1024]; /* Buffer for reading & writing */
unsigned u; /* Local index variable */
#ifdef H5_HAVE_UNISTD_H
pid_t pid; /* Process ID */
#endif /* H5_HAVE_UNISTD_H */
int status; /* Status returned from child process */
H5F_io_info_t fio_info; /* I/O info for operation */
char *new_argv[] = {NULL};
char *driver = NULL; /* VFD string (from env variable) */
if(newest_format) {
TESTING("SWMR write of large metadata: with latest format");
} else {
TESTING("SWMR write of large metadata: with non-latest-format");
} /* end if */
#if !(defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID))
SKIPPED();
HDputs(" Test skipped due to fork or waitpid not defined.");
return 0;
#else /* defined(H5_HAVE_FORK && defined(H5_HAVE_WAITPID) */
/* Skip this test if SWMR I/O is not supported for the VFD specified
* by the environment variable.
*/
driver = HDgetenv("HDF5_DRIVER");
if (!H5FD_supports_swmr_test(driver)) {
SKIPPED();
HDputs(" Test skipped due to VFD not supporting SWMR I/O.");
return 0;
} /* end if */
/* File access property list */
if((fapl = h5_fileaccess()) < 0)
FAIL_STACK_ERROR
/* Both cases will result in v3 superblock and version 2 object header for SWMR */
if(newest_format) { /* latest format */
if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
FAIL_STACK_ERROR
if((fid = H5Fcreate(SWMR_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
FAIL_STACK_ERROR
} else { /* non-latest-format */
if((fid = H5Fcreate(SWMR_FILENAME, H5F_ACC_TRUNC|H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl)) < 0)
FAIL_STACK_ERROR
} /* end if */
/* Close the file */
if(H5Fclose(fid) < 0)
FAIL_STACK_ERROR
/* Open the file with SWMR_WRITE */
if((fid = H5Fopen(SWMR_FILENAME, H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE, fapl)) < 0)
FAIL_STACK_ERROR
/* Get H5F_t * to internal file structure */
if(NULL == (rf = (H5F_t *)H5I_object(fid))) FAIL_STACK_ERROR
/* Set up I/O info for operation */
fio_info.f = rf;
if(NULL == (fio_info.dxpl = (H5P_genplist_t *)H5I_object(H5AC_ind_read_dxpl_id)))
FAIL_STACK_ERROR
/* We'll be writing lots of garbage data, so extend the
file a ways. 10MB should do. */
if(H5FD_set_eoa(rf->shared->lf, H5FD_MEM_DEFAULT, (haddr_t)(1024*1024*10)) < 0)
FAIL_STACK_ERROR
if(H5Fflush(fid, H5F_SCOPE_GLOBAL) < 0)
FAIL_STACK_ERROR;
/* Reset metadata accumulator for the file */
if(accum_reset(&fio_info) < 0)
FAIL_STACK_ERROR;
/* Allocate space for the write & read buffers */
if((wbuf2 = (uint8_t *)HDmalloc((size_t)BIG_BUF_SIZE)) == NULL)
FAIL_STACK_ERROR;
if((rbuf = (uint8_t *)HDmalloc((size_t)BIG_BUF_SIZE)) == NULL)
FAIL_STACK_ERROR;
/* Initialize wbuf with "0, 1, 2...1024"*/
for(u = 0; u < 1024; u++)
wbuf[u] = (uint8_t)u;
/* Write [1024, 1024] bytes with wbuf */
if(H5F_block_write(rf, H5FD_MEM_DEFAULT, (haddr_t)1024, (size_t)1024, H5AC_ind_read_dxpl_id, wbuf) < 0)
FAIL_STACK_ERROR;
/* Read the data */
if(H5F_block_read(rf, H5FD_MEM_DEFAULT, (haddr_t)1024, (size_t)1024, H5AC_ind_read_dxpl_id, rbuf) < 0)
FAIL_STACK_ERROR;
/* Verify the data read is correct */
if(HDmemcmp(wbuf, rbuf, (size_t)1024) != 0)
TEST_ERROR;
/* Flush the data to disk */
if(accum_reset(&fio_info) < 0)
FAIL_STACK_ERROR;
/* Initialize wbuf with all 1s */
for(u = 0; u < 1024; u++)
wbuf[u] = (uint8_t)1;
/* Initialize wbuf2 */
for(u = 0; u < BIG_BUF_SIZE; u++)
wbuf2[u] = (uint8_t)(u + 1);
/* Write [1024,1024] with wbuf--all 1s */
if(H5F_block_write(rf, H5FD_MEM_DEFAULT, (haddr_t)1024, (size_t)1024, H5AC_ind_read_dxpl_id, wbuf) < 0)
FAIL_STACK_ERROR;
/* Read the data */
if(H5F_block_read(rf, H5FD_MEM_DEFAULT, (haddr_t)1024, (size_t)1024, H5AC_ind_read_dxpl_id, rbuf) < 0)
FAIL_STACK_ERROR;
/* Verify the data read is correct */
if(HDmemcmp(wbuf, rbuf, (size_t)1024) != 0)
TEST_ERROR;
/* The data stays in the accumulator */
/* Write a large piece of metadata [2048, BIG_BUF_SIZE] with wbuf2 */
if(H5F_block_write(rf, H5FD_MEM_DEFAULT, (haddr_t)2048, (size_t)BIG_BUF_SIZE, H5AC_ind_read_dxpl_id, wbuf2) < 0)
FAIL_STACK_ERROR;
/* Read the data */
if(H5F_block_read(rf, H5FD_MEM_DEFAULT, (haddr_t)2048, (size_t)BIG_BUF_SIZE, H5AC_ind_read_dxpl_id, rbuf) < 0)
FAIL_STACK_ERROR;
/* Verify the data read is correct */
if(HDmemcmp(wbuf2, rbuf, (size_t)BIG_BUF_SIZE) != 0)
TEST_ERROR;
/* Fork child process to verify that the data at [1024, 2014] does get written to disk */
if((pid = HDfork()) < 0) {
HDperror("fork");
FAIL_STACK_ERROR;
} else if(0 == pid) { /* Child process */
/* Run the reader */
status = HDexecv(SWMR_READER, new_argv);
printf("errno from execv = %s\n", strerror(errno));
FAIL_STACK_ERROR;
} /* end if */
/* Parent process -- wait for the child process to complete */
while(pid != HDwaitpid(pid, &status, 0))
/*void*/;
/* Check if child process terminates normally and its return value */
if(WIFEXITED(status) && !WEXITSTATUS(status)) {
/* Flush the accumulator */
if(accum_reset(&fio_info) < 0)
FAIL_STACK_ERROR;
/* Close the property list */
if(H5Pclose(fapl) < 0)
FAIL_STACK_ERROR;
/* Close and remove the file */
if(H5Fclose(fid) < 0)
FAIL_STACK_ERROR;
HDremove(SWMR_FILENAME);
/* Release memory */
if(wbuf2)
HDfree(wbuf2);
if(rbuf)
HDfree(rbuf);
PASSED();
return 0;
} /* end if */
error:
/* Closing and remove the file */
H5Pclose(fapl);
H5Fclose(fid);
HDremove(SWMR_FILENAME);
/* Release memory */
if(wbuf2)
HDfree(wbuf2);
if(rbuf)
HDfree(rbuf);
return 1;
#endif
} /* end test_swmr_write_big() */
/*-------------------------------------------------------------------------
* Function: accum_printf