@@ -41,7 +41,7 @@ async def test_transaction_manager_tid(self, use_clc):
41
41
"""Test next TID."""
42
42
transact = TransactionManager (
43
43
use_clc ,
44
- FramerRTU (DecodePDU (False )),
44
+ FramerSocket (DecodePDU (False )),
45
45
5 ,
46
46
False ,
47
47
None ,
@@ -161,8 +161,7 @@ async def test_transaction_data_2(self, use_clc, test):
161
161
else :
162
162
pdu .dev_id = 0
163
163
transact .response_future .set_result ((1 , pdu ))
164
- with pytest .raises (ModbusIOException ):
165
- transact .callback_data (packet )
164
+ transact .callback_data (packet )
166
165
167
166
@pytest .mark .parametrize ("scenario" , range (8 ))
168
167
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):
264
263
None ,
265
264
)
266
265
transact .send = mock .Mock ()
266
+ transact .comm_params .timeout_connect = 0.1
267
267
request = ReadCoilsRequest (address = 117 , count = 5 , dev_id = 1 )
268
268
transact .retries = 0
269
269
transact .connection_made (mock .AsyncMock ())
@@ -272,13 +272,13 @@ async def test_client_protocol_execute_outside(self, use_clc, no_resp):
272
272
await asyncio .sleep (0.2 )
273
273
data = b"\x00 \x00 \x12 \x34 \x00 \x06 \x01 \x01 \x01 \x02 \x00 \x04 "
274
274
transact .data_received (data )
275
- result = await resp
276
275
if no_resp :
276
+ result = await resp
277
277
assert result .isError ()
278
278
assert isinstance (result , ExceptionResponse )
279
279
else :
280
- assert not result . isError ()
281
- assert isinstance ( result , ReadCoilsResponse )
280
+ with pytest . raises ( ModbusIOException ):
281
+ await resp
282
282
283
283
async def test_transaction_id0 (self , use_clc ):
284
284
"""Test tracers in disconnect."""
@@ -315,6 +315,58 @@ async def test_transaction_id0(self, use_clc):
315
315
await asyncio .sleep (0.1 )
316
316
assert response == await resp
317
317
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
318
370
319
371
@pytest .mark .parametrize ("use_port" , [5098 ])
320
372
class TestSyncTransaction :
0 commit comments