summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Geissler <geissonator@yahoo.com>2019-02-04 14:01:49 -0600
committerMatt Spinler <spinler@us.ibm.com>2019-04-05 15:05:32 +0000
commita80a3af035d4fe989acd81c45aee4acf8c3d998a (patch)
tree3742ccd1df1681aad50fe1b71a71dc81946f3333
parent67e5a420756d7ae96be91721138054be9d897a7b (diff)
downloadphosphor-objmgr-a80a3af035d4fe989acd81c45aee4acf8c3d998a.tar.gz
phosphor-objmgr-a80a3af035d4fe989acd81c45aee4acf8c3d998a.zip
unit-test: Create initial associations file
Make interface more unit testable by moving to separate file and documenting it. Change-Id: Ia27f33d706c62a0011790ec94185dd6be3922f21 Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
-rw-r--r--Makefile.am3
-rw-r--r--src/associations.cpp76
-rw-r--r--src/associations.hpp58
-rw-r--r--src/main.cpp109
4 files changed, 137 insertions, 109 deletions
diff --git a/Makefile.am b/Makefile.am
index 62fe99e..668a529 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -26,7 +26,8 @@ libmapper_la_SOURCES = libmapper/mapper.c
libmapper_la_LDFLAGS = $(SYSTEMD_LIBS) -version-info 1:0:0 -shared
libmapper_la_CFLAGS = $(SYSTEMD_CFLAGS)
-mapperx_SOURCES = src/main.cpp src/argument.cpp src/processing.cpp
+mapperx_SOURCES = src/main.cpp src/argument.cpp src/processing.cpp \
+ src/associations.cpp
mapperx_LDFLAGS = $(SDBUSPLUS_LIBS) -pthread -ltinyxml2
mapperx_CXXFLAGS = $(SYSTEMD_CFLAGS) -DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_ERROR_CODE_HEADER_ONLY -DBOOST_ALL_NO_LIB
diff --git a/src/associations.cpp b/src/associations.cpp
new file mode 100644
index 0000000..3ae7db4
--- /dev/null
+++ b/src/associations.cpp
@@ -0,0 +1,76 @@
+#include "associations.hpp"
+
+void removeAssociation(const std::string& sourcePath, const std::string& owner,
+ sdbusplus::asio::object_server& server,
+ AssociationOwnersType& assocOwners,
+ AssociationInterfaces& assocInterfaces)
+{
+ // Use associationOwners to find the association paths and endpoints
+ // that the passed in object path and service own. Remove all of
+ // these endpoints from the actual association D-Bus objects, and if
+ // the endpoints property is then empty, the whole association object
+ // can be removed. Note there can be multiple services that own an
+ // association, and also that sourcePath is the path of the object
+ // that contains the org.openbmc.Associations interface and not the
+ // association path itself.
+
+ // Find the services that have associations for this object path
+ auto owners = assocOwners.find(sourcePath);
+ if (owners == assocOwners.end())
+ {
+ return;
+ }
+
+ // Find the association paths and endpoints owned by this object
+ // path for this service.
+ auto assocs = owners->second.find(owner);
+ if (assocs == owners->second.end())
+ {
+ return;
+ }
+
+ for (const auto& [assocPath, endpointsToRemove] : assocs->second)
+ {
+ // Get the association D-Bus object for this assocPath
+ auto target = assocInterfaces.find(assocPath);
+ if (target == assocInterfaces.end())
+ {
+ continue;
+ }
+
+ // Remove the entries in the endpoints D-Bus property for this
+ // path/owner/association-path.
+ auto& existingEndpoints = std::get<endpointsPos>(target->second);
+ for (const auto& endpointToRemove : endpointsToRemove)
+ {
+ auto e = std::find(existingEndpoints.begin(),
+ existingEndpoints.end(), endpointToRemove);
+
+ if (e != existingEndpoints.end())
+ {
+ existingEndpoints.erase(e);
+ }
+ }
+
+ // Remove the association from D-Bus if there are no more endpoints,
+ // otherwise just update the endpoints property.
+ if (existingEndpoints.empty())
+ {
+ server.remove_interface(std::get<ifacePos>(target->second));
+ std::get<ifacePos>(target->second) = nullptr;
+ std::get<endpointsPos>(target->second).clear();
+ }
+ else
+ {
+ std::get<ifacePos>(target->second)
+ ->set_property("endpoints", existingEndpoints);
+ }
+ }
+
+ // Remove the associationOwners entries for this owning path/service.
+ owners->second.erase(assocs);
+ if (owners->second.empty())
+ {
+ assocOwners.erase(owners);
+ }
+}
diff --git a/src/associations.hpp b/src/associations.hpp
new file mode 100644
index 0000000..41df157
--- /dev/null
+++ b/src/associations.hpp
@@ -0,0 +1,58 @@
+#pragma once
+
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <memory>
+#include <sdbusplus/asio/object_server.hpp>
+#include <string>
+#include <vector>
+
+// Associations and some metadata are stored in associationInterfaces.
+// The fields are:
+// * ifacePos - holds the D-Bus interface object
+// * endpointsPos - holds the endpoints array that shadows the property
+static constexpr auto ifacePos = 0;
+static constexpr auto endpointsPos = 1;
+using Endpoints = std::vector<std::string>;
+
+using AssociationInterfaces = boost::container::flat_map<
+ std::string,
+ std::tuple<std::shared_ptr<sdbusplus::asio::dbus_interface>, Endpoints>>;
+
+// The associationOwners map contains information about creators of
+// associations, so that when a org.openbmc.Association interface is
+// removed or its 'associations' property is changed, the mapper owned
+// association objects can be correctly handled. It is a map of the
+// object path of the org.openbmc.Association owner to a map of the
+// service the path is owned by, to a map of the association objects to
+// their endpoint paths:
+// map[ownerPath : map[service : map[assocPath : [endpoint paths]]]
+// For example:
+// [/logging/entry/1 :
+// [xyz.openbmc_project.Logging :
+// [/logging/entry/1/callout : [/system/cpu0],
+// /system/cpu0/fault : [/logging/entry/1]]]]
+
+using AssociationPaths =
+ boost::container::flat_map<std::string,
+ boost::container::flat_set<std::string>>;
+
+using AssociationOwnersType = boost::container::flat_map<
+ std::string, boost::container::flat_map<std::string, AssociationPaths>>;
+
+/** @brief Remove input association
+ *
+ * @param[in] sourcePath - Path of the object that contains the
+ * org.openbmc.Associations
+ * @param[in] owner - The Dbus service having its associations
+ * removed
+ * @param[in,out] server - sdbus system object
+ * @param[in,out] assocOwners - Owners of associations
+ * @param[in,out] assocInterfaces - Associations endpoints
+ *
+ * @return Void, server, assocOwners, and assocInterfaces updated if needed
+ */
+void removeAssociation(const std::string& sourcePath, const std::string& owner,
+ sdbusplus::asio::object_server& server,
+ AssociationOwnersType& assocOwners,
+ AssociationInterfaces& assocInterfaces);
diff --git a/src/main.cpp b/src/main.cpp
index 801d910..e96ffe3 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,3 +1,4 @@
+#include "associations.hpp"
#include "processing.hpp"
#include "src/argument.hpp"
@@ -29,40 +30,7 @@ using interface_map_type = boost::container::flat_map<
using Association = std::tuple<std::string, std::string, std::string>;
-// Associations and some metadata are stored in associationInterfaces.
-// The fields are:
-// * ifacePos - holds the D-Bus interface object
-// * endpointsPos - holds the endpoints array that shadows the property
-static constexpr auto ifacePos = 0;
-static constexpr auto endpointsPos = 1;
-using Endpoints = std::vector<std::string>;
-using AssociationInterfaces = boost::container::flat_map<
- std::string,
- std::tuple<std::shared_ptr<sdbusplus::asio::dbus_interface>, Endpoints>>;
-
AssociationInterfaces associationInterfaces;
-
-// The associationOwners map contains information about creators of
-// associations, so that when a org.openbmc.Association interface is
-// removed or its 'associations' property is changed, the mapper owned
-// association objects can be correctly handled. It is a map of the
-// object path of the org.openbmc.Association owner to a map of the
-// service the path is owned by, to a map of the association objects to
-// their endpoint paths:
-// map[ownerPath : map[service : map[assocPath : [endpoint paths]]]
-// For example:
-// [/logging/entry/1 :
-// [xyz.openbmc_project.Logging :
-// [/logging/entry/1/callout : [/system/cpu0],
-// /system/cpu0/fault : [/logging/entry/1]]]]
-
-using AssociationPaths =
- boost::container::flat_map<std::string,
- boost::container::flat_set<std::string>>;
-
-using AssociationOwnersType = boost::container::flat_map<
- std::string, boost::container::flat_map<std::string, AssociationPaths>>;
-
AssociationOwnersType associationOwners;
static WhiteBlackList service_whitelist;
@@ -365,81 +333,6 @@ void associationChanged(sdbusplus::asio::object_server& objectServer,
}
}
-void removeAssociation(const std::string& sourcePath, const std::string& owner,
- sdbusplus::asio::object_server& server,
- AssociationOwnersType& assocOwners,
- AssociationInterfaces& assocInterfaces)
-{
- // Use associationOwners to find the association paths and endpoints
- // that the passed in object path and service own. Remove all of
- // these endpoints from the actual association D-Bus objects, and if
- // the endpoints property is then empty, the whole association object
- // can be removed. Note there can be multiple services that own an
- // association, and also that sourcePath is the path of the object
- // that contains the org.openbmc.Associations interface and not the
- // association path itself.
-
- // Find the services that have associations for this object path
- auto owners = assocOwners.find(sourcePath);
- if (owners == assocOwners.end())
- {
- return;
- }
-
- // Find the association paths and endpoints owned by this object
- // path for this service.
- auto assocs = owners->second.find(owner);
- if (assocs == owners->second.end())
- {
- return;
- }
-
- for (const auto& [assocPath, endpointsToRemove] : assocs->second)
- {
- // Get the association D-Bus object for this assocPath
- auto target = assocInterfaces.find(assocPath);
- if (target == assocInterfaces.end())
- {
- continue;
- }
-
- // Remove the entries in the endpoints D-Bus property for this
- // path/owner/association-path.
- auto& existingEndpoints = std::get<endpointsPos>(target->second);
- for (const auto& endpointToRemove : endpointsToRemove)
- {
- auto e = std::find(existingEndpoints.begin(),
- existingEndpoints.end(), endpointToRemove);
-
- if (e != existingEndpoints.end())
- {
- existingEndpoints.erase(e);
- }
- }
-
- // Remove the association from D-Bus if there are no more endpoints,
- // otherwise just update the endpoints property.
- if (existingEndpoints.empty())
- {
- server.remove_interface(std::get<ifacePos>(target->second));
- std::get<ifacePos>(target->second) = nullptr;
- std::get<endpointsPos>(target->second).clear();
- }
- else
- {
- std::get<ifacePos>(target->second)
- ->set_property("endpoints", existingEndpoints);
- }
- }
-
- // Remove the associationOwners entries for this owning path/service.
- owners->second.erase(assocs);
- if (owners->second.empty())
- {
- associationOwners.erase(owners);
- }
-}
-
void do_associations(sdbusplus::asio::connection* system_bus,
sdbusplus::asio::object_server& objectServer,
const std::string& processName, const std::string& path)
OpenPOWER on IntegriCloud