From feb5ff9258a6c46c4def3fc4e1dd169a62523b23 Mon Sep 17 00:00:00 2001 From: Michel Hidalgo Date: Wed, 26 Jan 2022 11:56:48 -0300 Subject: [PATCH] Add introspection typesupport tests for C/C++ services Signed-off-by: Michel Hidalgo --- .../api.hpp | 29 + .../gtest/service_introspection_test.hpp | 120 ++ .../helpers.hpp | 28 +- .../type_traits.hpp | 4 + .../introspection_libraries_under_test.hpp | 245 +++- .../test_arrays_service_introspection.cpp | 1111 +++++++++++++++++ ...test_basic_types_service_introspection.cpp | 583 +++++++++ .../test/test_empty_service_introspection.cpp | 82 ++ 8 files changed, 2183 insertions(+), 19 deletions(-) create mode 100644 rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/gtest/service_introspection_test.hpp create mode 100644 rosidl_typesupport_introspection_tests/test/test_arrays_service_introspection.cpp create mode 100644 rosidl_typesupport_introspection_tests/test/test_basic_types_service_introspection.cpp create mode 100644 rosidl_typesupport_introspection_tests/test/test_empty_service_introspection.cpp diff --git a/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/api.hpp b/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/api.hpp index 379b92245..efe9721ba 100644 --- a/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/api.hpp +++ b/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/api.hpp @@ -72,6 +72,35 @@ const char * get_message_name(const MessageDescriptorT * message_descriptor) return message_descriptor->message_name_; } +/// Get a service's namespace from its `service_descriptor`. +template +const char * +get_service_namespace(const ServiceDescriptorT * service_descriptor) +{ + return service_descriptor->service_namespace_; +} + +/// Get a service's name from its `service_descriptor`. +template +const char * get_service_name(const ServiceDescriptorT * service_descriptor) +{ + return service_descriptor->service_name_; +} + +/// Get a service request message descriptor from its `service_descriptor`. +template +auto get_service_request_descriptor(const ServiceDescriptorT * service_descriptor) +{ + return service_descriptor->request_members_; +} + +/// Get a service response message descriptor from its `service_descriptor`. +template +auto get_service_response_descriptor(const ServiceDescriptorT * service_descriptor) +{ + return service_descriptor->response_members_; +} + /// Get a message's (base) size from its `message_descriptor`. template size_t get_message_size(const MessageDescriptorT * message_descriptor) diff --git a/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/gtest/service_introspection_test.hpp b/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/gtest/service_introspection_test.hpp new file mode 100644 index 000000000..42db5af6e --- /dev/null +++ b/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/gtest/service_introspection_test.hpp @@ -0,0 +1,120 @@ +// Copyright 2022 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. + +#ifndef ROSIDL_TYPESUPPORT_INTROSPECTION_TESTS__GTEST__SERVICE_INTROSPECTION_TEST_HPP_ +#define ROSIDL_TYPESUPPORT_INTROSPECTION_TESTS__GTEST__SERVICE_INTROSPECTION_TEST_HPP_ + +#include + +#include "rosidl_typesupport_introspection_tests/gtest/shared_library_test.hpp" +#include "rosidl_typesupport_introspection_tests/api.hpp" +#include "rosidl_typesupport_introspection_tests/type_traits.hpp" +#include "rosidl_typesupport_introspection_tests/types.hpp" + +namespace rosidl_typesupport_introspection_tests +{ +namespace testing +{ + +/// A GTest fixture for service introspection tests +/** + * \tparam ServiceT type of the service to test. + * introspection_traits must exist. + * See test suite below for further reference + * on traits' requirements. + */ +template +class ServiceIntrospectionTest : public SharedLibraryTest +{ +public: + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using ServiceDescriptorT = + typename TypeSupportLibraryT::ServiceDescriptorT; + + ServiceIntrospectionTest() + : SharedLibraryTest(TypeSupportLibraryT::name) + { + } + + void SetUp() override + { + const char * typesupport_symbol = + introspection_traits::typesupport.symbol; + auto service_typesupport_fetch = + reinterpret_cast( + this->GetSharedLibrary().get_symbol(typesupport_symbol)); + ASSERT_NE(service_typesupport_fetch, nullptr); + const rosidl_service_type_support_t * service_typesupport = + get_service_typesupport_handle( + service_typesupport_fetch(), + TypeSupportLibraryT::identifier); + ASSERT_NE(service_typesupport, nullptr); + service_descriptor_ = + reinterpret_cast( + service_typesupport->data); + ASSERT_NE(service_descriptor_, nullptr); + } + + const ServiceDescriptorT * GetServiceDescriptor() const + { + return service_descriptor_; + } + + std::unique_ptr> + MakeTypeErasedRequestMessage() const + { + using MessageDescriptorT = + typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * request_message_descriptor = + get_service_request_descriptor(service_descriptor_); + using RequestMessageT = typename ServiceT::Request; + std::allocator allocator; + std::function type_erased_message_deleter = [ = ](void * ptr) mutable { + finalize_message(ptr, request_message_descriptor); + allocator.deallocate(reinterpret_cast(ptr), 1); + }; + std::unique_ptr> type_erased_message( + initialize_message(allocator.allocate(1), request_message_descriptor), + type_erased_message_deleter); + return type_erased_message; + } + + std::unique_ptr> + MakeTypeErasedResponseMessage() const + { + using MessageDescriptorT = + typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * response_message_descriptor = + get_service_response_descriptor(service_descriptor_); + using ResponseMessageT = typename ServiceT::Response; + std::allocator allocator; + std::function type_erased_message_deleter = [ = ](void * ptr) mutable { + finalize_message(ptr, response_message_descriptor); + allocator.deallocate(reinterpret_cast(ptr), 1); + }; + std::unique_ptr> type_erased_message( + initialize_message(allocator.allocate(1), response_message_descriptor), + type_erased_message_deleter); + return type_erased_message; + } + +private: + const ServiceDescriptorT * service_descriptor_{nullptr}; +}; + +} // namespace testing +} // namespace rosidl_typesupport_introspection_tests + +#endif // ROSIDL_TYPESUPPORT_INTROSPECTION_TESTS__GTEST__SERVICE_INTROSPECTION_TEST_HPP_ diff --git a/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/helpers.hpp b/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/helpers.hpp index 113b6986d..c423de5bb 100644 --- a/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/helpers.hpp +++ b/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/helpers.hpp @@ -172,16 +172,34 @@ getitem(const std::array & array, const size_t index) DEFINE_GETITEM_OVERLOAD_FOR_C_MESSAGE_SEQUENCE_MEMBER(type) \ DEFINE_LENGTH_OVERLOAD_FOR_C_MESSAGE_SEQUENCE_MEMBER(type) -#define C_MESSAGE_NAME(package_name, interface_type, message_name) \ - package_name ## __ ## interface_type ## __ ## message_name +#define C_INTERFACE_NAME(package_name, interface_type, interface_name) \ + RCUTILS_JOIN( \ + RCUTILS_JOIN( \ + RCUTILS_JOIN( \ + RCUTILS_JOIN( \ + package_name, __), interface_type), __), interface_name) /// Defines C++ helper API for a C message. #define DEFINE_CXX_API_FOR_C_MESSAGE(package_name, interface_type, message_name) \ DEFINE_CXX_API_FOR_C_MESSAGE_MEMBER( \ - C_MESSAGE_NAME(package_name, interface_type, message_name)) \ + C_INTERFACE_NAME(package_name, interface_type, message_name)) \ DEFINE_CXX_API_FOR_C_MESSAGE_SEQUENCE_MEMBER( \ - RCUTILS_JOIN( \ - C_MESSAGE_NAME(package_name, interface_type, message_name), __Sequence)) + RCUTILS_JOIN(C_INTERFACE_NAME(package_name, interface_type, message_name), __Sequence)) + +/// Defines C++ helper API for a C service. +#define DEFINE_CXX_API_FOR_C_SERVICE(package_name, interface_type, service_name) \ + DEFINE_CXX_API_FOR_C_MESSAGE_MEMBER( \ + C_INTERFACE_NAME(package_name, interface_type, RCUTILS_JOIN(service_name, _Request))) \ + DEFINE_CXX_API_FOR_C_MESSAGE_MEMBER( \ + C_INTERFACE_NAME(package_name, interface_type, RCUTILS_JOIN(service_name, _Response))) \ + struct C_INTERFACE_NAME (package_name, interface_type, service_name) { \ + using Request = C_INTERFACE_NAME( \ + package_name, interface_type, RCUTILS_JOIN( \ + service_name, \ + _Request)); \ + using Response = \ + C_INTERFACE_NAME(package_name, interface_type, RCUTILS_JOIN(service_name, _Response)); \ +}; // Extra C++ APIs to homogeneize access to rosidl_runtime_c primitives DEFINE_CXX_API_FOR_C_MESSAGE_MEMBER(rosidl_runtime_c__String) diff --git a/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/type_traits.hpp b/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/type_traits.hpp index c221b0887..06d4cb01b 100644 --- a/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/type_traits.hpp +++ b/rosidl_typesupport_introspection_tests/include/rosidl_typesupport_introspection_tests/type_traits.hpp @@ -48,6 +48,10 @@ namespace rosidl_typesupport_introspection_tests { +// Base definition, to be specialized +template +struct interface_traits; + // Base definition, to be specialized template struct introspection_traits; diff --git a/rosidl_typesupport_introspection_tests/test/introspection_libraries_under_test.hpp b/rosidl_typesupport_introspection_tests/test/introspection_libraries_under_test.hpp index 503de8554..0bce6c07c 100644 --- a/rosidl_typesupport_introspection_tests/test/introspection_libraries_under_test.hpp +++ b/rosidl_typesupport_introspection_tests/test/introspection_libraries_under_test.hpp @@ -35,6 +35,9 @@ #include "rosidl_typesupport_introspection_tests/msg/multi_nested.h" #include "rosidl_typesupport_introspection_tests/msg/strings.h" #include "rosidl_typesupport_introspection_tests/msg/unbounded_sequences.h" +#include "rosidl_typesupport_introspection_tests/srv/arrays.h" +#include "rosidl_typesupport_introspection_tests/srv/basic_types.h" +#include "rosidl_typesupport_introspection_tests/srv/empty.h" #include "rosidl_typesupport_introspection_tests/msg/arrays.hpp" #include "rosidl_typesupport_introspection_tests/msg/basic_types.hpp" @@ -45,12 +48,29 @@ #include "rosidl_typesupport_introspection_tests/msg/multi_nested.hpp" #include "rosidl_typesupport_introspection_tests/msg/strings.hpp" #include "rosidl_typesupport_introspection_tests/msg/unbounded_sequences.hpp" +#include "rosidl_typesupport_introspection_tests/srv/arrays.hpp" +#include "rosidl_typesupport_introspection_tests/srv/basic_types.hpp" +#include "rosidl_typesupport_introspection_tests/srv/empty.hpp" #include "rosidl_typesupport_introspection_tests/fixtures.hpp" #include "rosidl_typesupport_introspection_tests/helpers.hpp" #include "rosidl_typesupport_introspection_tests/libraries.hpp" #include "rosidl_typesupport_introspection_tests/type_traits.hpp" +// Extra C++ APIs to homogeneize access to test interfaces in C and C++ +DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Arrays) +DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, BasicTypes) +DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, BoundedSequences) +DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Constants) +DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Defaults) +DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Empty) +DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, MultiNested) +DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Strings) +DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, UnboundedSequences) +DEFINE_CXX_API_FOR_C_SERVICE(rosidl_typesupport_introspection_tests, srv, Arrays) +DEFINE_CXX_API_FOR_C_SERVICE(rosidl_typesupport_introspection_tests, srv, BasicTypes) +DEFINE_CXX_API_FOR_C_SERVICE(rosidl_typesupport_introspection_tests, srv, Empty) + namespace rosidl_typesupport_introspection_tests { @@ -110,7 +130,13 @@ struct IntrospectionCTypeSupportTestLibrary static constexpr const ServiceTypeSupportSymbolRecord services[] = { SERVICE_TYPESUPPORT_SYMBOL_RECORD( rosidl_typesupport_introspection_c, - rosidl_typesupport_introspection_tests, srv, BasicTypes) + rosidl_typesupport_introspection_tests, srv, Arrays), + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_c, + rosidl_typesupport_introspection_tests, srv, BasicTypes), + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_c, + rosidl_typesupport_introspection_tests, srv, Empty) }; // static constexpr const ActionTypeSupportSymbolRecord actions[] = { // ACTION_TYPESUPPORT_SYMBOL_RECORD( @@ -119,7 +145,7 @@ struct IntrospectionCTypeSupportTestLibrary // }; }; -// Traits to aid introspection of `rosidl_typesupport_introspection_tests` package interfaces in C +// Traits to aid introspection of tests interfaces in C template<> struct introspection_traits { @@ -204,6 +230,36 @@ struct introspection_traits +struct introspection_traits +{ + static constexpr const ServiceTypeSupportSymbolRecord typesupport = + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_c, + rosidl_typesupport_introspection_tests, srv, Arrays); + using TypeSupportLibraryT = IntrospectionCTypeSupportTestLibrary; +}; + +template<> +struct introspection_traits +{ + static constexpr const ServiceTypeSupportSymbolRecord typesupport = + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_c, + rosidl_typesupport_introspection_tests, srv, BasicTypes); + using TypeSupportLibraryT = IntrospectionCTypeSupportTestLibrary; +}; + +template<> +struct introspection_traits +{ + static constexpr const ServiceTypeSupportSymbolRecord typesupport = + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_c, + rosidl_typesupport_introspection_tests, srv, Empty); + using TypeSupportLibraryT = IntrospectionCTypeSupportTestLibrary; +}; + // Examples of test interfaces in C, useful in test fixtures template<> struct Example @@ -358,6 +414,88 @@ struct Example } }; +template<> +struct Example +{ + static auto MakeRequest() + { + using MessageT = rosidl_typesupport_introspection_tests__srv__Arrays_Request; + auto deleter = [](MessageT * message) { + rosidl_typesupport_introspection_tests__srv__Arrays_Request__fini(message); + delete message; + }; + using ReturnT = std::unique_ptr>; + ReturnT message{new MessageT, deleter}; + if (!rosidl_typesupport_introspection_tests__srv__Arrays_Request__init(message.get())) { + throw std::runtime_error(rcutils_get_error_string().str); + } + message->bool_values[2] = true; + message->float64_values[1] = 1.234; + message->uint16_values[0] = 1234u; + return message; + } + + static auto MakeResponse() + { + using MessageT = rosidl_typesupport_introspection_tests__srv__Arrays_Response; + auto deleter = [](MessageT * message) { + rosidl_typesupport_introspection_tests__srv__Arrays_Response__fini(message); + delete message; + }; + using ReturnT = std::unique_ptr>; + ReturnT message{new MessageT, deleter}; + if (!rosidl_typesupport_introspection_tests__srv__Arrays_Response__init(message.get())) { + throw std::runtime_error(rcutils_get_error_string().str); + } + message->byte_values[1] = 0xAB; + message->char_values[0] = 'b'; + message->int8_values[2] = 123; + return message; + } +}; + +template<> +struct Example +{ + static auto MakeRequest() + { + using MessageT = + rosidl_typesupport_introspection_tests__srv__BasicTypes_Request; + auto deleter = [](MessageT * message) { + rosidl_typesupport_introspection_tests__srv__BasicTypes_Request__fini(message); + delete message; + }; + using ReturnT = std::unique_ptr>; + ReturnT message{new MessageT, deleter}; + message->char_value = 'c'; + message->uint32_value = 1234u; + message->float32_value = 1.234f; + if (!rosidl_runtime_c__String__assign(&message->string_value, "foo")) { + throw std::runtime_error(rcutils_get_error_string().str); + } + return message; + } + + static auto MakeResponse() + { + using MessageT = + rosidl_typesupport_introspection_tests__srv__BasicTypes_Response; + auto deleter = [](MessageT * message) { + rosidl_typesupport_introspection_tests__srv__BasicTypes_Response__fini(message); + delete message; + }; + using ReturnT = std::unique_ptr>; + ReturnT message{new MessageT, deleter}; + message->bool_value = true; + message->byte_value = 0xAB; + message->float64_value = -1.234; + if (!rosidl_runtime_c__String__assign(&message->string_value, "bar")) { + throw std::runtime_error(rcutils_get_error_string().str); + } + return message; + } +}; + // Typesupport library definition for introspection of test interfaces in C++ struct IntrospectionCppTypeSupportTestLibrary { @@ -414,7 +552,13 @@ struct IntrospectionCppTypeSupportTestLibrary static constexpr const ServiceTypeSupportSymbolRecord services[] = { SERVICE_TYPESUPPORT_SYMBOL_RECORD( rosidl_typesupport_introspection_cpp, - rosidl_typesupport_introspection_tests, srv, BasicTypes) + rosidl_typesupport_introspection_tests, srv, Arrays), + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_cpp, + rosidl_typesupport_introspection_tests, srv, BasicTypes), + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_cpp, + rosidl_typesupport_introspection_tests, srv, Empty) }; // static constexpr const ActionTypeSupportSymbolRecord actions[] = { // ACTION_TYPESUPPORT_SYMBOL_RECORD( @@ -514,6 +658,36 @@ struct introspection_traits +struct introspection_traits +{ + static constexpr const ServiceTypeSupportSymbolRecord typesupport = + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_cpp, + rosidl_typesupport_introspection_tests, srv, Arrays); + using TypeSupportLibraryT = IntrospectionCppTypeSupportTestLibrary; +}; + +template<> +struct introspection_traits +{ + static constexpr const ServiceTypeSupportSymbolRecord typesupport = + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_cpp, + rosidl_typesupport_introspection_tests, srv, BasicTypes); + using TypeSupportLibraryT = IntrospectionCppTypeSupportTestLibrary; +}; + +template<> +struct introspection_traits +{ + static constexpr const ServiceTypeSupportSymbolRecord typesupport = + SERVICE_TYPESUPPORT_SYMBOL_RECORD( + rosidl_typesupport_introspection_cpp, + rosidl_typesupport_introspection_tests, srv, Empty); + using TypeSupportLibraryT = IntrospectionCppTypeSupportTestLibrary; +}; + // Examples of test interfaces in C++, useful in test fixtures template<> struct Example @@ -604,17 +778,60 @@ struct Example } }; -} // namespace rosidl_typesupport_introspection_tests +template<> +struct Example +{ + static auto MakeRequest() + { + using MessageT = + rosidl_typesupport_introspection_tests::srv::Arrays::Request; + auto message = std::make_unique(); + message->bool_values[2] = true; + message->float64_values[1] = 1.234; + message->uint16_values[0] = 1234u; + return message; + } -// Extra C++ APIs to homogeneize access to test interfaces in C and C++ -DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Arrays) -DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, BasicTypes) -DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, BoundedSequences) -DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Constants) -DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Defaults) -DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Empty) -DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, MultiNested) -DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, Strings) -DEFINE_CXX_API_FOR_C_MESSAGE(rosidl_typesupport_introspection_tests, msg, UnboundedSequences) + static auto MakeResponse() + { + using MessageT = + rosidl_typesupport_introspection_tests::srv::Arrays::Response; + auto message = std::make_unique(); + message->byte_values[1] = 0xAB; + message->char_values[0] = 'b'; + message->int8_values[2] = 123; + return message; + } +}; + +template<> +struct Example +{ + static auto MakeRequest() + { + using MessageT = + rosidl_typesupport_introspection_tests::srv::BasicTypes::Request; + auto message = std::make_unique(); + message->char_value = 'c'; + message->uint32_value = 1234u; + message->float32_value = 1.234f; + message->string_value = "foo"; + return message; + } + + static auto MakeResponse() + { + using MessageT = + rosidl_typesupport_introspection_tests::srv::BasicTypes::Response; + auto message = std::make_unique(); + message->bool_value = true; + message->byte_value = 0xAB; + message->float64_value = -1.234; + message->string_value = "bar"; + return message; + } +}; + +} // namespace rosidl_typesupport_introspection_tests #endif // INTROSPECTION_LIBRARIES_UNDER_TEST_HPP_ diff --git a/rosidl_typesupport_introspection_tests/test/test_arrays_service_introspection.cpp b/rosidl_typesupport_introspection_tests/test/test_arrays_service_introspection.cpp new file mode 100644 index 000000000..512a91f26 --- /dev/null +++ b/rosidl_typesupport_introspection_tests/test/test_arrays_service_introspection.cpp @@ -0,0 +1,1111 @@ +// Copyright 2022 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 "rosidl_typesupport_introspection_tests/fixtures.hpp" +#include "rosidl_typesupport_introspection_tests/gtest/macros.hpp" +#include "rosidl_typesupport_introspection_tests/gtest/service_introspection_test.hpp" +#include "rosidl_typesupport_introspection_tests/api.hpp" +#include "rosidl_typesupport_introspection_tests/type_traits.hpp" + +#include "rosidl_typesupport_introspection_tests/srv/arrays.h" +#include "rosidl_typesupport_introspection_tests/srv/arrays.hpp" + +#include "introspection_libraries_under_test.hpp" + +namespace rosidl_typesupport_introspection_tests +{ +namespace testing +{ +namespace +{ + +template +class ArraysServiceIntrospectionTest + : public ServiceIntrospectionTest +{ +}; + +using ArraysServiceTypes = ::testing::Types< + rosidl_typesupport_introspection_tests__srv__Arrays, + rosidl_typesupport_introspection_tests::srv::Arrays>; +TYPED_TEST_SUITE(ArraysServiceIntrospectionTest, ArraysServiceTypes); + +// NOTE(hidmic): cppcheck complains about gtest macros +// cppcheck-suppress syntaxError +TYPED_TEST(ArraysServiceIntrospectionTest, ServiceDescriptorIsCorrect) +{ + using ArraysServiceT = TypeParam; + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = typename TypeSupportLibraryT::MessageDescriptorT; + using ServiceDescriptorT = typename TypeSupportLibraryT::ServiceDescriptorT; + const ServiceDescriptorT * service_descriptor = this->GetServiceDescriptor(); + + EXPECT_STREQ( + get_service_namespace(service_descriptor), + TypeSupportLibraryT::services_namespace); + EXPECT_STREQ(get_service_name(service_descriptor), "Arrays"); + + const MessageDescriptorT * request_message_descriptor = + get_service_request_descriptor(service_descriptor); + using RequestMessageT = typename ArraysServiceT::Request; + EXPECT_STREQ( + get_message_namespace(request_message_descriptor), + TypeSupportLibraryT::services_namespace); + EXPECT_STREQ(get_message_name(request_message_descriptor), "Arrays_Request"); + EXPECT_EQ(get_message_size(request_message_descriptor), sizeof(RequestMessageT)); + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 0u); + EXPECT_STREQ(get_member_name(member_descriptor), "bool_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_BOOLEAN)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 1u); + EXPECT_STREQ(get_member_name(member_descriptor), "byte_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_OCTET)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 2u); + EXPECT_STREQ(get_member_name(member_descriptor), "char_values"); + // In ROS message definitions, char is an alias for uint8. + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 3u); + EXPECT_STREQ(get_member_name(member_descriptor), "float32_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_FLOAT)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 4u); + EXPECT_STREQ(get_member_name(member_descriptor), "float64_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_DOUBLE)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 5u); + EXPECT_STREQ(get_member_name(member_descriptor), "int8_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 6u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint8_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 7u); + EXPECT_STREQ(get_member_name(member_descriptor), "int16_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT16)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 8u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint16_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT16)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 9u); + EXPECT_STREQ(get_member_name(member_descriptor), "int32_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT32)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 10u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint32_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT32)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 11u); + EXPECT_STREQ(get_member_name(member_descriptor), "int64_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT64)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 12u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint64_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT64)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 13u); + EXPECT_STREQ(get_member_name(member_descriptor), "string_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_STRING)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 14u); + EXPECT_STREQ(get_member_name(member_descriptor), "basic_types_values"); + using basic_type = + MEMBER_EXPRESSION_TYPE(RequestMessageT, basic_types_values[0]); + EXPECT_TRUE(is_message_type_member(member_descriptor)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 15u); + EXPECT_STREQ(get_member_name(member_descriptor), "constants_values"); + using constants_type = + MEMBER_EXPRESSION_TYPE(RequestMessageT, constants_values[0]); + EXPECT_TRUE(is_message_type_member(member_descriptor)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 16u); + EXPECT_STREQ(get_member_name(member_descriptor), "defaults_values"); + using defaults_type = + MEMBER_EXPRESSION_TYPE(RequestMessageT, defaults_values[0]); + EXPECT_TRUE(is_message_type_member(member_descriptor)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 17u); + EXPECT_STREQ(get_member_name(member_descriptor), "bool_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_BOOLEAN)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 18u); + EXPECT_STREQ(get_member_name(member_descriptor), "byte_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_OCTET)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 19u); + EXPECT_STREQ(get_member_name(member_descriptor), "char_values_default"); + // In ROS message definitions, char is an alias for uint8. + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 20u); + EXPECT_STREQ(get_member_name(member_descriptor), "float32_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_FLOAT)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 21u); + EXPECT_STREQ(get_member_name(member_descriptor), "float64_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_DOUBLE)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 22u); + EXPECT_STREQ(get_member_name(member_descriptor), "int8_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 23u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint8_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 24u); + EXPECT_STREQ(get_member_name(member_descriptor), "int16_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT16)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 25u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint16_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT16)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 26u); + EXPECT_STREQ(get_member_name(member_descriptor), "int32_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT32)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 27u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint32_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT32)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 28u); + EXPECT_STREQ(get_member_name(member_descriptor), "int64_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT64)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 29u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint64_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT64)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 30u); + EXPECT_STREQ(get_member_name(member_descriptor), "string_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_STRING)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + const MessageDescriptorT * response_message_descriptor = + get_service_response_descriptor(service_descriptor); + using ResponseMessageT = typename ArraysServiceT::Response; + EXPECT_STREQ( + get_message_namespace(response_message_descriptor), + TypeSupportLibraryT::services_namespace); + EXPECT_STREQ(get_message_name(response_message_descriptor), "Arrays_Response"); + EXPECT_EQ(get_message_size(response_message_descriptor), sizeof(ResponseMessageT)); + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 0u); + EXPECT_STREQ(get_member_name(member_descriptor), "bool_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_BOOLEAN)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 1u); + EXPECT_STREQ(get_member_name(member_descriptor), "byte_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_OCTET)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 2u); + EXPECT_STREQ(get_member_name(member_descriptor), "char_values"); + // In ROS message definitions, char is an alias for uint8. + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 3u); + EXPECT_STREQ(get_member_name(member_descriptor), "float32_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_FLOAT)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 4u); + EXPECT_STREQ(get_member_name(member_descriptor), "float64_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_DOUBLE)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 5u); + EXPECT_STREQ(get_member_name(member_descriptor), "int8_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 6u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint8_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 7u); + EXPECT_STREQ(get_member_name(member_descriptor), "int16_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT16)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 8u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint16_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT16)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 9u); + EXPECT_STREQ(get_member_name(member_descriptor), "int32_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT32)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 10u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint32_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT32)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 11u); + EXPECT_STREQ(get_member_name(member_descriptor), "int64_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT64)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 12u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint64_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT64)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 13u); + EXPECT_STREQ(get_member_name(member_descriptor), "string_values"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_STRING)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 14u); + EXPECT_STREQ(get_member_name(member_descriptor), "basic_types_values"); + using basic_type = + MEMBER_EXPRESSION_TYPE(ResponseMessageT, basic_types_values[0]); + EXPECT_TRUE(is_message_type_member(member_descriptor)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 15u); + EXPECT_STREQ(get_member_name(member_descriptor), "constants_values"); + using constants_type = + MEMBER_EXPRESSION_TYPE(ResponseMessageT, constants_values[0]); + EXPECT_TRUE(is_message_type_member(member_descriptor)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 16u); + EXPECT_STREQ(get_member_name(member_descriptor), "defaults_values"); + using defaults_type = + MEMBER_EXPRESSION_TYPE(ResponseMessageT, defaults_values[0]); + EXPECT_TRUE(is_message_type_member(member_descriptor)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 17u); + EXPECT_STREQ(get_member_name(member_descriptor), "bool_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_BOOLEAN)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 18u); + EXPECT_STREQ(get_member_name(member_descriptor), "byte_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_OCTET)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 19u); + EXPECT_STREQ(get_member_name(member_descriptor), "char_values_default"); + // In ROS message definitions, char is an alias for uint8. + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 20u); + EXPECT_STREQ(get_member_name(member_descriptor), "float32_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_FLOAT)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 21u); + EXPECT_STREQ(get_member_name(member_descriptor), "float64_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_DOUBLE)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 22u); + EXPECT_STREQ(get_member_name(member_descriptor), "int8_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 23u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint8_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 24u); + EXPECT_STREQ(get_member_name(member_descriptor), "int16_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT16)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 25u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint16_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT16)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 26u); + EXPECT_STREQ(get_member_name(member_descriptor), "int32_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT32)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 27u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint32_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT32)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 28u); + EXPECT_STREQ(get_member_name(member_descriptor), "int64_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT64)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 29u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint64_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT64)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 30u); + EXPECT_STREQ(get_member_name(member_descriptor), "string_values_default"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_STRING)); + EXPECT_TRUE(has_array_structure(member_descriptor, 3u)); + } +} + +TYPED_TEST(ArraysServiceIntrospectionTest, CanReadTypeErasedRequestMessage) +{ + using ArraysServiceT = TypeParam; + using RequestMessageT = typename ArraysServiceT::Request; + + const auto message_ptr = Example::MakeRequest(); + const RequestMessageT & message = *message_ptr; + const void * type_erased_message = message_ptr.get(); + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = + typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * message_descriptor = + get_service_request_descriptor(this->GetServiceDescriptor()); + ASSERT_EQ(get_member_count(message_descriptor), 31u); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, bool_values, + get_member_descriptor(message_descriptor, 0u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, byte_values, + get_member_descriptor(message_descriptor, 1u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, char_values, + get_member_descriptor(message_descriptor, 2u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, float32_values, + get_member_descriptor(message_descriptor, 3u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, float64_values, + get_member_descriptor(message_descriptor, 4u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int8_values, + get_member_descriptor(message_descriptor, 5u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint8_values, + get_member_descriptor(message_descriptor, 6u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int16_values, + get_member_descriptor(message_descriptor, 7u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint16_values, + get_member_descriptor(message_descriptor, 8u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int32_values, + get_member_descriptor(message_descriptor, 9u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint32_values, + get_member_descriptor(message_descriptor, 10u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int64_values, + get_member_descriptor(message_descriptor, 11u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint64_values, + get_member_descriptor(message_descriptor, 12u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, string_values, + get_member_descriptor(message_descriptor, 13u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, basic_types_values, + get_member_descriptor(message_descriptor, 14u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, constants_values, + get_member_descriptor(message_descriptor, 15u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, defaults_values, + get_member_descriptor(message_descriptor, 16u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, bool_values_default, + get_member_descriptor(message_descriptor, 17u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, byte_values_default, + get_member_descriptor(message_descriptor, 18u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, char_values_default, + get_member_descriptor(message_descriptor, 19u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, float32_values_default, + get_member_descriptor(message_descriptor, 20u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, float64_values_default, + get_member_descriptor(message_descriptor, 21u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int8_values_default, + get_member_descriptor(message_descriptor, 22u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint8_values_default, + get_member_descriptor(message_descriptor, 23u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int16_values_default, + get_member_descriptor(message_descriptor, 24u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint16_values_default, + get_member_descriptor(message_descriptor, 25u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int32_values_default, + get_member_descriptor(message_descriptor, 26u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint32_values_default, + get_member_descriptor(message_descriptor, 27u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int64_values_default, + get_member_descriptor(message_descriptor, 28u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint64_values_default, + get_member_descriptor(message_descriptor, 29u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, string_values_default, + get_member_descriptor(message_descriptor, 30u)); +} + +TYPED_TEST(ArraysServiceIntrospectionTest, CanReadTypeErasedResponseMessage) +{ + using ArraysServiceT = TypeParam; + using ResponseMessageT = typename ArraysServiceT::Response; + + const auto message_ptr = Example::MakeResponse(); + const ResponseMessageT & message = *message_ptr; + const void * type_erased_message = message_ptr.get(); + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * message_descriptor = + get_service_response_descriptor(this->GetServiceDescriptor()); + ASSERT_EQ(get_member_count(message_descriptor), 31u); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, bool_values, + get_member_descriptor(message_descriptor, 0u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, byte_values, + get_member_descriptor(message_descriptor, 1u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, char_values, + get_member_descriptor(message_descriptor, 2u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, float32_values, + get_member_descriptor(message_descriptor, 3u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, float64_values, + get_member_descriptor(message_descriptor, 4u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int8_values, + get_member_descriptor(message_descriptor, 5u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint8_values, + get_member_descriptor(message_descriptor, 6u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int16_values, + get_member_descriptor(message_descriptor, 7u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint16_values, + get_member_descriptor(message_descriptor, 8u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int32_values, + get_member_descriptor(message_descriptor, 9u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint32_values, + get_member_descriptor(message_descriptor, 10u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int64_values, + get_member_descriptor(message_descriptor, 11u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint64_values, + get_member_descriptor(message_descriptor, 12u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, string_values, + get_member_descriptor(message_descriptor, 13u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, basic_types_values, + get_member_descriptor(message_descriptor, 14u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, constants_values, + get_member_descriptor(message_descriptor, 15u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, defaults_values, + get_member_descriptor(message_descriptor, 16u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, bool_values_default, + get_member_descriptor(message_descriptor, 17u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, byte_values_default, + get_member_descriptor(message_descriptor, 18u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, char_values_default, + get_member_descriptor(message_descriptor, 19u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, float32_values_default, + get_member_descriptor(message_descriptor, 20u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, float64_values_default, + get_member_descriptor(message_descriptor, 21u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int8_values_default, + get_member_descriptor(message_descriptor, 22u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint8_values_default, + get_member_descriptor(message_descriptor, 23u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int16_values_default, + get_member_descriptor(message_descriptor, 24u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint16_values_default, + get_member_descriptor(message_descriptor, 25u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int32_values_default, + get_member_descriptor(message_descriptor, 26u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint32_values_default, + get_member_descriptor(message_descriptor, 27u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, int64_values_default, + get_member_descriptor(message_descriptor, 28u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, uint64_values_default, + get_member_descriptor(message_descriptor, 29u)); + + EXPECT_ITERABLE_MEMBER_EQ( + type_erased_message, message, string_values_default, + get_member_descriptor(message_descriptor, 30u)); +} + +TYPED_TEST(ArraysServiceIntrospectionTest, CanWriteTypeErasedRequestMessage) +{ + using ArraysServiceT = TypeParam; + using RequestMessageT = typename ArraysServiceT::Request; + + const auto message_ptr = Example::MakeRequest(); + const RequestMessageT & message = *message_ptr; + + auto type_erased_message_copy = this->MakeTypeErasedRequestMessage(); + const auto & message_copy = + *reinterpret_cast(type_erased_message_copy.get()); + EXPECT_NE(message, message_copy); + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = + typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * message_descriptor = + get_service_request_descriptor(this->GetServiceDescriptor()); + ASSERT_EQ(get_member_count(message_descriptor), 31u); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, bool_values, + get_member_descriptor(message_descriptor, 0u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, byte_values, + get_member_descriptor(message_descriptor, 1u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, char_values, + get_member_descriptor(message_descriptor, 2u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float32_values, + get_member_descriptor(message_descriptor, 3u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float64_values, + get_member_descriptor(message_descriptor, 4u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int8_values, + get_member_descriptor(message_descriptor, 5u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint8_values, + get_member_descriptor(message_descriptor, 6u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int16_values, + get_member_descriptor(message_descriptor, 7u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint16_values, + get_member_descriptor(message_descriptor, 8u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int32_values, + get_member_descriptor(message_descriptor, 9u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint32_values, + get_member_descriptor(message_descriptor, 10u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int64_values, + get_member_descriptor(message_descriptor, 11u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint64_values, + get_member_descriptor(message_descriptor, 12u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, string_values, + get_member_descriptor(message_descriptor, 13u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, basic_types_values, + get_member_descriptor(message_descriptor, 14u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, constants_values, + get_member_descriptor(message_descriptor, 15u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, defaults_values, + get_member_descriptor(message_descriptor, 16u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, bool_values_default, + get_member_descriptor(message_descriptor, 17u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, byte_values_default, + get_member_descriptor(message_descriptor, 18u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, char_values_default, + get_member_descriptor(message_descriptor, 19u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float32_values_default, + get_member_descriptor(message_descriptor, 20u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float64_values_default, + get_member_descriptor(message_descriptor, 21u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int8_values_default, + get_member_descriptor(message_descriptor, 22u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint8_values_default, + get_member_descriptor(message_descriptor, 23u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int16_values_default, + get_member_descriptor(message_descriptor, 24u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint16_values_default, + get_member_descriptor(message_descriptor, 25u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int32_values_default, + get_member_descriptor(message_descriptor, 26u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint32_values_default, + get_member_descriptor(message_descriptor, 27u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int64_values_default, + get_member_descriptor(message_descriptor, 28u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint64_values_default, + get_member_descriptor(message_descriptor, 29u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, string_values_default, + get_member_descriptor(message_descriptor, 30u)); + + EXPECT_EQ(message, message_copy); +} + +TYPED_TEST(ArraysServiceIntrospectionTest, CanWriteTypeErasedResponseMessage) +{ + using ArraysServiceT = TypeParam; + using ResponseMessageT = typename ArraysServiceT::Response; + + const auto message_ptr = Example::MakeResponse(); + const ResponseMessageT & message = *message_ptr; + + auto type_erased_message_copy = this->MakeTypeErasedResponseMessage(); + const ResponseMessageT & message_copy = + *reinterpret_cast(type_erased_message_copy.get()); + EXPECT_NE(message, message_copy); + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * message_descriptor = + get_service_response_descriptor(this->GetServiceDescriptor()); + ASSERT_EQ(get_member_count(message_descriptor), 31u); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, bool_values, + get_member_descriptor(message_descriptor, 0u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, byte_values, + get_member_descriptor(message_descriptor, 1u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, char_values, + get_member_descriptor(message_descriptor, 2u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float32_values, + get_member_descriptor(message_descriptor, 3u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float64_values, + get_member_descriptor(message_descriptor, 4u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int8_values, + get_member_descriptor(message_descriptor, 5u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint8_values, + get_member_descriptor(message_descriptor, 6u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int16_values, + get_member_descriptor(message_descriptor, 7u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint16_values, + get_member_descriptor(message_descriptor, 8u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int32_values, + get_member_descriptor(message_descriptor, 9u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint32_values, + get_member_descriptor(message_descriptor, 10u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int64_values, + get_member_descriptor(message_descriptor, 11u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint64_values, + get_member_descriptor(message_descriptor, 12u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, string_values, + get_member_descriptor(message_descriptor, 13u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, basic_types_values, + get_member_descriptor(message_descriptor, 14u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, constants_values, + get_member_descriptor(message_descriptor, 15u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, defaults_values, + get_member_descriptor(message_descriptor, 16u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, bool_values_default, + get_member_descriptor(message_descriptor, 17u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, byte_values_default, + get_member_descriptor(message_descriptor, 18u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, char_values_default, + get_member_descriptor(message_descriptor, 19u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float32_values_default, + get_member_descriptor(message_descriptor, 20u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float64_values_default, + get_member_descriptor(message_descriptor, 21u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int8_values_default, + get_member_descriptor(message_descriptor, 22u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint8_values_default, + get_member_descriptor(message_descriptor, 23u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int16_values_default, + get_member_descriptor(message_descriptor, 24u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint16_values_default, + get_member_descriptor(message_descriptor, 25u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int32_values_default, + get_member_descriptor(message_descriptor, 26u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint32_values_default, + get_member_descriptor(message_descriptor, 27u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int64_values_default, + get_member_descriptor(message_descriptor, 28u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint64_values_default, + get_member_descriptor(message_descriptor, 29u)); + + EXPECT_ARRAY_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, string_values_default, + get_member_descriptor(message_descriptor, 30u)); + + EXPECT_EQ(message, message_copy); +} + +} // namespace +} // namespace testing +} // namespace rosidl_typesupport_introspection_tests diff --git a/rosidl_typesupport_introspection_tests/test/test_basic_types_service_introspection.cpp b/rosidl_typesupport_introspection_tests/test/test_basic_types_service_introspection.cpp new file mode 100644 index 000000000..25e2170d1 --- /dev/null +++ b/rosidl_typesupport_introspection_tests/test/test_basic_types_service_introspection.cpp @@ -0,0 +1,583 @@ +// Copyright 2022 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 "rosidl_typesupport_introspection_tests/fixtures.hpp" +#include "rosidl_typesupport_introspection_tests/gtest/macros.hpp" +#include "rosidl_typesupport_introspection_tests/gtest/service_introspection_test.hpp" +#include "rosidl_typesupport_introspection_tests/api.hpp" +#include "rosidl_typesupport_introspection_tests/type_traits.hpp" + +#include "introspection_libraries_under_test.hpp" + +namespace rosidl_typesupport_introspection_tests +{ +namespace testing +{ +namespace +{ + +template +class BasicTypesServiceIntrospectionTest + : public ServiceIntrospectionTest +{ +}; + +using BasicTypesServiceTypes = ::testing::Types< + rosidl_typesupport_introspection_tests__srv__BasicTypes, + rosidl_typesupport_introspection_tests::srv::BasicTypes>; +TYPED_TEST_SUITE(BasicTypesServiceIntrospectionTest, BasicTypesServiceTypes); + +// NOTE(hidmic): cppcheck complains about gtest macros +// cppcheck-suppress syntaxError +TYPED_TEST(BasicTypesServiceIntrospectionTest, ServiceDescriptorIsCorrect) +{ + using BasicTypesServiceT = TypeParam; + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = typename TypeSupportLibraryT::MessageDescriptorT; + using ServiceDescriptorT = typename TypeSupportLibraryT::ServiceDescriptorT; + const ServiceDescriptorT * service_descriptor = this->GetServiceDescriptor(); + + EXPECT_STREQ( + get_service_namespace(service_descriptor), + TypeSupportLibraryT::services_namespace); + EXPECT_STREQ(get_service_name(service_descriptor), "BasicTypes"); + + const MessageDescriptorT * request_message_descriptor = + get_service_request_descriptor(service_descriptor); + using RequestMessageT = typename BasicTypesServiceT::Request; + EXPECT_STREQ( + get_message_namespace(request_message_descriptor), + TypeSupportLibraryT::services_namespace); + EXPECT_STREQ(get_message_name(request_message_descriptor), "BasicTypes_Request"); + EXPECT_EQ(get_message_size(request_message_descriptor), sizeof(RequestMessageT)); + ASSERT_EQ(get_member_count(request_message_descriptor), 14u); + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 0u); + EXPECT_STREQ(get_member_name(member_descriptor), "bool_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_BOOLEAN)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 1u); + EXPECT_STREQ(get_member_name(member_descriptor), "byte_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_OCTET)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 2u); + EXPECT_STREQ(get_member_name(member_descriptor), "char_value"); + // In ROS message definitions, char is an alias for uint8. + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 3u); + EXPECT_STREQ(get_member_name(member_descriptor), "float32_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_FLOAT)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 4u); + EXPECT_STREQ(get_member_name(member_descriptor), "float64_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_DOUBLE)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 5u); + EXPECT_STREQ(get_member_name(member_descriptor), "int8_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT8)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 6u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint8_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 7u); + EXPECT_STREQ(get_member_name(member_descriptor), "int16_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT16)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 8u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint16_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT16)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 9u); + EXPECT_STREQ(get_member_name(member_descriptor), "int32_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT32)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 10u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint32_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT32)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 11u); + EXPECT_STREQ(get_member_name(member_descriptor), "int64_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT64)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 12u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint64_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT64)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(request_message_descriptor, 13u); + EXPECT_STREQ(get_member_name(member_descriptor), "string_value"); + EXPECT_TRUE(is_string_member(member_descriptor)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + const MessageDescriptorT * response_message_descriptor = + get_service_response_descriptor(service_descriptor); + using ResponseMessageT = typename BasicTypesServiceT::Response; + EXPECT_STREQ( + get_message_namespace(response_message_descriptor), + TypeSupportLibraryT::services_namespace); + EXPECT_STREQ(get_message_name(response_message_descriptor), "BasicTypes_Response"); + EXPECT_EQ(get_message_size(response_message_descriptor), sizeof(ResponseMessageT)); + ASSERT_EQ(get_member_count(response_message_descriptor), 14u); + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 0u); + EXPECT_STREQ(get_member_name(member_descriptor), "bool_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_BOOLEAN)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 1u); + EXPECT_STREQ(get_member_name(member_descriptor), "byte_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_OCTET)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 2u); + EXPECT_STREQ(get_member_name(member_descriptor), "char_value"); + // In ROS message definitions, char is an alias for uint8. + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 3u); + EXPECT_STREQ(get_member_name(member_descriptor), "float32_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_FLOAT)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 4u); + EXPECT_STREQ(get_member_name(member_descriptor), "float64_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_DOUBLE)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 5u); + EXPECT_STREQ(get_member_name(member_descriptor), "int8_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT8)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 6u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint8_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT8)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 7u); + EXPECT_STREQ(get_member_name(member_descriptor), "int16_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT16)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 8u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint16_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT16)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 9u); + EXPECT_STREQ(get_member_name(member_descriptor), "int32_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT32)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 10u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint32_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT32)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 11u); + EXPECT_STREQ(get_member_name(member_descriptor), "int64_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_INT64)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 12u); + EXPECT_STREQ(get_member_name(member_descriptor), "uint64_value"); + EXPECT_TRUE(is_base_type_member(member_descriptor, ROS_TYPE_UINT64)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } + + { + auto * member_descriptor = get_member_descriptor(response_message_descriptor, 13u); + EXPECT_STREQ(get_member_name(member_descriptor), "string_value"); + EXPECT_TRUE(is_string_member(member_descriptor)); + EXPECT_TRUE(has_simple_structure(member_descriptor)); + } +} + +TYPED_TEST(BasicTypesServiceIntrospectionTest, CanReadTypeErasedRequestMessage) +{ + using BasicTypesServiceT = TypeParam; + using RequestMessageT = typename BasicTypesServiceT::Request; + + const auto message_ptr = Example::MakeRequest(); + const RequestMessageT & message = *message_ptr; + const void * type_erased_message = message_ptr.get(); + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * message_descriptor = + get_service_request_descriptor(this->GetServiceDescriptor()); + ASSERT_EQ(get_member_count(message_descriptor), 14u); + + EXPECT_MEMBER_EQ( + type_erased_message, message, bool_value, + get_member_descriptor(message_descriptor, 0u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, byte_value, + get_member_descriptor(message_descriptor, 1u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, char_value, + get_member_descriptor(message_descriptor, 2u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, float32_value, + get_member_descriptor(message_descriptor, 3u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, float64_value, + get_member_descriptor(message_descriptor, 4u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, int8_value, + get_member_descriptor(message_descriptor, 5u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, uint8_value, + get_member_descriptor(message_descriptor, 6u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, int16_value, + get_member_descriptor(message_descriptor, 7u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, uint16_value, + get_member_descriptor(message_descriptor, 8u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, int32_value, + get_member_descriptor(message_descriptor, 9u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, uint32_value, + get_member_descriptor(message_descriptor, 10u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, int64_value, + get_member_descriptor(message_descriptor, 11u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, uint64_value, + get_member_descriptor(message_descriptor, 12u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, string_value, + get_member_descriptor(message_descriptor, 13u)); +} + +TYPED_TEST(BasicTypesServiceIntrospectionTest, CanReadTypeErasedResponseMessage) +{ + using BasicTypesServiceT = TypeParam; + using ResponseMessageT = typename BasicTypesServiceT::Response; + + const auto message_ptr = Example::MakeResponse(); + const ResponseMessageT & message = *message_ptr; + const void * type_erased_message = message_ptr.get(); + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * message_descriptor = + get_service_response_descriptor(this->GetServiceDescriptor()); + ASSERT_EQ(get_member_count(message_descriptor), 14u); + + EXPECT_MEMBER_EQ( + type_erased_message, message, bool_value, + get_member_descriptor(message_descriptor, 0u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, byte_value, + get_member_descriptor(message_descriptor, 1u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, char_value, + get_member_descriptor(message_descriptor, 2u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, float32_value, + get_member_descriptor(message_descriptor, 3u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, float64_value, + get_member_descriptor(message_descriptor, 4u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, int8_value, + get_member_descriptor(message_descriptor, 5u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, uint8_value, + get_member_descriptor(message_descriptor, 6u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, int16_value, + get_member_descriptor(message_descriptor, 7u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, uint16_value, + get_member_descriptor(message_descriptor, 8u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, int32_value, + get_member_descriptor(message_descriptor, 9u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, uint32_value, + get_member_descriptor(message_descriptor, 10u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, int64_value, + get_member_descriptor(message_descriptor, 11u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, uint64_value, + get_member_descriptor(message_descriptor, 12u)); + + EXPECT_MEMBER_EQ( + type_erased_message, message, string_value, + get_member_descriptor(message_descriptor, 13u)); +} + +TYPED_TEST(BasicTypesServiceIntrospectionTest, CanWriteTypeErasedRequestMessage) +{ + using BasicTypesServiceT = TypeParam; + using RequestMessageT = typename BasicTypesServiceT::Request; + + const auto message_ptr = Example::MakeRequest(); + const RequestMessageT & message = *message_ptr; + + auto type_erased_message_copy = this->MakeTypeErasedRequestMessage(); + const auto & message_copy = + *reinterpret_cast(type_erased_message_copy.get()); + EXPECT_NE(message, message_copy); + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * message_descriptor = + get_service_request_descriptor(this->GetServiceDescriptor()); + ASSERT_EQ(get_member_count(message_descriptor), 14u); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, bool_value, + get_member_descriptor(message_descriptor, 0u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, byte_value, + get_member_descriptor(message_descriptor, 1u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, char_value, + get_member_descriptor(message_descriptor, 2u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float32_value, + get_member_descriptor(message_descriptor, 3u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float64_value, + get_member_descriptor(message_descriptor, 4u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int8_value, + get_member_descriptor(message_descriptor, 5u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint8_value, + get_member_descriptor(message_descriptor, 6u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int16_value, + get_member_descriptor(message_descriptor, 7u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint16_value, + get_member_descriptor(message_descriptor, 8u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int32_value, + get_member_descriptor(message_descriptor, 9u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint32_value, + get_member_descriptor(message_descriptor, 10u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int64_value, + get_member_descriptor(message_descriptor, 11u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint64_value, + get_member_descriptor(message_descriptor, 12u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, string_value, + get_member_descriptor(message_descriptor, 13u)); + + EXPECT_EQ(message, message_copy); +} + +TYPED_TEST(BasicTypesServiceIntrospectionTest, CanWriteTypeErasedResponseMessage) +{ + using BasicTypesServiceT = TypeParam; + using ResponseMessageT = typename BasicTypesServiceT::Response; + + const auto message_ptr = Example::MakeResponse(); + const ResponseMessageT & message = *message_ptr; + + auto type_erased_message_copy = this->MakeTypeErasedResponseMessage(); + const auto & message_copy = + *reinterpret_cast(type_erased_message_copy.get()); + EXPECT_NE(message, message_copy); + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = typename TypeSupportLibraryT::MessageDescriptorT; + const MessageDescriptorT * message_descriptor = + get_service_response_descriptor(this->GetServiceDescriptor()); + ASSERT_EQ(get_member_count(message_descriptor), 14u); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, bool_value, + get_member_descriptor(message_descriptor, 0u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, byte_value, + get_member_descriptor(message_descriptor, 1u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, char_value, + get_member_descriptor(message_descriptor, 2u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float32_value, + get_member_descriptor(message_descriptor, 3u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, float64_value, + get_member_descriptor(message_descriptor, 4u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int8_value, + get_member_descriptor(message_descriptor, 5u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint8_value, + get_member_descriptor(message_descriptor, 6u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int16_value, + get_member_descriptor(message_descriptor, 7u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint16_value, + get_member_descriptor(message_descriptor, 8u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int32_value, + get_member_descriptor(message_descriptor, 9u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint32_value, + get_member_descriptor(message_descriptor, 10u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, int64_value, + get_member_descriptor(message_descriptor, 11u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, uint64_value, + get_member_descriptor(message_descriptor, 12u)); + + EXPECT_MEMBER_ASSIGNMENT( + type_erased_message_copy.get(), message, string_value, + get_member_descriptor(message_descriptor, 13u)); + + EXPECT_EQ(message, message_copy); +} + +} // namespace +} // namespace testing +} // namespace rosidl_typesupport_introspection_tests diff --git a/rosidl_typesupport_introspection_tests/test/test_empty_service_introspection.cpp b/rosidl_typesupport_introspection_tests/test/test_empty_service_introspection.cpp new file mode 100644 index 000000000..150966413 --- /dev/null +++ b/rosidl_typesupport_introspection_tests/test/test_empty_service_introspection.cpp @@ -0,0 +1,82 @@ +// Copyright 2022 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 "rosidl_typesupport_introspection_tests/fixtures.hpp" +#include "rosidl_typesupport_introspection_tests/gtest/macros.hpp" +#include "rosidl_typesupport_introspection_tests/gtest/service_introspection_test.hpp" +#include "rosidl_typesupport_introspection_tests/api.hpp" +#include "rosidl_typesupport_introspection_tests/type_traits.hpp" + +#include "introspection_libraries_under_test.hpp" + +namespace rosidl_typesupport_introspection_tests +{ +namespace testing +{ +namespace +{ + +template +class EmptyServiceIntrospectionTest + : public ServiceIntrospectionTest +{ +}; + +using EmptyServiceTypes = ::testing::Types< + rosidl_typesupport_introspection_tests__srv__Empty, + rosidl_typesupport_introspection_tests::srv::Empty>; +TYPED_TEST_SUITE(EmptyServiceIntrospectionTest, EmptyServiceTypes); + +// NOTE(hidmic): cppcheck complains about gtest macros +// cppcheck-suppress syntaxError +TYPED_TEST(EmptyServiceIntrospectionTest, ServiceDescriptorIsCorrect) +{ + using EmptyServiceT = TypeParam; + + using TypeSupportLibraryT = + typename introspection_traits::TypeSupportLibraryT; + using MessageDescriptorT = typename TypeSupportLibraryT::MessageDescriptorT; + using ServiceDescriptorT = typename TypeSupportLibraryT::ServiceDescriptorT; + const ServiceDescriptorT * service_descriptor = this->GetServiceDescriptor(); + + EXPECT_STREQ( + get_service_namespace(service_descriptor), + TypeSupportLibraryT::services_namespace); + EXPECT_STREQ(get_service_name(service_descriptor), "Empty"); + + const MessageDescriptorT * request_message_descriptor = + get_service_request_descriptor(service_descriptor); + EXPECT_STREQ( + get_message_namespace(request_message_descriptor), + TypeSupportLibraryT::services_namespace); + EXPECT_STREQ(get_message_name(request_message_descriptor), "Empty_Request"); + EXPECT_EQ( + get_message_size(request_message_descriptor), + sizeof(typename EmptyServiceT::Request)); + const MessageDescriptorT * response_message_descriptor = + get_service_response_descriptor(service_descriptor); + EXPECT_STREQ( + get_message_namespace(response_message_descriptor), + TypeSupportLibraryT::services_namespace); + EXPECT_STREQ(get_message_name(response_message_descriptor), "Empty_Response"); + EXPECT_EQ( + get_message_size(response_message_descriptor), + sizeof(typename EmptyServiceT::Response)); +} + +} // namespace +} // namespace testing +} // namespace rosidl_typesupport_introspection_tests