rosbag2
rosbag2 copied to clipboard
RecordOptions fails to deserialize YAML in large-scale topics/services scenarios
Description
When the topics and services in rosbag2_transport::RecordOptions contain a large number of elements and topic_qos_profile_overrides is not set, performing the YAML encode → decode process throws an exception during deserialization. Consequently, the serialization and deserialization loop cannot complete properly under valid configurations.
Expected Behavior
For valid RecordOptions, the YAML serialization and deserialization should work properly even when the number of topics/services is large.
Actual Behavior
Failed to serialize loop
To Reproduce
Test Case
#include <gmock/gmock.h>
#include <string>
#include "rosbag2_transport/record_options.hpp"
using namespace ::testing; // NOLINT
TEST(record_options, test)
{
rosbag2_transport::RecordOptions options;
options.topics = std::vector<std::string>(100000, "test_topic");
options.services = std::vector<std::string>(100000, "test_service");
ASSERT_NO_THROW({
auto node = YAML::convert<rosbag2_transport::RecordOptions>().encode(options);
std::stringstream serializer;
serializer << node;
auto recreated_node = YAML::Load(serializer.str()).as<rosbag2_transport::RecordOptions>();
ASSERT_EQ(options.topics, recreated_node.topics);
ASSERT_EQ(options.services, recreated_node.services);
});
}
Output
[ RUN ] record_options.test
/home/shangzh/rosbag2_ws/rosbag2/rosbag2_transport/test/rosbag2_transport/test_record_options.cpp:12: Failure
Expected: { auto node = YAML::convert<rosbag2_transport::RecordOptions>().encode(options); std::stringstream serializer; serializer << node; auto recreated_node = YAML::Load(serializer.str()).as<rosbag2_transport::RecordOptions>(); switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("options.topics", "recreated_node.topics", options.topics, recreated_node.topics))) ; else return ::testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure, "/home/shangzh/rosbag2_ws/rosbag2/rosbag2_transport/test/rosbag2_transport/test_record_options.cpp", 17, gtest_ar.failure_message()) = ::testing::Message(); switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal::EqHelper::Compare("options.services", "recreated_node.services", options.services, recreated_node.services))) ; else return ::testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure, "/home/shangzh/rosbag2_ws/rosbag2/rosbag2_transport/test/rosbag2_transport/test_record_options.cpp", 18, gtest_ar.failure_message()) = ::testing::Message(); } doesn't throw an exception.
Actual: it throws YAML::TypedBadConversion<std::unordered_map<std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char> >,rclcpp::QoS,std::hash<std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::equal_to<std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char> > const,rclcpp::QoS> > > > with description "yaml-cpp: error at line 200026, column 3: bad conversion".
[ FAILED ] record_options.test (2338 ms)
[----------] 1 test from record_options (2338 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (2338 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] record_options.test
1 FAILED TEST
System (please complete the following information)
OS: ubuntu 24.04 ROS 2 Distro: ros 2 jazzy Install Method: source Version: ros 2 jazzy build options: --mixin asan-gcc