mapper: Add GetAssociatedSubTreePathsById and GetAssociatedSubTreeById
dbus-interface change in:
https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/69999
This commit implements two new methods: GetAssociatedSubTreePathsById
and GetAssociatedSubTreeById. These methods retrieve the paths of
associated endpoints corresponding to the provided identifier, filtering
based on their association with specified endpoint interfaces.
GetAssociatedSubTreePathsById returns the D-Bus paths of associated
endpoints, while GetAssociatedSubTreeById retrieves a dictionary of
D-Bus paths of associated endpoints mapped to corresponding services
associated with the provided identifier.
Tested:
'''
busctl call -j "xyz.openbmc_project.ObjectMapper" "/xyz/openbmc_project/object_mapper" \
"xyz.openbmc_project.ObjectMapper" "GetAssociatedSubTreePathsById" ssassas \
"chassis" \
"/xyz/openbmc_project/inventory" \
1 "xyz.openbmc_project.Inventory.Item.Chassis" \
"powered_by" \
1 "xyz.openbmc_project.Inventory.Item.PowerSupply"
{
"type" : "as",
"data" : [
[
"/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply0",
"/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1",
"/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply2",
"/xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply3"
]
]
}
'''
Another example.
```
busctl call -j xyz.openbmc_project.ObjectMapper /xyz/openbmc_project/object_mapper \
xyz.openbmc_project.ObjectMapper GetAssociatedSubTreePathsById ssassas \
disk_backplane0 \
/xyz/openbmc_project/inventory \
1 xyz.openbmc_project.Inventory.Item.FabricAdapter \
connecting \
1 xyz.openbmc_project.Inventory.Connector.Port
{
"type" : "as",
"data" : [
[
"/xyz/openbmc_project/inventory/system/chassis/motherboard/disk_backplane0/dp0_connector0",
"/xyz/openbmc_project/inventory/system/chassis/motherboard/disk_backplane0/dp0_connector1",
"/xyz/openbmc_project/inventory/system/chassis/motherboard/disk_backplane0/dp0_connector2",
"/xyz/openbmc_project/inventory/system/chassis/motherboard/disk_backplane0/dp0_connector3",
"/xyz/openbmc_project/inventory/system/chassis/motherboard/disk_backplane0/dp0_connector4",
"/xyz/openbmc_project/inventory/system/chassis/motherboard/disk_backplane0/dp0_connector5"
]
]
}
```
Change-Id: Id55a9b41fe70f7204543d92b5396888f6914a1d4
Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
Signed-off-by: Myung Bae <myungbae@us.ibm.com>
diff --git a/src/test/handler.cpp b/src/test/handler.cpp
index aac2d0f..7f418e5 100644
--- a/src/test/handler.cpp
+++ b/src/test/handler.cpp
@@ -32,7 +32,16 @@
{
"/test/object_path_0/child/grandchild/dog",
{{"test_object_connection_3", {"test_interface_3"}}},
- }};
+ },
+ {
+ "/test/object_path_0/child1",
+ {{"test_object_connection_4", {"test_interface_4"}}},
+ },
+ {
+ "/test/object_path_0/grandchild/child1",
+ {{"test_object_connection_5", {"test_interface_5"}}},
+ },
+ };
AssociationMaps associationMap = {
.ifaces =
@@ -56,6 +65,25 @@
},
},
},
+ {
+ "/test/object_path_0/grandchild/child1/descendent",
+ {
+ std::shared_ptr<sdbusplus::asio::dbus_interface>(),
+ {
+ "/test/object_path_0/child",
+ },
+ },
+ },
+ {
+ "/test/object_path_0/child1/descendent",
+ {
+ std::shared_ptr<sdbusplus::asio::dbus_interface>(),
+ {
+ "/test/object_path_0/child1",
+ "/test/object_path_0/child1/grandchild",
+ },
+ },
+ },
},
.owners = {},
.pending = {},
@@ -79,7 +107,6 @@
"test_interface_1",
}));
ASSERT_EQ(interfaceMaps.size(), 1);
-
auto entry = std::find_if(
interfaceMaps.begin(), interfaceMaps.end(),
[](const auto& i) { return "test_object_path" == i.first; });
@@ -411,3 +438,151 @@
ASSERT_THAT(subtreePath,
ElementsAre("/test/object_path_0/child/grandchild"));
}
+
+TEST_F(TestHandler, getAssociatedSubTreeByIdBad)
+{
+ sdbusplus::message::object_path path("/test/object_path_0");
+ std::vector<std::string> subtreeInterfaces = {"test_interface_1",
+ "test_interface_3"};
+ std::vector<std::string> badsubtreeInterfaces = {"bad_interface"};
+ std::vector<std::string> endpointinvalidInterfaces = {"test_interface_3"};
+ std::vector<std::string> endpointvalidInterfaces = {"test_interface_1",
+ "test_interface_2"};
+ // invalid id
+ EXPECT_THROW(
+ getAssociatedSubTreeById(interfaceMap, associationMap, "childx", path,
+ subtreeInterfaces, "descendent",
+ endpointvalidInterfaces),
+ sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
+
+ // invalid subtreeInterfaces
+ EXPECT_THROW(
+ getAssociatedSubTreeById(interfaceMap, associationMap, "child", path,
+ badsubtreeInterfaces, "descendent",
+ endpointvalidInterfaces),
+ sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
+
+ // invalid endpointinterface
+ ASSERT_TRUE(getAssociatedSubTreeById(interfaceMap, associationMap, "child",
+ path, subtreeInterfaces, "descendent",
+ endpointinvalidInterfaces)
+ .empty());
+ // valid id, but doesn't have specified interface
+ EXPECT_THROW(
+ getAssociatedSubTreeById(interfaceMap, associationMap, "grandchild",
+ path, subtreeInterfaces, "descendent",
+ endpointvalidInterfaces),
+ sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
+
+ // invalid association
+ ASSERT_TRUE(getAssociatedSubTreeById(interfaceMap, associationMap, "child",
+ path, subtreeInterfaces, "dog",
+ endpointinvalidInterfaces)
+ .empty());
+
+ // Invalid path
+ path = sdbusplus::message::object_path("/invalid_path");
+ EXPECT_THROW(
+ getAssociatedSubTreeById(interfaceMap, associationMap, "child", path,
+ subtreeInterfaces, "descendent",
+ endpointvalidInterfaces),
+ sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
+}
+
+TEST_F(TestHandler, getAssociatedSubTreeByIdGood)
+{
+ sdbusplus::message::object_path path0("/test/object_path_0");
+ std::vector<std::string> interfaces = {
+ "test_interface_1", "test_interface_2", "test_interface_3"};
+
+ // Path0
+ std::vector<InterfaceMapType::value_type> subtree =
+ getAssociatedSubTreeById(interfaceMap, associationMap, "child", path0,
+ interfaces, "descendent", interfaces);
+ ASSERT_EQ(subtree.size(), 1);
+ ConnectionNames connection = subtree[0].second;
+ auto object = connection.find("test_object_connection_2");
+ ASSERT_NE(object, connection.end());
+ ASSERT_THAT(object->second, ElementsAre("test_interface_2"));
+
+ std::vector<std::string> interfaces1 = {
+ "test_interface_1", "test_interface_4", "test_interface_5"};
+ // Path0 with Depth path of 0
+ subtree =
+ getAssociatedSubTreeById(interfaceMap, associationMap, "child1", path0,
+ interfaces1, "descendent", interfaces1);
+ ASSERT_EQ(subtree.size(), 2);
+}
+
+TEST_F(TestHandler, getAssociatedSubTreePathsByIdBad)
+{
+ sdbusplus::message::object_path path("/test/object_path_0");
+ std::vector<std::string> subtreeInterfaces = {"test_interface_1",
+ "test_interface_3"};
+ std::vector<std::string> badsubtreeInterfaces = {"bad_interface"};
+ std::vector<std::string> endpointinvalidInterfaces = {"test_interface_3"};
+ std::vector<std::string> endpointvalidInterfaces = {"test_interface_1",
+ "test_interface_2"};
+ // invalid id
+ EXPECT_THROW(
+ getAssociatedSubTreePathsById(interfaceMap, associationMap, "childx",
+ path, subtreeInterfaces, "descendent",
+ endpointvalidInterfaces),
+ sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
+
+ // invalid subtreeInterfaces
+ EXPECT_THROW(
+ getAssociatedSubTreePathsById(interfaceMap, associationMap, "child",
+ path, badsubtreeInterfaces, "descendent",
+ endpointvalidInterfaces),
+ sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
+
+ // invalid endpointinterface
+ ASSERT_TRUE(getAssociatedSubTreePathsById(
+ interfaceMap, associationMap, "child", path,
+ subtreeInterfaces, "descendent", endpointinvalidInterfaces)
+ .empty());
+ // valid id, but doesn't have specified interface
+ EXPECT_THROW(
+ getAssociatedSubTreePathsById(interfaceMap, associationMap,
+ "grandchild", path, subtreeInterfaces,
+ "descendent", endpointvalidInterfaces),
+ sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
+
+ // invalid association
+ ASSERT_TRUE(getAssociatedSubTreePathsById(interfaceMap, associationMap,
+ "child", path, subtreeInterfaces,
+ "dog", endpointinvalidInterfaces)
+ .empty());
+
+ // Invalid path
+ path = sdbusplus::message::object_path("/invalid_path");
+ EXPECT_THROW(
+ getAssociatedSubTreePathsById(interfaceMap, associationMap, "child",
+ path, subtreeInterfaces, "descendent",
+ endpointvalidInterfaces),
+ sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
+}
+
+TEST_F(TestHandler, getAssociatedSubTreePathsByIdGood)
+{
+ sdbusplus::message::object_path path0("/test/object_path_0");
+ std::vector<std::string> interfaces = {
+ "test_interface_1", "test_interface_2", "test_interface_3"};
+
+ // Path0
+ std::vector<std::string> subtreePath = getAssociatedSubTreePathsById(
+ interfaceMap, associationMap, "child", path0, interfaces, "descendent",
+ interfaces);
+ ASSERT_THAT(subtreePath,
+ ElementsAre("/test/object_path_0/child/grandchild"));
+
+ std::vector<std::string> interfaces1 = {
+ "test_interface_1", "test_interface_4", "test_interface_5"};
+ // Path0 with Depth path of 0
+ subtreePath = getAssociatedSubTreePathsById(
+ interfaceMap, associationMap, "child1", path0, interfaces1,
+ "descendent", interfaces1);
+ ASSERT_THAT(subtreePath, ElementsAre("/test/object_path_0/child1",
+ "/test/object_path_0/child"));
+}