Skip to content

Commit c1f3847

Browse files
author
rodrigo.nogueira
committed
Fix socket leaks in TestShutdown suite for Windows CI
1 parent 1e0e7b5 commit c1f3847

1 file changed

Lines changed: 34 additions & 9 deletions

File tree

tests/test_run_app.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,23 +1219,35 @@ def test_shutdown_close_idle_keepalive(
12191219
sock = unused_port_socket
12201220
port = sock.getsockname()[1]
12211221
t = None
1222+
sess_holder: list[ClientSession] = []
12221223

12231224
async def test() -> None:
12241225
await asyncio.sleep(1)
1225-
async with ClientSession() as sess:
1226+
sess = ClientSession()
1227+
sess_holder.append(sess)
1228+
async with sess:
12261229
async with sess.get(f"http://127.0.0.1:{port}/stop"):
12271230
pass
1228-
12291231
# Hold on to keep-alive connection.
12301232
await asyncio.sleep(5)
12311233

12321234
async def run_test(app: web.Application) -> AsyncIterator[None]:
12331235
nonlocal t
12341236
t = asyncio.create_task(test())
12351237
yield
1236-
t.cancel()
1237-
with contextlib.suppress(asyncio.CancelledError):
1238-
await t
1238+
try:
1239+
t.cancel()
1240+
with contextlib.suppress(asyncio.CancelledError):
1241+
await t
1242+
finally:
1243+
if sys.platform == "win32":
1244+
# On Windows, explicitly close the session and yield to the
1245+
# event loop to mitigate resource warnings related to unclosed
1246+
# sockets, which are more common due to ProactorEventLoop
1247+
# timing issues.
1248+
for sess in sess_holder:
1249+
await sess.close()
1250+
await asyncio.sleep(0.1)
12391251

12401252
app = web.Application()
12411253
app.cleanup_ctx.append(run_test)
@@ -1268,9 +1280,13 @@ async def close_websockets(app: web.Application) -> None:
12681280
for ws in app[WS]:
12691281
await ws.close(code=WSCloseCode.GOING_AWAY)
12701282

1283+
sess_holder: list[ClientSession] = []
1284+
12711285
async def test() -> None:
12721286
await asyncio.sleep(1)
1273-
async with ClientSession() as sess:
1287+
sess = ClientSession()
1288+
sess_holder.append(sess)
1289+
async with sess:
12741290
async with sess.ws_connect(f"http://127.0.0.1:{port}/ws") as ws:
12751291
async with sess.get(f"http://127.0.0.1:{port}/stop"):
12761292
pass
@@ -1285,9 +1301,18 @@ async def run_test(app: web.Application) -> AsyncIterator[None]:
12851301
t = asyncio.create_task(test())
12861302
yield
12871303
await asyncio.sleep(0) # In case test() hasn't resumed yet.
1288-
t.cancel()
1289-
with contextlib.suppress(asyncio.CancelledError):
1290-
await t
1304+
try:
1305+
try:
1306+
await asyncio.wait_for(t, timeout=3.0)
1307+
except asyncio.TimeoutError:
1308+
t.cancel()
1309+
with contextlib.suppress(asyncio.CancelledError):
1310+
await t
1311+
finally:
1312+
if sys.platform == "win32":
1313+
for sess in sess_holder:
1314+
await sess.close()
1315+
await asyncio.sleep(0.1)
12911316

12921317
app = web.Application()
12931318
app[WS] = set()

0 commit comments

Comments
 (0)