From 45c13480daf74cd3acd74c280e61a4fe5c532392 Mon Sep 17 00:00:00 2001 From: Elvis Pranskevichus Date: Mon, 5 Oct 2026 08:40:56 -0700 Subject: [PATCH] tests: Capture expected pool retry warnings during role changes The role-change test restarts a primary as a standby with min_size=1. Background floor retries may collide with this and produce noisy warning tracebacks in test output. Silence those. --- tests/test_pool.py | 64 +++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/tests/test_pool.py b/tests/test_pool.py index fe56e107..95fd9ab2 100644 --- a/tests/test_pool.py +++ b/tests/test_pool.py @@ -8,6 +8,7 @@ import asyncio import gc import inspect +import logging import os import pathlib import platform @@ -1593,28 +1594,55 @@ async def test_full_reconnect_on_node_change_role(self): # Force a new connection to be created await pool.fetchval('SELECT 1') - await self.simulate_cluster_recovery_mode() + logs = [] - # current pool connection info cache is expired, - # but we don't know it yet - with self.assertRaises(asyncpg.TargetServerAttributeNotMatched) as cm: - await pool.execute('SELECT 1') + class CaptureLogs(logging.Handler): + def emit(self, record): + logs.append(record) - self.assertEqual( - cm.exception.args[0], - "None of the hosts match the target attribute requirement " - "" - ) + # Maintenance may race foreground acquisition, so retries are + # optional. Capture their expected warnings through pool shutdown. + with mock.patch.object(pg_pool.logger, 'handlers', [CaptureLogs()]), \ + mock.patch.object(pg_pool.logger, 'propagate', False): + try: + await self.simulate_cluster_recovery_mode() - # force reconnect - with self.assertRaises(asyncpg.TargetServerAttributeNotMatched) as cm: - await pool.execute('SELECT 1') + # current pool connection info cache is expired, + # but we don't know it yet + with self.assertRaises( + asyncpg.TargetServerAttributeNotMatched) as cm: + await pool.execute('SELECT 1') - self.assertEqual( - cm.exception.args[0], - "None of the hosts match the target attribute requirement " - "" - ) + self.assertEqual( + cm.exception.args[0], + "None of the hosts match the target attribute requirement " + "" + ) + + # force reconnect + with self.assertRaises( + asyncpg.TargetServerAttributeNotMatched) as cm: + await pool.execute('SELECT 1') + + self.assertEqual( + cm.exception.args[0], + "None of the hosts match the target attribute requirement " + "" + ) + finally: + await pool.close() + + for record in logs: + self.assertEqual(record.levelno, logging.WARNING) + self.assertEqual(record.getMessage(), + 'Failed to restore the pool connection floor; ' + 'retrying') + self.assertIsNotNone(record.exc_info) + self.assertIsInstance(record.exc_info[1], ( + OSError, + asyncpg.CannotConnectNowError, + asyncpg.TargetServerAttributeNotMatched, + )) @unittest.skipIf(os.environ.get('PGHOST'), 'using remote cluster for testing')