@@ -125,11 +125,16 @@ def test_custom_ros2_configuration_is_rendered_into_generated_files(self):
125125 """Custom ROS2 config values should appear in the generated package files."""
126126 ros2_dir = self .ros2_package_dir ()
127127
128+ # The package metadata should reflect the user-provided ROS2 package name
129+ # and description, not the defaults from the templates.
128130 with open (os .path .join (ros2_dir , "package.xml" ), encoding = "utf-8" ) as f :
129131 package_xml = f .read ()
130132 self .assertIn (f"<name>{ self .PACKAGE_NAME } </name>" , package_xml )
131133 self .assertIn (f"<description>{ self .DESCRIPTION } </description>" , package_xml )
132134
135+ # `open_optimizer.hpp` is where the generated node constants are wired in.
136+ # These assertions make sure the custom topic names, node name, rate, and
137+ # queue sizes are propagated into the generated C++ code.
133138 with open (os .path .join (ros2_dir , "include" , "open_optimizer.hpp" ), encoding = "utf-8" ) as f :
134139 optimizer_header = f .read ()
135140 self .assertIn (f'#define ROS2_NODE_{ self .OPTIMIZER_NAME .upper ()} _NODE_NAME "{ self .NODE_NAME } "' ,
@@ -147,12 +152,16 @@ def test_custom_ros2_configuration_is_rendered_into_generated_files(self):
147152 f"#define ROS2_NODE_{ self .OPTIMIZER_NAME .upper ()} _PARAMS_TOPIC_QUEUE_SIZE { self .PARAMS_QUEUE_SIZE } " ,
148153 optimizer_header )
149154
155+ # The runtime YAML configuration should carry the custom topic names and
156+ # timer rate so the launched node uses the intended ROS2 parameters.
150157 with open (os .path .join (ros2_dir , "config" , "open_params.yaml" ), encoding = "utf-8" ) as f :
151158 params_yaml = f .read ()
152159 self .assertIn (f'result_topic: "{ self .RESULT_TOPIC } "' , params_yaml )
153160 self .assertIn (f'params_topic: "{ self .PARAMS_TOPIC } "' , params_yaml )
154161 self .assertIn (f"rate: { self .RATE } " , params_yaml )
155162
163+ # The generated launch file should point to the correct package and
164+ # executable so `ros2 launch` can start the generated node.
156165 with open (os .path .join (ros2_dir , "launch" , "open_optimizer.launch.py" ), encoding = "utf-8" ) as f :
157166 launch_file = f .read ()
158167 self .assertIn (f'package="{ self .PACKAGE_NAME } "' , launch_file )
@@ -244,7 +253,11 @@ def ros2_test_env(cls):
244253 env = os .environ .copy ()
245254 ros2_dir = cls .ros2_package_dir ()
246255 os .makedirs (os .path .join (ros2_dir , ".ros_log" ), exist_ok = True )
256+ # Keep ROS2 logs inside the generated package directory so the tests do
257+ # not depend on a global writable log location.
247258 env ["ROS_LOG_DIR" ] = os .path .join (ros2_dir , ".ros_log" )
259+ # Fast DDS is the most reliable middleware choice in our CI/local test
260+ # setup when checking node discovery from separate processes.
248261 env .setdefault ("RMW_IMPLEMENTATION" , "rmw_fastrtps_cpp" )
249262 env .pop ("ROS_LOCALHOST_ONLY" , None )
250263 return env
@@ -337,6 +350,9 @@ def _wait_for_node_and_topics(self, ros2_dir, env):
337350 node_result = None
338351 topic_result = None
339352 for _ in range (6 ):
353+ # `ros2 node list` confirms that the process joined the ROS graph,
354+ # while `ros2 topic list` confirms that the expected interfaces are
355+ # actually being advertised.
340356 node_result = self ._run_shell (
341357 f"source { setup_script } && "
342358 "ros2 node list --no-daemon --spin-time 5" ,
@@ -364,13 +380,15 @@ def _wait_for_node_and_topics(self, ros2_dir, env):
364380
365381 def _assert_result_message (self , echo_stdout ):
366382 """Assert that the echoed result message indicates a successful solve."""
383+ # We do not compare the full numeric solution here; instead, we check
384+ # that the generated node returned a structurally valid result and that
385+ # the solver reported convergence.
367386 self .assertIn ("solution" , echo_stdout )
368- # A bit of integration testing: check whether the solver was able to
369- # solve the problem successfully.
370387 self .assertRegex (
371388 echo_stdout ,
372389 r"solution:\s*\n(?:- .+\n)+" ,
373390 msg = f"Expected a non-empty solution vector in result output:\n { echo_stdout } " )
391+ # `status: 0` matches `STATUS_CONVERGED` in the generated result message.
374392 self .assertIn ("status: 0" , echo_stdout )
375393 self .assertRegex (
376394 echo_stdout ,
@@ -389,10 +407,12 @@ def _assert_result_message(self, echo_stdout):
389407 def _exercise_running_optimizer (self , ros2_dir , env ):
390408 """Publish one request and verify that one valid result message is returned."""
391409 _ , setup_script = self .ros2_shell ()
410+ # Start listening before publishing so the single response is not missed.
392411 echo_process = self ._spawn_ros_process ("ros2 topic echo /result --once" , ros2_dir , env )
393412
394413 try :
395414 time .sleep (1 )
415+ # Send one concrete request through the generated ROS2 interface.
396416 self ._run_shell (
397417 f"source { setup_script } && "
398418 "ros2 topic pub --once /parameters "
@@ -411,6 +431,8 @@ def _exercise_running_optimizer(self, ros2_dir, env):
411431 def test_ros2_package_generation (self ):
412432 """Verify the ROS2 package files are generated."""
413433 ros2_dir = self .ros2_package_dir ()
434+ # This is a lightweight smoke test for the generator itself before we
435+ # attempt the slower build/run integration tests below.
414436 self .assertTrue (os .path .isfile (os .path .join (ros2_dir , "package.xml" )))
415437 self .assertTrue (os .path .isfile (os .path .join (ros2_dir , "CMakeLists.txt" )))
416438 self .assertTrue (os .path .isfile (
@@ -420,6 +442,9 @@ def test_generated_ros2_package_works(self):
420442 """Build, run, and call the generated ROS2 package."""
421443 ros2_dir = self .ros2_package_dir ()
422444 env = self .ros2_test_env ()
445+
446+ # First validate the plain `ros2 run` path, which exercises the
447+ # generated executable directly without going through the launch file.
423448 self ._build_generated_package (ros2_dir , env )
424449
425450 node_process = self ._spawn_ros_process (
@@ -438,6 +463,9 @@ def test_generated_ros2_launch_file_works(self):
438463 """Build the package, launch the node, and verify the launch file works."""
439464 ros2_dir = self .ros2_package_dir ()
440465 env = self .ros2_test_env ()
466+
467+ # Then validate the generated launch description, which should bring up
468+ # the exact same node and parameters via `ros2 launch`.
441469 self ._build_generated_package (ros2_dir , env )
442470
443471 launch_process = self ._spawn_ros_process (
0 commit comments