From b14963b4a0f1909ae2a2b5f965156cbf1b7ea103 Mon Sep 17 00:00:00 2001 From: Filip Muller Date: Thu, 1 Jun 2023 12:23:30 +0200 Subject: [PATCH 1/2] #7297 Add tests for closed keepalive connections --- tests/test_client_functional.py | 58 +++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index 4edc00483cb..f976246b572 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -9,6 +9,7 @@ import pathlib import socket import ssl +import time from typing import Any, AsyncIterator from unittest import mock @@ -126,6 +127,63 @@ async def handler(request): assert 0 == len(client._session.connector._conns) +async def test_keepalive_timeout_async_sleep() -> None: + async def handler(request): + body = await request.read() + assert b"" == body + return web.Response(body=b"OK") + + app = web.Application() + app.router.add_route("GET", "/", handler) + + runner = web.AppRunner(app, tcp_keepalive=True, keepalive_timeout=0.001) + await runner.setup() + + port = unused_port() + site = web.TCPSite(runner, host="localhost", port=port) + await site.start() + + try: + async with aiohttp.client.ClientSession() as sess: + resp1 = await sess.get(f"http://localhost:{port}/") + await resp1.read() + # wait for server keepalive_timeout + await asyncio.sleep(0.01) + resp2 = await sess.get(f"http://localhost:{port}/") + await resp2.read() + finally: + await asyncio.gather(runner.shutdown(), site.stop()) + + +async def test_keepalive_timeout_sync_sleep() -> None: + async def handler(request): + body = await request.read() + assert b"" == body + return web.Response(body=b"OK") + + app = web.Application() + app.router.add_route("GET", "/", handler) + + runner = web.AppRunner(app, tcp_keepalive=True, keepalive_timeout=0.001) + await runner.setup() + + port = unused_port() + site = web.TCPSite(runner, host="localhost", port=port) + await site.start() + + try: + async with aiohttp.client.ClientSession() as sess: + resp1 = await sess.get(f"http://localhost:{port}/") + await resp1.read() + # wait for server keepalive_timeout + # time.sleep is a more challenging scenario than asyncio.sleep + time.sleep(0.01) + resp2 = await sess.get(f"http://localhost:{port}/") + await resp2.read() + finally: + await asyncio.gather(runner.shutdown(), site.stop()) + + async def test_release_early(aiohttp_client: Any) -> None: async def handler(request): await request.read() From bb318662ab0dc3ff97b48a99decb8db9b1ce9744 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Sun, 4 Jun 2023 20:12:48 +0100 Subject: [PATCH 2/2] Update test_client_functional.py --- tests/test_client_functional.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index f976246b572..fa16b324ec7 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -155,6 +155,7 @@ async def handler(request): await asyncio.gather(runner.shutdown(), site.stop()) +@pytest.mark.xfail(reason="Reproducer for #7297") async def test_keepalive_timeout_sync_sleep() -> None: async def handler(request): body = await request.read()