@@ -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