Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Test Case for rclcpp_action Where the Status Message is Received Before the Service Response #2781

Open
wants to merge 1 commit into
base: rolling
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions rclcpp_action/test/test_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,38 @@ TEST_F(TestClientAgainstServer, async_send_goal_no_callbacks)
EXPECT_FALSE(goal_handle->is_result_aware());
}

TEST_F(TestClientAgainstServer, receive_status_before_service_response)
{
auto action_client = rclcpp_action::create_client<ActionType>(client_node, action_name);
ASSERT_TRUE(action_client->wait_for_action_server(WAIT_FOR_SERVER_TIMEOUT));

ActionGoal good_goal;
good_goal.order = 5;
auto future_goal_handle = action_client->async_send_goal(good_goal);
// Spin the client, to send out the goals
client_executor.spin_some();
// Spin the server until a goal is received
while (goals.empty()) {
server_executor.spin_once();
}
// Set the goals to an executing state
ActionStatusMessage status_message;
for (const auto & [goal_uuid, goal] : goals) {
rclcpp_action::GoalStatus goal_status;
goal_status.goal_info.goal_id.uuid = goal.first->goal_id.uuid;
goal_status.goal_info.stamp = goal.second->stamp;
goal_status.status = rclcpp_action::GoalStatus::STATUS_EXECUTING;
status_message.status_list.push_back(goal_status);
}
status_publisher->publish(status_message);
// Spin until the client receives the goal
dual_spin_until_future_complete(future_goal_handle);
Comment on lines +456 to +457
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this particular case, i believe that GoalResponse(accepted) and Status messages are already in the rmw implementation, and the question here is which should be taken 1st. currently, the order to take the action entities is feedback, status, goal_response, result_response and cancel_response. so that status is going to be taken and processed before goal_response.

but this order only matters when the messages are already in the queue of rmw implementation.

auto goal_handle = future_goal_handle.get();
EXPECT_EQ(rclcpp_action::GoalStatus::STATUS_EXECUTING, goal_handle->get_status());
EXPECT_FALSE(goal_handle->is_feedback_aware());
EXPECT_FALSE(goal_handle->is_result_aware());
}

TEST_F(TestClientAgainstServer, bad_goal_handles)
{
auto action_client0 = rclcpp_action::create_client<ActionType>(client_node, action_name);
Expand Down
36 changes: 36 additions & 0 deletions rclcpp_action/test/test_generic_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,42 @@ TEST_F(TestGenericClientAgainstServer, async_send_goal_no_callbacks)
EXPECT_FALSE(goal_handle->is_result_aware());
}

TEST_F(TestGenericClientAgainstServer, receive_status_before_service_response)
{
auto action_generic_client = rclcpp_action::create_generic_client(
client_node,
action_name,
"test_msgs/action/Fibonacci");
ASSERT_TRUE(action_generic_client->wait_for_action_server(WAIT_FOR_SERVER_TIMEOUT));

ActionGoal good_goal;
good_goal.order = 5;
auto future_goal_handle =
action_generic_client->async_send_goal(&good_goal, sizeof(good_goal));
// Spin the client, to send out the goals
client_executor.spin_some();
// Spin the server until a goal is received
while (goals.empty()) {
server_executor.spin_once();
}
// Set the goals to an executing state
ActionStatusMessage status_message;
for (const auto & [goal_uuid, goal] : goals) {
rclcpp_action::GoalStatus goal_status;
goal_status.goal_info.goal_id.uuid = goal.first->goal_id.uuid;
goal_status.goal_info.stamp = goal.second->stamp;
goal_status.status = rclcpp_action::GoalStatus::STATUS_EXECUTING;
status_message.status_list.push_back(goal_status);
}
status_publisher->publish(status_message);
// Spin until the client receives the goal
dual_spin_until_future_complete(future_goal_handle);
auto goal_handle = future_goal_handle.get();
EXPECT_EQ(rclcpp_action::GoalStatus::STATUS_EXECUTING, goal_handle->get_status());
EXPECT_FALSE(goal_handle->is_feedback_aware());
EXPECT_FALSE(goal_handle->is_result_aware());
}

TEST_F(TestGenericClientAgainstServer, async_send_goal_request_no_callbacks)
{
auto action_generic_client = rclcpp_action::create_generic_client(
Expand Down