Skip to content

MSVC phase 5: Windows subprocess API in CLI test runner (issue #71) - #182

Merged
dnovick merged 2 commits into
mainfrom
claude-msvc-phase5-test-runner
May 20, 2026
Merged

MSVC phase 5: Windows subprocess API in CLI test runner (issue #71)#182
dnovick merged 2 commits into
mainfrom
claude-msvc-phase5-test-runner

Conversation

@dnovick

@dnovick dnovick commented May 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds #ifdef _WIN32 / #else guard to cli_test_runner.hpp so the POSIX fork/pipe/poll/execv/waitpid code compiles only on POSIX; a new Windows path uses CreateProcessA, CreatePipe, PeekNamedPipe/ReadFile, WaitForSingleObject, and GetExitCodeProcess
  • Updates io_tests.hpp to replace <sys/stat.h>/<unistd.h> includes and ::stat()/::symlink() calls with #ifdef _WIN32 guarded Windows API equivalents (GetNamedSecurityInfoA for permission checks, CreateSymbolicLinkW for symlink creation with GTEST_SKIP if insufficient privilege)
  • Both the strip_trailing_newline parameter and all existing test logic are preserved unchanged

Test plan

🤖 Generated with Claude Code

Replace POSIX-only fork/pipe/poll/execv/waitpid in cli_test_runner.hpp
with a _WIN32-guarded CreateProcess/CreatePipe/PeekNamedPipe/ReadFile
implementation.  Update io_tests.hpp to replace POSIX stat/symlink calls
with Windows API equivalents guarded by _WIN32.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dnovick
dnovick force-pushed the claude-msvc-phase5-test-runner branch from 78930fb to 7ea9e6d Compare May 20, 2026 19:39
@dnovick

dnovick commented May 20, 2026

Copy link
Copy Markdown
Owner Author

Blocking review finding after the rebase: in the new Windows runner loop, has_new_data is computed from the current post-drain output size: out.size() + err.size() > (had_data_before ? out.size() + err.size() - 1U : 0U). Once either stream has any data, that expression remains true even when this iteration read zero bytes, so a child process that writes once and then keeps running will bypass both Sleep(1) and the WaitForSingleObject(..., 0) exit check and spin hot. Please compare against a saved byte count from before both drains, e.g. const auto before = out.size() + err.size(); ... const bool has_new_data = out.size() + err.size() > before;.

The previous expression compared against a stale sentinel that remained
true once any data had been read, causing the drain loop to skip the
Sleep(1)/WaitForSingleObject idle check and spin hot.  Save the total
byte count before both drain_pipe calls and compare against it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@dnovick
dnovick merged commit 7a0472f into main May 20, 2026
11 checks passed
@dnovick
dnovick deleted the claude-msvc-phase5-test-runner branch May 20, 2026 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant