diff --git a/ros_gz_sim/CMakeLists.txt b/ros_gz_sim/CMakeLists.txt
index 514587de..7f420e09 100644
--- a/ros_gz_sim/CMakeLists.txt
+++ b/ros_gz_sim/CMakeLists.txt
@@ -123,11 +123,15 @@ if(BUILD_TESTING)
# GTest
find_package(ament_cmake_gtest REQUIRED)
+ find_package(launch_testing_ament_cmake REQUIRED)
ament_find_gtest()
ament_add_gtest_executable(test_stopwatch
test/test_stopwatch.cpp
)
+ ament_add_gtest_executable(test_create
+ test/test_create.cpp
+ )
ament_target_dependencies(test_stopwatch rclcpp)
@@ -139,12 +143,16 @@ if(BUILD_TESTING)
target_link_libraries(test_stopwatch
${PROJECT_NAME}
)
+ target_link_libraries(test_create
+ ${GZ_TARGET_PREFIX}-transport${GZ_TRANSPORT_VER}::core
+ )
install(
- TARGETS test_stopwatch
+ TARGETS test_stopwatch test_create
DESTINATION lib/${PROJECT_NAME}
)
ament_add_gtest_test(test_stopwatch)
+ add_launch_test(test/test_create_node.launch.py TIMEOUT 200)
endif()
ament_package()
diff --git a/ros_gz_sim/package.xml b/ros_gz_sim/package.xml
index bec29ff7..a4cad906 100644
--- a/ros_gz_sim/package.xml
+++ b/ros_gz_sim/package.xml
@@ -33,6 +33,9 @@
ament_lint_auto
ament_lint_common
+ launch_testing_ament_cmake
+ launch_ros
+ launch_testing
ament_cmake
diff --git a/ros_gz_sim/src/create.cpp b/ros_gz_sim/src/create.cpp
index 09bbfec0..3fa5bbcc 100644
--- a/ros_gz_sim/src/create.cpp
+++ b/ros_gz_sim/src/create.cpp
@@ -59,7 +59,9 @@ int main(int _argc, char ** _argv)
char ** filtered_argv = new char *[(filtered_argc + 1)];
for (int ii = 0; ii < filtered_argc; ++ii) {
filtered_argv[ii] = new char[filtered_arguments[ii].size() + 1];
- snprintf(filtered_argv[ii], sizeof(filtered_argv), "%s", filtered_arguments[ii].c_str());
+ snprintf(
+ filtered_argv[ii],
+ filtered_arguments[ii].size() + 1, "%s", filtered_arguments[ii].c_str());
}
filtered_argv[filtered_argc] = nullptr;
diff --git a/ros_gz_sim/test/test_create.cpp b/ros_gz_sim/test/test_create.cpp
new file mode 100644
index 00000000..ee92bf39
--- /dev/null
+++ b/ros_gz_sim/test/test_create.cpp
@@ -0,0 +1,56 @@
+// Copyright 2023 Open Source Robotics Foundation, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Simple application that provides a `/create` service and prints out the
+// sdf_filename of the request. This works in conjection with
+// test_create_node.launch.py
+int main()
+{
+ std::mutex m;
+ std::condition_variable cv;
+ bool test_complete = false;
+
+ gz::transport::Node node;
+ auto cb = std::function(
+ [&](
+ const gz::msgs::EntityFactory & _req,
+ gz::msgs::Boolean & _res) -> bool {
+ std::cout << _req.sdf_filename() << std::endl;
+ _res.set_data(true);
+
+ {
+ std::lock_guard lk(m);
+ test_complete = true;
+ }
+ cv.notify_one();
+ return true;
+ });
+
+ node.Advertise("/world/default/create", cb);
+ // wait until we receive a message.
+ std::unique_lock lk(m);
+ cv.wait(lk, [&] {return test_complete;});
+ // Sleep so that the service response can be sent before exiting.
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+}
diff --git a/ros_gz_sim/test/test_create_node.launch.py b/ros_gz_sim/test/test_create_node.launch.py
new file mode 100644
index 00000000..14710f58
--- /dev/null
+++ b/ros_gz_sim/test/test_create_node.launch.py
@@ -0,0 +1,47 @@
+# Copyright 2023 Open Source Robotics Foundation, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+
+from launch import LaunchDescription
+
+from launch_ros.actions import Node
+
+import launch_testing
+
+
+def generate_test_description():
+ expected_file_name = 'nonexistent/long/file_name'
+ create = Node(package='ros_gz_sim', executable='create',
+ arguments=['-world', 'default', '-file', expected_file_name], output='screen')
+ test_create = Node(package='ros_gz_sim', executable='test_create', output='screen')
+ return LaunchDescription([
+ create,
+ test_create,
+ launch_testing.util.KeepAliveProc(),
+ launch_testing.actions.ReadyToTest(),
+ ]), locals()
+
+
+class WaitForTests(unittest.TestCase):
+
+ def test_termination(self, test_create, proc_info):
+ proc_info.assertWaitForShutdown(process=test_create, timeout=200)
+
+
+@launch_testing.post_shutdown_test()
+class CreateTest(unittest.TestCase):
+
+ def test_output(self, expected_file_name, test_create, proc_output):
+ launch_testing.asserts.assertInStdout(proc_output, expected_file_name, test_create)