[tests] Don't crash macOS test runner on late log output - #26321
Conversation
…rives late
The 'arm64 - Mac Golden Gate (27) macOS tests' job failed twice on this PR even
though every test passed:
5 suites passed, 0 suites failed.
Wrote 792232215 bytes to .../DiagnosticReports/system.log
Unhandled exception. System.ObjectDisposedException: Cannot write to a closed TextWriter.
at System.IO.StreamWriter.WriteLine(String value)
at Program.<>c__DisplayClass0_1.<<Main>$>b__11(Object _, DataReceivedEventArgs e)
at System.Diagnostics.AsyncStreamReader.FlushMessageQueue(Boolean rethrowInNewThread)
We run 'log stream' with both stdout and stderr redirected to asynchronous
handlers that write to a StreamWriter. On shutdown we SIGINT it and call
WaitForExit (10_000), but that overload only waits for the process to exit, not
for the asynchronous handlers to finish delivering buffered output - the same
caveat ExecuteWithTimeout already documents. So a queued line could still be
delivered after the writer was disposed and throw on a thread pool thread,
which is unhandled and fails the job even when all the tests passed. The
several hundred megabytes of 'log stream' output make the window easy to hit
on a loaded bot.
Guard the writes with a flag set under the same lock the handlers already take,
so a late callback becomes a no-op instead of an unhandled exception, and stop
reading once we're done. Also drain the handlers before disposing so we don't
lose the tail of the log, but do it on a background thread with a timeout: the
parameterless WaitForExit () can block indefinitely if anything still holds the
redirected pipes, and hanging the job for hours would be worse than the crash
this fixes.
Note this is a test-infrastructure fix rather than a ScreenCaptureKit change.
It is included here because the bug reproducibly blocks this PR's CI.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ebf4376b-3b4c-4492-acef-18607e6f4ea1
Bound every log-stream shutdown step so test completion cannot hang indefinitely, and force-terminate the specific log process if SIGINT is ignored. Report drain, flush, and disposal failures instead of silently truncating diagnostics or allowing cleanup exceptions to fail an otherwise successful test run. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f09fc2f9-a071-47c6-84ff-02aa45e9e0c0
Move the macOS test-runner race fix to #26321 targeting main, as requested in review. Keep this PR focused on the ScreenCaptureKit binding update; the infrastructure fix can flow from main to xcode27.0 independently if needed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f09fc2f9-a071-47c6-84ff-02aa45e9e0c0
There was a problem hiding this comment.
Pull request overview
This PR hardens the macOS packaged test runner’s diagnostic logging shutdown so that late asynchronous log stream output callbacks can’t crash the runner after all test suites have already completed.
Changes:
- Prevent
ObjectDisposedExceptionby gatinglog streamoutput handlers on alogStreamWriterClosedflag synchronized via the writer lock. - Bound shutdown waits (SIGINT → timed wait → Kill fallback → bounded output drain) to avoid cleanup hangs.
- Convert shutdown/flush/dispose failures into warnings so a successful test run doesn’t fail during teardown.
✅ API diff for current PR / commitNET (empty diffs)✅ API diff vs stableNET (empty diffs)ℹ️ Generator diffGenerator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes) Pipeline on Agent |
🚀 [CI Build #0809d94] Test results 🚀Test results✅ All tests passed on VSTS: test results. 🎉 All 203 tests passed 🎉 Tests counts✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download macOS tests✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download Linux Build VerificationPipeline on Agent |
Summary
log streamcallbacks from writing after the diagnosticStreamWriteris closedRoot cause
The macOS 27 test leg twice completed all suites successfully, then failed while shutting down diagnostic logging:
WaitForExit (10_000)waited for the process but not the asynchronous output handlers, so bufferedDataReceivedcallbacks could arrive after writer disposal.This was split from #26280 at reviewer request so the infrastructure fix can flow through
mainindependently.Validation
scripts/run-packaged-macos-tests/run-packaged-macos-tests.csprojwith 0 warnings and 0 errors