requester: support multi-host MCTP devices hot plug
Currently, pldmd listens for new MCTP endpoint exposed by mctpd, but
they only shows their EID, Network Id, and SupportedMessageTypes, which
cannot fulfill some requirements, e.g., get the device's name or check
the host slot number which contains the MCTP endpoint in multi-host
system.
In openbmc, the additional information are exposed by Entity Manager,
so that we add ConfigurationDiscoveryHandler, search for Entity
Manager's configuration when a new MCTP endpoint has been register by
mctpd.
Objects who want to obtain the configuration can include the
ConfigurationDiscoveryHandler as their attribute, get the configuration
when needed.
TESTED:
A series of unit test case to simulate the response of dbus call,
confirm that the configurations are successfully stored.
Change-Id: I59b8bf434576cbdea651848a8da11e5b870e2dfa
Signed-off-by: Delphine CC Chiu <Delphine_CC_Chiu@wiwynn.com>
Signed-off-by: MandyMCHung <mandy.hung.wiwynn@gmail.com>
Signed-off-by: LioraGuo-wiwynn <liora.guo.wiwynn@gmail.com>
Signed-off-by: Unive Tien <unive.tien.wiwynn@gmail.com>
diff --git a/requester/test/configuration_discovery_handler_test.cpp b/requester/test/configuration_discovery_handler_test.cpp
new file mode 100644
index 0000000..cd28c42
--- /dev/null
+++ b/requester/test/configuration_discovery_handler_test.cpp
@@ -0,0 +1,115 @@
+#include "config.h"
+
+#include "common/test/mocked_utils.hpp"
+#include "common/types.hpp"
+#include "common/utils.hpp"
+#include "requester/configuration_discovery_handler.hpp"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using ::testing::_;
+
+TEST(ConfigurationDiscoveryHandlerTest, succesfullyDiscoverConfig)
+{
+ constexpr uint8_t EID = 10;
+ constexpr auto mockedDbusPath =
+ "/xyz/openbmc_project/inventory/system/board/Mocked_Board_Slot_1/MockedDevice";
+ constexpr auto mockedService = "xyz.openbmc_project.EntityManager";
+ constexpr auto mockedInterface =
+ "xyz.openbmc_project.Configuration.MCTPEndpoint";
+ MockdBusHandler mockedUtils;
+ auto handler =
+ std::make_unique<pldm::ConfigurationDiscoveryHandler>(&mockedUtils);
+
+ pldm::utils::GetSubTreeResponse mockedGetSubtreeResponse{std::make_pair(
+ mockedDbusPath,
+ pldm::utils::MapperServiceMap{std::make_pair(
+ mockedService, pldm::utils::Interfaces{mockedInterface})})};
+
+ EXPECT_CALL(mockedUtils, getSubtree(_, _, _))
+ .Times(1)
+ .WillOnce(testing::Return(mockedGetSubtreeResponse));
+
+ pldm::utils::PropertyMap mockGetAllResponse{
+ {"Address", std::vector<uint64_t>{0x1}},
+ {"Bus", uint64_t(0)},
+ {"EndpointId", uint64_t(EID)},
+ {"Name", std::string("MockedDevice")}};
+
+ EXPECT_CALL(mockedUtils,
+ getAll(mockedService, mockedDbusPath, mockedInterface))
+ .Times(1)
+ .WillOnce(testing::Return(mockGetAllResponse));
+
+ pldm::MctpInfos mctpInfos;
+ mctpInfos.emplace_back(pldm::MctpInfo(EID, "emptyUUID", "", 1));
+
+ // Act
+ handler->handleMctpEndpoints(mctpInfos);
+
+ ASSERT_EQ(1, handler->getConfigurations().size());
+}
+
+TEST(ConfigurationDiscoveryHandlerTest, BlockedByNoSuchElement)
+{
+ constexpr uint8_t EID = 10;
+ constexpr auto mockedDbusPath =
+ "/xyz/openbmc_project/inventory/system/board/Mocked_Board_Slot_1/MockedDevice";
+ constexpr auto mockedService = "xyz.openbmc_project.EntityManager";
+ constexpr auto mockedInterface =
+ "xyz.openbmc_project.Configuration.MCTPEndpoint";
+ MockdBusHandler mockedUtils;
+ auto handler =
+ std::make_unique<pldm::ConfigurationDiscoveryHandler>(&mockedUtils);
+
+ pldm::utils::GetSubTreeResponse mockedGetSubtreeResponse{std::make_pair(
+ mockedDbusPath,
+ pldm::utils::MapperServiceMap{std::make_pair(
+ mockedService, pldm::utils::Interfaces{mockedInterface})})};
+
+ EXPECT_CALL(mockedUtils, getSubtree(_, _, _))
+ .Times(1)
+ .WillOnce(testing::Return(mockedGetSubtreeResponse));
+
+ pldm::utils::PropertyMap mockGetAllResponse{
+ {"Address", uint64_t(0x1)},
+ {"Bus", uint64_t(0)},
+ /* No EndpointId */
+ {"Name", std::string("MockedDevice")}};
+
+ EXPECT_CALL(mockedUtils,
+ getAll(mockedService, mockedDbusPath, mockedInterface))
+ .Times(1)
+ .WillOnce(testing::Return(mockGetAllResponse));
+
+ pldm::MctpInfos mctpInfos;
+ mctpInfos.emplace_back(pldm::MctpInfo(EID, "emptyUUID", "", 1));
+
+ // Act
+ EXPECT_NO_THROW(handler->handleMctpEndpoints(mctpInfos));
+
+ ASSERT_EQ(0, handler->getConfigurations().size());
+}
+
+TEST(ConfigurationDiscoveryHandlerTest, succesfullyRemoveConfig)
+{
+ constexpr uint8_t EID = 10;
+
+ MockdBusHandler mockedUtils;
+ auto handler =
+ std::make_unique<pldm::ConfigurationDiscoveryHandler>(&mockedUtils);
+
+ pldm::MctpEndpoint mockedMctpEndpoint = {
+ uint64_t(0x1), uint64_t(EID), uint64_t(0), "MockedDevice",
+ std::nullopt};
+ handler->getConfigurations().emplace(
+ "/xyz/openbmc_project/inventory/system/board/Mocked_Board_Slot_1/MockedDevice",
+ mockedMctpEndpoint);
+
+ pldm::MctpInfos mctpInfos;
+ mctpInfos.emplace_back(pldm::MctpInfo(EID, "emptyUUID", "", 1));
+ handler->handleRemovedMctpEndpoints(mctpInfos);
+
+ ASSERT_EQ(0, handler->getConfigurations().size());
+}