Skip to content

Commit 55e4300

Browse files
Cherry-pick some pytest-asyncio fixes (#11247)
1 parent 2dcf534 commit 55e4300

File tree

5 files changed

+1194
-1294
lines changed

5 files changed

+1194
-1294
lines changed

tests/conftest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,11 @@ def assert_sock_fits(sock_path: str) -> None:
243243
return
244244

245245

246+
@pytest.fixture
247+
async def event_loop(loop: asyncio.AbstractEventLoop) -> asyncio.AbstractEventLoop:
248+
return asyncio.get_running_loop()
249+
250+
246251
@pytest.fixture
247252
def selector_loop() -> Iterator[asyncio.AbstractEventLoop]:
248253
factory = asyncio.SelectorEventLoop
Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import asyncio
22
import contextlib
33
import gc
4+
import socket
45
import sys
56

67
from aiohttp import ClientError, ClientSession, web
7-
from aiohttp.test_utils import get_unused_port_socket
8+
from aiohttp.test_utils import REUSE_ADDRESS
89

910
gc.set_debug(gc.DEBUG_LEAK)
1011

@@ -18,30 +19,32 @@ async def stream_handler(request: web.Request) -> web.Response:
1819
return web.Response()
1920

2021
app.router.add_get("/stream", stream_handler)
21-
sock = get_unused_port_socket("127.0.0.1")
22-
port = sock.getsockname()[1]
23-
24-
runner = web.AppRunner(app)
25-
await runner.setup()
26-
site = web.SockSite(runner, sock)
27-
await site.start()
28-
29-
session = ClientSession()
30-
31-
async def fetch_stream(url: str) -> None:
32-
"""Fetch a stream and read a few bytes from it."""
33-
with contextlib.suppress(ClientError):
34-
await session.get(url)
35-
36-
client_task = asyncio.create_task(fetch_stream(f"http://localhost:{port}/stream"))
37-
await client_task
38-
gc.collect()
39-
client_response_present = any(
40-
type(obj).__name__ == "ClientResponse" for obj in gc.garbage
41-
)
42-
await session.close()
43-
await runner.cleanup()
44-
sys.exit(1 if client_response_present else 0)
22+
with socket.create_server(("127.0.0.1", 0), reuse_port=REUSE_ADDRESS) as sock:
23+
port = sock.getsockname()[1]
24+
25+
runner = web.AppRunner(app)
26+
await runner.setup()
27+
site = web.SockSite(runner, sock)
28+
await site.start()
29+
30+
session = ClientSession()
31+
32+
async def fetch_stream(url: str) -> None:
33+
"""Fetch a stream and read a few bytes from it."""
34+
with contextlib.suppress(ClientError):
35+
await session.get(url)
36+
37+
client_task = asyncio.create_task(
38+
fetch_stream(f"http://localhost:{port}/stream")
39+
)
40+
await client_task
41+
gc.collect()
42+
client_response_present = any(
43+
type(obj).__name__ == "ClientResponse" for obj in gc.garbage
44+
)
45+
await session.close()
46+
await runner.cleanup()
47+
sys.exit(1 if client_response_present else 0)
4548

4649

4750
asyncio.run(main())

tests/isolated/check_for_request_leak.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import asyncio
22
import gc
3+
import socket
34
import sys
45
from typing import NoReturn
56

67
from aiohttp import ClientSession, web
7-
from aiohttp.test_utils import get_unused_port_socket
8+
from aiohttp.test_utils import REUSE_ADDRESS
89

910
gc.set_debug(gc.DEBUG_LEAK)
1011

@@ -17,24 +18,24 @@ async def handler(request: web.Request) -> NoReturn:
1718
assert False
1819

1920
app.router.add_route("GET", "/json", handler)
20-
sock = get_unused_port_socket("127.0.0.1")
21-
port = sock.getsockname()[1]
22-
23-
runner = web.AppRunner(app)
24-
await runner.setup()
25-
site = web.SockSite(runner, sock)
26-
await site.start()
27-
28-
async with ClientSession() as session:
29-
async with session.get(f"http://127.0.0.1:{port}/json") as resp:
30-
await resp.read()
31-
32-
# Give time for the cancelled task to be collected
33-
await asyncio.sleep(0.5)
34-
gc.collect()
35-
request_present = any(type(obj).__name__ == "Request" for obj in gc.garbage)
36-
await session.close()
37-
await runner.cleanup()
21+
with socket.create_server(("127.0.0.1", 0), reuse_port=REUSE_ADDRESS) as sock:
22+
port = sock.getsockname()[1]
23+
24+
runner = web.AppRunner(app)
25+
await runner.setup()
26+
site = web.SockSite(runner, sock)
27+
await site.start()
28+
29+
async with ClientSession() as session:
30+
async with session.get(f"http://127.0.0.1:{port}/json") as resp:
31+
await resp.read()
32+
33+
# Give time for the cancelled task to be collected
34+
await asyncio.sleep(0.5)
35+
gc.collect()
36+
request_present = any(type(obj).__name__ == "Request" for obj in gc.garbage)
37+
await session.close()
38+
await runner.cleanup()
3839
sys.exit(1 if request_present else 0)
3940

4041

0 commit comments

Comments
 (0)