From 1d6d98225c0ce5ffaef3ab6a314c44e2f6f39d30 Mon Sep 17 00:00:00 2001 From: Elvis Pranskevichus Date: Sat, 19 Sep 2026 17:23:16 -0700 Subject: [PATCH] Avoid initialization race in pool inactivity test Pool connections start their idle timers as soon as they connect. If opening the second connection takes longer than 200 ms, the first can expire before pool initialization finishes. This makes the initial holder assertions in `test_pool_max_inactive_time_05` fail intermittently. Register termination listeners through the init callback and wait for both connections to close with a bounded timeout. Leave both connections unacquired and verify their creation, closure, and holder cleanup. This accepts expiry during initialization while still detecting missing idle cleanup, without relying on fixed sleeps. --- tests/test_pool.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/tests/test_pool.py b/tests/test_pool.py index d76e655e..0f664616 100644 --- a/tests/test_pool.py +++ b/tests/test_pool.py @@ -719,20 +719,31 @@ async def worker(pool): async def test_pool_max_inactive_time_05(self): # Test that idle never-acquired connections abide by # the max inactive lifetime. + connections = {} + + async def init(con): + terminated = asyncio.Event() + connections[con] = terminated + con.add_termination_listener(lambda _: terminated.set()) + async with self.create_pool( database='postgres', min_size=2, max_size=2, + init=init, max_inactive_connection_lifetime=0.2) as pool: - self.assertIsNotNone(pool._holders[0]._con) - self.assertIsNotNone(pool._holders[1]._con) + # A connection may expire while the remaining connections are + # still being initialized, so observe termination from init(). + self.assertEqual(len(connections), 2) - await pool.execute('SELECT pg_sleep(0.3)') - await asyncio.sleep(0.3) + await asyncio.wait_for( + asyncio.gather(*(event.wait() + for event in connections.values())), + timeout=5) - self.assertIs(pool._holders[0]._con, None) - # The connection in the second holder was never used, - # but should be closed nonetheless. - self.assertIs(pool._holders[1]._con, None) + for con in connections: + self.assertTrue(con.is_closed()) + for holder in pool._holders: + self.assertIsNone(holder._con) async def test_pool_handles_inactive_connection_errors(self): pool = await self.create_pool(database='postgres',