Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@
module load time, which is only installed in the dedicated CI job. Ignore that
directory during normal collection so the suite runs without the native
toolchain. The Hypothesis property tests under ``tests/fuzz/`` are unaffected.

The suite also stands hundreds of throwaway ``http.server`` instances in for
provider endpoints, every one of them started as
``threading.Thread(target=server.serve_forever, daemon=True)``.
``socketserver.BaseServer.serve_forever`` only checks its stop flag once per
``poll_interval`` seconds, and ``shutdown()`` blocks until that next check, so
each teardown pays up to the 0.5s default. No call site in this repository
passes the argument, so that default is paid several hundred times per run and
dominates the wall clock: shortening it takes the suite from about eleven
minutes to about one, with no change to what is asserted.

This overrides the default rather than the call sites because a mocked server
in ``tests/test_telemetry.py`` pins production ``serve()`` to invoking
``serve_forever()`` with no arguments.
"""

import socketserver

collect_ignore = ["fuzz"]

_ORIGINAL_SERVE_FOREVER = socketserver.BaseServer.serve_forever


def _serve_forever(self, poll_interval: float = 0.01):
"""Serve with a short stop-flag poll so ``shutdown()`` returns promptly."""
return _ORIGINAL_SERVE_FOREVER(self, poll_interval)


socketserver.BaseServer.serve_forever = _serve_forever
35 changes: 35 additions & 0 deletions tests/test_test_server_poll_interval.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Regression contracts for the pytest-only server polling override."""

import socketserver

import conftest


def test_default_test_server_poll_interval_is_short(monkeypatch):
calls = []
sentinel = object()

def fake_serve_forever(server, poll_interval=0.5):
calls.append((server, poll_interval))
return sentinel

monkeypatch.setattr(conftest, "_ORIGINAL_SERVE_FOREVER", fake_serve_forever)
server = object()

assert conftest._serve_forever(server) is sentinel
assert calls == [(server, 0.01)]
assert socketserver.BaseServer.serve_forever is conftest._serve_forever


def test_explicit_test_server_poll_interval_is_preserved(monkeypatch):
calls = []

def fake_serve_forever(server, poll_interval=0.5):
calls.append((server, poll_interval))

monkeypatch.setattr(conftest, "_ORIGINAL_SERVE_FOREVER", fake_serve_forever)
server = object()

conftest._serve_forever(server, poll_interval=0.25)

assert calls == [(server, 0.25)]
Loading