@@ -41,7 +41,7 @@ async def test_transaction_manager_tid(self, use_clc):
4141 """Test next TID."""
4242 transact = TransactionManager (
4343 use_clc ,
44- FramerRTU (DecodePDU (False )),
44+ FramerSocket (DecodePDU (False )),
4545 5 ,
4646 False ,
4747 None ,
@@ -161,8 +161,7 @@ async def test_transaction_data_2(self, use_clc, test):
161161 else :
162162 pdu .dev_id = 0
163163 transact .response_future .set_result ((1 , pdu ))
164- with pytest .raises (ModbusIOException ):
165- transact .callback_data (packet )
164+ transact .callback_data (packet )
166165
167166 @pytest .mark .parametrize ("scenario" , range (8 ))
168167 async def test_transaction_execute (self , use_clc , scenario ):
@@ -264,6 +263,7 @@ async def test_client_protocol_execute_outside(self, use_clc, no_resp):
264263 None ,
265264 )
266265 transact .send = mock .Mock ()
266+ transact .comm_params .timeout_connect = 0.1
267267 request = ReadCoilsRequest (address = 117 , count = 5 , dev_id = 1 )
268268 transact .retries = 0
269269 transact .connection_made (mock .AsyncMock ())
@@ -272,13 +272,13 @@ async def test_client_protocol_execute_outside(self, use_clc, no_resp):
272272 await asyncio .sleep (0.2 )
273273 data = b"\x00 \x00 \x12 \x34 \x00 \x06 \x01 \x01 \x01 \x02 \x00 \x04 "
274274 transact .data_received (data )
275- result = await resp
276275 if no_resp :
276+ result = await resp
277277 assert result .isError ()
278278 assert isinstance (result , ExceptionResponse )
279279 else :
280- assert not result . isError ()
281- assert isinstance ( result , ReadCoilsResponse )
280+ with pytest . raises ( ModbusIOException ):
281+ await resp
282282
283283 async def test_transaction_id0 (self , use_clc ):
284284 """Test tracers in disconnect."""
@@ -315,6 +315,58 @@ async def test_transaction_id0(self, use_clc):
315315 await asyncio .sleep (0.1 )
316316 assert response == await resp
317317
318+ @pytest .mark .parametrize (("framer" ), [FramerRTU , FramerSocket ])
319+ @pytest .mark .parametrize ("scenario" , range (2 ))
320+ async def test_delayed_response (self , use_clc , framer , scenario ):
321+ """Test delayed rtu response combined with retries."""
322+ transact = TransactionManager (
323+ use_clc ,
324+ framer (DecodePDU (False )),
325+ 5 ,
326+ False ,
327+ None ,
328+ None ,
329+ None ,
330+ )
331+ transact .send = mock .Mock ()
332+ request1 = ReadCoilsRequest (address = 117 , count = 5 , dev_id = 1 )
333+ request2 = ReadCoilsRequest (address = 118 , count = 2 , dev_id = 1 )
334+ response1 = ReadCoilsResponse (bits = [True , False , True , True ] + [False ]* 4 , dev_id = 1 )
335+ response2 = ReadCoilsResponse (bits = [True ] + [False ]* 7 , dev_id = 1 )
336+ if framer == FramerRTU :
337+ cb_response1 = b'\x01 \x01 \x01 \r \x90 M'
338+ cb_response2 = b'\x01 \x01 \x01 \x01 \x90 H'
339+ else :
340+ cb_response1 = b'\x00 \x01 \x00 \x00 \x00 \x04 \x01 \x01 \x01 \r '
341+ cb_response2 = b'\x00 \x02 \x00 \x00 \x00 \x04 \x01 \x01 \x01 \x01 '
342+ transact .retries = 1
343+ transact .connection_made (mock .AsyncMock ())
344+ transact .transport .write = mock .Mock ()
345+ transact .comm_params .timeout_connect = 0.1
346+
347+ if scenario == 0 : # timeout + double response
348+ resp = asyncio .create_task (transact .execute (False , request1 ))
349+ await asyncio .sleep (0.15 )
350+ transact .callback_data (cb_response1 , None )
351+ transact .callback_data (cb_response1 , None )
352+ result = await resp
353+ assert result .bits == response1 .bits
354+ elif scenario == 1 : # timeout + new request + double response
355+ resp = asyncio .create_task (transact .execute (False , request1 ))
356+ await asyncio .sleep (0.25 )
357+ with pytest .raises (ModbusIOException ):
358+ await resp
359+ resp = asyncio .create_task (transact .execute (False , request2 ))
360+ await asyncio .sleep (0.05 )
361+ transact .callback_data (cb_response1 , None )
362+ transact .callback_data (cb_response2 , None )
363+ result = await resp
364+ if framer == FramerRTU :
365+ # Return WRONG response
366+ assert result .bits == response1 .bits
367+ else :
368+ # Return CORRECT response
369+ assert result .bits == response2 .bits
318370
319371@pytest .mark .parametrize ("use_port" , [5098 ])
320372class TestSyncTransaction :
0 commit comments