11from  tornado  import  testing 
22import  tornado .websocket 
33import  tornado .web 
4- import  tornado .ioloop 
54import  json 
65from  unittest .mock  import  Mock 
76from  donkeycar .parts .web_controller .web  import  WebSocketCalibrateAPI 
8- from  time  import  sleep 
9- 
10- SLEEP  =  0.5 
7+ import  tornado .gen 
118
129
1310class  WebSocketCalibrateTest (testing .AsyncHTTPTestCase ):
@@ -24,6 +21,17 @@ def get_app(self):
2421
2522    def  get_ws_url (self ):
2623        return  "ws://localhost:"  +  str (self .get_http_port ()) +  "/" 
24+     
25+     async  def  wait_for_attribute_value (self , obj , attr_name , 
26+                                        expected_value , timeout_seconds = 5 ):
27+         """Poll until an object's attribute equals the expected value or timeout.""" 
28+         iterations  =  int (timeout_seconds  /  0.1 )
29+         for  _  in  range (iterations ):
30+             if  (hasattr (obj , attr_name ) 
31+                 and  getattr (obj , attr_name ) ==  expected_value ):
32+                 return  True 
33+             await  tornado .gen .sleep (0.1 )
34+         return  False 
2735
2836    @tornado .testing .gen_test  
2937    def  test_calibrate_servo_esc_1b (self ):
@@ -40,7 +48,10 @@ def test_calibrate_servo_esc_1b(self):
4048        data  =  {"config" : {"STEERING_LEFT_PWM" : 444 }}
4149        yield  ws_client .write_message (json .dumps (data ))
4250        yield  ws_client .close ()
43-         sleep (SLEEP )
51+         
52+         result  =  yield  self .wait_for_attribute_value (
53+             self .app .drive_train ['steering' ], 'left_pulse' , 444 )
54+         assert  result , "WebSocket message not processed within timeout" 
4455        assert  self .app .drive_train ['steering' ].left_pulse  ==  444 
4556        assert  self .app .drive_train ['steering' ].right_pulse  is  None 
4657
@@ -59,7 +70,10 @@ def test_calibrate_servo_esc_1a(self):
5970        data  =  {"config" : {"STEERING_LEFT_PWM" : 444 }}
6071        yield  ws_client .write_message (json .dumps (data ))
6172        yield  ws_client .close ()
62-         sleep (SLEEP )
73+         
74+         result  =  yield  self .wait_for_attribute_value (
75+             self .app .drive_train ['steering' ], 'left_pulse' , 444 )
76+         assert  result , "WebSocket message not processed within timeout" 
6377        assert  self .app .drive_train ['steering' ].left_pulse  ==  444 
6478        assert  self .app .drive_train ['steering' ].right_pulse  is  None 
6579
@@ -78,7 +92,10 @@ def test_calibrate_servo_esc_2b(self):
7892        data  =  {"config" : {"STEERING_RIGHT_PWM" : 555 }}
7993        yield  ws_client .write_message (json .dumps (data ))
8094        yield  ws_client .close ()
81-         sleep (SLEEP )
95+         
96+         result  =  yield  self .wait_for_attribute_value (
97+             self .app .drive_train ['steering' ], 'right_pulse' , 555 )
98+         assert  result , "WebSocket message not processed within timeout" 
8299        assert  self .app .drive_train ['steering' ].right_pulse  ==  555 
83100        assert  self .app .drive_train ['steering' ].left_pulse  is  None 
84101
@@ -97,7 +114,10 @@ def test_calibrate_servo_esc_2a(self):
97114        data  =  {"config" : {"STEERING_RIGHT_PWM" : 555 }}
98115        yield  ws_client .write_message (json .dumps (data ))
99116        yield  ws_client .close ()
100-         sleep (SLEEP )
117+         
118+         result  =  yield  self .wait_for_attribute_value (
119+             self .app .drive_train ['steering' ], 'right_pulse' , 555 )
120+         assert  result , "WebSocket message not processed within timeout" 
101121        assert  self .app .drive_train ['steering' ].right_pulse  ==  555 
102122        assert  self .app .drive_train ['steering' ].left_pulse  is  None 
103123
@@ -116,7 +136,10 @@ def test_calibrate_servo_esc_3b(self):
116136        data  =  {"config" : {"THROTTLE_FORWARD_PWM" : 666 }}
117137        yield  ws_client .write_message (json .dumps (data ))
118138        yield  ws_client .close ()
119-         sleep (SLEEP )
139+         
140+         result  =  yield  self .wait_for_attribute_value (
141+             self .app .drive_train ['throttle' ], 'max_pulse' , 666 )
142+         assert  result , "WebSocket message not processed within timeout" 
120143        assert  self .app .drive_train ['throttle' ].max_pulse  ==  666 
121144        assert  self .app .drive_train ['throttle' ].min_pulse  is  None 
122145
@@ -135,7 +158,10 @@ def test_calibrate_servo_esc_3a(self):
135158        data  =  {"config" : {"THROTTLE_FORWARD_PWM" : 666 }}
136159        yield  ws_client .write_message (json .dumps (data ))
137160        yield  ws_client .close ()
138-         sleep (SLEEP )
161+         
162+         result  =  yield  self .wait_for_attribute_value (
163+             self .app .drive_train ['throttle' ], 'max_pulse' , 666 )
164+         assert  result , "WebSocket message not processed within timeout" 
139165        assert  self .app .drive_train ['throttle' ].max_pulse  ==  666 
140166        assert  self .app .drive_train ['throttle' ].min_pulse  is  None 
141167
@@ -151,5 +177,8 @@ def test_calibrate_mm1(self):
151177        data  =  {"config" : {"MM1_STEERING_MID" : 1234 }}
152178        yield  ws_client .write_message (json .dumps (data ))
153179        yield  ws_client .close ()
154-         sleep (SLEEP )
180+         
181+         result  =  yield  self .wait_for_attribute_value (
182+             self .app .drive_train , 'STEERING_MID' , 1234 )
183+         assert  result , "WebSocket message not processed within timeout" 
155184        assert  self .app .drive_train .STEERING_MID  ==  1234 
0 commit comments