Skip to content

Commit

Permalink
Remove signal testing order dependency (#2382)
Browse files Browse the repository at this point in the history
* test received signal

* improve error feedback, do not shadow earlier failures

* fix import sorting

---------

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
  • Loading branch information
maxfischer2781 and Kludex authored Aug 11, 2024
1 parent ff54b02 commit 0f513d2
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 10 deletions.
20 changes: 10 additions & 10 deletions tests/supervisors/test_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import httpx
import pytest

from tests.utils import run_server
from tests.utils import assert_signal, run_server
from uvicorn import Server
from uvicorn.config import Config

Expand All @@ -31,8 +31,8 @@ async def wait_app(scope, receive, send):

config = Config(app=wait_app, reload=False, port=unused_tcp_port, timeout_graceful_shutdown=1)
server: Server
async with run_server(config) as server:
async with httpx.AsyncClient() as client:
with assert_signal(signal.SIGINT):
async with run_server(config) as server, httpx.AsyncClient() as client:
req = asyncio.create_task(client.get(f"http://127.0.0.1:{unused_tcp_port}"))
await asyncio.sleep(0.1) # ensure next tick
server.handle_exit(sig=signal.SIGINT, frame=None) # exit
Expand Down Expand Up @@ -64,8 +64,8 @@ async def forever_app(scope, receive, send):

config = Config(app=forever_app, reload=False, port=unused_tcp_port, timeout_graceful_shutdown=1)
server: Server
async with run_server(config) as server:
async with httpx.AsyncClient() as client:
with assert_signal(signal.SIGINT):
async with run_server(config) as server, httpx.AsyncClient() as client:
req = asyncio.create_task(client.get(f"http://127.0.0.1:{unused_tcp_port}"))
await asyncio.sleep(0.1) # next tick
# trigger exit, this request should time out in ~1 sec
Expand Down Expand Up @@ -94,10 +94,10 @@ async def app(scope, receive, send):

config = Config(app=app, reload=False, port=unused_tcp_port, timeout_graceful_shutdown=1)
server: Server
async with run_server(config) as server:
# exit and ensure we do not accept more requests
server.handle_exit(sig=signal.SIGINT, frame=None)
await asyncio.sleep(0.1) # next tick
async with httpx.AsyncClient() as client:
with assert_signal(signal.SIGINT):
async with run_server(config) as server, httpx.AsyncClient() as client:
# exit and ensure we do not accept more requests
server.handle_exit(sig=signal.SIGINT, frame=None)
await asyncio.sleep(0.1) # next tick
with pytest.raises(httpx.ConnectError):
await client.get(f"http://127.0.0.1:{unused_tcp_port}")
13 changes: 13 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import asyncio
import os
import signal
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager, contextmanager
from pathlib import Path
Expand All @@ -22,6 +23,18 @@ async def run_server(config: Config, sockets: list[socket] | None = None) -> Asy
task.cancel()


@contextmanager
def assert_signal(sig: signal.Signals):
"""Check that a signal was received and handled in a block"""
seen: set[int] = set()
prev_handler = signal.signal(sig, lambda num, frame: seen.add(num))
try:
yield
assert sig in seen, f"process signal {signal.Signals(sig)!r} was not received or handled"
finally:
signal.signal(sig, prev_handler)


@contextmanager
def as_cwd(path: Path):
"""Changes working directory and returns to previous on exit."""
Expand Down

0 comments on commit 0f513d2

Please sign in to comment.