Skip to content

Fix HTTPS httpx mocking in wrap_bio() plus regressions occurred#324

Merged
mindflayer merged 19 commits into
mainfrom
copilot/fix-failing-github-actions-job
Jul 13, 2026
Merged

Fix HTTPS httpx mocking in wrap_bio() plus regressions occurred#324
mindflayer merged 19 commits into
mainfrom
copilot/fix-failing-github-actions-job

Conversation

Copilot AI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What this MR fixes

This MR resolves async networking regressions introduced while fixing large-response behavior, and stabilizes HTTP/SSL mocking across httpx and aiohttp.

1) Large async response hang (test_async_case_high_number)

  • Fixed a deadlock caused by writing large mocked responses directly into OS pipes.
  • Introduced a hybrid pipe strategy:
    • small responses mirror bytes into pipes (legacy-compatible behavior),
    • large responses use bounded readiness signaling to avoid pipe-buffer blocking.
  • Kept response payloads in shared in-memory buffers per address.

2) aiohttp SSL failures (test_aiohttp)

  • Fixed ServerDisconnectedError / SSL read-loop instability by decoupling SSL reads from shared socket cursor state.
  • MocketSSLSocket now keeps a private pending SSL read buffer snapshot after writes, so protocol reads are deterministic across runtimes.
  • Preserved expected pre-write SSL probing behavior (SSLWantReadError before first write after handshake).

3) Multi-socket regression during full test run

  • Fixed TypeError: 'NoneType' object cannot be interpreted as an integer in recv() when called via recv_into() with buffersize=None and pipe-backed reads.
  • recv() now normalizes None to the socket default buffer size.

4) PyPy compatibility regression (BufferError)

  • Fixed BufferError: Existing exports of data: object cannot be re-sized seen in true-send HTTP flows on PyPy.
  • Root cause: BytesIO.getbuffer() exports remained active while later writes resized the buffer.
  • Replaced resize-sensitive getbuffer() reads with getvalue()-based logic in socket buffering paths.

5) Coverage recovery for new logic

  • Added targeted tests for:
    • shared per-address I/O behavior,
    • pipe-mode flags and reset behavior,
    • large-response readiness sentinel drain/resync path,
    • SSL read behavior around handshake/write ordering,
    • empty server_hostname handling in SSL bio wrapping,
    • getpeercert() fallback to Mocket._address when host/port are unset.

Result

  • Local full test target passes (make test).
  • Previously failing async paths (httpx high payload + aiohttp SSL flow) now pass consistently.
  • PyPy-specific true-send path is stable again.
  • Coverage remains high (overall 99%; mocket/socket.py and mocket/ssl/socket.py at 100%).
  • Latest local run: 228 passed, 3 xfailed (+ tests/test_pook.py passed).

@mindflayer mindflayer marked this pull request as ready for review July 13, 2026 06:29
Copilot AI review requested due to automatic review settings July 13, 2026 06:29
Copilot AI changed the title [WIP] Fix failing GitHub Actions job "build (3.10)" Fix HTTPS httpx mocking in wrap_bio() for the Python 3.10 build Jul 13, 2026
Copilot AI requested a review from mindflayer July 13, 2026 06:32

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 adjusts Mocket’s fake SSLContext.wrap_bio() behavior to better match how HTTPS clients (notably httpx on Python 3.10) provide/expect server_hostname, and adds a focused regression test to ensure the SSL object reflects the currently connected Mocket address.

Changes:

  • Decode server_hostname when it is passed as bytes (UTF-8 with replacement) so internal host handling stays string-based.
  • When server_hostname is None, derive the host/port (and _address) from Mocket._address to preserve expected HTTPS behavior.
  • Add a parametrized test covering bytes/str/None/empty/invalid-byte hostnames for wrap_bio().

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
tests/test_socket.py Adds a regression test asserting wrap_bio() populates _host, _port, and _address consistently (including bytes hostname decoding).
mocket/ssl/context.py Updates MocketSSLContext.wrap_bio() to normalize server_hostname and to use Mocket._address for host/port derivation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.66667% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.09%. Comparing base (c5daccb) to head (2329887).

Files with missing lines Patch % Lines
mocket/socket.py 86.25% 11 Missing ⚠️
mocket/ssl/socket.py 92.59% 2 Missing ⚠️
mocket/ssl/context.py 92.85% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #324      +/-   ##
==========================================
- Coverage   99.06%   98.09%   -0.98%     
==========================================
  Files          22       22              
  Lines        1075     1207     +132     
==========================================
+ Hits         1065     1184     +119     
- Misses         10       23      +13     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment thread mocket/socket.py Outdated
Comment thread mocket/ssl/context.py
Comment on lines +126 to +131
effective_host = hostname if hostname is not None else current_host
ssl_obj._host = effective_host
if current_port is not None:
ssl_obj._port = current_port
if effective_host is not None and current_port is not None:
ssl_obj._address = (effective_host, current_port)
mindflayer and others added 2 commits July 13, 2026 10:18
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@mindflayer mindflayer changed the title Fix HTTPS httpx mocking in wrap_bio() for the Python 3.10 build Fix HTTPS httpx mocking in wrap_bio() plus regressions occurred Jul 13, 2026
@sonarqubecloud

Copy link
Copy Markdown

@mindflayer mindflayer merged commit aba1797 into main Jul 13, 2026
10 of 12 checks passed
@mindflayer mindflayer deleted the copilot/fix-failing-github-actions-job branch July 13, 2026 09:42
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.

3 participants