1+ import threading
12import time
23import unittest
34
@@ -41,28 +42,28 @@ def test_state_set_invalid(self):
4142
4243class TestNmtMaster (unittest .TestCase ):
4344 NODE_ID = 2
44- COB_ID = 0x700 + NODE_ID
4545 PERIOD = 0.01
46- TIMEOUT = PERIOD * 2
46+ TIMEOUT = PERIOD * 10
4747
4848 def setUp (self ):
49- bus = can .ThreadSafeBus (
50- interface = "virtual" ,
51- channel = "test" ,
52- receive_own_messages = True ,
53- )
54- net = canopen .Network (bus )
49+ net = canopen .Network ()
5550 net .NOTIFIER_SHUTDOWN_TIMEOUT = 0.0
56- net .connect ()
51+ net .connect (interface = "virtual" )
5752 with self .assertLogs ():
5853 node = net .add_node (self .NODE_ID , SAMPLE_EDS )
5954
60- self .bus = bus
55+ self .bus = can . Bus ( interface = "virtual" )
6156 self .net = net
6257 self .node = node
6358
6459 def tearDown (self ):
6560 self .net .disconnect ()
61+ self .bus .shutdown ()
62+
63+ def dispatch_heartbeat (self , code ):
64+ cob_id = 0x700 + self .NODE_ID
65+ hb = can .Message (arbitration_id = cob_id , data = [code ])
66+ self .bus .send (hb )
6667
6768 def test_nmt_master_no_heartbeat (self ):
6869 with self .assertRaisesRegex (NmtError , "heartbeat" ):
@@ -74,47 +75,54 @@ def test_nmt_master_on_heartbeat(self):
7475 # Skip the special INITIALISING case.
7576 for code in [st for st in NMT_STATES if st != 0 ]:
7677 with self .subTest (code = code ):
77- task = self .net .send_periodic (self .COB_ID , [code ], self .PERIOD )
78- try :
79- actual = self .node .nmt .wait_for_heartbeat (self .TIMEOUT )
80- finally :
81- task .stop ()
78+ t = threading .Timer (0.01 , self .dispatch_heartbeat , args = (code ,))
79+ t .start ()
80+ self .addCleanup (t .join )
81+ actual = self .node .nmt .wait_for_heartbeat (0.1 )
8282 expected = NMT_STATES [code ]
8383 self .assertEqual (actual , expected )
8484
85- def test_nmt_master_on_heartbeat_initialising (self ):
86- task = self .net .send_periodic (self .COB_ID , [0 ], self .PERIOD )
87- self .addCleanup (task .stop )
85+ def test_nmt_master_wait_for_bootup (self ):
86+ t = threading .Timer (0.01 , self .dispatch_heartbeat , args = (0x00 ,))
87+ t .start ()
88+ self .addCleanup (t .join )
8889 self .node .nmt .wait_for_bootup (self .TIMEOUT )
90+ self .assertEqual (self .node .nmt .state , "PRE-OPERATIONAL" )
91+
92+ def test_nmt_master_on_heartbeat_initialising (self ):
93+ t = threading .Timer (0.01 , self .dispatch_heartbeat , args = (0x00 ,))
94+ t .start ()
95+ self .addCleanup (t .join )
8996 state = self .node .nmt .wait_for_heartbeat (self .TIMEOUT )
9097 self .assertEqual (state , "PRE-OPERATIONAL" )
9198
9299 def test_nmt_master_on_heartbeat_unknown_state (self ):
93- task = self .net .send_periodic (self .COB_ID , [0xcb ], self .PERIOD )
94- self .addCleanup (task .stop )
100+ t = threading .Timer (0.01 , self .dispatch_heartbeat , args = (0xcb ,))
101+ t .start ()
102+ self .addCleanup (t .join )
95103 state = self .node .nmt .wait_for_heartbeat (self .TIMEOUT )
96104 # Expect the high bit to be masked out, and a formatted string to
97105 # be returned.
98106 self .assertEqual (state , "UNKNOWN STATE '75'" )
99107
100108 def test_nmt_master_add_heartbeat_callback (self ):
101- from threading import Event
102- event = Event ()
109+ event = threading .Event ()
103110 state = None
104111 def hook (st ):
105112 nonlocal state
106113 state = st
107114 event .set ()
108115 self .node .nmt .add_heartbeat_callback (hook )
109- self .net .send_message (self .COB_ID , bytes ([127 ]))
116+
117+ self .dispatch_heartbeat (0x7f )
110118 self .assertTrue (event .wait (self .TIMEOUT ))
111119 self .assertEqual (state , 127 )
112120
113121 def test_nmt_master_node_guarding (self ):
114122 self .node .nmt .start_node_guarding (self .PERIOD )
115123 msg = self .bus .recv (self .TIMEOUT )
116124 self .assertIsNotNone (msg )
117- self .assertEqual (msg .arbitration_id , self .COB_ID )
125+ self .assertEqual (msg .arbitration_id , 0x700 + self .NODE_ID )
118126 self .assertEqual (msg .dlc , 0 )
119127
120128 self .node .nmt .stop_node_guarding ()
0 commit comments