-
Notifications
You must be signed in to change notification settings - Fork 11
Add timed test suite wrapper macros for process_watchdog integration #520
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
base: master
Are you sure you want to change the base?
Conversation
Types are now provided by windows.h which is always included first.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
/AzurePipelines run #Resolved |
|
Azure Pipelines successfully started running 1 pipeline(s). #Resolved |
|
/AzurePipelines run #Resolved |
|
Azure Pipelines successfully started running 1 pipeline(s). #Resolved |
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
/AzurePipelines run #Resolved |
|
Azure Pipelines successfully started running 1 pipeline(s). #Resolved |
|
/AzurePipelines run #Resolved |
|
Azure Pipelines successfully started running 1 pipeline(s). #Resolved |
common/tests/CMakeLists.txt
Outdated
| build_test_folder(thandle_ptr_ut) | ||
| build_test_folder(real_thandle_log_context_handle_ut) | ||
| build_test_folder(tqueue_ut) | ||
| add_subdirectory(timed_test_suite_ut) |
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.
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.
Changed to use c-testrunnerswitcher.
| if (timed_test_suite_ut_succeeded() != 0) | ||
| { | ||
| // Final validation of fixture ordering has failed | ||
| failedTests++; |
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.
can we Log something here? #Resolved
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.
Added log
| add_subdirectory(timed_test_suite_ut) | ||
| endif() | ||
|
|
||
| if(${run_int_tests}) |
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.
Consider an int test that demonstrates the timeout works. I guess since the process_watchdog will terminate, the test would probably need to launch that process and make sure it gets terminated within the timeout (+ delta) #Resolved
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.
Added int test.
mattdurak
left a comment
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.
![]()
| static int call_counter = 0; | ||
|
|
||
| // Mock process_watchdog functions | ||
| int process_watchdog_init(uint32_t timeout_ms) |
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.
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.
This is called inside TIMED_TEST_SUITE_INITIALIZE macro.
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.
Added specs and comment.
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
|
||
| // The child should NOT have exited cleanly (it was terminated by watchdog) | ||
| // On Windows, LogCriticalAndTerminate calls TerminateProcess which can give various exit codes | ||
| ASSERT_ARE_NOT_EQUAL(int, CHILD_EXIT_CODE_SURVIVED_TIMEOUT, exit_code, |
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.
That's not true, it calls abort(). #Resolved
| ASSERT_IS_NOT_NULL(dir); | ||
| int snprintf_result = snprintf(buffer, buffer_size, "%s/../process_watchdog_int_child/process_watchdog_int_child", dir); | ||
| ASSERT_IS_TRUE(snprintf_result > 0 && (size_t)snprintf_result < buffer_size); | ||
| } |
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.
Add comment explaining this. in windows too. #Resolved
| { | ||
| // Child process - exec the test program | ||
| char timeout_str[32]; | ||
| (void)snprintf(timeout_str, sizeof(timeout_str), "%" PRIu32, timeout_ms); |
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.
| execl(exe_path, exe_path, timeout_str, NULL); | ||
|
|
||
| // If execl returns, it failed | ||
| (void)fprintf(stderr, "execl failed: %s\n", strerror(errno)); |
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.
| LogError("waitpid failed with error: %s", strerror(errno)); | ||
| result = -1; | ||
| } | ||
| else if (WIFEXITED(status)) |
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.
…ests - Fix comment: watchdog calls abort(), not TerminateProcess - Add comments explaining WIFEXITED/WIFSIGNALED/WTERMSIG on Linux - Add comments explaining WaitForSingleObject/GetExitCodeProcess on Windows - Add comments explaining get_child_exe_path path construction logic - Add snprintf error handling in forked child (can't use ASSERT in child) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
/AzurePipelines run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
| "Process terminated too late: %.0f ms > %d ms", elapsed_ms, WATCHDOG_TIMEOUT_MS + TOLERANCE_MS); | ||
|
|
||
| // The child should NOT have exited cleanly (it was terminated by watchdog) | ||
| // On Windows, the watchdog calls abort() which terminates the process |
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.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
/AzurePipelines run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
|
/AzurePipelines run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
|
/AzurePipelines run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
| /*Codes_SRS_TIMED_TEST_SUITE_43_003: [ TIMED_TEST_SUITE_INITIALIZE shall call TEST_SUITE_INITIALIZE with the watchdog init fixture as the first fixture, followed by any additional fixtures passed via variadic arguments. ]*/ | ||
| /*Codes_SRS_TIMED_TEST_SUITE_43_004: [ The watchdog init fixture shall execute before the user's initialization code. ]*/ | ||
| #define TIMED_TEST_SUITE_INITIALIZE(name, timeout_ms, ...) \ | ||
| static void MU_C2(timed_test_watchdog_init_, name)(void) { (void)process_watchdog_init(timeout_ms); } \ |
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.
| { | ||
| int result; | ||
|
|
||
| LogInfo("Launching child process: %s %" PRIu32, exe_path, timeout_ms); |
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.
| pid_t pid = fork(); | ||
| if (pid < 0) | ||
| { | ||
| LogError("fork failed with error: %s", strerror(errno)); |
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.
| if (snprintf_result < 0 || (size_t)snprintf_result >= sizeof(timeout_str)) | ||
| { | ||
| (void)fprintf(stderr, "snprintf failed for timeout_ms\n"); | ||
| _exit(126); |
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.
| } | ||
| else | ||
| { | ||
| execl(exe_path, exe_path, timeout_str, NULL); |
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.
| execl(exe_path, exe_path, timeout_str, NULL); | ||
|
|
||
| // If execl returns, it failed. fprintf return value is ignored since we're exiting immediately | ||
| (void)fprintf(stderr, "execl failed: %s\n", strerror(errno)); |
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.
|
|
||
| // Sleep longer than the timeout - the watchdog should terminate us | ||
| uint32_t sleep_time_ms = timeout_ms * 2; | ||
| usleep(sleep_time_ms * 1000); |
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.
| } | ||
| else | ||
| { | ||
| uint32_t timeout_ms = (uint32_t)atoi(argv[1]); |
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.
|
|
||
| // Sleep longer than the timeout - the watchdog should terminate us | ||
| uint32_t sleep_time_ms = timeout_ms * 2; | ||
| Sleep(sleep_time_ms); |
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.
dcristoloveanu
left a comment
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.
![]()
| // Navigate up one level (..) then into the child test directory | ||
| int snprintf_result = snprintf(buffer, buffer_size, "%s\\..\\process_watchdog_int_child\\process_watchdog_int_child.exe", module_path); | ||
| ASSERT_IS_TRUE(snprintf_result > 0 && (size_t)snprintf_result < buffer_size); | ||
| } |
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.
consider just setting the exe as a dependency in cmake (which is better anyway so you can't build this test without the dependent exe) and then the exe ends up in the same directory as the test (so no directory navigation needed here)
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.
Seems the dependency is added, so the exe should be present in the current directory
| // Navigate up one level (..) then into the child test directory | ||
| int snprintf_result = snprintf(buffer, buffer_size, "%s/../process_watchdog_int_child/process_watchdog_int_child", dir); | ||
| ASSERT_IS_TRUE(snprintf_result > 0 && (size_t)snprintf_result < buffer_size); | ||
| } |
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.
same comment as in windows that this should just be in the current directory already
Summary
TIMED_TEST_SUITE_INITIALIZEandTIMED_TEST_SUITE_CLEANUPmacros incommon/inc/c_pal/timed_test_suite.hprocess_watchdogDependencies