1+ import asyncio
12from unittest import mock
23
4+ import pytest
5+
36from ydb ._grpc .common .protos import ydb_query_pb2
7+ from ydb .aio .pool import ConnectionPool as AsyncConnectionPool
8+ from ydb .pool import ConnectionPool
49from ydb .query .session import QuerySession
510
611
712def _make_session (node_id = 42 ):
813 driver = mock .Mock ()
9- driver ._store = mock .Mock ()
10- driver ._store .connections_by_node_id = {node_id : mock .Mock ()}
11- driver ._on_disconnected = mock .Mock (return_value = None )
14+ driver ._pessimize_node = mock .Mock ()
1215 session = QuerySession (driver )
1316 session ._session_id = "test-session"
1417 session ._node_id = node_id
@@ -18,7 +21,6 @@ def _make_session(node_id=42):
1821class TestQuerySessionAttachHints :
1922 def test_node_shutdown_pessimizes_node_and_invalidates_session (self ):
2023 session , driver = _make_session (node_id = 42 )
21- connection = driver ._store .connections_by_node_id [42 ]
2224
2325 session ._handle_attach_session_state (
2426 ydb_query_pb2 .SessionState (
@@ -27,7 +29,7 @@ def test_node_shutdown_pessimizes_node_and_invalidates_session(self):
2729 )
2830 )
2931
30- driver ._on_disconnected .assert_called_once_with (connection )
32+ driver ._pessimize_node .assert_called_once_with (42 )
3133 assert session ._invalidated
3234 assert session ._closed
3335
@@ -41,11 +43,11 @@ def test_session_shutdown_invalidates_without_pessimizing_node(self):
4143 )
4244 )
4345
44- driver ._on_disconnected .assert_not_called ()
46+ driver ._pessimize_node .assert_not_called ()
4547 assert session ._invalidated
4648 assert session ._closed
4749
48- def test_node_shutdown_with_zero_node_id_skips_pessimization (self ):
50+ def test_node_shutdown_with_zero_node_id_delegates_to_driver (self ):
4951 session , driver = _make_session (node_id = 0 )
5052
5153 session ._handle_attach_session_state (
@@ -55,7 +57,7 @@ def test_node_shutdown_with_zero_node_id_skips_pessimization(self):
5557 )
5658 )
5759
58- driver ._on_disconnected . assert_not_called ( )
60+ driver ._pessimize_node . assert_called_once_with ( 0 )
5961 assert session ._invalidated
6062
6163 def test_no_hint_does_not_invalidate (self ):
@@ -65,6 +67,46 @@ def test_no_hint_does_not_invalidate(self):
6567 ydb_query_pb2 .SessionState (status = 0 ),
6668 )
6769
68- driver ._on_disconnected .assert_not_called ()
70+ driver ._pessimize_node .assert_not_called ()
6971 assert not session ._invalidated
7072 assert not session ._closed
73+
74+
75+ class TestConnectionPoolAttachHintPessimization :
76+ def test_sync_pool_pessimizes_node_connection (self ):
77+ pool = ConnectionPool .__new__ (ConnectionPool )
78+ connection = mock .Mock ()
79+ pool ._store = mock .Mock ()
80+ pool ._store .connections_by_node_id = {42 : connection }
81+ pool ._on_disconnected = mock .Mock ()
82+
83+ pool ._pessimize_node (42 )
84+
85+ pool ._on_disconnected .assert_called_once_with (connection )
86+
87+ def test_sync_pool_ignores_missing_node_connection (self ):
88+ pool = ConnectionPool .__new__ (ConnectionPool )
89+ pool ._store = mock .Mock ()
90+ pool ._store .connections_by_node_id = {}
91+ pool ._on_disconnected = mock .Mock ()
92+
93+ pool ._pessimize_node (42 )
94+ pool ._pessimize_node (0 )
95+ pool ._pessimize_node (None )
96+
97+ pool ._on_disconnected .assert_not_called ()
98+
99+ @pytest .mark .asyncio
100+ async def test_async_pool_pessimizes_node_connection (self ):
101+ pool = AsyncConnectionPool .__new__ (AsyncConnectionPool )
102+ connection = mock .Mock ()
103+ disconnect = mock .AsyncMock ()
104+ pool ._store = mock .Mock ()
105+ pool ._store .connections_by_node_id = {42 : connection }
106+ pool ._on_disconnected = mock .Mock (return_value = disconnect )
107+
108+ pool ._pessimize_node (42 )
109+ await asyncio .sleep (0 )
110+
111+ pool ._on_disconnected .assert_called_once_with (connection )
112+ disconnect .assert_awaited_once_with ()
0 commit comments