ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

[ROS2 Humble + Gtest] Test throwing an exception when looking for lib[package]__rosidl_typesupport_fastrtps_cpp.so

asked 2022-09-20 03:27:28 -0500

Hello.

I am using ROS2 Humble on Ubuntu 22.04 for this project. I am able to compile and run the packages I wrote (in C++), I also wrote a few unit tests (with Google Test). However I am facing an error when trying to use a custom service in one of my tests:

arnix@Faye:~/src/alfred/workspace$ ./build/hal_pigpio/hal_pigpio_init_test
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from PigpioInitTest
[ RUN      ] PigpioInitTest.SetInputMode
unknown file: Failure
C++ exception with description "could not create client: Type support not from this implementation. Got:
    Handle's typesupport identifier (rosidl_typesupport_cpp) is not supported by this library, at ./src/type_support_dispatch.hpp:111
    Could not load library libhal_pigpio_interfaces__rosidl_typesupport_fastrtps_cpp.so: dlopen error: libhal_pigpio_interfaces__rosidl_typesupport_fastrtps_cpp.so: cannot open shared object file: No such file or directory, at ./src/shared_library.c:99, at ./src/type_support_dispatch.hpp:76
while fetching it, at ./src/rmw_client.cpp:120, at ./src/rcl/client.c:113" thrown in SetUp().
Segmentation fault (core dumped)

This is the test in question.

I am creating 2 nodes in the global SetUp of the test fixture (one with the service I want to test and the other one that is using the service and checking its response). In the constructor of the checker node I am creating a client for the service, and then sending the request in the test case.

#include "gtest/gtest.h"
#include "rclcpp/rclcpp.hpp"
#include "lifecycle_msgs/srv/change_state.hpp"

#include "hal_pigpio.hpp"

class PigioCheckerNode : public rclcpp::Node
{
public:
  PigioCheckerNode()
  : rclcpp::Node("hal_pigpio_checker_node"),
    changeStateClient(this->create_client<lifecycle_msgs::srv::ChangeState>(
        "hal_pigpio_node/change_state")),
    setInputModeClient(this->create_client<hal_pigpio_interfaces::srv::HalPigpioSetInputMode>(
        "hal_pigpioSetInputMode"))
  {
  }
  ~PigioCheckerNode() = default;
  void changePigpioNodeToState(std::uint8_t transition)
  {
    auto request = std::make_shared<lifecycle_msgs::srv::ChangeState::Request>();
    request->transition.id = transition;
    auto result = changeStateClient->async_send_request(request);
  }
  rclcpp::Client<hal_pigpio_interfaces::srv::HalPigpioSetInputMode>::SharedPtr
  getSetInputModeClient(void)
  {
    return setInputModeClient;
  }

private:
  rclcpp::Client<lifecycle_msgs::srv::ChangeState>::SharedPtr changeStateClient;
  rclcpp::Client<hal_pigpio_interfaces::srv::HalPigpioSetInputMode>::SharedPtr setInputModeClient;
};

/* Test fixture */
class PigpioInitTest : public testing::Test
{
protected:
  std::shared_ptr<Pigpio> pigpioInit;
  std::shared_ptr<PigioCheckerNode> pigioChecker;
  rclcpp::executors::SingleThreadedExecutor executor;

  void SetUp()
  {
    pigioChecker = std::make_shared<PigioCheckerNode>();
    pigpioInit = std::make_shared<Pigpio>();

    executor.add_node(pigpioInit->get_node_base_interface());
    executor.add_node(pigioChecker);

    pigioChecker->changePigpioNodeToState(
      lifecycle_msgs::msg::Transition::TRANSITION_CONFIGURE);
    executor.spin_some();
    pigioChecker->changePigpioNodeToState(
      lifecycle_msgs::msg::Transition::TRANSITION_ACTIVATE);
    executor.spin_some();
  }

  void TearDown()
  {
    executor.cancel();
    executor.remove_node(pigpioInit->get_node_base_interface());
    executor.remove_node(pigioChecker);
    pigpioInit.reset();
    pigioChecker.reset();
  }
};

/* Test cases */
TEST_F(PigpioInitTest, SetInputMode)
{
  auto setInputModeRequest =
    std::make_shared<hal_pigpio_interfaces::srv::HalPigpioSetInputMode::Request>();

  setInputModeRequest->gpio_id = 1;

  auto setInputModeFuture = pigioChecker->getSetInputModeClient()->async_send_request(
    setInputModeRequest);

  ASSERT_EQ(setInputModeFuture.get()->has_succeeded, true);
}

int main(int argc, char ** argv)
{
  testing::InitGoogleTest(&argc, argv);
  rclcpp::init(argc, argv);

  auto result = RUN_ALL_TESTS();

  rclcpp::shutdown();
  return result;
}

I am not using Fast DDS middleware (i.e. I didn't set RMW_IMPLEMENTATION environnement variable).

I searched around for the cause of this error but I didn't find any solution. Any help is welcomed, thank you!

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2022-12-06 10:07:24 -0500

As it turns out, executing the test directly calling the test executable is not a good idea... When using colcon, everything runs smoothly.

edit flag offensive delete link more

Comments

@Arnix Can you explain why this is the case? I cannot find anything about this issue mentioned

mandicLuka gravatar image mandicLuka  ( 2023-02-15 10:39:53 -0500 )edit

Hi @mandicLuka, I didn't investigate more as using colcon to run my tests is fine.

Arnix gravatar image Arnix  ( 2023-02-16 02:21:27 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2022-09-20 03:27:28 -0500

Seen: 623 times

Last updated: Dec 06 '22