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

Fix sub menues deletion wrong order #3748

Conversation

AKalinich-Luxoft
Copy link
Contributor

@AKalinich-Luxoft AKalinich-Luxoft commented Aug 2, 2021

Fixes #3747

This PR is ready for review.

Risk

This PR makes no API changes.

Testing Plan

Can be reproduced manually:

Reproduction Steps
  1. SDL and HMI are started
  2. Mobile device connected
  3. Mobile app is registered and activated
  4. SubMenu item is added
    AddSubMenu("menuID":1, "menuName":"Submenu Name 1")`
  5. Nested submenu items are added (each submenu is nested in the previous submenu)
    Send AddSubMenu(parentID=1, "menuID":2, "menuName":"Submenu Name 2")
    Send AddSubMenu(parentID=2, "menuID":3, "menuName":"Submenu Name 3")
    Send AddSubMenu(parentID=3, "menuID":4, "menuName":"Submenu Name 4")
  6. AddCommand item is added to nested SubMenu
    Send AddCommand("menuParams: { "parentID:4, "menuName":"Item to Add 1", "position":0)
  7. Delete submenu item (item is menu-tree branch)
    Send DeleteSubMenu("menuID":1)

Summary

The issue which was observed is that SDL sends DeleteSubMenu request to HMI for a "parent node" submenu and then sends
subsequent DeleteSubMenu requests recursively for all child nodes starting from the bottom one. Such an order confuses HMI because deletion of parent node may automatically trigger deletion of all its child nodes on the HMI side so subsequent requests from SDL for a child node might be rejected.
To make sure that HMI removes all the hierarchy properly, SDL should start deletion sequence from the bottom nodes and delete the parent node in the end. To resolve that issue, DeleteSubMenu request logic was updated. Currently, SDL recursively iterates through the submenu and command nodes and collects them in a queue.
Once the queue is ready, SDL sends requests one by one, waiting for an HMI response for each sent request before sending the
subsequent. Once the responses to all requests are received, SDL sends the final response to the mobile app and finalizes the
command.
Also updated DeleteSubMenu unit tests to cover new logic.

CLA

The issue which was observed is that SDL sends `DeleteSubMenu`
request to HMI for a "parent node" submenu and then sends
subsequent `DeleteSubMenu` requests recursively for all child
nodes starting from the bottom one. Such order confuses HMI
because deletion of parent node may automatically trigger
deletion of all its child nodes on HMI side so subsequent
requests from SDL for a child nodes might be rejected.
To make sure that HMI removes all the hierarchy properly,
SDL should start deletion sequence from the bottom nodes
and delete the parent node in the end.
To resolve that issue, DeleteSubMenu request logic was
updated. Currently, SDL recursively iterates through the
submenu and command nodes and collects them in a queue.
Once queue is ready, SDL sends requests one by one, waiting
for a HMI response for each sent request before sending the
subsequent. Once the responses to all requests are received,
SDL sends the final response to mobile app and finalizes the
command.
@AKalinich-Luxoft
Copy link
Contributor Author

@theresalech this PR is ready for Livio review

return smartObjectPtr;
}

void RunDeleteSubMenuHappyPath(
Copy link
Contributor

Choose a reason for hiding this comment

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

I think these functions could definitely use descriptions, what exactly they are doing isn't entirely clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jacobkeeler so I made some refactoring and split these functions on more atomic with more obvious names:

  • SetUp* functions for setting up the expectations for a corresponding test case
  • Prepare* functions for preparing event object
  • Generate* functions for generating corresponding smart objects

See 0b07d16

Copy link
Contributor

@jacobkeeler jacobkeeler left a comment

Choose a reason for hiding this comment

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

Also looks like the following ATF tests are failing because of the change in message order:

FAILED test_scripts/API/Additional_Submenus/003_delete_nested_submenu_with_nested_submenu_and_commands.lua
FAILED test_scripts/API/Additional_Submenus/004_delete_top_level_submenu_with_nested_submenus_and_commands.lua

EXPECT_CALL(
mock_rpc_service_,
ManageMobileCommand(MobileResultCodeIs(mobile_apis::Result::SUCCESS),
am::commands::Command::SOURCE_SDL));
Copy link
Contributor

Choose a reason for hiding this comment

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

The name of this test specifically says UNSUCCESS, why would we see a SUCCESS response?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jacobkeeler looks like fix changed the behavior and now SDL sends the response even if the app is not registered. I updated the fix to keep the behavior that was before. This unit test has been updated accordingly. See 0aec1a7

@@ -216,174 +432,219 @@ TEST_F(DeleteSubMenuRequestTest, Run_FindSubMenuFalse_UNSUCCESS) {
}

TEST_F(DeleteSubMenuRequestTest, Run_SendHMIRequest_SUCCESS) {
Copy link
Contributor

Choose a reason for hiding this comment

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

These two Run_* tests seems to just be subsets of later OnEvent_* tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jacobkeeler these two tests were removed. See 0aec1a7

@AKalinich-Luxoft
Copy link
Contributor Author

Also looks like the following ATF tests are failing because of the change in message order:

FAILED test_scripts/API/Additional_Submenus/003_delete_nested_submenu_with_nested_submenu_and_commands.lua
FAILED test_scripts/API/Additional_Submenus/004_delete_top_level_submenu_with_nested_submenus_and_commands.lua

@jacobkeeler right, these two scripts should be updated to work with the new order of the commands.
Appropriate changes were done in smartdevicelink/sdl_atf_test_scripts#2569
This PR has been linked to GitHub issue as well and should be merged together with that PR.

Comment on lines 227 to 228
auto app = application_manager_.application(
msg_params[strings::app_id].asUInt());
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
auto app = application_manager_.application(
msg_params[strings::app_id].asUInt());
auto app = application_manager_.application(connection_key());

While they should act the same, I think it's safer and easier to use the original connection key here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jacobkeeler good point. Fixed in b4ba264

Comment on lines 256 to 257
auto app = application_manager_.application(
msg_params[strings::app_id].asUInt());
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
auto app = application_manager_.application(
msg_params[strings::app_id].asUInt());
auto app = application_manager_.application(connection_key());

While they should act the same, I think it's safer to use the original connection key here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jacobkeeler good point. Fixed in b4ba264

Comment on lines 280 to 281
auto app = application_manager_.application(
msg_params[strings::app_id].asUInt());
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
auto app = application_manager_.application(
msg_params[strings::app_id].asUInt());
auto app = application_manager_.application(connection_key());

While they should act the same, I think it's safer to use the original connection key here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jacobkeeler good point. Fixed in b4ba264

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants