Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates that allow accum SWMR tests to work on Windows #493

Merged
merged 6 commits into from
Mar 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/H5Tconv.c
Original file line number Diff line number Diff line change
Expand Up @@ -3843,7 +3843,7 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
size_t half_size; /*half the type size */
size_t olap; /*num overlapping elements */
uint8_t * s, *sp, *d, *dp; /*source and dest traversal ptrs*/
uint8_t * src_rev = NULL; /*order-reversed source buffer */
uint8_t * src_rev = NULL; /*order-reversed source buffer */
uint8_t dbuf[64] = {0}; /*temp destination buffer */
size_t first;
ssize_t sfirst; /*a signed version of `first' */
Expand Down Expand Up @@ -4286,7 +4286,7 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
size_t olap; /*num overlapping elements */
ssize_t bitno = 0; /*bit number */
uint8_t * s, *sp, *d, *dp; /*source and dest traversal ptrs*/
uint8_t * src_rev = NULL; /*order-reversed source buffer */
uint8_t * src_rev = NULL; /*order-reversed source buffer */
uint8_t dbuf[64] = {0}; /*temp destination buffer */
uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/

Expand Down Expand Up @@ -8401,7 +8401,7 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
size_t tsize; /*type size for swapping bytes */
size_t olap; /*num overlapping elements */
uint8_t * s, *sp, *d, *dp; /*source and dest traversal ptrs*/
uint8_t * src_rev = NULL; /*order-reversed source buffer */
uint8_t * src_rev = NULL; /*order-reversed source buffer */
uint8_t dbuf[64] = {0}; /*temp destination buffer */
uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/

Expand Down Expand Up @@ -9027,7 +9027,7 @@ H5T__conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz
size_t tsize; /*type size for swapping bytes */
size_t olap; /*num overlapping elements */
uint8_t * s, *sp, *d, *dp; /*source and dest traversal ptrs*/
uint8_t * src_rev = NULL; /*order-reversed source buffer */
uint8_t * src_rev = NULL; /*order-reversed source buffer */
uint8_t dbuf[64] = {0}; /*temp destination buffer */
uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/

Expand Down
162 changes: 102 additions & 60 deletions test/accum.c
Original file line number Diff line number Diff line change
Expand Up @@ -2074,13 +2074,14 @@ HDfprintf(stderr, "Random # seed was: %u\n", seed);
/*-------------------------------------------------------------------------
* 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.
* 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
Expand All @@ -2092,24 +2093,31 @@ HDfprintf(stderr, "Random # seed was: %u\n", seed);
unsigned
test_swmr_write_big(hbool_t newest_format)
{
#ifdef H5_HAVE_UNISTD_H

hid_t fid = -1; /* File ID */
hid_t fapl = -1; /* File access property list */
H5F_t * rf = NULL; /* File pointer */
char filename[1024];
uint8_t *wbuf2 = NULL, *rbuf = NULL; /* Buffers for reading & writing */
uint8_t wbuf[1024]; /* Buffer for reading & writing */
unsigned u; /* Local index variable */
pid_t pid; /* Process ID */
int status; /* Status returned from child process */
char * driver = NULL; /* VFD string (from env variable) */
hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */
hbool_t process_success = FALSE;
char * driver = NULL; /* VFD string (from env variable) */
hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */

if (newest_format)
TESTING("SWMR write of large metadata: with latest format")
else
TESTING("SWMR write of large metadata: with non-latest-format")

#if !defined(H5_HAVE_UNISTD_H) && !defined(H5_HAVE_WIN32_API)

/* Not a Windows or POSIX system */
SKIPPED();
HDputs(" Test skipped: Not a Windows or POSIX system.");
return 0;

#else
/* Skip this test if SWMR I/O is not supported for the VFD specified
* by the environment variable.
*/
Expand Down Expand Up @@ -2219,56 +2227,94 @@ test_swmr_write_big(hbool_t newest_format)
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 */
/* By convention, argv[0] tells the name of program invoked.
*
* execv on NetBSD 8 will actually return EFAULT if there is a
* NULL at argv[0], so we follow the convention unconditionally.
*/
char swmr_reader[] = SWMR_READER;
char *const new_argv[] = {swmr_reader, NULL};
/* Run the reader */
status = HDexecv(SWMR_READER, new_argv);
HDprintf("errno from execv = %s\n", HDstrerror(errno));
FAIL_STACK_ERROR;
} /* end if */
#if defined(H5_HAVE_WIN32_API)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD exit_code = EXIT_FAILURE;

/* Parent process -- wait for the child process to complete */
while (pid != HDwaitpid(pid, &status, 0))
/*void*/;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

/* Check if child process terminates normally and its return value */
if (WIFEXITED(status) && !WEXITSTATUS(status)) {
/* Flush the accumulator */
if (accum_reset(rf) < 0)
if (0 == CreateProcess(NULL, SWMR_READER, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
HDprintf("CreateProcess failed (%d).\n", GetLastError());
FAIL_STACK_ERROR;
}

/* Close and remove the file */
if (H5Fclose(fid) < 0)
FAIL_STACK_ERROR;
(void)WaitForSingleObject(pi.hProcess, INFINITE);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type of WaitForSingleObject() tells you why the wait stopped. We don't care about this and instead check the return value of the sub-program launched by CreateProcess().


if (FALSE == GetExitCodeProcess(pi.hProcess, &exit_code) || EXIT_FAILURE == exit_code)
process_success = FALSE;
else
process_success = TRUE;

/* Close the property list */
if (H5Pclose(fapl) < 0)
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
#else /* defined(H5_HAVE_WIN32_API) */
{
pid_t pid; /* Process ID */
int status; /* Status returned from child process */

/* 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 */
/* By convention, argv[0] tells the name of program invoked.
*
* execv on NetBSD 8 will actually return EFAULT if there is a
* NULL at argv[0], so we follow the convention unconditionally.
*/
char swmr_reader[] = SWMR_READER;
char *const new_argv[] = {swmr_reader, NULL};
/* Run the reader */
status = HDexecv(SWMR_READER, new_argv);
HDprintf("errno from execv = %s\n", HDstrerror(errno));
FAIL_STACK_ERROR;
} /* end if */

/* Pop API context */
if (api_ctx_pushed && H5CX_pop(FALSE) < 0)
FAIL_STACK_ERROR
api_ctx_pushed = FALSE;

/* Release memory */
if (wbuf2)
HDfree(wbuf2);
if (rbuf)
HDfree(rbuf);
PASSED();
return 0;
} /* 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))
process_success = TRUE;
}
#endif /* defined(H5_HAVE_WIN32_API) */

/* Check if the process terminated correctly */
if (!process_success)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:-? This seems opposite of the success state for non-WIN32 from before!

FAIL_PUTS_ERROR("child process exited abnormally")

/* Flush the accumulator */
if (accum_reset(rf) < 0)
FAIL_STACK_ERROR;

/* Close and remove the file */
if (H5Fclose(fid) < 0)
FAIL_STACK_ERROR;

/* Close the property list */
if (H5Pclose(fapl) < 0)
FAIL_STACK_ERROR;

/* Pop API context */
if (api_ctx_pushed && H5CX_pop(FALSE) < 0)
FAIL_STACK_ERROR
api_ctx_pushed = FALSE;

/* Release memory */
if (wbuf2)
HDfree(wbuf2);
if (rbuf)
HDfree(rbuf);

PASSED();
return 0;

error:
/* Closing and remove the file */
Expand All @@ -2287,11 +2333,7 @@ test_swmr_write_big(hbool_t newest_format)

return 1;

#else /* H5_HAVE_UNISTD_H */
SKIPPED();
HDputs(" Test skipped due to fork, waitpid, or pid_t not defined.");
return 0;
#endif /* H5_HAVE_UNISTD_H */
#endif /* !defined(H5_HAVE_UNISTD_H) && !defined(H5_HAVE_WIN32_API) */

} /* end test_swmr_write_big() */

Expand Down