@@ -37,68 +37,68 @@ def generate_test_description():
3737 """Generate launch description with gateway node, demo nodes, and tests."""
3838 # Launch the ROS 2 Medkit Gateway node
3939 gateway_node = launch_ros .actions .Node (
40- package = " ros2_medkit_gateway" ,
41- executable = " gateway_node" ,
42- name = " ros2_medkit_gateway" ,
43- output = " screen" ,
40+ package = ' ros2_medkit_gateway' ,
41+ executable = ' gateway_node' ,
42+ name = ' ros2_medkit_gateway' ,
43+ output = ' screen' ,
4444 parameters = [],
4545 )
4646
4747 # Launch demo automotive sensor nodes
4848 engine_temp_sensor = launch_ros .actions .Node (
49- package = " ros2_medkit_gateway" ,
50- executable = " demo_engine_temp_sensor" ,
51- name = " temp_sensor" ,
52- namespace = " /powertrain/engine" ,
53- output = " screen" ,
49+ package = ' ros2_medkit_gateway' ,
50+ executable = ' demo_engine_temp_sensor' ,
51+ name = ' temp_sensor' ,
52+ namespace = ' /powertrain/engine' ,
53+ output = ' screen' ,
5454 )
5555
5656 rpm_sensor = launch_ros .actions .Node (
57- package = " ros2_medkit_gateway" ,
58- executable = " demo_rpm_sensor" ,
59- name = " rpm_sensor" ,
60- namespace = " /powertrain/engine" ,
61- output = " screen" ,
57+ package = ' ros2_medkit_gateway' ,
58+ executable = ' demo_rpm_sensor' ,
59+ name = ' rpm_sensor' ,
60+ namespace = ' /powertrain/engine' ,
61+ output = ' screen' ,
6262 )
6363
6464 brake_pressure_sensor = launch_ros .actions .Node (
65- package = " ros2_medkit_gateway" ,
66- executable = " demo_brake_pressure_sensor" ,
67- name = " pressure_sensor" ,
68- namespace = " /chassis/brakes" ,
69- output = " screen" ,
65+ package = ' ros2_medkit_gateway' ,
66+ executable = ' demo_brake_pressure_sensor' ,
67+ name = ' pressure_sensor' ,
68+ namespace = ' /chassis/brakes' ,
69+ output = ' screen' ,
7070 )
7171
7272 door_status_sensor = launch_ros .actions .Node (
73- package = " ros2_medkit_gateway" ,
74- executable = " demo_door_status_sensor" ,
75- name = " status_sensor" ,
76- namespace = " /body/door/front_left" ,
77- output = " screen" ,
73+ package = ' ros2_medkit_gateway' ,
74+ executable = ' demo_door_status_sensor' ,
75+ name = ' status_sensor' ,
76+ namespace = ' /body/door/front_left' ,
77+ output = ' screen' ,
7878 )
7979
8080 brake_actuator = launch_ros .actions .Node (
81- package = " ros2_medkit_gateway" ,
82- executable = " demo_brake_actuator" ,
83- name = " actuator" ,
84- namespace = " /chassis/brakes" ,
85- output = " screen" ,
81+ package = ' ros2_medkit_gateway' ,
82+ executable = ' demo_brake_actuator' ,
83+ name = ' actuator' ,
84+ namespace = ' /chassis/brakes' ,
85+ output = ' screen' ,
8686 )
8787
8888 light_controller = launch_ros .actions .Node (
89- package = " ros2_medkit_gateway" ,
90- executable = " demo_light_controller" ,
91- name = " controller" ,
92- namespace = " /body/lights" ,
93- output = " screen" ,
89+ package = ' ros2_medkit_gateway' ,
90+ executable = ' demo_light_controller' ,
91+ name = ' controller' ,
92+ namespace = ' /body/lights' ,
93+ output = ' screen' ,
9494 )
9595
9696 calibration_service = launch_ros .actions .Node (
97- package = " ros2_medkit_gateway" ,
98- executable = " demo_calibration_service" ,
99- name = " calibration" ,
100- namespace = " /powertrain/engine" ,
101- output = " screen" ,
97+ package = ' ros2_medkit_gateway' ,
98+ executable = ' demo_calibration_service' ,
99+ name = ' calibration' ,
100+ namespace = ' /powertrain/engine' ,
101+ output = ' screen' ,
102102 )
103103
104104 # Start demo nodes with a delay to ensure gateway starts first
@@ -127,15 +127,15 @@ def generate_test_description():
127127 ]
128128 ),
129129 {
130- " gateway_node" : gateway_node ,
130+ ' gateway_node' : gateway_node ,
131131 },
132132 )
133133
134134
135135class TestROS2MedkitGatewayIntegration (unittest .TestCase ):
136136 """Integration tests for ROS 2 Medkit Gateway REST API and discovery."""
137137
138- BASE_URL = " http://localhost:8080"
138+ BASE_URL = ' http://localhost:8080'
139139 # Wait for cache refresh + safety margin
140140 # Must be kept in sync with gateway_params.yaml refresh_interval_ms (2000ms)
141141 # Need to wait for at least 2 refresh cycles to ensure all demo nodes are discovered
@@ -151,17 +151,17 @@ def setUpClass(cls):
151151 max_retries = 5
152152 for i in range (max_retries ):
153153 try :
154- response = requests .get (f" { cls .BASE_URL } /" , timeout = 1 )
154+ response = requests .get (f' { cls .BASE_URL } /' , timeout = 1 )
155155 if response .status_code == 200 :
156156 return
157157 except requests .exceptions .RequestException :
158158 if i == max_retries - 1 :
159- raise unittest .SkipTest (" Gateway not responding" )
159+ raise unittest .SkipTest (' Gateway not responding' )
160160 time .sleep (1 )
161161
162162 def _get_json (self , endpoint : str ):
163163 """Get JSON from an endpoint."""
164- response = requests .get (f" { self .BASE_URL } { endpoint } " , timeout = 5 )
164+ response = requests .get (f' { self .BASE_URL } { endpoint } ' , timeout = 5 )
165165 response .raise_for_status ()
166166 return response .json ()
167167
@@ -171,64 +171,64 @@ def test_01_root_endpoint(self):
171171
172172 @verifies REQ_INTEROP_010
173173 """
174- data = self ._get_json ("/" )
175- self .assertIn (" status" , data )
176- self .assertIn (" version" , data )
177- self .assertEqual (data [" status" ], " ROS 2 Medkit Gateway running" )
178- self .assertEqual (data [" version" ], " 0.1.0" )
179- print (" ✓ Root endpoint test passed" )
174+ data = self ._get_json ('/' )
175+ self .assertIn (' status' , data )
176+ self .assertIn (' version' , data )
177+ self .assertEqual (data [' status' ], ' ROS 2 Medkit Gateway running' )
178+ self .assertEqual (data [' version' ], ' 0.1.0' )
179+ print (' ✓ Root endpoint test passed' )
180180
181181 def test_02_list_areas (self ):
182182 """
183183 Test GET /areas returns all discovered areas.
184184
185185 @verifies REQ_INTEROP_003
186186 """
187- areas = self ._get_json (" /areas" )
187+ areas = self ._get_json (' /areas' )
188188 self .assertIsInstance (areas , list )
189189 self .assertGreaterEqual (len (areas ), 1 )
190- area_ids = [area ["id" ] for area in areas ]
191- self .assertIn (" root" , area_ids )
192- print (f" ✓ Areas test passed: { len (areas )} areas discovered" )
190+ area_ids = [area ['id' ] for area in areas ]
191+ self .assertIn (' root' , area_ids )
192+ print (f' ✓ Areas test passed: { len (areas )} areas discovered' )
193193
194194 def test_03_list_components (self ):
195195 """
196196 Test GET /components returns all discovered components.
197197
198198 @verifies REQ_INTEROP_003
199199 """
200- components = self ._get_json (" /components" )
200+ components = self ._get_json (' /components' )
201201 self .assertIsInstance (components , list )
202202 # Should have at least 7 demo nodes + gateway node
203203 self .assertGreaterEqual (len (components ), 7 )
204204
205205 # Verify response structure - all components should have required fields
206206 for component in components :
207- self .assertIn ("id" , component )
208- self .assertIn (" namespace" , component )
209- self .assertIn (" fqn" , component )
210- self .assertIn (" type" , component )
211- self .assertIn (" area" , component )
212- self .assertEqual (component [" type" ], " Component" )
207+ self .assertIn ('id' , component )
208+ self .assertIn (' namespace' , component )
209+ self .assertIn (' fqn' , component )
210+ self .assertIn (' type' , component )
211+ self .assertIn (' area' , component )
212+ self .assertEqual (component [' type' ], ' Component' )
213213
214214 # Verify some expected component IDs are present
215- component_ids = [comp ["id" ] for comp in components ]
216- self .assertIn (" temp_sensor" , component_ids )
217- self .assertIn (" rpm_sensor" , component_ids )
218- self .assertIn (" pressure_sensor" , component_ids )
215+ component_ids = [comp ['id' ] for comp in components ]
216+ self .assertIn (' temp_sensor' , component_ids )
217+ self .assertIn (' rpm_sensor' , component_ids )
218+ self .assertIn (' pressure_sensor' , component_ids )
219219
220- print (f" ✓ Components test passed: { len (components )} components discovered" )
220+ print (f' ✓ Components test passed: { len (components )} components discovered' )
221221
222222 def test_04_automotive_areas_discovery (self ):
223223 """Test that automotive areas are properly discovered."""
224- areas = self ._get_json (" /areas" )
225- area_ids = [area ["id" ] for area in areas ]
224+ areas = self ._get_json (' /areas' )
225+ area_ids = [area ['id' ] for area in areas ]
226226
227- expected_areas = [" powertrain" , " chassis" , " body" ]
227+ expected_areas = [' powertrain' , ' chassis' , ' body' ]
228228 for expected in expected_areas :
229229 self .assertIn (expected , area_ids )
230230
231- print (f" ✓ All automotive areas discovered: { area_ids } " )
231+ print (f' ✓ All automotive areas discovered: { area_ids } ' )
232232
233233 def test_05_area_components_success (self ):
234234 """
@@ -237,36 +237,36 @@ def test_05_area_components_success(self):
237237 @verifies REQ_INTEROP_006
238238 """
239239 # Test powertrain area
240- components = self ._get_json (" /areas/powertrain/components" )
240+ components = self ._get_json (' /areas/powertrain/components' )
241241 self .assertIsInstance (components , list )
242242 self .assertGreater (len (components ), 0 )
243243
244244 # All components should belong to powertrain area
245245 for component in components :
246- self .assertEqual (component [" area" ], " powertrain" )
247- self .assertIn ("id" , component )
248- self .assertIn (" namespace" , component )
246+ self .assertEqual (component [' area' ], ' powertrain' )
247+ self .assertIn ('id' , component )
248+ self .assertIn (' namespace' , component )
249249
250250 # Verify expected powertrain components
251- component_ids = [comp ["id" ] for comp in components ]
252- self .assertIn (" temp_sensor" , component_ids )
253- self .assertIn (" rpm_sensor" , component_ids )
251+ component_ids = [comp ['id' ] for comp in components ]
252+ self .assertIn (' temp_sensor' , component_ids )
253+ self .assertIn (' rpm_sensor' , component_ids )
254254
255255 print (
256- f" ✓ Area components test passed: { len (components )} components in powertrain"
256+ f' ✓ Area components test passed: { len (components )} components in powertrain'
257257 )
258258
259259 def test_06_area_components_nonexistent_error (self ):
260260 """Test GET /areas/{area_id}/components returns 404 for nonexistent area."""
261261 response = requests .get (
262- f" { self .BASE_URL } /areas/nonexistent/components" , timeout = 5
262+ f' { self .BASE_URL } /areas/nonexistent/components' , timeout = 5
263263 )
264264 self .assertEqual (response .status_code , 404 )
265265
266266 data = response .json ()
267- self .assertIn (" error" , data )
268- self .assertEqual (data [" error" ], " Area not found" )
269- self .assertIn (" area_id" , data )
270- self .assertEqual (data [" area_id" ], " nonexistent" )
267+ self .assertIn (' error' , data )
268+ self .assertEqual (data [' error' ], ' Area not found' )
269+ self .assertIn (' area_id' , data )
270+ self .assertEqual (data [' area_id' ], ' nonexistent' )
271271
272- print (" ✓ Nonexistent area error test passed" )
272+ print (' ✓ Nonexistent area error test passed' )
0 commit comments