@@ -116,8 +116,27 @@ def test_LRC_CRC(self, func, lrc, expect):
116116 data = b'\x12 \x34 \x23 \x45 \x34 \x56 \x45 \x67 '
117117 assert expect == func (data , lrc ) if lrc else func (data )
118118
119+ def test_roundtrip_LRC (self ):
120+ """Test combined compute/check LRC."""
121+ data = b'\x12 \x34 \x23 \x45 \x34 \x56 \x45 \x67 '
122+ assert MessageAscii .compute_LRC (data ) == 0x1c
123+ assert MessageAscii .check_LRC (data , 0x1C )
124+
125+ def test_crc16_table (self ):
126+ """Test the crc16 table is prefilled."""
127+ assert len (MessageRTU .crc16_table ) == 256
128+ assert isinstance (MessageRTU .crc16_table [0 ], int )
129+ assert isinstance (MessageRTU .crc16_table [255 ], int )
130+
131+ def test_roundtrip_CRC (self ):
132+ """Test combined compute/check CRC."""
133+ data = b'\x12 \x34 \x23 \x45 \x34 \x56 \x45 \x67 '
134+ assert MessageRTU .compute_CRC (data ) == 0xE2DB
135+ assert MessageRTU .check_CRC (data , 0xE2DB )
119136
120- class TestMessages : # pylint: disable=too-few-public-methods
137+
138+
139+ class TestMessages :
121140 """Test message classes."""
122141
123142 @pytest .mark .parametrize (
@@ -198,10 +217,114 @@ class TestMessages: # pylint: disable=too-few-public-methods
198217 def test_encode (self , frame , frame_expected , data , dev_id , tid , inx1 , inx2 , inx3 ):
199218 """Test encode method."""
200219 if frame != MessageSocket and tid :
201- return
220+ pytest . skip ( "Not supported" )
202221 if frame == MessageTLS and (tid or dev_id ):
203- return
222+ pytest . skip ( "Not supported" )
204223 frame_obj = frame (None , True )
205224 expected = frame_expected [inx1 + inx2 + inx3 ]
206225 encoded_data = frame_obj .encode (data , dev_id , tid )
207226 assert encoded_data == expected
227+
228+ @pytest .mark .parametrize (
229+ ("msg_type" , "data" , "dev_id" , "tid" , "expected" ),
230+ [
231+ (MessageType .ASCII , b':0003007C00027F\r \n ' , 0 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
232+ (MessageType .ASCII , b':000304008D008EDE\r \n ' , 0 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
233+ (MessageType .ASCII , b':0083027B\r \n ' , 0 , 0 , b'\x83 \x02 ' ,), # Exception
234+ (MessageType .ASCII , b':1103007C00026E\r \n ' , 17 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
235+ (MessageType .ASCII , b':110304008D008ECD\r \n ' , 17 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
236+ (MessageType .ASCII , b':1183026A\r \n ' , 17 , 0 , b'\x83 \x02 ' ,), # Exception
237+ (MessageType .ASCII , b':FF03007C000280\r \n ' , 255 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
238+ (MessageType .ASCII , b':FF0304008D008EDF\r \n ' , 255 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
239+ (MessageType .ASCII , b':FF83027C\r \n ' , 255 , 0 , b'\x83 \x02 ' ,), # Exception
240+ (MessageType .RTU , b'\x00 \x03 \x00 \x7c \x00 \x02 \x04 \x02 ' , 0 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
241+ (MessageType .RTU , b'\x00 \x03 \x04 \x00 \x8d \x00 \x8e \xfa \xbc ' , 0 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
242+ (MessageType .RTU , b'\x00 \x83 \x02 \x91 \x31 ' , 0 , 0 , b'\x83 \x02 ' ,), # Exception
243+ (MessageType .RTU , b'\x11 \x03 \x00 \x7c \x00 \x02 \x07 \x43 ' , 17 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
244+ (MessageType .RTU , b'\x11 \x03 \x04 \x00 \x8d \x00 \x8e \xfb \xbd ' , 17 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
245+ (MessageType .RTU , b'\x11 \x83 \x02 \xc1 \x34 ' , 17 , 0 , b'\x83 \x02 ' ,), # Exception
246+ (MessageType .RTU , b'\xff \x03 \x00 |\x00 \x02 \x10 \x0d ' , 255 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
247+ (MessageType .RTU , b'\xff \x03 \x04 \x00 \x8d \x00 \x8e \xf5 \xb3 ' , 255 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
248+ (MessageType .RTU , b'\xff \x83 \x02 \xa1 \x01 ' , 255 , 0 , b'\x83 \x02 ' ,), # Exception
249+ (MessageType .SOCKET , b'\x00 \x00 \x00 \x00 \x00 \x06 \x00 \x03 \x00 \x7c \x00 \x02 ' , 0 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
250+ (MessageType .SOCKET , b'\x00 \x00 \x00 \x00 \x00 \x07 \x00 \x03 \x04 \x00 \x8d \x00 \x8e ' , 0 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
251+ (MessageType .SOCKET , b'\x00 \x00 \x00 \x00 \x00 \x03 \x00 \x83 \x02 ' , 0 , 0 , b'\x83 \x02 ' ,), # Exception
252+ (MessageType .SOCKET , b'\x00 \x00 \x00 \x00 \x00 \x06 \x11 \x03 \x00 \x7c \x00 \x02 ' , 17 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
253+ (MessageType .SOCKET , b'\x00 \x00 \x00 \x00 \x00 \x07 \x11 \x03 \x04 \x00 \x8d \x00 \x8e ' , 17 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
254+ (MessageType .SOCKET , b'\x00 \x00 \x00 \x00 \x00 \x03 \x11 \x83 \x02 ' , 17 , 0 , b'\x83 \x02 ' ,), # Exception
255+ (MessageType .SOCKET , b'\x00 \x00 \x00 \x00 \x00 \x06 \xff \x03 \x00 \x7c \x00 \x02 ' , 255 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
256+ (MessageType .SOCKET , b'\x00 \x00 \x00 \x00 \x00 \x07 \xff \x03 \x04 \x00 \x8d \x00 \x8e ' , 255 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
257+ (MessageType .SOCKET , b'\x00 \x00 \x00 \x00 \x00 \x03 \xff \x83 \x02 ' , 255 , 0 , b'\x83 \x02 ' ,), # Exception
258+ (MessageType .SOCKET , b'\x0c \x05 \x00 \x00 \x00 \x06 \x00 \x03 \x00 \x7c \x00 \x02 ' , 0 , 3077 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
259+ (MessageType .SOCKET , b'\x0c \x05 \x00 \x00 \x00 \x07 \x00 \x03 \x04 \x00 \x8d \x00 \x8e ' , 0 , 3077 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
260+ (MessageType .SOCKET , b'\x0c \x05 \x00 \x00 \x00 \x03 \x00 \x83 \x02 ' , 0 , 3077 , b'\x83 \x02 ' ,), # Exception
261+ (MessageType .SOCKET , b'\x0c \x05 \x00 \x00 \x00 \x06 \x11 \x03 \x00 \x7c \x00 \x02 ' , 17 , 3077 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
262+ (MessageType .SOCKET , b'\x0c \x05 \x00 \x00 \x00 \x07 \x11 \x03 \x04 \x00 \x8d \x00 \x8e ' , 17 , 3077 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
263+ (MessageType .SOCKET , b'\x0c \x05 \x00 \x00 \x00 \x03 \x11 \x83 \x02 ' , 17 , 3077 , b'\x83 \x02 ' ,), # Exception
264+ (MessageType .SOCKET , b'\x0c \x05 \x00 \x00 \x00 \x06 \xff \x03 \x00 \x7c \x00 \x02 ' , 255 , 3077 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
265+ (MessageType .SOCKET , b'\x0c \x05 \x00 \x00 \x00 \x07 \xff \x03 \x04 \x00 \x8d \x00 \x8e ' , 255 , 3077 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
266+ (MessageType .SOCKET , b'\x0c \x05 \x00 \x00 \x00 \x03 \xff \x83 \x02 ' , 255 , 3077 , b'\x83 \x02 ' ,), # Exception
267+ (MessageType .TLS , b'\x03 \x00 \x7c \x00 \x02 ' , 0 , 0 , b"\x03 \x00 \x7c \x00 \x02 " ,), # Request
268+ (MessageType .TLS , b'\x03 \x04 \x00 \x8d \x00 \x8e ' , 0 , 0 , b"\x03 \x04 \x00 \x8d \x00 \x8e " ,), # Response
269+ (MessageType .TLS , b'\x83 \x02 ' , 0 , 0 , b'\x83 \x02 ' ,), # Exception
270+ ]
271+ )
272+ @pytest .mark .parametrize (
273+ ("split" ),
274+ [
275+ "no" ,
276+ "half" ,
277+ "single" ,
278+ ]
279+ )
280+ async def test_decode (self , dummy_message , msg_type , data , dev_id , tid , expected , split ):
281+ """Test encode method."""
282+ if msg_type == MessageType .RTU :
283+ pytest .skip ("Waiting on implementation!" )
284+ if msg_type == MessageType .TLS and split != "no" :
285+ pytest .skip ("Not supported." )
286+ frame = dummy_message (
287+ msg_type ,
288+ CommParams (),
289+ False ,
290+ [1 ],
291+ )
292+ frame .callback_request_response = mock .Mock ()
293+ if split == "no" :
294+ used_len = frame .callback_data (data )
295+
296+ elif split == "half" :
297+ split_len = int (len (data ) / 2 )
298+ assert not frame .callback_data (data [0 :split_len ])
299+ frame .callback_request_response .assert_not_called ()
300+ used_len = frame .callback_data (data )
301+ else :
302+ last = len (data )
303+ for i in range (0 , last - 1 ):
304+ assert not frame .callback_data (data [0 :i + 1 ])
305+ frame .callback_request_response .assert_not_called ()
306+ used_len = frame .callback_data (data )
307+ assert used_len == len (data )
308+ frame .callback_request_response .assert_called_with (expected , dev_id , tid )
309+
310+ @pytest .mark .parametrize (
311+ ("frame" , "data" , "exp_len" ),
312+ [
313+ (MessageAscii , b':0003007C00017F\r \n ' , 17 ), # bad crc
314+ # (MessageAscii, b'abc:0003007C00027F\r\n', 3), # garble in front
315+ # (MessageAscii, b':0003007C00017F\r\nabc', 17), # bad crc, garble after
316+ # (MessageAscii, b':0003007C00017F\r\n:0003', 17), # part second message
317+ (MessageRTU , b'\x00 \x83 \x02 \x91 \x31 ' , 0 ), # bad crc
318+ # (MessageRTU, b'\x00\x83\x02\x91\x31', 0), # garble in front
319+ # (MessageRTU, b'\x00\x83\x02\x91\x31', 0), # garble after
320+ # (MessageRTU, b'\x00\x83\x02\x91\x31', 0), # part second message
321+ ]
322+ )
323+ async def test_decode_bad_crc (self , frame , data , exp_len ):
324+ """Test encode method."""
325+ if frame == MessageRTU :
326+ pytest .skip ("Waiting for implementation." )
327+ frame_obj = frame (None , True )
328+ used_len , _ , _ , data = frame_obj .decode (data )
329+ assert used_len == exp_len
330+ assert not data
0 commit comments