| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/developer/forensics/utils/inspect_node_manager.h" |
| |
| #include <string> |
| #include <vector> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "src/developer/forensics/testing/unit_test_fixture.h" |
| |
| namespace forensics { |
| namespace { |
| |
| using inspect::testing::ChildrenMatch; |
| using inspect::testing::NameMatches; |
| using inspect::testing::NodeMatches; |
| using inspect::testing::PropertyList; |
| using inspect::testing::StringIs; |
| using inspect::testing::UintIs; |
| using testing::AllOf; |
| using testing::Contains; |
| using testing::ElementsAreArray; |
| using testing::HasSubstr; |
| using testing::IsEmpty; |
| using testing::UnorderedElementsAreArray; |
| |
| class InspectNodeManagerTest : public UnitTestFixture { |
| public: |
| void SetUp() override { |
| inspect_node_manager_ = std::make_unique<InspectNodeManager>(&InspectRoot()); |
| } |
| |
| protected: |
| std::unique_ptr<InspectNodeManager> inspect_node_manager_; |
| }; |
| |
| TEST_F(InspectNodeManagerTest, Check_Get_RootNode) { |
| inspect_node_manager_->Get(""); |
| inspect_node_manager_->Get("/"); |
| EXPECT_THAT(InspectTree(), ChildrenMatch(IsEmpty())); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Check_Get_MultipleLevelOneNodes) { |
| inspect_node_manager_->Get("/child1"); |
| inspect_node_manager_->Get("/child2"); |
| inspect_node_manager_->Get("/child3"); |
| |
| EXPECT_THAT(InspectTree(), ChildrenMatch(UnorderedElementsAreArray({ |
| NodeMatches(NameMatches("child1")), |
| NodeMatches(NameMatches("child2")), |
| NodeMatches(NameMatches("child3")), |
| }))); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Check_Get_NodeAlreadyExists) { |
| inspect_node_manager_->Get("/child1"); |
| inspect_node_manager_->Get("/child1"); |
| |
| EXPECT_THAT(InspectTree(), ChildrenMatch(UnorderedElementsAreArray({ |
| NodeMatches(NameMatches("child1")), |
| }))); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Check_Get_OneLevelTwoNode) { |
| inspect_node_manager_->Get("/child1/grandchild1.1"); |
| |
| EXPECT_THAT(InspectTree(), |
| ChildrenMatch(ElementsAre( |
| AllOf(NodeMatches(NameMatches("child1")), |
| ChildrenMatch(ElementsAre(NodeMatches(NameMatches("grandchild1.1")))))))); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Check_Get_MultipleLevelTwoNodes) { |
| inspect_node_manager_->Get("/child1"); |
| inspect_node_manager_->Get("/child1/grandchild1.1"); |
| inspect_node_manager_->Get("/child1/grandchild1.2"); |
| |
| EXPECT_THAT(InspectTree(), |
| ChildrenMatch(ElementsAre(AllOf(NodeMatches(NameMatches("child1")), |
| ChildrenMatch(UnorderedElementsAreArray({ |
| NodeMatches(NameMatches("grandchild1.1")), |
| NodeMatches(NameMatches("grandchild1.2")), |
| })))))); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Check_Get_OneLevelThreeNode) { |
| inspect_node_manager_->Get("/child1/grandchild1.1/greatgrandchild1.1.1"); |
| |
| EXPECT_THAT( |
| InspectTree(), |
| ChildrenMatch(ElementsAre(AllOf( |
| NodeMatches(NameMatches("child1")), |
| ChildrenMatch(UnorderedElementsAreArray({ |
| AllOf(NodeMatches(NameMatches("grandchild1.1")), |
| ChildrenMatch(ElementsAre(NodeMatches(NameMatches("greatgrandchild1.1.1"))))), |
| })))))); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Check_Update_OneLevelThreeNode) { |
| inspect::Node& node = inspect_node_manager_->Get("/child1/grandchild1.1/greatgrandchild1.1.1"); |
| |
| inspect::StringProperty s = node.CreateString("string", "value"); |
| EXPECT_THAT(InspectTree(), |
| ChildrenMatch(ElementsAre( |
| AllOf(NodeMatches(NameMatches("child1")), |
| ChildrenMatch(UnorderedElementsAreArray({ |
| AllOf(NodeMatches(NameMatches("grandchild1.1")), |
| ChildrenMatch(ElementsAre(NodeMatches(AllOf( |
| NameMatches("greatgrandchild1.1.1"), |
| PropertyList(ElementsAre(StringIs("string", "value")))))))), |
| })))))); |
| |
| inspect::UintProperty u = node.CreateUint("uint", 10u); |
| EXPECT_THAT(InspectTree(), |
| ChildrenMatch(ElementsAre(AllOf(NodeMatches(NameMatches("child1")), |
| ChildrenMatch(UnorderedElementsAreArray({ |
| AllOf(NodeMatches(NameMatches("grandchild1.1")), |
| ChildrenMatch(ElementsAre(NodeMatches(AllOf( |
| NameMatches("greatgrandchild1.1.1"), |
| PropertyList(UnorderedElementsAreArray({ |
| StringIs("string", "value"), |
| UintIs("uint", 10u), |
| }))))))), |
| })))))); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Check_Remove_LevelOneNode) { |
| inspect_node_manager_->Get("/child1"); |
| |
| EXPECT_THAT(InspectTree(), ChildrenMatch(UnorderedElementsAreArray({ |
| NodeMatches(NameMatches("child1")), |
| }))); |
| |
| EXPECT_TRUE(inspect_node_manager_->Remove("/child1")); |
| EXPECT_THAT(InspectTree(), ChildrenMatch(IsEmpty())); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Check_Remove_LevelTwoNode) { |
| inspect_node_manager_->Get("/child1/grandchild1.1"); |
| |
| EXPECT_THAT(InspectTree(), |
| ChildrenMatch(ElementsAre( |
| AllOf(NodeMatches(NameMatches("child1")), |
| ChildrenMatch(ElementsAre(NodeMatches(NameMatches("grandchild1.1")))))))); |
| |
| EXPECT_TRUE(inspect_node_manager_->Remove("/child1/grandchild1.1")); |
| EXPECT_THAT(InspectTree(), ChildrenMatch(ElementsAre(AllOf(NodeMatches(NameMatches("child1")), |
| ChildrenMatch(IsEmpty()))))); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Attempt_Remove_NodesDoNotExist) { |
| // Try to remove a node that doesn't exist, then create it. |
| EXPECT_FALSE(inspect_node_manager_->Remove("/child1")); |
| inspect_node_manager_->Get("/child1"); |
| |
| // Try to remove a node that doesn't exist, then create it. |
| EXPECT_FALSE(inspect_node_manager_->Remove("/child1/grandchild1.1")); |
| inspect_node_manager_->Get("/child1/grandchild1.1"); |
| |
| EXPECT_THAT(InspectTree(), |
| ChildrenMatch(ElementsAre( |
| AllOf(NodeMatches(NameMatches("child1")), |
| ChildrenMatch(ElementsAre(NodeMatches(NameMatches("grandchild1.1")))))))); |
| } |
| |
| TEST_F(InspectNodeManagerTest, Check_SanitizedPath) { |
| constexpr char expected_sanitized_name[] = { |
| 'p', 'r', 'o', 'g', 'r', 'a', 'm', 0x07, 'n', 0x07, 0x07, 'a', |
| 0x07, 0x07, 0x07, 'm', 0x07, 0x07, 0x07, 0x07, 0x07, 'e', '\0', |
| }; |
| |
| std::string name_with_backslashes = "program/n//a///m/////e"; |
| auto sanitized_name = InspectNodeManager::SanitizeString(name_with_backslashes); |
| |
| EXPECT_EQ(sanitized_name, expected_sanitized_name); |
| |
| const std::string full_path = "/child1/" + sanitized_name; |
| inspect_node_manager_->Get(full_path); |
| |
| EXPECT_THAT(InspectTree(), |
| ChildrenMatch(ElementsAre(AllOf( |
| NodeMatches(NameMatches("child1")), |
| ChildrenMatch(ElementsAre(NodeMatches(NameMatches(name_with_backslashes)))))))); |
| |
| EXPECT_TRUE(inspect_node_manager_->Remove(full_path)); |
| EXPECT_THAT(InspectTree(), ChildrenMatch(ElementsAre(AllOf(NodeMatches(NameMatches("child1")), |
| ChildrenMatch(IsEmpty()))))); |
| } |
| |
| } // namespace |
| } // namespace forensics |