Skip to content

Add pure server tests using lori's TCPBackend generic - #173

Open
SeanTAllen wants to merge 1 commit into
mainfrom
pure-tests-via-fake-backend
Open

Add pure server tests using lori's TCPBackend generic#173
SeanTAllen wants to merge 1 commit into
mainfrom
pure-tests-via-fake-backend

Conversation

@SeanTAllen

Copy link
Copy Markdown
Member

Propagates lori 0.19.0's TCPBackend type parameter through HTTPServer, HTTPServerActor, and _ConnectionState with a RuntimeBackend default (no user-facing API change). Adds a package-private _install_send_capture hook on HTTPServer so pure tests can observe wire bytes handed to lori's send.

Replaces most of the TCP-backed server test suite with pure equivalents that drive HTTPServer[_TestFakeBackend] through _on_received, respond from on_request_complete, and assert on the captured wire bytes or lifecycle callbacks — no listener, client, port, or timeout.

Kept TCP-backed: the smoke suite (server/hello world, server/keep-alive), ASIO timer tests (need real timers), all SSL tests (TLS sits between HTTPServer and the backend), and the pure property tests that were already pure.

204 tests pass; lint clean.

Parked for your input

  • Pre-existing HTTPServer bug surfaced by the adversarial review. HTTPServer.request_received overflow path (stallion/http_server.pony:312-321) calls _close_connection() but not _parser.stop(). Consequence: the parser finishes the overflow-rejected request, which calls HTTPServer.request_complete, which fires on_request_complete on the actor for the overflow-rejected request (the docstring at line 337-340 claims the else branch is unreachable — it isn't reachable, but the request_complete itself is reachable for the overflow case). parse_error sidesteps this by calling stop(). I did not fix this in this PR — it is a production behavior change outside the scope of "test refactor + type parameter". Filing as a follow-up unless you want it here.
  • _TestFakeBackend naming. The API-design reviewer flagged that _Test is narrower than the reusable role. Rename to _FakeBackend (matching lori's _FBSendOk… style)? Cosmetic.
  • Public asymmetric type parameter. HTTPServer[TCP] is a public class parameter, but every mechanism a caller needs to use it (_TestFakeBackend, _install_send_capture, _TestSendCapture, _SendCaptureNotify) is package-private. An external user can HTTPServer[MyBackend] and get no way to observe wire bytes. Options: commit to a public capability, hide the parameter, or leave it and say why it's asymmetric. Docstrings currently say "primarily for stallion's own pure-test suite" — is that the right message?
  • Coupling documentation. When lori adds a method to TCPBackend, _TestFakeBackend must gain the same method or every pure test stops compiling. I documented this in _TestFakeBackend's docstring; should it also go in AGENTS.md?
  • Alternative design. The _send_capture hook exists because TCPConnection[TCP] field-inits _tcp: TCP = TCP, so tests can't inject a pre-built fake to observe later. A lori change to accept a caller-built backend would let stallion drop the production-side hook. Worth exploring in a separate discussion.
  • Pre-existing coverage gaps. No pure test hits _flush_data's SendError branch (fake sendv always returns OK); no test exercises lori's own throttle detection end-to-end. Both existed before this branch.

Propagates lori 0.19.0's `TCPBackend` type parameter through `HTTPServer`,
`HTTPServerActor`, and `_ConnectionState` with a `RuntimeBackend` default,
so existing users see no API change. Adds a package-private
`_install_send_capture` hook on `HTTPServer` that lets pure tests observe
the wire bytes handed to lori's `send` for the connection.

Replaces the majority of the TCP-backed server test suite with pure
equivalents that drive `HTTPServer[_TestFakeBackend]` directly through
`_on_received`, respond from `on_request_complete`, and assert on the
captured wire bytes or on lifecycle callbacks. The whole scenario runs
inside one actor behavior, so no listener, client, port, or timeout is
involved.

Kept as TCP-backed tests: the smoke suite (`server/hello world`,
`server/keep-alive`), the ASIO timer tests (which need real timers), all
SSL tests (TLS sits between HTTPServer and the backend, so the fake sees
ciphertext), and the pure property-based tests that were already pure.

Deletes `_test_server_conformance.pony`, `_test_server_pipeline.pony`,
`_test_server_close_ordering.pony`, and `_test_server_body.pony`. Moves
`_TestTimerFiresWhileClosing` into `_test_server_timer.pony`. Moves
`_TestStreamServer` and its factory into `_test_server_ssl.pony`, where
the last remaining caller lives.
@SeanTAllen SeanTAllen added the changelog - changed Automatically add "Changed" CHANGELOG entry on merge label Aug 22, 2026
@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Aug 22, 2026
@SeanTAllen SeanTAllen added the do not merge This PR should not be merged at this time label Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog - changed Automatically add "Changed" CHANGELOG entry on merge discuss during sync Should be discussed during an upcoming sync do not merge This PR should not be merged at this time

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants