Skip to content

Commit fc3347f

Browse files
hidmicahcorde
authored andcommitted
Add service/client construction/destruction API test coverage. (#138)
Signed-off-by: Michel Hidalgo <[email protected]>
1 parent ce5e840 commit fc3347f

File tree

3 files changed

+432
-0
lines changed

3 files changed

+432
-0
lines changed

test_rmw_implementation/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,26 @@ if(BUILD_TESTING)
129129
ament_target_dependencies(test_unique_identifiers${target_suffix}
130130
osrf_testing_tools_cpp rcutils rmw rmw_implementation test_msgs
131131
)
132+
133+
ament_add_gtest(test_service${target_suffix}
134+
test/test_service.cpp
135+
ENV ${rmw_implementation_env_var}
136+
)
137+
target_compile_definitions(test_service${target_suffix}
138+
PUBLIC "RMW_IMPLEMENTATION=${rmw_implementation}")
139+
ament_target_dependencies(test_service${target_suffix}
140+
osrf_testing_tools_cpp rcutils rmw rmw_implementation test_msgs
141+
)
142+
143+
ament_add_gtest(test_client${target_suffix}
144+
test/test_client.cpp
145+
ENV ${rmw_implementation_env_var}
146+
)
147+
target_compile_definitions(test_client${target_suffix}
148+
PUBLIC "RMW_IMPLEMENTATION=${rmw_implementation}")
149+
ament_target_dependencies(test_client${target_suffix}
150+
osrf_testing_tools_cpp rcutils rmw rmw_implementation test_msgs
151+
)
132152
endmacro()
133153

134154
call_for_each_rmw_implementation(test_api)
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
// Copyright 2020 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <gtest/gtest.h>
16+
17+
#include "osrf_testing_tools_cpp/scope_exit.hpp"
18+
19+
#include "rcutils/allocator.h"
20+
#include "rcutils/strdup.h"
21+
22+
#include "rmw/rmw.h"
23+
#include "rmw/error_handling.h"
24+
25+
#include "test_msgs/srv/basic_types.h"
26+
27+
#include "./config.hpp"
28+
#include "./testing_macros.hpp"
29+
30+
#ifdef RMW_IMPLEMENTATION
31+
# define CLASSNAME_(NAME, SUFFIX) NAME ## __ ## SUFFIX
32+
# define CLASSNAME(NAME, SUFFIX) CLASSNAME_(NAME, SUFFIX)
33+
#else
34+
# define CLASSNAME(NAME, SUFFIX) NAME
35+
#endif
36+
37+
class CLASSNAME (TestClient, RMW_IMPLEMENTATION) : public ::testing::Test
38+
{
39+
protected:
40+
void SetUp() override
41+
{
42+
rmw_init_options_t init_options = rmw_get_zero_initialized_init_options();
43+
rmw_ret_t ret = rmw_init_options_init(&init_options, rcutils_get_default_allocator());
44+
ASSERT_EQ(RMW_RET_OK, ret) << rcutils_get_error_string().str;
45+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
46+
{
47+
rmw_ret_t ret = rmw_init_options_fini(&init_options);
48+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
49+
});
50+
init_options.enclave = rcutils_strdup("/", rcutils_get_default_allocator());
51+
ASSERT_STREQ("/", init_options.enclave);
52+
ret = rmw_init(&init_options, &context);
53+
ASSERT_EQ(RMW_RET_OK, ret) << rcutils_get_error_string().str;
54+
constexpr char node_name[] = "my_test_node";
55+
constexpr char node_namespace[] = "/my_test_ns";
56+
node = rmw_create_node(&context, node_name, node_namespace);
57+
ASSERT_NE(nullptr, node) << rcutils_get_error_string().str;
58+
}
59+
60+
void TearDown() override
61+
{
62+
rmw_ret_t ret = rmw_destroy_node(node);
63+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
64+
ret = rmw_shutdown(&context);
65+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
66+
ret = rmw_context_fini(&context);
67+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
68+
}
69+
70+
rmw_context_t context{rmw_get_zero_initialized_context()};
71+
rmw_node_t * node{nullptr};
72+
};
73+
74+
TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), create_and_destroy) {
75+
constexpr char service_name[] = "/test";
76+
const rosidl_service_type_support_t * ts =
77+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes);
78+
rmw_client_t * client =
79+
rmw_create_client(node, ts, service_name, &rmw_qos_profile_default);
80+
ASSERT_NE(nullptr, client) << rmw_get_error_string().str;
81+
rmw_ret_t ret = rmw_destroy_client(node, client);
82+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
83+
}
84+
85+
TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), create_and_destroy_native) {
86+
constexpr char service_name[] = "/test";
87+
const rosidl_service_type_support_t * ts =
88+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes);
89+
rmw_qos_profile_t native_qos_profile = rmw_qos_profile_default;
90+
native_qos_profile.avoid_ros_namespace_conventions = true;
91+
rmw_client_t * client =
92+
rmw_create_client(node, ts, service_name, &native_qos_profile);
93+
ASSERT_NE(nullptr, client) << rmw_get_error_string().str;
94+
rmw_ret_t ret = rmw_destroy_client(node, client);
95+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
96+
}
97+
98+
TEST_F(CLASSNAME(TestClient, RMW_IMPLEMENTATION), create_with_bad_arguments) {
99+
constexpr char service_name[] = "/test";
100+
const rosidl_service_type_support_t * ts =
101+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes);
102+
103+
rmw_client_t * client =
104+
rmw_create_client(nullptr, ts, service_name, &rmw_qos_profile_default);
105+
EXPECT_EQ(nullptr, client);
106+
rmw_reset_error();
107+
108+
client = rmw_create_client(node, nullptr, service_name, &rmw_qos_profile_default);
109+
EXPECT_EQ(nullptr, client);
110+
rmw_reset_error();
111+
112+
const char * implementation_identifier = node->implementation_identifier;
113+
node->implementation_identifier = "not-an-rmw-implementation-identifier";
114+
client = rmw_create_client(node, ts, service_name, &rmw_qos_profile_default);
115+
node->implementation_identifier = implementation_identifier;
116+
EXPECT_EQ(nullptr, client);
117+
rmw_reset_error();
118+
119+
client = rmw_create_client(node, ts, nullptr, &rmw_qos_profile_default);
120+
EXPECT_EQ(nullptr, client);
121+
rmw_reset_error();
122+
123+
client = rmw_create_client(node, ts, "", &rmw_qos_profile_default);
124+
EXPECT_EQ(nullptr, client);
125+
rmw_reset_error();
126+
127+
constexpr char service_name_with_spaces[] = "/foo bar";
128+
client = rmw_create_client(node, ts, service_name_with_spaces, &rmw_qos_profile_default);
129+
EXPECT_EQ(nullptr, client);
130+
rmw_reset_error();
131+
132+
constexpr char relative_service_name[] = "foo";
133+
client = rmw_create_client(node, ts, relative_service_name, &rmw_qos_profile_default);
134+
EXPECT_EQ(nullptr, client);
135+
rmw_reset_error();
136+
137+
client = rmw_create_client(node, ts, service_name, nullptr);
138+
EXPECT_EQ(nullptr, client);
139+
rmw_reset_error();
140+
141+
client = rmw_create_client(node, ts, service_name, &rmw_qos_profile_unknown);
142+
EXPECT_EQ(nullptr, client);
143+
rmw_reset_error();
144+
145+
// Creating and destroying a client still succeeds.
146+
client = rmw_create_client(node, ts, service_name, &rmw_qos_profile_default);
147+
ASSERT_NE(nullptr, client) << rmw_get_error_string().str;
148+
rmw_ret_t ret = rmw_destroy_client(node, client);
149+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
150+
}
151+
152+
class CLASSNAME (TestClientUse, RMW_IMPLEMENTATION)
153+
: public CLASSNAME(TestClient, RMW_IMPLEMENTATION)
154+
{
155+
protected:
156+
using Base = CLASSNAME(TestClient, RMW_IMPLEMENTATION);
157+
158+
void SetUp() override
159+
{
160+
Base::SetUp();
161+
constexpr char service_name[] = "/test";
162+
const rosidl_service_type_support_t * ts =
163+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes);
164+
client = rmw_create_client(node, ts, service_name, &rmw_qos_profile_default);
165+
ASSERT_NE(nullptr, client) << rmw_get_error_string().str;
166+
}
167+
168+
void TearDown() override
169+
{
170+
rmw_ret_t ret = rmw_destroy_client(node, client);
171+
EXPECT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
172+
Base::TearDown();
173+
}
174+
175+
rmw_client_t * client{nullptr};
176+
};
177+
178+
TEST_F(CLASSNAME(TestClientUse, RMW_IMPLEMENTATION), destroy_with_null_node) {
179+
rmw_ret_t ret = rmw_destroy_client(nullptr, client);
180+
EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, ret);
181+
rmw_reset_error();
182+
}
183+
184+
TEST_F(CLASSNAME(TestClientUse, RMW_IMPLEMENTATION), destroy_null_client) {
185+
rmw_ret_t ret = rmw_destroy_client(node, nullptr);
186+
EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, ret);
187+
rmw_reset_error();
188+
}
189+
190+
TEST_F(CLASSNAME(TestClientUse, RMW_IMPLEMENTATION), destroy_with_node_of_another_impl) {
191+
const char * implementation_identifier = node->implementation_identifier;
192+
node->implementation_identifier = "not-an-rmw-implementation-identifier";
193+
rmw_ret_t ret = rmw_destroy_client(node, client);
194+
node->implementation_identifier = implementation_identifier;
195+
EXPECT_EQ(RMW_RET_INCORRECT_RMW_IMPLEMENTATION, ret);
196+
rmw_reset_error();
197+
}
198+
199+
TEST_F(CLASSNAME(TestClientUse, RMW_IMPLEMENTATION), destroy_client_of_another_impl) {
200+
const char * implementation_identifier = client->implementation_identifier;
201+
client->implementation_identifier = "not-an-rmw-implementation-identifier";
202+
rmw_ret_t ret = rmw_destroy_client(node, client);
203+
client->implementation_identifier = implementation_identifier;
204+
EXPECT_EQ(RMW_RET_INCORRECT_RMW_IMPLEMENTATION, ret);
205+
rmw_reset_error();
206+
}

0 commit comments

Comments
 (0)