blob: cf2f7d0021add9bf112c8c530385297c7f5e7052 [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
Brad Bishopa098a372022-05-05 15:19:04 -040024 removeAssociation(sourcePath, defaultDbusSvc, *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
Brad Bishopa098a372022-05-05 15:19:04 -040033 removeAssociation(defaultSourcePath, defaultDbusSvc, *server, assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060034}
35
36// Verify call when path is not in associated interfaces
37TEST_F(TestAssociations, PathNotInAssocInterfaces)
38{
Matt Spinlere2359fb2019-04-05 14:11:33 -050039 AssociationMaps assocMaps;
Andrew Geissler271b7dd2019-02-05 11:23:30 -060040
Matt Spinlere2359fb2019-04-05 14:11:33 -050041 assocMaps.owners = createDefaultOwnerAssociation();
Andrew Geissler271b7dd2019-02-05 11:23:30 -060042
Brad Bishopa098a372022-05-05 15:19:04 -040043 removeAssociation(defaultSourcePath, defaultDbusSvc, *server, assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060044
Matt Spinlere2359fb2019-04-05 14:11:33 -050045 EXPECT_TRUE(assocMaps.owners.empty());
Andrew Geissler271b7dd2019-02-05 11:23:30 -060046}
47
48// Verify call when path is in associated interfaces
49TEST_F(TestAssociations, PathIsInAssociatedInterfaces)
50{
51 // Build up these objects so that an associated interface will match
52 // with the associated owner being removed
Matt Spinlere2359fb2019-04-05 14:11:33 -050053 AssociationMaps assocMaps;
54 assocMaps.owners = createDefaultOwnerAssociation();
55 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060056
Brad Bishopa098a372022-05-05 15:19:04 -040057 removeAssociation(defaultSourcePath, defaultDbusSvc, *server, assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060058
59 // Verify owner association was deleted
Matt Spinlere2359fb2019-04-05 14:11:33 -050060 EXPECT_TRUE(assocMaps.owners.empty());
Andrew Geissler271b7dd2019-02-05 11:23:30 -060061
62 // Verify endpoint was deleted from interface association
63 auto intfEndpoints =
Brad Bishopa098a372022-05-05 15:19:04 -040064 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060065 EXPECT_EQ(intfEndpoints.size(), 0);
Brad Bishopa098a372022-05-05 15:19:04 -040066 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060067 EXPECT_EQ(intfEndpoints.size(), 0);
68}
69
70// Verify call when path is in associated interfaces, with extra endpoints
71TEST_F(TestAssociations, PathIsInAssociatedInterfacesExtraEndpoints)
72{
73 // Build up these objects so that an associated interface will match
74 // with the associated owner being removed
Matt Spinlere2359fb2019-04-05 14:11:33 -050075 AssociationMaps assocMaps;
76 assocMaps.owners = createDefaultOwnerAssociation();
77 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060078
79 // Add another endpoint to the assoc interfaces
Matt Spinlere2359fb2019-04-05 14:11:33 -050080 addEndpointToInterfaceAssociation(assocMaps.ifaces);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060081
Brad Bishopa098a372022-05-05 15:19:04 -040082 removeAssociation(defaultSourcePath, defaultDbusSvc, *server, assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060083
84 // Verify owner association was deleted
Matt Spinlere2359fb2019-04-05 14:11:33 -050085 EXPECT_TRUE(assocMaps.owners.empty());
Andrew Geissler271b7dd2019-02-05 11:23:30 -060086
87 // Verify all endpoints are deleted since source path was deleted
88 auto intfEndpoints =
Brad Bishopa098a372022-05-05 15:19:04 -040089 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060090 EXPECT_EQ(intfEndpoints.size(), 0);
Brad Bishopa098a372022-05-05 15:19:04 -040091 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060092 EXPECT_EQ(intfEndpoints.size(), 0);
93}
Andrew Geisslere4ab6c92019-02-21 15:07:27 -060094
95// Verify no associations or endpoints removed when the change is identical
96TEST_F(TestAssociations, checkAssociationEndpointRemovesNoEpRemove)
97{
Brad Bishopa098a372022-05-05 15:19:04 -040098 AssociationPaths newAssocPaths = {{defaultFwdPath, {defaultEndpoint}},
99 {defaultRevPath, {defaultSourcePath}}};
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600100
Matt Spinlere2359fb2019-04-05 14:11:33 -0500101 AssociationMaps assocMaps;
102 assocMaps.owners = createDefaultOwnerAssociation();
103 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600104
Brad Bishopa098a372022-05-05 15:19:04 -0400105 checkAssociationEndpointRemoves(defaultSourcePath, defaultDbusSvc,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500106 newAssocPaths, *server, assocMaps);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600107
108 // Verify endpoints were not deleted because they matche with what was
109 // in the original
110 auto intfEndpoints =
Brad Bishopa098a372022-05-05 15:19:04 -0400111 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600112 EXPECT_EQ(intfEndpoints.size(), 1);
Brad Bishopa098a372022-05-05 15:19:04 -0400113 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600114 EXPECT_EQ(intfEndpoints.size(), 1);
115}
116
117// Verify endpoint is removed when assoc path is different
118TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveApDiff)
119{
Brad Bishopa098a372022-05-05 15:19:04 -0400120 AssociationPaths newAssocPaths = {{"/different/path", {defaultEndpoint}}};
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600121
Matt Spinlere2359fb2019-04-05 14:11:33 -0500122 AssociationMaps assocMaps;
123 assocMaps.owners = createDefaultOwnerAssociation();
124 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600125
Brad Bishopa098a372022-05-05 15:19:04 -0400126 checkAssociationEndpointRemoves(defaultSourcePath, defaultDbusSvc,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500127 newAssocPaths, *server, assocMaps);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600128
129 // Verify initial endpoints were deleted because the new path
130 auto intfEndpoints =
Brad Bishopa098a372022-05-05 15:19:04 -0400131 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600132 EXPECT_EQ(intfEndpoints.size(), 0);
Brad Bishopa098a372022-05-05 15:19:04 -0400133 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600134 EXPECT_EQ(intfEndpoints.size(), 0);
135}
136
137// Verify endpoint is removed when endpoint is different
138TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveEpChanged)
139{
140 AssociationPaths newAssocPaths = {
Brad Bishopa098a372022-05-05 15:19:04 -0400141 {defaultFwdPath, {defaultEndpoint + "/different"}},
142 {defaultRevPath, {defaultSourcePath + "/different"}}};
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600143
Matt Spinlere2359fb2019-04-05 14:11:33 -0500144 AssociationMaps assocMaps;
145 assocMaps.owners = createDefaultOwnerAssociation();
146 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600147
Brad Bishopa098a372022-05-05 15:19:04 -0400148 checkAssociationEndpointRemoves(defaultSourcePath, defaultDbusSvc,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500149 newAssocPaths, *server, assocMaps);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600150
151 // Verify initial endpoints were deleted because of different endpoints
152 auto intfEndpoints =
Brad Bishopa098a372022-05-05 15:19:04 -0400153 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600154 EXPECT_EQ(intfEndpoints.size(), 0);
Brad Bishopa098a372022-05-05 15:19:04 -0400155 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600156 EXPECT_EQ(intfEndpoints.size(), 0);
157}
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600158
159// Verify existing endpoint deleted when empty endpoint is provided
160TEST_F(TestAssociations, associationChangedEmptyEndpoint)
161{
Andrew Geisslereecc1962020-06-10 19:58:35 -0500162 std::vector<Association> associations = {
163 {"inventory_cee", "error_cee", ""}};
Brad Bishopa098a372022-05-05 15:19:04 -0400164 InterfaceMapType interfaceMap;
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600165
Matt Spinlere2359fb2019-04-05 14:11:33 -0500166 AssociationMaps assocMaps;
167 assocMaps.owners = createDefaultOwnerAssociation();
168 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600169
170 // Empty endpoint will result in deletion of corresponding assocInterface
Brad Bishopa098a372022-05-05 15:19:04 -0400171 associationChanged(*server, associations, defaultSourcePath, defaultDbusSvc,
172 interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600173
Andrew Geissler0a560a52019-03-22 10:59:07 -0500174 // Both of these should be 0 since we have an invalid endpoint
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600175 auto intfEndpoints =
Brad Bishopa098a372022-05-05 15:19:04 -0400176 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
Andrew Geissler0a560a52019-03-22 10:59:07 -0500177 EXPECT_EQ(intfEndpoints.size(), 0);
Brad Bishopa098a372022-05-05 15:19:04 -0400178 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600179 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500180
181 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600182}
183
184// Add a new association with endpoint
185TEST_F(TestAssociations, associationChangedAddNewAssoc)
186{
187 std::vector<Association> associations = {
188 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
189
Matt Spinlere2359fb2019-04-05 14:11:33 -0500190 AssociationMaps assocMaps;
191 assocMaps.owners = createDefaultOwnerAssociation();
192 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600193
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500194 // Make it look like the assoc endpoints are on D-Bus
Brad Bishopa098a372022-05-05 15:19:04 -0400195 InterfaceMapType interfaceMap = {
196 {"/new/source/path", {{defaultDbusSvc, {"a"}}}},
197 {"/xyz/openbmc_project/new/endpoint", {{defaultDbusSvc, {"a"}}}}};
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500198
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600199 associationChanged(*server, associations, "/new/source/path",
Brad Bishopa098a372022-05-05 15:19:04 -0400200 defaultDbusSvc, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600201
202 // Two source paths
Matt Spinlere2359fb2019-04-05 14:11:33 -0500203 EXPECT_EQ(assocMaps.owners.size(), 2);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600204
205 // Four interfaces
Matt Spinlere2359fb2019-04-05 14:11:33 -0500206 EXPECT_EQ(assocMaps.ifaces.size(), 4);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600207
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500208 // Nothing pending
209 EXPECT_EQ(assocMaps.pending.size(), 0);
210
Matt Spinlere2359fb2019-04-05 14:11:33 -0500211 // New endpoint so assocMaps.ifaces should be same size
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600212 auto intfEndpoints =
Brad Bishopa098a372022-05-05 15:19:04 -0400213 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600214 EXPECT_EQ(intfEndpoints.size(), 1);
215}
216
217// Add a new association to empty objects
218TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
219{
220 std::string sourcePath = "/logging/entry/1";
221 std::string owner = "xyz.openbmc_project.Test";
222 std::vector<Association> associations = {
Andrew Geisslereecc1962020-06-10 19:58:35 -0500223 {"inventory_canaeo", "error_canaeo",
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600224 "/xyz/openbmc_project/inventory/system/chassis"}};
225
226 // Empty objects because this test will ensure assocOwners adds the
227 // changed association and interface
Matt Spinlere2359fb2019-04-05 14:11:33 -0500228 AssociationMaps assocMaps;
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600229
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500230 // Make it look like the assoc endpoints are on D-Bus
Brad Bishopa098a372022-05-05 15:19:04 -0400231 InterfaceMapType interfaceMap = createDefaultInterfaceMap();
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500232
Brad Bishopa098a372022-05-05 15:19:04 -0400233 associationChanged(*server, associations, defaultSourcePath, defaultDbusSvc,
234 interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600235
236 // New associations so ensure it now contains a single entry
Matt Spinlere2359fb2019-04-05 14:11:33 -0500237 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600238
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500239 // Nothing pending
240 EXPECT_EQ(assocMaps.pending.size(), 0);
241
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600242 // Verify corresponding assoc paths each have one endpoint in assoc
243 // interfaces and that those endpoints match
Brad Bishopa098a372022-05-05 15:19:04 -0400244 auto singleOwner = assocMaps.owners[defaultSourcePath];
245 auto singleIntf = singleOwner[defaultDbusSvc];
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600246 for (auto i : singleIntf)
247 {
Matt Spinlere2359fb2019-04-05 14:11:33 -0500248 auto intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[i.first]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600249 EXPECT_EQ(intfEndpoints.size(), 1);
250 EXPECT_EQ(intfEndpoints[0], *i.second.begin());
251 }
252}
253
254// Add a new association to same source path but with new owner
255TEST_F(TestAssociations, associationChangedAddNewAssocNewOwner)
256{
257 std::string newOwner = "xyz.openbmc_project.Test2";
258 std::vector<Association> associations = {
Andrew Geisslereecc1962020-06-10 19:58:35 -0500259 {"inventory_canano", "error_canano",
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600260 "/xyz/openbmc_project/inventory/system/chassis"}};
261
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500262 // Make it look like the assoc endpoints are on D-Bus
Brad Bishopa098a372022-05-05 15:19:04 -0400263 InterfaceMapType interfaceMap = createDefaultInterfaceMap();
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500264
Matt Spinlere2359fb2019-04-05 14:11:33 -0500265 AssociationMaps assocMaps;
266 assocMaps.owners = createDefaultOwnerAssociation();
267 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600268
Brad Bishopa098a372022-05-05 15:19:04 -0400269 associationChanged(*server, associations, defaultSourcePath, newOwner,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500270 interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600271
272 // New endpoint so assocOwners should be same size
Matt Spinlere2359fb2019-04-05 14:11:33 -0500273 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600274
275 // Ensure only one endpoint under first path
276 auto intfEndpoints =
Brad Bishopa098a372022-05-05 15:19:04 -0400277 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600278 EXPECT_EQ(intfEndpoints.size(), 1);
279
280 // Ensure the 2 new association endpoints are under the new owner
Brad Bishopa098a372022-05-05 15:19:04 -0400281 auto a = assocMaps.owners.find(defaultSourcePath);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600282 auto o = a->second.find(newOwner);
283 EXPECT_EQ(o->second.size(), 2);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500284
285 // Nothing pending
286 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600287}
288
289// Add a new association to existing interface path
290TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
291{
292 std::vector<Association> associations = {
293 {"abc", "error", "/xyz/openbmc_project/inventory/system/chassis"}};
294
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500295 // Make it look like the assoc endpoints are on D-Bus
Brad Bishopa098a372022-05-05 15:19:04 -0400296 InterfaceMapType interfaceMap = createDefaultInterfaceMap();
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500297
Matt Spinlere2359fb2019-04-05 14:11:33 -0500298 AssociationMaps assocMaps;
299 assocMaps.owners = createDefaultOwnerAssociation();
300 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600301
Brad Bishopa098a372022-05-05 15:19:04 -0400302 associationChanged(*server, associations, defaultSourcePath, defaultDbusSvc,
303 interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600304
305 // Should have 3 entries in AssociationInterfaces, one is just missing an
306 // endpoint
Matt Spinlere2359fb2019-04-05 14:11:33 -0500307 EXPECT_EQ(assocMaps.ifaces.size(), 3);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600308
309 // Change to existing interface so it will be removed here
310 auto intfEndpoints =
Brad Bishopa098a372022-05-05 15:19:04 -0400311 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600312 EXPECT_EQ(intfEndpoints.size(), 0);
313
314 // The new endpoint should exist though in it's place
315 intfEndpoints = std::get<endpointsPos>(
Brad Bishopa098a372022-05-05 15:19:04 -0400316 assocMaps.ifaces[defaultSourcePath + "/" + "abc"]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600317 EXPECT_EQ(intfEndpoints.size(), 1);
318
319 // Added to an existing owner path so still 1
Matt Spinlere2359fb2019-04-05 14:11:33 -0500320 EXPECT_EQ(assocMaps.owners.size(), 1);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500321
322 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600323}
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500324
325// Add 2 pending associations
326TEST_F(TestAssociations, addPendingAssocs)
327{
328 AssociationMaps assocMaps;
329
Brad Bishopa098a372022-05-05 15:19:04 -0400330 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
331 "error", defaultDbusSvc, assocMaps);
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500332
333 EXPECT_TRUE(assocMaps.ifaces.empty());
334 EXPECT_TRUE(assocMaps.owners.empty());
335
336 EXPECT_EQ(assocMaps.pending.size(), 1);
337
Brad Bishopa098a372022-05-05 15:19:04 -0400338 addPendingAssociation("some/other/path", "inventory", defaultEndpoint,
339 "error", defaultDbusSvc, assocMaps);
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500340
341 EXPECT_TRUE(assocMaps.ifaces.empty());
342 EXPECT_TRUE(assocMaps.owners.empty());
343
344 EXPECT_EQ(assocMaps.pending.size(), 2);
345}
346
347// Test adding a new endpoint to a pending association
348TEST_F(TestAssociations, addPendingAssocsNewEndpoints)
349{
350 AssociationMaps assocMaps;
351
Brad Bishopa098a372022-05-05 15:19:04 -0400352 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
353 "error", defaultDbusSvc, assocMaps);
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500354
355 EXPECT_EQ(assocMaps.pending.size(), 1);
356
Brad Bishopa098a372022-05-05 15:19:04 -0400357 addPendingAssociation(defaultSourcePath, "inventory", "some/other/endpoint",
358 "error", defaultDbusSvc, assocMaps);
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500359
360 // Same pending path, so still just 1 entry
361 EXPECT_EQ(assocMaps.pending.size(), 1);
362
Brad Bishopa098a372022-05-05 15:19:04 -0400363 auto assoc = assocMaps.pending.find(defaultSourcePath);
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500364 EXPECT_NE(assoc, assocMaps.pending.end());
365
366 auto& endpoints = assoc->second;
367 EXPECT_EQ(endpoints.size(), 2);
368}
369
370// Test adding a new owner to a pending association
371TEST_F(TestAssociations, addPendingAssocsNewOwner)
372{
373 AssociationMaps assocMaps;
374
Brad Bishopa098a372022-05-05 15:19:04 -0400375 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
376 "error", defaultDbusSvc, assocMaps);
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500377
378 EXPECT_EQ(assocMaps.pending.size(), 1);
379
Brad Bishopa098a372022-05-05 15:19:04 -0400380 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500381 "error", "new owner", assocMaps);
382
383 EXPECT_EQ(assocMaps.pending.size(), 1);
384
Brad Bishopa098a372022-05-05 15:19:04 -0400385 auto assoc = assocMaps.pending.find(defaultSourcePath);
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500386 EXPECT_NE(assoc, assocMaps.pending.end());
387
388 auto& endpoints = assoc->second;
389 EXPECT_EQ(endpoints.size(), 2);
390}
391
392// Add a pending association inside associationChanged
393TEST_F(TestAssociations, associationChangedPending)
394{
395 std::vector<Association> associations = {
396 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
397
398 AssociationMaps assocMaps;
Brad Bishopa098a372022-05-05 15:19:04 -0400399 InterfaceMapType interfaceMap;
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500400
401 associationChanged(*server, associations, "/new/source/path",
Brad Bishopa098a372022-05-05 15:19:04 -0400402 defaultDbusSvc, interfaceMap, assocMaps);
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500403
404 // No associations were actually added
405 EXPECT_EQ(assocMaps.owners.size(), 0);
406 EXPECT_EQ(assocMaps.ifaces.size(), 0);
407
408 // 1 pending association
409 EXPECT_EQ(assocMaps.pending.size(), 1);
410}
Matt Spinlercb9bcdb2019-04-08 10:58:49 -0500411
412// Test removing pending associations
413TEST_F(TestAssociations, testRemoveFromPendingAssociations)
414{
415 AssociationMaps assocMaps;
416
Brad Bishopa098a372022-05-05 15:19:04 -0400417 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
418 "error", defaultDbusSvc, assocMaps);
Matt Spinlercb9bcdb2019-04-08 10:58:49 -0500419
Brad Bishopa098a372022-05-05 15:19:04 -0400420 addPendingAssociation(defaultSourcePath, "inventory", "some/other/endpoint",
421 "error", defaultDbusSvc, assocMaps);
Matt Spinlercb9bcdb2019-04-08 10:58:49 -0500422
423 EXPECT_EQ(assocMaps.pending.size(), 1);
424
425 removeFromPendingAssociations("some/other/endpoint", assocMaps);
426
427 // Still 1 pending entry, but down to 1 endpoint
428 EXPECT_EQ(assocMaps.pending.size(), 1);
429
Brad Bishopa098a372022-05-05 15:19:04 -0400430 auto assoc = assocMaps.pending.find(defaultSourcePath);
Matt Spinlercb9bcdb2019-04-08 10:58:49 -0500431 EXPECT_NE(assoc, assocMaps.pending.end());
432 auto& endpoints = assoc->second;
433 EXPECT_EQ(endpoints.size(), 1);
434
435 // Now nothing pending
Brad Bishopa098a372022-05-05 15:19:04 -0400436 removeFromPendingAssociations(defaultEndpoint, assocMaps);
Matt Spinlercb9bcdb2019-04-08 10:58:49 -0500437 EXPECT_EQ(assocMaps.pending.size(), 0);
438}
Matt Spinler11401e22019-04-08 13:13:25 -0500439
440// Test moving a pending association to a real one
441TEST_F(TestAssociations, checkIfPending)
442{
443 AssociationMaps assocMaps;
Brad Bishopa098a372022-05-05 15:19:04 -0400444 InterfaceMapType interfaceMap = {
445 {defaultSourcePath, {{defaultDbusSvc, {"a"}}}},
446 {defaultEndpoint, {{defaultDbusSvc, {"b"}}}}};
Matt Spinler11401e22019-04-08 13:13:25 -0500447
Brad Bishopa098a372022-05-05 15:19:04 -0400448 addPendingAssociation(defaultSourcePath, "inventory_cip", defaultEndpoint,
449 "error_cip", defaultDbusSvc, assocMaps);
Matt Spinler11401e22019-04-08 13:13:25 -0500450 EXPECT_EQ(assocMaps.pending.size(), 1);
451
452 // Move the pending association to a real association
Brad Bishopa098a372022-05-05 15:19:04 -0400453 checkIfPendingAssociation(defaultSourcePath, interfaceMap, assocMaps,
Matt Spinler11401e22019-04-08 13:13:25 -0500454 *server);
455
456 EXPECT_TRUE(assocMaps.pending.empty());
457 EXPECT_EQ(assocMaps.owners.size(), 1);
458 EXPECT_EQ(assocMaps.ifaces.size(), 2);
459
460 // This shouldn't do anything, since /new/path isn't pending
461 checkIfPendingAssociation("/new/path", interfaceMap, assocMaps, *server);
462 EXPECT_TRUE(assocMaps.pending.empty());
463 EXPECT_EQ(assocMaps.owners.size(), 1);
464 EXPECT_EQ(assocMaps.ifaces.size(), 2);
465}
Matt Spinler7f8fd1f2019-04-08 15:21:59 -0500466
467TEST_F(TestAssociations, findAssociations)
468{
469 std::vector<std::tuple<std::string, Association>> associationData;
470 AssociationMaps assocMaps;
471
472 assocMaps.owners = {
473 {"pathA",
474 {{"ownerA",
475 {{"pathA/typeA", {"endpointA", "endpointB"}},
476 {"endpointA/type0", {"pathA"}}}}}},
477
478 {"pathJ",
479 {{"ownerC",
480 {{"pathJ/typeA", {"endpointF"}}, {"endpointF/type0", {"pathJ"}}}}}},
481
482 {"pathX",
483 {{"ownerB",
484 {{"pathX/typeB", {"endpointA"}}, {"endpointA/type1", {"pathX"}}}}}}};
485
486 findAssociations("endpointA", assocMaps, associationData);
487 ASSERT_EQ(associationData.size(), 2);
488
489 {
490 auto ad = std::find_if(
491 associationData.begin(), associationData.end(),
492 [](const auto& ad) { return std::get<0>(ad) == "ownerA"; });
493 ASSERT_NE(ad, associationData.end());
494
495 auto& a = std::get<1>(*ad);
496 ASSERT_EQ(std::get<0>(a), "type0");
497 ASSERT_EQ(std::get<1>(a), "typeA");
498 ASSERT_EQ(std::get<2>(a), "pathA");
499 }
500 {
501 auto ad = std::find_if(
502 associationData.begin(), associationData.end(),
503 [](const auto& ad) { return std::get<0>(ad) == "ownerB"; });
504 ASSERT_NE(ad, associationData.end());
505
506 auto& a = std::get<1>(*ad);
507 ASSERT_EQ(std::get<0>(a), "type1");
508 ASSERT_EQ(std::get<1>(a), "typeB");
509 ASSERT_EQ(std::get<2>(a), "pathX");
510 }
511}
Matt Spinler9c3d2852019-04-08 15:57:19 -0500512
513TEST_F(TestAssociations, moveAssocToPendingNoOp)
514{
515 AssociationMaps assocMaps;
516
517 // Not an association, so it shouldn't do anything
Brad Bishopa098a372022-05-05 15:19:04 -0400518 moveAssociationToPending(defaultEndpoint, assocMaps, *server);
Matt Spinler9c3d2852019-04-08 15:57:19 -0500519
520 EXPECT_TRUE(assocMaps.pending.empty());
521 EXPECT_TRUE(assocMaps.owners.empty());
522 EXPECT_TRUE(assocMaps.ifaces.empty());
523}
524
525TEST_F(TestAssociations, moveAssocToPending)
526{
527 AssociationMaps assocMaps;
528 assocMaps.owners = createDefaultOwnerAssociation();
529 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
530
Brad Bishopa098a372022-05-05 15:19:04 -0400531 moveAssociationToPending(defaultEndpoint, assocMaps, *server);
Matt Spinler9c3d2852019-04-08 15:57:19 -0500532
533 // Check it's now pending
534 EXPECT_EQ(assocMaps.pending.size(), 1);
Brad Bishopa098a372022-05-05 15:19:04 -0400535 EXPECT_EQ(assocMaps.pending.begin()->first, defaultEndpoint);
Matt Spinler9c3d2852019-04-08 15:57:19 -0500536
537 // No more assoc owners
538 EXPECT_TRUE(assocMaps.owners.empty());
539
540 // Check the association interfaces were removed
541 {
Brad Bishopa098a372022-05-05 15:19:04 -0400542 auto assocs = assocMaps.ifaces.find(defaultFwdPath);
Matt Spinler9c3d2852019-04-08 15:57:19 -0500543 auto& iface = std::get<ifacePos>(assocs->second);
544 auto& endpoints = std::get<endpointsPos>(assocs->second);
545
546 EXPECT_EQ(iface.get(), nullptr);
547 EXPECT_TRUE(endpoints.empty());
548 }
549 {
Brad Bishopa098a372022-05-05 15:19:04 -0400550 auto assocs = assocMaps.ifaces.find(defaultRevPath);
Matt Spinler9c3d2852019-04-08 15:57:19 -0500551 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}