rosbag2 icon indicating copy to clipboard operation
rosbag2 copied to clipboard

RecordOptions fails to deserialize YAML in large-scale topics/services scenarios

Open zhihaoshang opened this issue 1 week ago • 0 comments

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

zhihaoshang avatar Dec 19 '25 11:12 zhihaoshang