88from pymodbus .exceptions import ModbusIOException
99from pymodbus .compat import IS_PYTHON3
1010if IS_PYTHON3 :
11- from unittest .mock import Mock
11+ from unittest .mock import Mock , patch
1212else : # Python 2
1313 from mock import Mock
1414
@@ -44,7 +44,7 @@ def test_framer_initialization(framer):
4444 assert framer ._start == b':'
4545 assert framer ._end == b"\r \n "
4646 elif isinstance (framer , ModbusRtuFramer ):
47- assert framer ._header == {'uid' : 0x00 , 'len' : 0 , 'crc' : '0000 ' }
47+ assert framer ._header == {'uid' : 0x00 , 'len' : 0 , 'crc' : b' \x00 \x00 ' }
4848 assert framer ._hsize == 0x01
4949 assert framer ._end == b'\x0d \x0a '
5050 assert framer ._min_frame_size == 4
@@ -64,47 +64,78 @@ def test_decode_data(rtu_framer, data):
6464 assert decoded == expected
6565
6666
67- @pytest .mark .parametrize ("data" , [(b'' , False ),
68- (b'\x02 \x01 \x01 \x00 Q\xcc ' , True )])
67+ @pytest .mark .parametrize ("data" , [
68+ (b'' , False ),
69+ (b'\x02 \x01 \x01 \x00 Q\xcc ' , True ),
70+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD ' , True ), # valid frame
71+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAC ' , False ), # invalid frame CRC
72+ ])
6973def test_check_frame (rtu_framer , data ):
7074 data , expected = data
7175 rtu_framer ._buffer = data
7276 assert expected == rtu_framer .checkFrame ()
7377
7478
75- @pytest .mark .parametrize ("data" , [b'' , b'abcd' ])
76- def test_advance_framer (rtu_framer , data ):
77- rtu_framer ._buffer = data
79+ @pytest .mark .parametrize ("data" , [
80+ (b'' , {'uid' : 0x00 , 'len' : 0 , 'crc' : b'\x00 \x00 ' }, b'' ),
81+ (b'abcd' , {'uid' : 0x00 , 'len' : 2 , 'crc' : b'\x00 \x00 ' }, b'cd' ),
82+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD \x12 \x03 ' , # real case, frame size is 11
83+ {'uid' : 0x00 , 'len' : 11 , 'crc' : b'\x00 \x00 ' }, b'\x12 \x03 ' ),
84+ ])
85+ def test_rtu_advance_framer (rtu_framer , data ):
86+ before_buf , before_header , after_buf = data
87+
88+ rtu_framer ._buffer = before_buf
89+ rtu_framer ._header = before_header
7890 rtu_framer .advanceFrame ()
79- assert rtu_framer ._header == {}
80- assert rtu_framer ._buffer == data
91+ assert rtu_framer ._header == {'uid' : 0x00 , 'len' : 0 , 'crc' : b' \x00 \x00 ' }
92+ assert rtu_framer ._buffer == after_buf
8193
8294
8395@pytest .mark .parametrize ("data" , [b'' , b'abcd' ])
84- def test_reset_framer (rtu_framer , data ):
96+ def test_rtu_reset_framer (rtu_framer , data ):
8597 rtu_framer ._buffer = data
8698 rtu_framer .resetFrame ()
87- assert rtu_framer ._header == {}
99+ assert rtu_framer ._header == {'uid' : 0x00 , 'len' : 0 , 'crc' : b' \x00 \x00 ' }
88100 assert rtu_framer ._buffer == b''
89101
90102
91103@pytest .mark .parametrize ("data" , [
92104 (b'' , False ),
105+ (b'\x11 ' , False ),
106+ (b'\x11 \x03 ' , False ),
93107 (b'\x11 \x03 \x06 ' , False ),
94108 (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 ' , False ),
95109 (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD ' , True ),
96- (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD \xAB \xCD ' , True )
110+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD \xAB \xCD ' , True ),
97111])
98112def test_is_frame_ready (rtu_framer , data ):
99113 data , expected = data
100114 rtu_framer ._buffer = data
101- rtu_framer .advanceFrame ()
115+ # rtu_framer.advanceFrame()
102116 assert rtu_framer .isFrameReady () == expected
103117
104118
105- def test_populate_header (rtu_framer ):
106- rtu_framer .populateHeader (b'abcd' )
107- assert rtu_framer ._header == {'crc' : b'd' , 'uid' : 97 , 'len' : 5 }
119+ @pytest .mark .parametrize ("data" , [
120+ b'' ,
121+ b'\x11 ' ,
122+ b'\x11 \x03 ' ,
123+ b'\x11 \x03 \x06 ' ,
124+ b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x43 ' ,
125+ ])
126+ def test_rtu_populate_header_fail (rtu_framer , data ):
127+ with pytest .raises (IndexError ):
128+ rtu_framer .populateHeader (data )
129+
130+
131+ @pytest .mark .parametrize ("data" , [
132+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD ' , {'crc' : b'\x49 \xAD ' , 'uid' : 17 , 'len' : 11 }),
133+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD \x11 \x03 ' , {'crc' : b'\x49 \xAD ' , 'uid' : 17 , 'len' : 11 })
134+ ])
135+ def test_rtu_populate_header (rtu_framer , data ):
136+ buffer , expected = data
137+ rtu_framer .populateHeader (buffer )
138+ assert rtu_framer ._header == expected
108139
109140
110141def test_add_to_frame (rtu_framer ):
@@ -126,12 +157,26 @@ def test_populate_result(rtu_framer):
126157 assert result .unit_id == 255
127158
128159
129- @pytest .mark .parametrize ('framer' , [ascii_framer , rtu_framer , binary_framer ])
130- def test_process_incoming_packet (framer ):
131- def cb (res ):
132- return res
133- # data = b''
134- # framer.processIncomingPacket(data, cb, unit=1, single=False)
160+ @pytest .mark .parametrize ("data" , [
161+ (b'\x11 ' , 17 , False , False ), # not complete frame
162+ (b'\x11 \x03 ' , 17 , False , False ), # not complete frame
163+ (b'\x11 \x03 \x06 ' , 17 , False , False ), # not complete frame
164+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 ' , 17 , False , False ), # not complete frame
165+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 ' , 17 , False , False ), # not complete frame
166+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 ' , 17 , False , False ), # not complete frame
167+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAC ' , 17 , True , False ), # bad crc
168+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD ' , 17 , False , True ), # good frame
169+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD ' , 16 , True , False ), # incorrect unit id
170+ (b'\x11 \x03 \x06 \xAE \x41 \x56 \x52 \x43 \x40 \x49 \xAD \x11 \x03 ' , 17 , False , True ), # good frame + part of next frame
171+ ])
172+ def test_rtu_process_incoming_packet (rtu_framer , data ):
173+ buffer , units , reset_called , process_called = data
174+
175+ with patch .object (rtu_framer , '_process' ) as mock_process , \
176+ patch .object (rtu_framer , 'resetFrame' ) as mock_reset :
177+ rtu_framer .processIncomingPacket (buffer , Mock (), units )
178+ assert mock_process .call_count == (1 if process_called else 0 )
179+ assert mock_reset .call_count == (1 if reset_called else 0 )
135180
136181
137182def test_build_packet (rtu_framer ):
0 commit comments