Skip to content

testing: Fix POSIX result pipe EOF and descriptor ownership - #26082

Draft
Eleanor Boyd (eleanorjboyd) wants to merge 3 commits into
microsoft:mainfrom
eleanorjboyd:agents/vscode-python-issue-26071-feedback
Draft

Eleanor Boyd (eleanorjboyd) wants to merge 3 commits into
microsoft:mainfrom
eleanorjboyd:agents/vscode-python-issue-26071-feedback

Conversation

@eleanorjboyd

@eleanorjboyd Eleanor Boyd (eleanorjboyd) commented Jul 31, 2026 •

Copy link
Copy Markdown
Member

Summary

  • replace the POSIX FIFO net.Socket reader with a directly owned nonblocking reader that detects writer disconnect and closes its descriptor exactly once
  • honor parser-stream backpressure while draining buffered test results
  • signal pipe completion when pytest and unittest subprocess work ends, including empty-writer and failed-spawn paths
  • explicitly dispose result-pipe resources after the drain timeout fallback
  • add real POSIX FIFO coverage for buffered payloads, backpressure, empty writers, cancellation, and adapter cleanup

Why

The previous implementation gave the same FIFO descriptor to both net.Socket and an explicit fs.close(fd) callback. On Linux, the socket could close the descriptor, the OS could reuse that descriptor number, and the asynchronous second close could close an unrelated descriptor and abort the extension host.

The socket reader also did not surface FIFO EOF, causing completed test runs to wait for the five-second drain fallback. The new reader owns the descriptor for its full lifecycle, drains to EOF, observes backpressure, and receives explicit completion signals from test adapters so short empty writers or failed subprocess launches do not leave polling readers behind.

Validation

  • npx gulp prePublishNonBundle
  • ESLint on all changed TypeScript files
  • Prettier check on all changed TypeScript files
  • 39 targeted unit tests covering POSIX named pipes plus pytest/unittest discovery, execution, cancellation, and cleanup

Fixes #26071
Fixes #26173

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a POSIX FIFO EOF detection gap in the test result named-pipe reader that caused test runs to regularly wait for the 5s RESULT_PIPE_DRAIN_TIMEOUT_MS fallback after the Python subprocess exited. It replaces the FIFO net.Socket reader with a direct FD reader that can reliably settle onClose on writer disconnect, and updates adapters to explicitly dispose result-pipe resources after the drain/timeout window.

Changes:

  • Replace the POSIX FIFO reader implementation to detect writer EOF and fire close reliably (FifoMessageReader).
  • Change startRunResultNamedPipe() to return an owned { name, dispose } handle and have pytest/unittest execution adapters dispose it after drain/timeout.
  • Update/extend unit tests to cover POSIX FIFO reader behavior and adapter disposal during cancellation.
Show a summary per file
File Description
src/client/common/pipes/namedPipes.ts Adds a POSIX FIFO FD-based message reader and wires it into createReaderPipe().
src/client/testing/testController/common/utils.ts Changes startRunResultNamedPipe() to return an owned handle with a dispose() method.
src/client/testing/testController/pytest/pytestExecutionAdapter.ts Uses resultPipe.name and disposes the result pipe after drain/timeout.
src/client/testing/testController/unittest/testExecutionAdapter.ts Uses resultPipe.name and disposes the result pipe after drain/timeout.
src/test/common/pipes/namedPipes.unit.test.ts Adds POSIX FIFO tests for buffered payloads, empty writer, and cancellation close.
src/test/testing/testController/pytest/pytestExecutionAdapter.unit.test.ts Updates stubs to match the new { name, dispose } result-pipe return type.
src/test/testing/testController/unittest/testExecutionAdapter.unit.test.ts Updates stubs to match the new { name, dispose } result-pipe return type.
src/test/testing/testController/testCancellationRunAdapters.unit.test.ts Asserts the adapter disposes the result-pipe handle during cancellation flows.

Review details

  • Files reviewed: 8/8 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines +197 to +201
if (bytesRead > 0) {
this.hasReadData = true;
this.stream.write(Buffer.from(this.buffer.subarray(0, bytesRead)));
continue;
}
Drain nonblocking FIFO readers to EOF and explicitly dispose result pipes after the fallback timeout.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the disposable result pipe handle returned by the updated test utility.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Honor parser backpressure and signal pipe completion when test subprocess work ends so empty or failed writers cannot leave polling readers behind. Add focused coverage for backpressure and empty-writer cleanup.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eleanorjboyd
Eleanor Boyd (eleanorjboyd) force-pushed the agents/vscode-python-issue-26071-feedback branch from 0edcb77 to eec9b72 Compare September 29, 2026 20:33
@eleanorjboyd Eleanor Boyd (eleanorjboyd) changed the title testing: Close POSIX result pipes on FIFO EOF testing: Fix POSIX result pipe EOF and descriptor ownership Sep 29, 2026
@eleanorjboyd
Eleanor Boyd (eleanorjboyd) marked this pull request as ready for review September 29, 2026 20:33
@eleanorjboyd
Eleanor Boyd (eleanorjboyd) marked this pull request as draft September 29, 2026 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Issue identified by VS Code Team member as probable bug

Projects

None yet

2 participants