Skip to content

Commit c83119c

Browse files
Re-add "Improve trigger test for graph guard condition (#811)" (#884)
Signed-off-by: Barry Xu <[email protected]>
1 parent db576d5 commit c83119c

File tree

1 file changed

+161
-60
lines changed

1 file changed

+161
-60
lines changed

rcl/test/rcl/test_graph.cpp

Lines changed: 161 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,75 +1223,176 @@ TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), test_graph_query_functio
12231223
9); // number of retries
12241224
}
12251225

1226-
/* Test the graph guard condition notices topic changes.
1226+
/* Test the graph guard condition notices below changes.
1227+
* publisher create/destroy, subscription create/destroy
1228+
* service create/destroy, client create/destroy
1229+
* Other node added/removed
12271230
*
12281231
* Note: this test could be impacted by other communications on the same ROS Domain.
12291232
*/
1230-
TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), test_graph_guard_condition_topics) {
1233+
TEST_F(CLASSNAME(TestGraphFixture, RMW_IMPLEMENTATION), test_graph_guard_condition_trigger_check) {
1234+
#define CHECK_GUARD_CONDITION_CHANGE(EXPECTED_RESULT, TIMEOUT) do { \
1235+
ret = rcl_wait_set_clear(&wait_set); \
1236+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; \
1237+
ret = rcl_wait_set_add_guard_condition(&wait_set, graph_guard_condition, NULL); \
1238+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str; \
1239+
ret = rcl_wait(&wait_set, TIMEOUT.count()); \
1240+
ASSERT_EQ(EXPECTED_RESULT, ret) << rcl_get_error_string().str; \
1241+
} while (0)
1242+
12311243
rcl_ret_t ret;
1232-
// Create a thread to sleep for a time, then create a publisher, sleep more, then a subscriber,
1233-
// sleep more, destroy the subscriber, sleep more, and then destroy the publisher.
1234-
std::promise<bool> topic_changes_promise;
1235-
std::thread topic_thread(
1236-
[this, &topic_changes_promise]() {
1237-
// sleep
1238-
std::this_thread::sleep_for(std::chrono::milliseconds(200));
1239-
// create the publisher
1240-
rcl_publisher_t pub = rcl_get_zero_initialized_publisher();
1241-
rcl_publisher_options_t pub_ops = rcl_publisher_get_default_options();
1242-
rcl_ret_t ret = rcl_publisher_init(
1243-
&pub, this->node_ptr, ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes),
1244-
"/chatter_test_graph_guard_condition_topics", &pub_ops);
1245-
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1246-
// sleep
1247-
std::this_thread::sleep_for(std::chrono::milliseconds(200));
1248-
// create the subscription
1249-
rcl_subscription_t sub = rcl_get_zero_initialized_subscription();
1250-
rcl_subscription_options_t sub_ops = rcl_subscription_get_default_options();
1251-
ret = rcl_subscription_init(
1252-
&sub, this->node_ptr, ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes),
1253-
"/chatter_test_graph_guard_condition_topics", &sub_ops);
1254-
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1255-
// sleep
1256-
std::this_thread::sleep_for(std::chrono::milliseconds(200));
1257-
// destroy the subscription
1258-
ret = rcl_subscription_fini(&sub, this->node_ptr);
1259-
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1260-
// sleep
1261-
std::this_thread::sleep_for(std::chrono::milliseconds(200));
1262-
// destroy the publication
1263-
ret = rcl_publisher_fini(&pub, this->node_ptr);
1264-
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1265-
// notify that the thread is done
1266-
topic_changes_promise.set_value(true);
1267-
});
1268-
// Wait for the graph state to change, expecting it to do so at least 4 times,
1269-
// once for each change in the topics thread.
1244+
std::chrono::nanoseconds timeout_1s = std::chrono::seconds(1);
1245+
std::chrono::nanoseconds timeout_3s = std::chrono::seconds(3);
1246+
1247+
rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
1248+
ret = rcl_wait_set_init(
1249+
&wait_set, 0, 1, 0, 0, 0, 0, context_ptr, rcl_get_default_allocator());
1250+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1251+
OSRF_TESTING_TOOLS_CPP_SCOPE_EXIT(
1252+
{
1253+
EXPECT_EQ(RCL_RET_OK, rcl_wait_set_fini(&wait_set)) << rcl_get_error_string().str;
1254+
});
1255+
12701256
const rcl_guard_condition_t * graph_guard_condition =
1271-
rcl_node_get_graph_guard_condition(this->node_ptr);
1272-
ASSERT_NE(nullptr, graph_guard_condition) << rcl_get_error_string().str;
1273-
std::shared_future<bool> future = topic_changes_promise.get_future();
1274-
size_t graph_changes_count = 0;
1275-
// while the topic thread is not done, wait and count the graph changes
1276-
while (future.wait_for(std::chrono::seconds(0)) != std::future_status::ready) {
1277-
ret = rcl_wait_set_clear(this->wait_set_ptr);
1257+
rcl_node_get_graph_guard_condition(node_ptr);
1258+
1259+
// Wait for no graph change condition
1260+
int idx = 0;
1261+
for (; idx < 100; idx++) {
1262+
ret = rcl_wait_set_clear(&wait_set);
12781263
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1279-
ret = rcl_wait_set_add_guard_condition(this->wait_set_ptr, graph_guard_condition, NULL);
1264+
ret = rcl_wait_set_add_guard_condition(&wait_set, graph_guard_condition, NULL);
12801265
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1281-
std::chrono::nanoseconds time_to_sleep = std::chrono::milliseconds(400);
1282-
RCUTILS_LOG_INFO_NAMED(
1283-
ROS_PACKAGE_NAME,
1284-
"waiting up to '%s' nanoseconds for graph changes",
1285-
std::to_string(time_to_sleep.count()).c_str());
1286-
ret = rcl_wait(this->wait_set_ptr, time_to_sleep.count());
1287-
if (ret == RCL_RET_TIMEOUT) {
1288-
continue;
1266+
ret = rcl_wait(&wait_set, timeout_3s.count());
1267+
if (RCL_RET_TIMEOUT == ret) {
1268+
break;
1269+
} else {
1270+
RCUTILS_LOG_INFO_NAMED(
1271+
ROS_PACKAGE_NAME,
1272+
"waiting for no graph change condition ...");
12891273
}
1290-
graph_changes_count++;
12911274
}
1292-
topic_thread.join();
1293-
// expect at least 4 changes
1294-
ASSERT_GE(graph_changes_count, 4ul);
1275+
ASSERT_NE(idx, 100);
1276+
1277+
// Graph change since creating the publisher
1278+
rcl_publisher_t pub = rcl_get_zero_initialized_publisher();
1279+
rcl_publisher_options_t pub_ops = rcl_publisher_get_default_options();
1280+
ret = rcl_publisher_init(
1281+
&pub, node_ptr, ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes),
1282+
"/chatter_test_graph_guard_condition_topics", &pub_ops);
1283+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1284+
1285+
{
1286+
SCOPED_TRACE("Check guard condition change failed !");
1287+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_1s);
1288+
}
1289+
1290+
// Graph change since destroying the publisher
1291+
ret = rcl_publisher_fini(&pub, node_ptr);
1292+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1293+
1294+
{
1295+
SCOPED_TRACE("Check guard condition change failed !");
1296+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_1s);
1297+
}
1298+
1299+
// Graph change since creating the subscription
1300+
rcl_subscription_t sub = rcl_get_zero_initialized_subscription();
1301+
rcl_subscription_options_t sub_ops = rcl_subscription_get_default_options();
1302+
ret = rcl_subscription_init(
1303+
&sub, node_ptr, ROSIDL_GET_MSG_TYPE_SUPPORT(test_msgs, msg, BasicTypes),
1304+
"/chatter_test_graph_guard_condition_topics", &sub_ops);
1305+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1306+
1307+
{
1308+
SCOPED_TRACE("Check guard condition change failed !");
1309+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_1s);
1310+
}
1311+
1312+
// Graph change since destroying the subscription
1313+
ret = rcl_subscription_fini(&sub, node_ptr);
1314+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1315+
1316+
{
1317+
SCOPED_TRACE("Check guard condition change failed !");
1318+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_1s);
1319+
}
1320+
1321+
// Graph change since creating service
1322+
rcl_service_t service = rcl_get_zero_initialized_service();
1323+
rcl_service_options_t service_options = rcl_service_get_default_options();
1324+
ret = rcl_service_init(
1325+
&service,
1326+
node_ptr,
1327+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes),
1328+
"test_graph_guard_condition_service",
1329+
&service_options);
1330+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1331+
1332+
{
1333+
SCOPED_TRACE("Check guard condition change failed !");
1334+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_1s);
1335+
}
1336+
1337+
// Graph change since destroy service
1338+
ret = rcl_service_fini(&service, node_ptr);
1339+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1340+
1341+
{
1342+
SCOPED_TRACE("Check guard condition change failed !");
1343+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_1s);
1344+
}
1345+
1346+
// Graph change since creating client
1347+
rcl_client_t client = rcl_get_zero_initialized_client();
1348+
rcl_client_options_t client_options = rcl_client_get_default_options();
1349+
ret = rcl_client_init(
1350+
&client,
1351+
node_ptr,
1352+
ROSIDL_GET_SRV_TYPE_SUPPORT(test_msgs, srv, BasicTypes),
1353+
"test_graph_guard_condition_service",
1354+
&client_options);
1355+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1356+
1357+
{
1358+
SCOPED_TRACE("Check guard condition change failed !");
1359+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_1s);
1360+
}
1361+
1362+
// Graph change since destroying client
1363+
ret = rcl_client_fini(&client, node_ptr);
1364+
EXPECT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1365+
1366+
{
1367+
SCOPED_TRACE("Check guard condition change failed !");
1368+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_1s);
1369+
}
1370+
1371+
// Graph change since adding new node
1372+
rcl_node_t node_new = rcl_get_zero_initialized_node();
1373+
rcl_node_options_t node_options = rcl_node_get_default_options();
1374+
ret = rcl_node_init(&node_new, "test_graph2", "", context_ptr, &node_options);
1375+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1376+
1377+
{
1378+
SCOPED_TRACE("Check guard condition change failed !");
1379+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_3s);
1380+
}
1381+
1382+
// Graph change since destroying new node
1383+
ret = rcl_node_fini(&node_new);
1384+
ASSERT_EQ(RCL_RET_OK, ret) << rcl_get_error_string().str;
1385+
1386+
{
1387+
SCOPED_TRACE("Check guard condition change failed !");
1388+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_OK, timeout_1s);
1389+
}
1390+
1391+
// Should not get graph change if no change
1392+
{
1393+
SCOPED_TRACE("Check guard condition change failed !");
1394+
CHECK_GUARD_CONDITION_CHANGE(RCL_RET_TIMEOUT, timeout_1s);
1395+
}
12951396
}
12961397

12971398
/* Test the rcl_service_server_is_available function.

0 commit comments

Comments
 (0)