MCPcopy
hub / github.com/encode/uvicorn / test_reset_contextvars_asyncio

Function test_reset_contextvars_asyncio

tests/test_server.py:214–263  ·  view source on GitHub ↗

With reset_contextvars=True, each ASGI run starts with a fresh context. Non-regression test for https://github.com/encode/uvicorn/issues/2167.

(
    http_protocol_cls: type[H11Protocol | HttpToolsProtocol], unused_tcp_port: int
)

Source from the content-addressed store, hash-verified

212
213
214async def test_reset_contextvars_asyncio(
215 http_protocol_cls: type[H11Protocol | HttpToolsProtocol], unused_tcp_port: int
216):
217 """With reset_contextvars=True, each ASGI run starts with a fresh context.
218
219 Non-regression test for https://github.com/encode/uvicorn/issues/2167.
220 """
221 default_contextvars = {c.name for c in contextvars.copy_context().keys()}
222 ctx: contextvars.ContextVar[str] = contextvars.ContextVar("ctx")
223
224 async def app(scope: Scope, receive: ASGIReceiveCallable, send: ASGISendCallable):
225 assert scope["type"] == "http"
226
227 # initial context should be empty
228 initial_context = {
229 n: v for c, v in contextvars.copy_context().items() if (n := c.name) not in default_contextvars
230 }
231 # set any contextvar before the body is read
232 ctx.set(scope["path"])
233
234 while True:
235 message = await receive()
236 assert message["type"] == "http.request"
237 if not message["more_body"]:
238 break
239
240 body = json.dumps(initial_context).encode("utf-8")
241 headers = [(b"content-type", b"application/json"), (b"content-length", str(len(body)).encode("utf-8"))]
242 await send({"type": "http.response.start", "status": 200, "headers": headers})
243 await send({"type": "http.response.body", "body": body})
244
245 # body larger than HIGH_WATER_LIMIT forces a reading pause on the main thread
246 # and a resumption inside the ASGI task, which is where the original pollution showed up.
247 large_body = b"a" * (HIGH_WATER_LIMIT + 1)
248 large_request = b"\r\n".join(
249 [
250 b"POST /large-body HTTP/1.1",
251 b"Host: example.org",
252 b"Content-Type: application/octet-stream",
253 f"Content-Length: {len(large_body)}".encode(),
254 b"",
255 large_body,
256 ]
257 )
258
259 async with _raw_server(
260 app=app, http_protocol_cls=http_protocol_cls, port=unused_tcp_port, reset_contextvars=True
261 ) as extract_json_body:
262 assert await extract_json_body(large_request) == {}
263 assert await extract_json_body(SIMPLE_GET_REQUEST) == {}

Callers

nothing calls this directly

Calls 3

_raw_serverFunction · 0.85
extract_json_bodyFunction · 0.85
joinMethod · 0.80

Tested by

no test coverage detected