Title: tests: resolve TOCTOU port race conditions for streamable-HTTP/SSE tests by Ar-maan05 · Pull Request #2705 · modelcontextprotocol/python-sdk · GitHub
Open Graph Title: tests: resolve TOCTOU port race conditions for streamable-HTTP/SSE tests by Ar-maan05 · Pull Request #2705 · modelcontextprotocol/python-sdk
X Title: tests: resolve TOCTOU port race conditions for streamable-HTTP/SSE tests by Ar-maan05 · Pull Request #2705 · modelcontextprotocol/python-sdk
Description: This PR resolves intermittent test failures and flakiness in the CI matrix (specifically under pytest -n auto parallelism) caused by a time-of-check/time-of-use (TOCTOU) port race when allocating ports for test servers. Closes #2704 Root Cause Previously, test server port fixtures bound to 127.0.0.1:0 to find a free port, then closed the socket immediately to return the port number. Between this allocation and the server starting in a separate multiprocessing.Process to bind that port, another parallel worker could be assigned the same port. This caused two primary issues: OSError: [Errno 98] Address already in use (failing to start the server) Crossed/interleaved connections where a client connects to the wrong test server instance. Solution I converted the server processes to bind their socket ephemerally (127.0.0.1:0) and called listen() inside the child process itself. The socket remains open and in a listening state throughout the process lifecycle. The child process reports its dynamically allocated port back to the parent process using a unidirectional multiprocessing.Pipe. • This fully closes the TOCTOU gap because the socket is never closed between check and use. • It removes the need for wait_for_server polling (since the socket is already listening before the fixture yields). • It remains fully cross-platform compatible as it does not require inheriting or pickling socket descriptors across process boundaries (only the pipe connection and integers are sent across process boundaries). Affected Files Migrated • tests/shared/test_streamable_http.py • tests/shared/test_sse.py • tests/server/test_sse_security.py • tests/server/test_streamable_http_security.py • tests/client/test_http_unicode.py Other Cleanups • Added a reusable running_server context manager in tests/test_helpers.py. • Removed the unused wait_for_server helper from tests/test_helpers.py to maintain 100% test coverage. • Updated affected test cases to consume these fixtures directly as URL strings, avoiding unnecessary server startups. Verification Automated Tests uv run --frozen --no-default-groups --group dev pytest • Result: 1271 passed (1172 passed, 98 skipped, 1 xfailed). Linting & Formatting uv run --frozen --no-default-groups --group dev ruff check . uv run --frozen --no-default-groups --group dev pyright • Result: 0 errors, 0 warnings. Test Coverage uv run --frozen --no-default-groups --group dev coverage report • Result: 100.00% Coverage (19,675 statements, 0 missed).
Open Graph Description: This PR resolves intermittent test failures and flakiness in the CI matrix (specifically under pytest -n auto parallelism) caused by a time-of-check/time-of-use (TOCTOU) port race when allocating p...
X Description: This PR resolves intermittent test failures and flakiness in the CI matrix (specifically under pytest -n auto parallelism) caused by a time-of-check/time-of-use (TOCTOU) port race when allocating p...
Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/pull/2705
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:beef0516-e56f-e9ed-61ca-affbebc25a64 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | 952A:30B305:B3F086:F3351E:6A5A91FD |
| html-safe-nonce | 3dbbce2e5c1b38b7d0f900f951778a277dac662e51b9bdf689d17571be550b48 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5NTJBOjMwQjMwNTpCM0YwODY6RjMzNTFFOjZBNUE5MUZEIiwidmlzaXRvcl9pZCI6Ijg3ODE4ODA0NzQ2OTg2ODI4NzciLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 3fb9e39fb6edb45101d0f272083aed4db47950cb03f21ab1d3f20acd1231f113 |
| hovercard-subject-tag | pull_request:3760832237 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/modelcontextprotocol/python-sdk/pull/2705/files |
| twitter:image | https://avatars.githubusercontent.com/u/74664101?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/74664101?s=400&v=4 |
| og:image:alt | This PR resolves intermittent test failures and flakiness in the CI matrix (specifically under pytest -n auto parallelism) caused by a time-of-check/time-of-use (TOCTOU) port race when allocating p... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 9989a1a1d89aa5a38a19e5d0c7ee88a8ffde84acde90048990492aae52f235db |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/modelcontextprotocol/python-sdk git https://github.com/modelcontextprotocol/python-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 862584018 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/python-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 862584018 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/python-sdk |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | ba6769fbf719c56dbf7bed650ce454dafc5b1528 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width