-
-
Notifications
You must be signed in to change notification settings - Fork 275
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
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
ba9deae
Committing clang-format changes
github-actions[bot] 00f9750
Merge remote-tracking branch 'canonical/develop' into develop
2734f06
Updates the accum test to work on Windows
f7219fb
Source formatting
9fd8e12
Fix for Unix child result
a6f93db
Fixes process return code bug on Windows
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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. | ||
*/ | ||
|
@@ -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); | ||
|
||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 */ | ||
|
@@ -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() */ | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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().