requester: Modified MctpDiscovery class
Modified MctpDiscovery class to take list of managers instead of single
fwManager. The change is for adding platform-mc manager.
Added loadStaticEndpoints API for MCTP layer which doesn't implement
/xyz/openbmc_project/MCTP/Endpoint.Interface
The patch is part of implementation of design document below.
https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/47252
Signed-off-by: Gilbert Chen <gilbert.chen@arm.com>
Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Change-Id: I1e1673504583a87f2a9bc3adf76fb49c2dc30254
diff --git a/common/types.hpp b/common/types.hpp
index 0c7514c..90c94c6 100644
--- a/common/types.hpp
+++ b/common/types.hpp
@@ -16,10 +16,16 @@
{
using eid = uint8_t;
+using UUID = std::string;
using Request = std::vector<uint8_t>;
using Response = std::vector<uint8_t>;
using Command = uint8_t;
+using MctpMedium = std::string;
+using NetworkId = uint32_t;
+using MctpInfo = std::tuple<eid, UUID, MctpMedium, NetworkId>;
+using MctpInfos = std::vector<MctpInfo>;
+
namespace dbus
{
diff --git a/common/utils.cpp b/common/utils.cpp
index 9eed1be..e9b2c68 100644
--- a/common/utils.cpp
+++ b/common/utils.cpp
@@ -569,6 +569,18 @@
return bus.call(method).unpack<ObjectValueTree>();
}
+PropertyMap
+ DBusHandler::getDbusPropertiesVariant(const char* serviceName,
+ const char* objPath,
+ const char* dbusInterface) const
+{
+ auto& bus = DBusHandler::getBus();
+ auto method = bus.new_method_call(serviceName, objPath, dbusProperties,
+ "GetAll");
+ method.append(dbusInterface);
+ return bus.call(method, dbusTimeout).unpack<PropertyMap>();
+}
+
PropertyValue jsonEntryToDbusVal(std::string_view type,
const nlohmann::json& value)
{
diff --git a/common/utils.hpp b/common/utils.hpp
index c2bdb0d..10038b4 100644
--- a/common/utils.hpp
+++ b/common/utils.hpp
@@ -16,6 +16,7 @@
#include <sdbusplus/server.hpp>
#include <xyz/openbmc_project/Inventory/Manager/client.hpp>
#include <xyz/openbmc_project/Logging/Entry/server.hpp>
+#include <xyz/openbmc_project/ObjectMapper/client.hpp>
#include <deque>
#include <exception>
@@ -46,6 +47,14 @@
using Entities = std::vector<pldm_entity_node*>;
using EntityAssociations = std::vector<Entities>;
using ObjectPathMaps = std::map<fs::path, pldm_entity_node*>;
+using ObjectMapper = sdbusplus::client::xyz::openbmc_project::ObjectMapper<>;
+
+using inventoryManager =
+ sdbusplus::client::xyz::openbmc_project::inventory::Manager<>;
+
+constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
+constexpr auto mapperService = ObjectMapper::default_service;
+constexpr auto inventoryPath = "/xyz/openbmc_project/inventory";
const std::map<EntityType, EntityName> entityMaps = {
{PLDM_ENTITY_SYSTEM_CHASSIS, "chassis"},
@@ -166,13 +175,6 @@
return bcd;
}
-using inventoryManager =
- sdbusplus::client::xyz::openbmc_project::inventory::Manager<>;
-
-constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
-constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
-constexpr auto inventoryPath = "/xyz/openbmc_project/inventory";
-
struct DBusMapping
{
std::string objectPath; //!< D-Bus object path
@@ -220,6 +222,10 @@
virtual PropertyValue
getDbusPropertyVariant(const char* objPath, const char* dbusProp,
const char* dbusInterface) const = 0;
+
+ virtual PropertyMap
+ getDbusPropertiesVariant(const char* serviceName, const char* objPath,
+ const char* dbusInterface) const = 0;
};
/**
@@ -284,6 +290,20 @@
getDbusPropertyVariant(const char* objPath, const char* dbusProp,
const char* dbusInterface) const override;
+ /** @brief Get All properties(type: variant) from the requested dbus
+ *
+ * @param[in] serviceName - The Dbus service name
+ * @param[in] objPath - The Dbus object path
+ * @param[in] dbusInterface - The Dbus interface
+ *
+ * @return The values of the properties(type: variant)
+ *
+ * @throw sdbusplus::exception_t when it fails
+ */
+ PropertyMap
+ getDbusPropertiesVariant(const char* serviceName, const char* objPath,
+ const char* dbusInterface) const override;
+
/** @brief The template function to get property from the requested dbus
* path
*
diff --git a/fw-update/manager.hpp b/fw-update/manager.hpp
index 018a703..be45eb7 100644
--- a/fw-update/manager.hpp
+++ b/fw-update/manager.hpp
@@ -6,6 +6,7 @@
#include "device_updater.hpp"
#include "inventory_manager.hpp"
#include "requester/handler.hpp"
+#include "requester/mctp_endpoint_discovery.hpp"
#include "update_manager.hpp"
#include <unordered_map>
@@ -22,7 +23,7 @@
* This class handles all the aspects of the PLDM FW update specification for
* the MCTP devices
*/
-class Manager
+class Manager : public pldm::MctpDiscoveryHandlerIntf
{
public:
Manager() = delete;
@@ -44,18 +45,32 @@
componentInfoMap)
{}
- /** @brief Discover MCTP endpoints that support the PLDM firmware update
- * specification
+ /** @brief Helper function to invoke registered handlers for
+ * the added MCTP endpoints
*
- * @param[in] eids - Array of MCTP endpoints
- *
- * @return return PLDM_SUCCESS on success and PLDM_ERROR otherwise
+ * @param[in] mctpInfos - information of discovered MCTP endpoints
*/
- void handleMCTPEndpoints(const std::vector<mctp_eid_t>& eids)
+ void handleMctpEndpoints(const MctpInfos& mctpInfos)
{
+ std::vector<mctp_eid_t> eids;
+ for (const auto& mctpInfo : mctpInfos)
+ {
+ eids.emplace_back(std::get<mctp_eid_t>(mctpInfo));
+ }
+
inventoryMgr.discoverFDs(eids);
}
+ /** @brief Helper function to invoke registered handlers for
+ * the removed MCTP endpoints
+ *
+ * @param[in] mctpInfos - information of removed MCTP endpoints
+ */
+ void handleRemovedMctpEndpoints(const MctpInfos&)
+ {
+ return;
+ }
+
/** @brief Handle PLDM request for the commands in the FW update
* specification
*
diff --git a/pldmd/pldmd.cpp b/pldmd/pldmd.cpp
index 1dd5de8..0adba8c 100644
--- a/pldmd/pldmd.cpp
+++ b/pldmd/pldmd.cpp
@@ -308,7 +308,9 @@
std::unique_ptr<fw_update::Manager> fwManager =
std::make_unique<fw_update::Manager>(event, reqHandler, instanceIdDb);
std::unique_ptr<MctpDiscovery> mctpDiscoveryHandler =
- std::make_unique<MctpDiscovery>(bus, fwManager.get());
+ std::make_unique<MctpDiscovery>(
+ bus,
+ std::initializer_list<MctpDiscoveryHandlerIntf*>{fwManager.get()});
auto callback = [verbose, &invoker, &reqHandler, &fwManager, &pldmTransport,
TID](IO& io, int fd, uint32_t revents) mutable {
if (!(revents & EPOLLIN))
diff --git a/requester/mctp_endpoint_discovery.cpp b/requester/mctp_endpoint_discovery.cpp
index a962228..9440ed0 100644
--- a/requester/mctp_endpoint_discovery.cpp
+++ b/requester/mctp_endpoint_discovery.cpp
@@ -1,100 +1,214 @@
+#include "config.h"
+
#include "mctp_endpoint_discovery.hpp"
#include "common/types.hpp"
#include "common/utils.hpp"
+#include <phosphor-logging/lg2.hpp>
+
#include <algorithm>
+#include <fstream>
+#include <iostream>
#include <map>
#include <string>
#include <string_view>
#include <vector>
+using namespace sdbusplus::bus::match::rules;
+
+PHOSPHOR_LOG2_USING;
+
namespace pldm
{
-MctpDiscovery::MctpDiscovery(sdbusplus::bus_t& bus,
- fw_update::Manager* fwManager) :
+MctpDiscovery::MctpDiscovery(
+ sdbusplus::bus::bus& bus,
+ std::initializer_list<MctpDiscoveryHandlerIntf*> list) :
bus(bus),
- fwManager(fwManager),
- mctpEndpointSignal(bus,
- sdbusplus::bus::match::rules::interfacesAdded(
- "/xyz/openbmc_project/mctp"),
- std::bind_front(&MctpDiscovery::dicoverEndpoints, this))
+ mctpEndpointAddedSignal(
+ bus, interfacesAdded(MCTPPath),
+ std::bind_front(&MctpDiscovery::discoverEndpoints, this)),
+ mctpEndpointRemovedSignal(
+ bus, interfacesRemoved(MCTPPath),
+ std::bind_front(&MctpDiscovery::removeEndpoints, this)),
+ handlers(list)
{
- pldm::utils::ObjectValueTree objects;
+ getMctpInfos(existingMctpInfos);
+ handleMctpEndpoints(existingMctpInfos);
+}
+void MctpDiscovery::getMctpInfos(MctpInfos& mctpInfos)
+{
+ // Find all implementations of the MCTP Endpoint interface
+ pldm::utils::GetSubTreeResponse mapperResponse;
try
{
- objects = pldm::utils::DBusHandler::getManagedObj(MCTPService,
- MCTPPath);
+ mapperResponse = pldm::utils::DBusHandler().getSubtree(
+ MCTPPath, 0, std::vector<std::string>({MCTPInterface}));
}
- catch (const std::exception& e)
+ catch (const sdbusplus::exception_t& e)
{
- error("Failed to call the D-Bus Method: {ERROR}", "ERROR", e);
+ error("getSubtree call failed with, {ERROR} {PATH} {INTERFACE}",
+ "ERROR", e, "PATH", MCTPPath, "INTERFACE", MCTPInterface);
return;
}
- std::vector<mctp_eid_t> eids;
-
- for (const auto& [objectPath, interfaces] : objects)
+ for (const auto& [path, services] : mapperResponse)
{
- for (const auto& [intfName, properties] : interfaces)
+ for (const auto& serviceIter : services)
{
- if (intfName == mctpEndpointIntfName)
+ const std::string& service = serviceIter.first;
+ try
{
- if (properties.contains("EID") &&
+ auto properties =
+ pldm::utils::DBusHandler().getDbusPropertiesVariant(
+ service.c_str(), path.c_str(), MCTPInterface);
+
+ if (properties.contains("NetworkId") &&
+ properties.contains("EID") &&
properties.contains("SupportedMessageTypes"))
{
+ auto networkId =
+ std::get<NetworkId>(properties.at("NetworkId"));
auto eid = std::get<mctp_eid_t>(properties.at("EID"));
auto types = std::get<std::vector<uint8_t>>(
properties.at("SupportedMessageTypes"));
if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
types.end())
{
- eids.emplace_back(eid);
+ info("Adding Endpoint networkId={NETWORK} EID={EID}",
+ "NETWORK", networkId, "EID", unsigned(eid));
+ mctpInfos.emplace_back(
+ MctpInfo(eid, emptyUUID, "", networkId));
}
}
}
+ catch (const sdbusplus::exception_t& e)
+ {
+ error(
+ "Error reading MCTP Endpoint property, {ERROR} {SERVICE} {PATH}",
+ "ERROR", e, "SERVICE", service, "PATH", path);
+ return;
+ }
}
}
-
- if (eids.size() && fwManager)
- {
- fwManager->handleMCTPEndpoints(eids);
- }
}
-void MctpDiscovery::dicoverEndpoints(sdbusplus::message_t& msg)
+void MctpDiscovery::getAddedMctpInfos(sdbusplus::message_t& msg,
+ MctpInfos& mctpInfos)
{
- constexpr std::string_view mctpEndpointIntfName{
- "xyz.openbmc_project.MCTP.Endpoint"};
- std::vector<mctp_eid_t> eids;
+ using ObjectPath = sdbusplus::message::object_path;
+ ObjectPath objPath;
+ using Property = std::string;
+ using PropertyMap = std::map<Property, dbus::Value>;
+ std::map<std::string, PropertyMap> interfaces;
- sdbusplus::message::object_path objPath;
- std::map<std::string, std::map<std::string, dbus::Value>> interfaces;
- msg.read(objPath, interfaces);
+ try
+ {
+ msg.read(objPath, interfaces);
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ error("Error reading MCTP Endpoint addedInterace message, {ERROR}",
+ "ERROR", e);
+ return;
+ }
for (const auto& [intfName, properties] : interfaces)
{
- if (intfName == mctpEndpointIntfName)
+ if (intfName == MCTPInterface)
{
- if (properties.contains("EID") &&
+ if (properties.contains("NetworkId") &&
+ properties.contains("EID") &&
properties.contains("SupportedMessageTypes"))
{
+ auto networkId =
+ std::get<NetworkId>(properties.at("NetworkId"));
auto eid = std::get<mctp_eid_t>(properties.at("EID"));
auto types = std::get<std::vector<uint8_t>>(
properties.at("SupportedMessageTypes"));
if (std::find(types.begin(), types.end(), mctpTypePLDM) !=
types.end())
{
- eids.emplace_back(eid);
+ info("Adding Endpoint networkId={NETWORK} EID={EID}",
+ "NETWORK", networkId, "EID", unsigned(eid));
+ mctpInfos.emplace_back(
+ MctpInfo(eid, emptyUUID, "", networkId));
}
}
}
}
+}
- if (eids.size() && fwManager)
+void MctpDiscovery::addToExistingMctpInfos(const MctpInfos& addedInfos)
+{
+ for (const auto& mctpInfo : addedInfos)
{
- fwManager->handleMCTPEndpoints(eids);
+ if (std::find(existingMctpInfos.begin(), existingMctpInfos.end(),
+ mctpInfo) == existingMctpInfos.end())
+ {
+ existingMctpInfos.emplace_back(mctpInfo);
+ }
+ }
+}
+
+void MctpDiscovery::removeFromExistingMctpInfos(MctpInfos& mctpInfos,
+ MctpInfos& removedInfos)
+{
+ for (const auto& mctpInfo : existingMctpInfos)
+ {
+ if (std::find(mctpInfos.begin(), mctpInfos.end(), mctpInfo) ==
+ mctpInfos.end())
+ {
+ removedInfos.emplace_back(mctpInfo);
+ }
+ }
+ for (const auto& mctpInfo : removedInfos)
+ {
+ info("Removing Endpoint networkId={NETWORK} EID={EID}", "NETWORK",
+ std::get<3>(mctpInfo), "EID", unsigned(std::get<0>(mctpInfo)));
+ existingMctpInfos.erase(std::remove(existingMctpInfos.begin(),
+ existingMctpInfos.end(), mctpInfo),
+ existingMctpInfos.end());
+ }
+}
+
+void MctpDiscovery::discoverEndpoints(sdbusplus::message_t& msg)
+{
+ MctpInfos addedInfos;
+ getAddedMctpInfos(msg, addedInfos);
+ addToExistingMctpInfos(addedInfos);
+ handleMctpEndpoints(addedInfos);
+}
+
+void MctpDiscovery::removeEndpoints(sdbusplus::message_t&)
+{
+ MctpInfos mctpInfos;
+ MctpInfos removedInfos;
+ getMctpInfos(mctpInfos);
+ removeFromExistingMctpInfos(mctpInfos, removedInfos);
+ handleRemovedMctpEndpoints(removedInfos);
+}
+
+void MctpDiscovery::handleMctpEndpoints(const MctpInfos& mctpInfos)
+{
+ for (const auto& handler : handlers)
+ {
+ if (handler)
+ {
+ handler->handleMctpEndpoints(mctpInfos);
+ }
+ }
+}
+
+void MctpDiscovery::handleRemovedMctpEndpoints(const MctpInfos& mctpInfos)
+{
+ for (const auto& handler : handlers)
+ {
+ if (handler)
+ {
+ handler->handleRemovedMctpEndpoints(mctpInfos);
+ }
}
}
diff --git a/requester/mctp_endpoint_discovery.hpp b/requester/mctp_endpoint_discovery.hpp
index de3a6bd..675b6c7 100644
--- a/requester/mctp_endpoint_discovery.hpp
+++ b/requester/mctp_endpoint_discovery.hpp
@@ -1,14 +1,36 @@
#pragma once
-#include "fw-update/manager.hpp"
+#include "common/types.hpp"
+#include "common/utils.hpp"
+
+#include <libpldm/pldm.h>
#include <sdbusplus/bus/match.hpp>
+#include <filesystem>
+#include <initializer_list>
+#include <vector>
+
namespace pldm
{
-constexpr auto MCTPService = "xyz.openbmc_project.MCTP";
-constexpr auto MCTPPath = "/xyz/openbmc_project/mctp";
+const std::string emptyUUID = "00000000-0000-0000-0000-000000000000";
+constexpr const char* MCTPService = "xyz.openbmc_project.MCTP";
+constexpr const char* MCTPInterface = "xyz.openbmc_project.MCTP.Endpoint";
+constexpr const char* MCTPPath = "/xyz/openbmc_project/mctp";
+
+/** @class MctpDiscoveryHandlerIntf
+ *
+ * This abstract class defines the APIs for MctpDiscovery class has common
+ * interface to execute function from different Manager Classes
+ */
+class MctpDiscoveryHandlerIntf
+{
+ public:
+ virtual void handleMctpEndpoints(const MctpInfos& mctpInfos) = 0;
+ virtual void handleRemovedMctpEndpoints(const MctpInfos& mctpInfos) = 0;
+ virtual ~MctpDiscoveryHandlerIntf() {}
+};
class MctpDiscovery
{
@@ -24,26 +46,85 @@
* MCTP enabled devices
*
* @param[in] bus - reference to systemd bus
- * @param[in] fwManager - pointer to the firmware manager
+ * @param[in] list - initializer list to the MctpDiscoveryHandlerIntf
*/
- explicit MctpDiscovery(sdbusplus::bus_t& bus,
- fw_update::Manager* fwManager);
+ explicit MctpDiscovery(
+ sdbusplus::bus::bus& bus,
+ std::initializer_list<MctpDiscoveryHandlerIntf*> list);
- private:
/** @brief reference to the systemd bus */
sdbusplus::bus_t& bus;
- fw_update::Manager* fwManager;
-
/** @brief Used to watch for new MCTP endpoints */
- sdbusplus::bus::match_t mctpEndpointSignal;
+ sdbusplus::bus::match_t mctpEndpointAddedSignal;
- void dicoverEndpoints(sdbusplus::message_t& msg);
+ /** @brief Used to watch for the removed MCTP endpoints */
+ sdbusplus::bus::match_t mctpEndpointRemovedSignal;
+ /** @brief List of handlers need to notify when new MCTP
+ * Endpoint is Added/Removed */
+ std::vector<MctpDiscoveryHandlerIntf*> handlers;
+
+ /** @brief The existing MCTP endpoints */
+ MctpInfos existingMctpInfos;
+
+ /** @brief Callback function when MCTP endpoints addedInterface
+ * D-Bus signal raised.
+ *
+ * @param[in] msg - Data associated with subscribed signal
+ */
+ void discoverEndpoints(sdbusplus::message_t& msg);
+
+ /** @brief Callback function when MCTP endpoint removedInterface
+ * D-Bus signal raised.
+ *
+ * @param[in] msg - Data associated with subscribed signal
+ */
+ void removeEndpoints(sdbusplus::message_t& msg);
+
+ /** @brief Helper function to invoke registered handlers for
+ * the added MCTP endpoints
+ *
+ * @param[in] mctpInfos - information of discovered MCTP endpoints
+ */
+ void handleMctpEndpoints(const MctpInfos& mctpInfos);
+
+ /** @brief Helper function to invoke registered handlers for
+ * the removed MCTP endpoints
+ *
+ * @param[in] mctpInfos - information of removed MCTP endpoints
+ */
+ void handleRemovedMctpEndpoints(const MctpInfos& mctpInfos);
+
+ /** @brief Get list of MctpInfos in MCTP control interface.
+ *
+ * @param[in] mctpInfos - information of discovered MCTP endpoints
+ */
+ void getMctpInfos(MctpInfos& mctpInfos);
+
+ /** @brief Get list of new MctpInfos in addedInterace D-Bus signal message.
+ *
+ * @param[in] msg - addedInterace D-Bus signal message
+ * @param[in] mctpInfos - information of added MCTP endpoints
+ */
+ void getAddedMctpInfos(sdbusplus::message_t& msg, MctpInfos& mctpInfos);
+
+ /** @brief Add new MctpInfos to existingMctpInfos.
+ *
+ * @param[in] mctpInfos - information of new MCTP endpoints
+ */
+ void addToExistingMctpInfos(const MctpInfos& mctpInfos);
+
+ /** @brief Erase the removed MCTP endpoint from existingMctpInfos.
+ *
+ * @param[in] mctpInfos - the remaining MCTP endpoints
+ * @param[out] removedInfos - the removed MCTP endpoints
+ */
+ void removeFromExistingMctpInfos(MctpInfos& mctpInfos,
+ MctpInfos& removedInfos);
+
+ private:
static constexpr uint8_t mctpTypePLDM = 1;
-
- static constexpr std::string_view mctpEndpointIntfName{
- "xyz.openbmc_project.MCTP.Endpoint"};
};
} // namespace pldm
diff --git a/requester/test/mctp_endpoint_discovery_test.cpp b/requester/test/mctp_endpoint_discovery_test.cpp
new file mode 100644
index 0000000..df390a0
--- /dev/null
+++ b/requester/test/mctp_endpoint_discovery_test.cpp
@@ -0,0 +1,137 @@
+#include "config.h"
+
+#include "common/utils.hpp"
+#include "requester/test/mock_mctp_discovery_handler_intf.hpp"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using ::testing::_;
+
+TEST(MctpEndpointDiscoveryTest, SingleHandleMctpEndpoint)
+{
+ auto& bus = pldm::utils::DBusHandler::getBus();
+ pldm::MockManager manager;
+
+ EXPECT_CALL(manager, handleMctpEndpoints(_)).Times(1);
+
+ auto mctpDiscoveryHandler = std::make_unique<pldm::MctpDiscovery>(
+ bus, std::initializer_list<pldm::MctpDiscoveryHandlerIntf*>{&manager});
+ mctpDiscoveryHandler = nullptr;
+}
+
+TEST(MctpEndpointDiscoveryTest, MultipleHandleMctpEndpoints)
+{
+ auto& bus = pldm::utils::DBusHandler::getBus();
+ pldm::MockManager manager1;
+ pldm::MockManager manager2;
+
+ EXPECT_CALL(manager1, handleMctpEndpoints(_)).Times(1);
+ EXPECT_CALL(manager2, handleMctpEndpoints(_)).Times(1);
+
+ auto mctpDiscoveryHandler = std::make_unique<pldm::MctpDiscovery>(
+ bus, std::initializer_list<pldm::MctpDiscoveryHandlerIntf*>{&manager1,
+ &manager2});
+ mctpDiscoveryHandler = nullptr;
+}
+
+TEST(MctpEndpointDiscoveryTest, goodGetMctpInfos)
+{
+ auto& bus = pldm::utils::DBusHandler::getBus();
+ pldm::MockManager manager;
+ pldm::MctpInfos mctpInfos;
+
+ auto mctpDiscoveryHandler = std::make_unique<pldm::MctpDiscovery>(
+ bus, std::initializer_list<pldm::MctpDiscoveryHandlerIntf*>{&manager});
+ mctpDiscoveryHandler->getMctpInfos(mctpInfos);
+ EXPECT_EQ(mctpInfos.size(), 0);
+}
+
+TEST(MctpEndpointDiscoveryTest, goodAddToExistingMctpInfos)
+{
+ auto& bus = pldm::utils::DBusHandler::getBus();
+ pldm::MockManager manager;
+ const pldm::MctpInfos& mctpInfos = {
+ pldm::MctpInfo(11, pldm::emptyUUID, "", 1),
+ pldm::MctpInfo(12, pldm::emptyUUID, "abc", 1)};
+
+ auto mctpDiscoveryHandler = std::make_unique<pldm::MctpDiscovery>(
+ bus, std::initializer_list<pldm::MctpDiscoveryHandlerIntf*>{&manager});
+ mctpDiscoveryHandler->addToExistingMctpInfos(mctpInfos);
+ EXPECT_EQ(mctpDiscoveryHandler->existingMctpInfos.size(), 2);
+ pldm::MctpInfo mctpInfo = mctpDiscoveryHandler->existingMctpInfos.back();
+ EXPECT_EQ(std::get<0>(mctpInfo), 12);
+ EXPECT_EQ(std::get<2>(mctpInfo), "abc");
+ EXPECT_EQ(std::get<3>(mctpInfo), 1);
+}
+
+TEST(MctpEndpointDiscoveryTest, badAddToExistingMctpInfos)
+{
+ auto& bus = pldm::utils::DBusHandler::getBus();
+ pldm::MockManager manager;
+ const pldm::MctpInfos& mctpInfos = {
+ pldm::MctpInfo(11, pldm::emptyUUID, "", 1)};
+
+ auto mctpDiscoveryHandler = std::make_unique<pldm::MctpDiscovery>(
+ bus, std::initializer_list<pldm::MctpDiscoveryHandlerIntf*>{&manager});
+ mctpDiscoveryHandler->addToExistingMctpInfos(mctpInfos);
+ EXPECT_NE(mctpDiscoveryHandler->existingMctpInfos.size(), 2);
+}
+
+TEST(MctpEndpointDiscoveryTest, goodRemoveFromExistingMctpInfos)
+{
+ auto& bus = pldm::utils::DBusHandler::getBus();
+ pldm::MockManager manager;
+ const pldm::MctpInfos& mctpInfos = {
+ pldm::MctpInfo(11, pldm::emptyUUID, "def", 2),
+ pldm::MctpInfo(12, pldm::emptyUUID, "abc", 1)};
+
+ auto mctpDiscoveryHandler = std::make_unique<pldm::MctpDiscovery>(
+ bus, std::initializer_list<pldm::MctpDiscoveryHandlerIntf*>{&manager});
+ mctpDiscoveryHandler->addToExistingMctpInfos(mctpInfos);
+ EXPECT_EQ(mctpDiscoveryHandler->existingMctpInfos.size(), 2);
+ pldm::MctpInfo mctpInfo = mctpDiscoveryHandler->existingMctpInfos.back();
+ EXPECT_EQ(std::get<0>(mctpInfo), 12);
+ EXPECT_EQ(std::get<2>(mctpInfo), "abc");
+ EXPECT_EQ(std::get<3>(mctpInfo), 1);
+ pldm::MctpInfos removedInfos;
+ pldm::MctpInfos remainMctpInfos;
+ remainMctpInfos.emplace_back(pldm::MctpInfo(12, pldm::emptyUUID, "abc", 1));
+
+ mctpDiscoveryHandler->removeFromExistingMctpInfos(remainMctpInfos,
+ removedInfos);
+ EXPECT_EQ(mctpDiscoveryHandler->existingMctpInfos.size(), 1);
+ mctpInfo = mctpDiscoveryHandler->existingMctpInfos.back();
+ EXPECT_EQ(std::get<0>(mctpInfo), 12);
+ EXPECT_EQ(std::get<2>(mctpInfo), "abc");
+ EXPECT_EQ(std::get<3>(mctpInfo), 1);
+ EXPECT_EQ(removedInfos.size(), 1);
+ mctpInfo = removedInfos.back();
+ EXPECT_EQ(std::get<0>(mctpInfo), 11);
+ EXPECT_EQ(std::get<2>(mctpInfo), "def");
+ EXPECT_EQ(std::get<3>(mctpInfo), 2);
+}
+
+TEST(MctpEndpointDiscoveryTest, goodRemoveEndpoints)
+{
+ auto& bus = pldm::utils::DBusHandler::getBus();
+ pldm::MockManager manager;
+ const pldm::MctpInfos& mctpInfos = {
+ pldm::MctpInfo(11, pldm::emptyUUID, "def", 2),
+ pldm::MctpInfo(12, pldm::emptyUUID, "abc", 1)};
+
+ auto mctpDiscoveryHandler = std::make_unique<pldm::MctpDiscovery>(
+ bus, std::initializer_list<pldm::MctpDiscoveryHandlerIntf*>{&manager});
+ mctpDiscoveryHandler->addToExistingMctpInfos(mctpInfos);
+ EXPECT_EQ(mctpDiscoveryHandler->existingMctpInfos.size(), 2);
+ pldm::MctpInfo mctpInfo = mctpDiscoveryHandler->existingMctpInfos.back();
+ EXPECT_EQ(std::get<0>(mctpInfo), 12);
+ EXPECT_EQ(std::get<2>(mctpInfo), "abc");
+ EXPECT_EQ(std::get<3>(mctpInfo), 1);
+ sdbusplus::message_t msg = sdbusplus::bus::new_default().new_method_call(
+ "xyz.openbmc_project.sdbusplus.test.Object",
+ "/xyz/openbmc_project/sdbusplus/test/object",
+ "xyz.openbmc_project.sdbusplus.test.Object", "Unused");
+ mctpDiscoveryHandler->removeEndpoints(msg);
+ EXPECT_EQ(mctpDiscoveryHandler->existingMctpInfos.size(), 0);
+}
diff --git a/requester/test/meson.build b/requester/test/meson.build
index 29f4303..a08a990 100644
--- a/requester/test/meson.build
+++ b/requester/test/meson.build
@@ -1,6 +1,13 @@
+test_src = declare_dependency(
+ sources: [
+ '../mctp_endpoint_discovery.cpp',
+ '../../common/utils.cpp',
+ ])
+
tests = [
'handler_test',
'request_test',
+ 'mctp_endpoint_discovery_test',
]
foreach t : tests
@@ -16,6 +23,7 @@
phosphor_logging_dep,
sdbusplus,
sdeventplus,
+ test_src,
]),
workdir: meson.current_source_dir())
endforeach
diff --git a/requester/test/mock_mctp_discovery_handler_intf.hpp b/requester/test/mock_mctp_discovery_handler_intf.hpp
new file mode 100644
index 0000000..8aada96
--- /dev/null
+++ b/requester/test/mock_mctp_discovery_handler_intf.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "requester/mctp_endpoint_discovery.hpp"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace pldm
+{
+
+class MockManager : public pldm::MctpDiscoveryHandlerIntf
+{
+ public:
+ MOCK_METHOD(void, handleMctpEndpoints, (const MctpInfos& mctpInfos),
+ (override));
+ MOCK_METHOD(void, handleRemovedMctpEndpoints, (const MctpInfos& mctpInfos),
+ (override));
+};
+
+} // namespace pldm