Skip to content

Commit 71b827d

Browse files
Add tests to improve patch coverage for attach hint handling.
Cover attach stream wrapper, ConnectionsCache lookup, and async pool pessimize edge cases to satisfy codecov/patch threshold. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 17cf9da commit 71b827d

1 file changed

Lines changed: 73 additions & 1 deletion

File tree

tests/query/test_query_session_hints.py

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
import pytest
55

66
from ydb._grpc.common.protos import ydb_query_pb2
7+
from ydb._grpc.grpcwrapper import common_utils
78
from ydb.aio.pool import ConnectionPool as AsyncConnectionPool
8-
from ydb.pool import ConnectionPool
9+
from ydb.pool import ConnectionPool, ConnectionsCache
910
from ydb.query.session import QuerySession
1011

1112

@@ -85,8 +86,52 @@ def test_no_hint_does_not_invalidate(self):
8586
assert not session._invalidated
8687
assert not session._closed
8788

89+
def test_none_response_does_not_invalidate(self):
90+
session, driver = _make_session()
91+
92+
session._handle_attach_session_state(None)
93+
94+
driver._pessimize_node.assert_not_called()
95+
assert not session._invalidated
96+
assert not session._closed
97+
98+
def test_attach_stream_wrapper_handles_hint_and_returns_status(self):
99+
session, driver = _make_session(node_id=42)
100+
response = ydb_query_pb2.SessionState(
101+
status=0,
102+
session_shutdown=ydb_query_pb2.SessionShutdownHint(),
103+
)
104+
105+
status = session._attach_stream_wrapper(response)
106+
107+
driver._pessimize_node.assert_not_called()
108+
assert session._invalidated
109+
assert isinstance(status, common_utils.ServerStatus)
110+
111+
def test_attach_stream_wrapper_returns_status_without_hint(self):
112+
session, driver = _make_session()
113+
response = ydb_query_pb2.SessionState(status=0)
114+
115+
status = session._attach_stream_wrapper(response)
116+
117+
driver._pessimize_node.assert_not_called()
118+
assert not session._invalidated
119+
assert isinstance(status, common_utils.ServerStatus)
120+
88121

89122
class TestConnectionPoolAttachHintPessimization:
123+
def test_connections_cache_get_connection_by_node_id(self):
124+
cache = ConnectionsCache()
125+
connection = mock.Mock()
126+
connection.endpoint = "grpc://localhost:2135"
127+
connection.node_id = 42
128+
connection.add_cleanup_callback = mock.Mock()
129+
130+
cache.add(connection)
131+
132+
assert cache.get_connection_by_node_id(42) is connection
133+
assert cache.get_connection_by_node_id(99) is None
134+
90135
def test_sync_pool_pessimizes_node_connection(self):
91136
pool = ConnectionPool.__new__(ConnectionPool)
92137
connection = mock.Mock()
@@ -107,7 +152,34 @@ def test_sync_pool_ignores_missing_node_connection(self):
107152

108153
pool._pessimize_node(42)
109154
pool._pessimize_node(0)
155+
pool._pessimize_node(-1)
156+
157+
pool._store.get_connection_by_node_id.assert_called_once_with(42)
158+
pool._on_disconnected.assert_not_called()
159+
160+
@pytest.mark.asyncio
161+
async def test_async_pool_ignores_non_positive_node_id(self):
162+
pool = AsyncConnectionPool.__new__(AsyncConnectionPool)
163+
pool._store = mock.Mock()
164+
pool._on_disconnected = mock.Mock()
165+
166+
pool._pessimize_node(0)
167+
pool._pessimize_node(-1)
110168

169+
pool._store.get_connection_by_node_id.assert_not_called()
170+
pool._on_disconnected.assert_not_called()
171+
172+
@pytest.mark.asyncio
173+
async def test_async_pool_ignores_missing_node_connection(self):
174+
pool = AsyncConnectionPool.__new__(AsyncConnectionPool)
175+
pool._store = mock.Mock()
176+
pool._store.get_connection_by_node_id.return_value = None
177+
pool._on_disconnected = mock.Mock()
178+
179+
pool._pessimize_node(42)
180+
await asyncio.sleep(0)
181+
182+
pool._store.get_connection_by_node_id.assert_called_once_with(42)
111183
pool._on_disconnected.assert_not_called()
112184

113185
@pytest.mark.asyncio

0 commit comments

Comments
 (0)