55import grpc
66import pytest
77
8+ import ydb
89from ydb import aio
910from .datatypes import PublicBatch , PublicMessage
1011from .topic_reader import PublicReaderSettings
1112from .topic_reader_asyncio import ReaderStream , PartitionSession
12- from .._topic_wrapper .common import OffsetsRange , Codec
13+ from .._topic_wrapper .common import OffsetsRange , Codec , ServerStatus
1314from .._topic_wrapper .reader import StreamReadMessage
1415from .._topic_wrapper .test_helpers import StreamMock , wait_condition , wait_for_fast
1516from ..issues import Unavailable
1617
18+ # Workaround for good autocomplete in IDE and universal import at runtime
19+ # noinspection PyUnreachableCode
20+ if False :
21+ from .._grpc .v4 .protos import ydb_status_codes_pb2
22+ else :
23+ from .._grpc .common .protos import ydb_status_codes_pb2
24+
1725
1826@pytest .fixture ()
1927def default_reader_settings ():
@@ -58,7 +66,7 @@ def second_partition_session(self, default_reader_settings):
5866 )
5967
6068 @pytest .fixture ()
61- async def stream_reader (self , stream , default_reader_settings , partition_session ,
69+ async def stream_reader_started (self , stream , default_reader_settings , partition_session ,
6270 second_partition_session ) -> ReaderStream :
6371 reader = ReaderStream (default_reader_settings )
6472 init_message = object ()
@@ -67,7 +75,8 @@ async def stream_reader(self, stream, default_reader_settings, partition_session
6775 start = asyncio .create_task (reader ._start (stream , init_message ))
6876
6977 stream .from_server .put_nowait (StreamReadMessage .FromServer (
70- StreamReadMessage .InitResponse (session_id = "test-session" )
78+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
79+ server_message = StreamReadMessage .InitResponse (session_id = "test-session" ),
7180 ))
7281
7382 init_request = await wait_for_fast (stream .from_client .get ())
@@ -77,7 +86,9 @@ async def stream_reader(self, stream, default_reader_settings, partition_session
7786 assert isinstance (read_request .client_message , StreamReadMessage .ReadRequest )
7887
7988 stream .from_server .put_nowait (
80- StreamReadMessage .FromServer (server_message = StreamReadMessage .StartPartitionSessionRequest (
89+ StreamReadMessage .FromServer (
90+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
91+ server_message = StreamReadMessage .StartPartitionSessionRequest (
8192 partition_session = StreamReadMessage .PartitionSession (
8293 partition_session_id = partition_session .id ,
8394 path = partition_session .topic_path ,
@@ -96,7 +107,9 @@ async def stream_reader(self, stream, default_reader_settings, partition_session
96107 assert isinstance (start_partition_resp .client_message , StreamReadMessage .StartPartitionSessionResponse )
97108
98109 stream .from_server .put_nowait (
99- StreamReadMessage .FromServer (server_message = StreamReadMessage .StartPartitionSessionRequest (
110+ StreamReadMessage .FromServer (
111+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
112+ server_message = StreamReadMessage .StartPartitionSessionRequest (
100113 partition_session = StreamReadMessage .PartitionSession (
101114 partition_session_id = second_partition_session .id ,
102115 path = second_partition_session .topic_path ,
@@ -116,11 +129,22 @@ async def stream_reader(self, stream, default_reader_settings, partition_session
116129 with pytest .raises (asyncio .QueueEmpty ):
117130 stream .from_client .get_nowait ()
118131
119- yield reader
132+ return reader
120133
121- assert reader ._first_error is None
134+ @pytest .fixture ()
135+ async def stream_reader (self , stream_reader_started : ReaderStream ):
136+ yield stream_reader_started
137+
138+ assert stream_reader_started ._first_error is None
139+ await stream_reader_started .close ()
140+
141+ @pytest .fixture ()
142+ async def stream_reader_finish_with_error (self , stream_reader_started : ReaderStream ):
143+ yield stream_reader_started
144+
145+ assert stream_reader_started ._first_error is not None
146+ await stream_reader_started .close ()
122147
123- await reader .close ()
124148
125149 @staticmethod
126150 def create_message (partition_session : PartitionSession , seqno : int ):
@@ -143,7 +167,9 @@ def batch_count():
143167 initial_batches = batch_count ()
144168
145169 stream = stream_reader ._stream # type: StreamMock
146- stream .from_server .put_nowait (StreamReadMessage .FromServer (server_message = StreamReadMessage .ReadResponse (
170+ stream .from_server .put_nowait (StreamReadMessage .FromServer (
171+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
172+ server_message = StreamReadMessage .ReadResponse (
147173 partition_data = [StreamReadMessage .ReadResponse .PartitionData (
148174 partition_session_id = message ._partition_session .id ,
149175 batches = [
@@ -169,20 +195,25 @@ def batch_count():
169195 )))
170196 await wait_condition (lambda : batch_count () > initial_batches )
171197
172- async def test_convert_errors_to_ydb (self , stream , stream_reader ):
173- class TestError (grpc .RpcError ):
174- _code : grpc .StatusCode
175-
176- def __init__ (self , code : grpc .StatusCode ):
177- self ._code = code
198+ async def test_first_error (self , stream , stream_reader_finish_with_error ):
199+ class TestError (grpc .RpcError , grpc .Call ):
200+ def __init__ (self ):
201+ pass
178202
179203 def code (self ):
180- return self . _code
204+ return grpc . StatusCode . UNAUTHENTICATED
181205
182- stream .from_server .put_nowait (TestError (grpc .StatusCode .UNAVAILABLE ))
206+ def details (self ):
207+ return "test error"
183208
184- with pytest .raises (Unavailable ):
185- await wait_for_fast (stream_reader .wait_messages ())
209+ test_err = TestError ()
210+ stream .from_server .put_nowait (test_err )
211+
212+ with pytest .raises (TestError ):
213+ await wait_for_fast (stream_reader_finish_with_error .wait_messages ())
214+
215+ with pytest .raises (TestError ):
216+ stream_reader_finish_with_error .receive_batch_nowait ()
186217
187218 async def test_init_reader (self , stream , default_reader_settings ):
188219 reader = ReaderStream (default_reader_settings )
@@ -202,6 +233,7 @@ async def test_init_reader(self, stream, default_reader_settings):
202233 assert sent_message == expected_sent_init_message
203234
204235 stream .from_server .put_nowait (StreamReadMessage .FromServer (
236+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
205237 server_message = StreamReadMessage .InitResponse (session_id = "test" ))
206238 )
207239
@@ -231,6 +263,7 @@ def session_count():
231263 test_topic_path = default_reader_settings .topic + "-asd"
232264
233265 stream .from_server .put_nowait (StreamReadMessage .FromServer (
266+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
234267 server_message = StreamReadMessage .StartPartitionSessionRequest (
235268 partition_session = StreamReadMessage .PartitionSession (
236269 partition_session_id = test_partition_session_id ,
@@ -266,6 +299,7 @@ def session_count():
266299 initial_session_count = session_count ()
267300
268301 stream .from_server .put_nowait (StreamReadMessage .FromServer (
302+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
269303 server_message = StreamReadMessage .StopPartitionSessionRequest (
270304 partition_session_id = partition_session .id ,
271305 graceful = False ,
@@ -287,6 +321,7 @@ def session_count():
287321 initial_session_count = session_count ()
288322
289323 stream .from_server .put_nowait (StreamReadMessage .FromServer (
324+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
290325 server_message = StreamReadMessage .StopPartitionSessionRequest (
291326 partition_session_id = partition_session .id ,
292327 graceful = True ,
@@ -303,6 +338,7 @@ def session_count():
303338 )
304339
305340 stream .from_server .put_nowait (StreamReadMessage .FromServer (
341+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
306342 server_message = StreamReadMessage .StopPartitionSessionRequest (
307343 partition_session_id = partition_session .id ,
308344 graceful = False ,
@@ -330,7 +366,9 @@ def reader_batch_count():
330366 session_meta = {"a" : "b" }
331367 message_group_id = "test-message-group-id"
332368
333- stream .from_server .put_nowait (StreamReadMessage .FromServer (server_message = StreamReadMessage .ReadResponse (
369+ stream .from_server .put_nowait (StreamReadMessage .FromServer (
370+ server_status = ServerStatus (ydb_status_codes_pb2 .StatusIds .SUCCESS , []),
371+ server_message = StreamReadMessage .ReadResponse (
334372 bytes_size = bytes_size ,
335373 partition_data = [
336374 StreamReadMessage .ReadResponse .PartitionData (
0 commit comments