@@ -286,13 +286,73 @@ def periodicity():
286286
287287
288288class TestScanner (unittest .TestCase ):
289+ TIMEOUT = 0.1
289290
290- def test_passive_scanning (self ):
291- scanner = canopen .network .NodeScanner ()
292- scanner .on_message_received (0x586 )
293- scanner .on_message_received (0x587 )
294- scanner .on_message_received (0x586 )
295- self .assertListEqual (scanner .nodes , [6 , 7 ])
291+ def setUp (self ):
292+ self .scanner = canopen .network .NodeScanner ()
293+
294+ def test_scanner_on_message_received (self ):
295+ # Emergency frames should be recognized.
296+ self .scanner .on_message_received (0x081 )
297+ # Heartbeats should be recognized.
298+ self .scanner .on_message_received (0x703 )
299+ # Tx PDOs should be recognized, but not Rx PDOs.
300+ self .scanner .on_message_received (0x185 )
301+ self .scanner .on_message_received (0x206 )
302+ self .scanner .on_message_received (0x287 )
303+ self .scanner .on_message_received (0x308 )
304+ self .scanner .on_message_received (0x389 )
305+ self .scanner .on_message_received (0x40a )
306+ self .scanner .on_message_received (0x48b )
307+ self .scanner .on_message_received (0x50c )
308+ # SDO responses from .search() should be recognized,
309+ # but not SDO requests.
310+ self .scanner .on_message_received (0x58d )
311+ self .scanner .on_message_received (0x50e )
312+ self .assertListEqual (self .scanner .nodes , [1 , 3 , 5 , 7 , 9 , 11 , 13 ])
313+
314+ def test_scanner_reset (self ):
315+ self .scanner .nodes = [1 , 2 , 3 ] # Mock scan.
316+ self .scanner .reset ()
317+ self .assertListEqual (self .scanner .nodes , [])
318+
319+ def test_scanner_search_no_network (self ):
320+ with self .assertRaisesRegex (RuntimeError , "Network is required" ):
321+ self .scanner .search ()
322+
323+ def test_scanner_search (self ):
324+ bus = can .Bus (interface = "virtual" , receive_own_messages = True )
325+ net = canopen .Network (bus )
326+ net .connect ()
327+ self .addCleanup (net .disconnect )
328+
329+ self .scanner .network = net
330+ self .scanner .search ()
331+
332+ payload = bytes ([64 , 0 , 16 , 0 , 0 , 0 , 0 , 0 ])
333+ acc = [bus .recv (self .TIMEOUT ) for _ in range (127 )]
334+ for node_id , msg in enumerate (acc , start = 1 ):
335+ with self .subTest (node_id = node_id ):
336+ self .assertIsNotNone (msg )
337+ self .assertEqual (msg .arbitration_id , 0x600 + node_id )
338+ self .assertEqual (msg .data , payload )
339+ # Check that no spurious packets were sent.
340+ self .assertIsNone (bus .recv (self .TIMEOUT ))
341+
342+ def test_scanner_search_limit (self ):
343+ bus = can .Bus (interface = "virtual" , receive_own_messages = True )
344+ net = canopen .Network (bus )
345+ net .connect ()
346+ self .addCleanup (net .disconnect )
347+
348+ self .scanner .network = net
349+ self .scanner .search (limit = 1 )
350+
351+ msg = bus .recv (self .TIMEOUT )
352+ self .assertIsNotNone (msg )
353+ self .assertEqual (msg .arbitration_id , 0x601 )
354+ # Check that no spurious packets were sent.
355+ self .assertIsNone (bus .recv (self .TIMEOUT ))
296356
297357
298358if __name__ == "__main__" :
0 commit comments