blob: 4e1b2bdcf454d51ef3be9d1f5252370368571c42 [file] [log] [blame]
Andrew Geissler271b7dd2019-02-05 11:23:30 -06001#include "src/associations.hpp"
2
Andrew Geisslerb04f0332019-02-08 14:07:56 -06003#include "src/test/util/asio_server_class.hpp"
Andrew Geisslerbb7b5922019-02-08 14:16:48 -06004#include "src/test/util/association_objects.hpp"
Andrew Geissler491f9ac2019-02-22 15:23:33 -06005#include "src/test/util/debug_output.hpp"
Andrew Geisslerb04f0332019-02-08 14:07:56 -06006
Andrew Geissler271b7dd2019-02-05 11:23:30 -06007#include <sdbusplus/asio/connection.hpp>
8#include <sdbusplus/asio/object_server.hpp>
9
10#include <gtest/gtest.h>
11
Andrew Geisslerb04f0332019-02-08 14:07:56 -060012class TestAssociations : public AsioServerClassTest
Brad Bishop23520882022-05-26 21:39:53 -040013{};
Andrew Geisslerb04f0332019-02-08 14:07:56 -060014sdbusplus::asio::object_server* TestAssociations::AsioServerClassTest::server =
15 nullptr;
Andrew Geissler271b7dd2019-02-05 11:23:30 -060016
Andrew Geissler271b7dd2019-02-05 11:23:30 -060017// Verify call when path is not in associated owners
18TEST_F(TestAssociations, SourcePathNotInAssociations)
19{
20 EXPECT_NE(nullptr, server);
21 std::string sourcePath = "/xyz/openbmc_project/no/association";
Matt Spinlere2359fb2019-04-05 14:11:33 -050022 AssociationMaps assocMaps;
Andrew Geissler271b7dd2019-02-05 11:23:30 -060023
Matt Spinlere2359fb2019-04-05 14:11:33 -050024 removeAssociation(sourcePath, DEFAULT_DBUS_SVC, *server, assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060025}
26
27// Verify call when owner is not in associated owners
28TEST_F(TestAssociations, OwnerNotInAssociations)
29{
Matt Spinlere2359fb2019-04-05 14:11:33 -050030 AssociationMaps assocMaps;
31 assocMaps.owners = createDefaultOwnerAssociation();
Andrew Geissler271b7dd2019-02-05 11:23:30 -060032
33 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
Matt Spinlere2359fb2019-04-05 14:11:33 -050034 assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060035}
36
37// Verify call when path is not in associated interfaces
38TEST_F(TestAssociations, PathNotInAssocInterfaces)
39{
Matt Spinlere2359fb2019-04-05 14:11:33 -050040 AssociationMaps assocMaps;
Andrew Geissler271b7dd2019-02-05 11:23:30 -060041
Matt Spinlere2359fb2019-04-05 14:11:33 -050042 assocMaps.owners = createDefaultOwnerAssociation();
Andrew Geissler271b7dd2019-02-05 11:23:30 -060043
44 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
Matt Spinlere2359fb2019-04-05 14:11:33 -050045 assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060046
Matt Spinlere2359fb2019-04-05 14:11:33 -050047 EXPECT_TRUE(assocMaps.owners.empty());
Andrew Geissler271b7dd2019-02-05 11:23:30 -060048}
49
50// Verify call when path is in associated interfaces
51TEST_F(TestAssociations, PathIsInAssociatedInterfaces)
52{
53 // Build up these objects so that an associated interface will match
54 // with the associated owner being removed
Matt Spinlere2359fb2019-04-05 14:11:33 -050055 AssociationMaps assocMaps;
56 assocMaps.owners = createDefaultOwnerAssociation();
57 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060058
59 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
Matt Spinlere2359fb2019-04-05 14:11:33 -050060 assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060061
62 // Verify owner association was deleted
Matt Spinlere2359fb2019-04-05 14:11:33 -050063 EXPECT_TRUE(assocMaps.owners.empty());
Andrew Geissler271b7dd2019-02-05 11:23:30 -060064
65 // Verify endpoint was deleted from interface association
66 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -050067 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060068 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -050069 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060070 EXPECT_EQ(intfEndpoints.size(), 0);
71}
72
73// Verify call when path is in associated interfaces, with extra endpoints
74TEST_F(TestAssociations, PathIsInAssociatedInterfacesExtraEndpoints)
75{
76 // Build up these objects so that an associated interface will match
77 // with the associated owner being removed
Matt Spinlere2359fb2019-04-05 14:11:33 -050078 AssociationMaps assocMaps;
79 assocMaps.owners = createDefaultOwnerAssociation();
80 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060081
82 // Add another endpoint to the assoc interfaces
Matt Spinlere2359fb2019-04-05 14:11:33 -050083 addEndpointToInterfaceAssociation(assocMaps.ifaces);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060084
85 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
Matt Spinlere2359fb2019-04-05 14:11:33 -050086 assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060087
88 // Verify owner association was deleted
Matt Spinlere2359fb2019-04-05 14:11:33 -050089 EXPECT_TRUE(assocMaps.owners.empty());
Andrew Geissler271b7dd2019-02-05 11:23:30 -060090
91 // Verify all endpoints are deleted since source path was deleted
92 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -050093 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060094 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -050095 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060096 EXPECT_EQ(intfEndpoints.size(), 0);
97}
Andrew Geisslere4ab6c92019-02-21 15:07:27 -060098
99// Verify no associations or endpoints removed when the change is identical
100TEST_F(TestAssociations, checkAssociationEndpointRemovesNoEpRemove)
101{
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600102 AssociationPaths newAssocPaths = {
103 {DEFAULT_FWD_PATH, {DEFAULT_ENDPOINT}},
104 {DEFAULT_REV_PATH, {DEFAULT_SOURCE_PATH}}};
105
Matt Spinlere2359fb2019-04-05 14:11:33 -0500106 AssociationMaps assocMaps;
107 assocMaps.owners = createDefaultOwnerAssociation();
108 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600109
110 checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500111 newAssocPaths, *server, assocMaps);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600112
113 // Verify endpoints were not deleted because they matche with what was
114 // in the original
115 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500116 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600117 EXPECT_EQ(intfEndpoints.size(), 1);
Matt Spinlere2359fb2019-04-05 14:11:33 -0500118 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600119 EXPECT_EQ(intfEndpoints.size(), 1);
120}
121
122// Verify endpoint is removed when assoc path is different
123TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveApDiff)
124{
125 AssociationPaths newAssocPaths = {{"/different/path", {DEFAULT_ENDPOINT}}};
126
Matt Spinlere2359fb2019-04-05 14:11:33 -0500127 AssociationMaps assocMaps;
128 assocMaps.owners = createDefaultOwnerAssociation();
129 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600130
131 checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500132 newAssocPaths, *server, assocMaps);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600133
134 // Verify initial endpoints were deleted because the new path
135 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500136 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600137 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -0500138 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600139 EXPECT_EQ(intfEndpoints.size(), 0);
140}
141
142// Verify endpoint is removed when endpoint is different
143TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveEpChanged)
144{
145 AssociationPaths newAssocPaths = {
146 {DEFAULT_FWD_PATH, {DEFAULT_ENDPOINT + "/different"}},
147 {DEFAULT_REV_PATH, {DEFAULT_SOURCE_PATH + "/different"}}};
148
Matt Spinlere2359fb2019-04-05 14:11:33 -0500149 AssociationMaps assocMaps;
150 assocMaps.owners = createDefaultOwnerAssociation();
151 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600152
153 checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500154 newAssocPaths, *server, assocMaps);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600155
156 // Verify initial endpoints were deleted because of different endpoints
157 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500158 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600159 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -0500160 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600161 EXPECT_EQ(intfEndpoints.size(), 0);
162}
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600163
164// Verify existing endpoint deleted when empty endpoint is provided
165TEST_F(TestAssociations, associationChangedEmptyEndpoint)
166{
Andrew Geisslereecc1962020-06-10 19:58:35 -0500167 std::vector<Association> associations = {
168 {"inventory_cee", "error_cee", ""}};
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500169 interface_map_type interfaceMap;
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600170
Matt Spinlere2359fb2019-04-05 14:11:33 -0500171 AssociationMaps assocMaps;
172 assocMaps.owners = createDefaultOwnerAssociation();
173 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600174
175 // Empty endpoint will result in deletion of corresponding assocInterface
176 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500177 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600178
Andrew Geissler0a560a52019-03-22 10:59:07 -0500179 // Both of these should be 0 since we have an invalid endpoint
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600180 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500181 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler0a560a52019-03-22 10:59:07 -0500182 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -0500183 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600184 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500185
186 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600187}
188
189// Add a new association with endpoint
190TEST_F(TestAssociations, associationChangedAddNewAssoc)
191{
192 std::vector<Association> associations = {
193 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
194
Matt Spinlere2359fb2019-04-05 14:11:33 -0500195 AssociationMaps assocMaps;
196 assocMaps.owners = createDefaultOwnerAssociation();
197 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600198
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500199 // Make it look like the assoc endpoints are on D-Bus
200 interface_map_type interfaceMap = {
201 {"/new/source/path", {{DEFAULT_DBUS_SVC, {"a"}}}},
202 {"/xyz/openbmc_project/new/endpoint", {{DEFAULT_DBUS_SVC, {"a"}}}}};
203
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600204 associationChanged(*server, associations, "/new/source/path",
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500205 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600206
207 // Two source paths
Matt Spinlere2359fb2019-04-05 14:11:33 -0500208 EXPECT_EQ(assocMaps.owners.size(), 2);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600209
210 // Four interfaces
Matt Spinlere2359fb2019-04-05 14:11:33 -0500211 EXPECT_EQ(assocMaps.ifaces.size(), 4);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600212
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500213 // Nothing pending
214 EXPECT_EQ(assocMaps.pending.size(), 0);
215
Matt Spinlere2359fb2019-04-05 14:11:33 -0500216 // New endpoint so assocMaps.ifaces should be same size
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600217 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500218 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600219 EXPECT_EQ(intfEndpoints.size(), 1);
220}
221
222// Add a new association to empty objects
223TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
224{
225 std::string sourcePath = "/logging/entry/1";
226 std::string owner = "xyz.openbmc_project.Test";
227 std::vector<Association> associations = {
Andrew Geisslereecc1962020-06-10 19:58:35 -0500228 {"inventory_canaeo", "error_canaeo",
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600229 "/xyz/openbmc_project/inventory/system/chassis"}};
230
231 // Empty objects because this test will ensure assocOwners adds the
232 // changed association and interface
Matt Spinlere2359fb2019-04-05 14:11:33 -0500233 AssociationMaps assocMaps;
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600234
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500235 // Make it look like the assoc endpoints are on D-Bus
236 interface_map_type interfaceMap = createDefaultInterfaceMap();
237
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600238 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500239 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600240
241 // New associations so ensure it now contains a single entry
Matt Spinlere2359fb2019-04-05 14:11:33 -0500242 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600243
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500244 // Nothing pending
245 EXPECT_EQ(assocMaps.pending.size(), 0);
246
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600247 // Verify corresponding assoc paths each have one endpoint in assoc
248 // interfaces and that those endpoints match
Matt Spinlere2359fb2019-04-05 14:11:33 -0500249 auto singleOwner = assocMaps.owners[DEFAULT_SOURCE_PATH];
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600250 auto singleIntf = singleOwner[DEFAULT_DBUS_SVC];
251 for (auto i : singleIntf)
252 {
Matt Spinlere2359fb2019-04-05 14:11:33 -0500253 auto intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[i.first]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600254 EXPECT_EQ(intfEndpoints.size(), 1);
255 EXPECT_EQ(intfEndpoints[0], *i.second.begin());
256 }
257}
258
259// Add a new association to same source path but with new owner
260TEST_F(TestAssociations, associationChangedAddNewAssocNewOwner)
261{
262 std::string newOwner = "xyz.openbmc_project.Test2";
263 std::vector<Association> associations = {
Andrew Geisslereecc1962020-06-10 19:58:35 -0500264 {"inventory_canano", "error_canano",
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600265 "/xyz/openbmc_project/inventory/system/chassis"}};
266
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500267 // Make it look like the assoc endpoints are on D-Bus
268 interface_map_type interfaceMap = createDefaultInterfaceMap();
269
Matt Spinlere2359fb2019-04-05 14:11:33 -0500270 AssociationMaps assocMaps;
271 assocMaps.owners = createDefaultOwnerAssociation();
272 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600273
274 associationChanged(*server, associations, DEFAULT_SOURCE_PATH, newOwner,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500275 interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600276
277 // New endpoint so assocOwners should be same size
Matt Spinlere2359fb2019-04-05 14:11:33 -0500278 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600279
280 // Ensure only one endpoint under first path
281 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500282 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600283 EXPECT_EQ(intfEndpoints.size(), 1);
284
285 // Ensure the 2 new association endpoints are under the new owner
Matt Spinlere2359fb2019-04-05 14:11:33 -0500286 auto a = assocMaps.owners.find(DEFAULT_SOURCE_PATH);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600287 auto o = a->second.find(newOwner);
288 EXPECT_EQ(o->second.size(), 2);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500289
290 // Nothing pending
291 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600292}
293
294// Add a new association to existing interface path
295TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
296{
297 std::vector<Association> associations = {
298 {"abc", "error", "/xyz/openbmc_project/inventory/system/chassis"}};
299
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500300 // Make it look like the assoc endpoints are on D-Bus
301 interface_map_type interfaceMap = createDefaultInterfaceMap();
302
Matt Spinlere2359fb2019-04-05 14:11:33 -0500303 AssociationMaps assocMaps;
304 assocMaps.owners = createDefaultOwnerAssociation();
305 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600306
307 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500308 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600309
310 // Should have 3 entries in AssociationInterfaces, one is just missing an
311 // endpoint
Matt Spinlere2359fb2019-04-05 14:11:33 -0500312 EXPECT_EQ(assocMaps.ifaces.size(), 3);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600313
314 // Change to existing interface so it will be removed here
315 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500316 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600317 EXPECT_EQ(intfEndpoints.size(), 0);
318
319 // The new endpoint should exist though in it's place
320 intfEndpoints = std::get<endpointsPos>(
Matt Spinlere2359fb2019-04-05 14:11:33 -0500321 assocMaps.ifaces[DEFAULT_SOURCE_PATH + "/" + "abc"]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600322 EXPECT_EQ(intfEndpoints.size(), 1);
323
324 // Added to an existing owner path so still 1
Matt Spinlere2359fb2019-04-05 14:11:33 -0500325 EXPECT_EQ(assocMaps.owners.size(), 1);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500326
327 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600328}
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500329
330// Add 2 pending associations
331TEST_F(TestAssociations, addPendingAssocs)
332{
333 AssociationMaps assocMaps;
334
335 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
336 "error", DEFAULT_DBUS_SVC, assocMaps);
337
338 EXPECT_TRUE(assocMaps.ifaces.empty());
339 EXPECT_TRUE(assocMaps.owners.empty());
340
341 EXPECT_EQ(assocMaps.pending.size(), 1);
342
343 addPendingAssociation("some/other/path", "inventory", DEFAULT_ENDPOINT,
344 "error", DEFAULT_DBUS_SVC, assocMaps);
345
346 EXPECT_TRUE(assocMaps.ifaces.empty());
347 EXPECT_TRUE(assocMaps.owners.empty());
348
349 EXPECT_EQ(assocMaps.pending.size(), 2);
350}
351
352// Test adding a new endpoint to a pending association
353TEST_F(TestAssociations, addPendingAssocsNewEndpoints)
354{
355 AssociationMaps assocMaps;
356
357 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
358 "error", DEFAULT_DBUS_SVC, assocMaps);
359
360 EXPECT_EQ(assocMaps.pending.size(), 1);
361
362 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory",
363 "some/other/endpoint", "error", DEFAULT_DBUS_SVC,
364 assocMaps);
365
366 // Same pending path, so still just 1 entry
367 EXPECT_EQ(assocMaps.pending.size(), 1);
368
369 auto assoc = assocMaps.pending.find(DEFAULT_SOURCE_PATH);
370 EXPECT_NE(assoc, assocMaps.pending.end());
371
372 auto& endpoints = assoc->second;
373 EXPECT_EQ(endpoints.size(), 2);
374}
375
376// Test adding a new owner to a pending association
377TEST_F(TestAssociations, addPendingAssocsNewOwner)
378{
379 AssociationMaps assocMaps;
380
381 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
382 "error", DEFAULT_DBUS_SVC, assocMaps);
383
384 EXPECT_EQ(assocMaps.pending.size(), 1);
385
386 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
387 "error", "new owner", assocMaps);
388
389 EXPECT_EQ(assocMaps.pending.size(), 1);
390
391 auto assoc = assocMaps.pending.find(DEFAULT_SOURCE_PATH);
392 EXPECT_NE(assoc, assocMaps.pending.end());
393
394 auto& endpoints = assoc->second;
395 EXPECT_EQ(endpoints.size(), 2);
396}
397
398// Add a pending association inside associationChanged
399TEST_F(TestAssociations, associationChangedPending)
400{
401 std::vector<Association> associations = {
402 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
403
404 AssociationMaps assocMaps;
405 interface_map_type interfaceMap;
406
407 associationChanged(*server, associations, "/new/source/path",
408 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
409
410 // No associations were actually added
411 EXPECT_EQ(assocMaps.owners.size(), 0);
412 EXPECT_EQ(assocMaps.ifaces.size(), 0);
413
414 // 1 pending association
415 EXPECT_EQ(assocMaps.pending.size(), 1);
416}
Matt Spinlercb9bcdb2019-04-08 10:58:49 -0500417
418// Test removing pending associations
419TEST_F(TestAssociations, testRemoveFromPendingAssociations)
420{
421 AssociationMaps assocMaps;
422
423 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
424 "error", DEFAULT_DBUS_SVC, assocMaps);
425
426 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory",
427 "some/other/endpoint", "error", DEFAULT_DBUS_SVC,
428 assocMaps);
429
430 EXPECT_EQ(assocMaps.pending.size(), 1);
431
432 removeFromPendingAssociations("some/other/endpoint", assocMaps);
433
434 // Still 1 pending entry, but down to 1 endpoint
435 EXPECT_EQ(assocMaps.pending.size(), 1);
436
437 auto assoc = assocMaps.pending.find(DEFAULT_SOURCE_PATH);
438 EXPECT_NE(assoc, assocMaps.pending.end());
439 auto& endpoints = assoc->second;
440 EXPECT_EQ(endpoints.size(), 1);
441
442 // Now nothing pending
443 removeFromPendingAssociations(DEFAULT_ENDPOINT, assocMaps);
444 EXPECT_EQ(assocMaps.pending.size(), 0);
445}
Matt Spinler11401e22019-04-08 13:13:25 -0500446
447// Test moving a pending association to a real one
448TEST_F(TestAssociations, checkIfPending)
449{
450 AssociationMaps assocMaps;
451 interface_map_type interfaceMap = {
452 {DEFAULT_SOURCE_PATH, {{DEFAULT_DBUS_SVC, {"a"}}}},
453 {DEFAULT_ENDPOINT, {{DEFAULT_DBUS_SVC, {"b"}}}}};
454
Andrew Geisslereecc1962020-06-10 19:58:35 -0500455 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory_cip",
456 DEFAULT_ENDPOINT, "error_cip", DEFAULT_DBUS_SVC,
457 assocMaps);
Matt Spinler11401e22019-04-08 13:13:25 -0500458 EXPECT_EQ(assocMaps.pending.size(), 1);
459
460 // Move the pending association to a real association
461 checkIfPendingAssociation(DEFAULT_SOURCE_PATH, interfaceMap, assocMaps,
462 *server);
463
464 EXPECT_TRUE(assocMaps.pending.empty());
465 EXPECT_EQ(assocMaps.owners.size(), 1);
466 EXPECT_EQ(assocMaps.ifaces.size(), 2);
467
468 // This shouldn't do anything, since /new/path isn't pending
469 checkIfPendingAssociation("/new/path", interfaceMap, assocMaps, *server);
470 EXPECT_TRUE(assocMaps.pending.empty());
471 EXPECT_EQ(assocMaps.owners.size(), 1);
472 EXPECT_EQ(assocMaps.ifaces.size(), 2);
473}
Matt Spinler7f8fd1f2019-04-08 15:21:59 -0500474
475TEST_F(TestAssociations, findAssociations)
476{
477 std::vector<std::tuple<std::string, Association>> associationData;
478 AssociationMaps assocMaps;
479
480 assocMaps.owners = {
481 {"pathA",
482 {{"ownerA",
483 {{"pathA/typeA", {"endpointA", "endpointB"}},
484 {"endpointA/type0", {"pathA"}}}}}},
485
486 {"pathJ",
487 {{"ownerC",
488 {{"pathJ/typeA", {"endpointF"}}, {"endpointF/type0", {"pathJ"}}}}}},
489
490 {"pathX",
491 {{"ownerB",
492 {{"pathX/typeB", {"endpointA"}}, {"endpointA/type1", {"pathX"}}}}}}};
493
494 findAssociations("endpointA", assocMaps, associationData);
495 ASSERT_EQ(associationData.size(), 2);
496
497 {
498 auto ad = std::find_if(
499 associationData.begin(), associationData.end(),
500 [](const auto& ad) { return std::get<0>(ad) == "ownerA"; });
501 ASSERT_NE(ad, associationData.end());
502
503 auto& a = std::get<1>(*ad);
504 ASSERT_EQ(std::get<0>(a), "type0");
505 ASSERT_EQ(std::get<1>(a), "typeA");
506 ASSERT_EQ(std::get<2>(a), "pathA");
507 }
508 {
509 auto ad = std::find_if(
510 associationData.begin(), associationData.end(),
511 [](const auto& ad) { return std::get<0>(ad) == "ownerB"; });
512 ASSERT_NE(ad, associationData.end());
513
514 auto& a = std::get<1>(*ad);
515 ASSERT_EQ(std::get<0>(a), "type1");
516 ASSERT_EQ(std::get<1>(a), "typeB");
517 ASSERT_EQ(std::get<2>(a), "pathX");
518 }
519}
Matt Spinler9c3d2852019-04-08 15:57:19 -0500520
521TEST_F(TestAssociations, moveAssocToPendingNoOp)
522{
523 AssociationMaps assocMaps;
524
525 // Not an association, so it shouldn't do anything
526 moveAssociationToPending(DEFAULT_ENDPOINT, assocMaps, *server);
527
528 EXPECT_TRUE(assocMaps.pending.empty());
529 EXPECT_TRUE(assocMaps.owners.empty());
530 EXPECT_TRUE(assocMaps.ifaces.empty());
531}
532
533TEST_F(TestAssociations, moveAssocToPending)
534{
535 AssociationMaps assocMaps;
536 assocMaps.owners = createDefaultOwnerAssociation();
537 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
538
539 moveAssociationToPending(DEFAULT_ENDPOINT, assocMaps, *server);
540
541 // Check it's now pending
542 EXPECT_EQ(assocMaps.pending.size(), 1);
543 EXPECT_EQ(assocMaps.pending.begin()->first, DEFAULT_ENDPOINT);
544
545 // No more assoc owners
546 EXPECT_TRUE(assocMaps.owners.empty());
547
548 // Check the association interfaces were removed
549 {
550 auto assocs = assocMaps.ifaces.find(DEFAULT_FWD_PATH);
551 auto& iface = std::get<ifacePos>(assocs->second);
552 auto& endpoints = std::get<endpointsPos>(assocs->second);
553
554 EXPECT_EQ(iface.get(), nullptr);
555 EXPECT_TRUE(endpoints.empty());
556 }
557 {
558 auto assocs = assocMaps.ifaces.find(DEFAULT_REV_PATH);
559 auto& iface = std::get<ifacePos>(assocs->second);
560 auto& endpoints = std::get<endpointsPos>(assocs->second);
561
562 EXPECT_EQ(iface.get(), nullptr);
563 EXPECT_TRUE(endpoints.empty());
564 }
565}