blob: 73c36ed2f433cceb2c7ca1355a34414c1d746ab5 [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
Andrew Geissler271b7dd2019-02-05 11:23:30 -060013{
Andrew Geissler271b7dd2019-02-05 11:23:30 -060014};
Andrew Geisslerb04f0332019-02-08 14:07:56 -060015sdbusplus::asio::object_server* TestAssociations::AsioServerClassTest::server =
16 nullptr;
Andrew Geissler271b7dd2019-02-05 11:23:30 -060017
Andrew Geissler271b7dd2019-02-05 11:23:30 -060018// Verify call when path is not in associated owners
19TEST_F(TestAssociations, SourcePathNotInAssociations)
20{
21 EXPECT_NE(nullptr, server);
22 std::string sourcePath = "/xyz/openbmc_project/no/association";
Matt Spinlere2359fb2019-04-05 14:11:33 -050023 AssociationMaps assocMaps;
Andrew Geissler271b7dd2019-02-05 11:23:30 -060024
Matt Spinlere2359fb2019-04-05 14:11:33 -050025 removeAssociation(sourcePath, DEFAULT_DBUS_SVC, *server, assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060026}
27
28// Verify call when owner is not in associated owners
29TEST_F(TestAssociations, OwnerNotInAssociations)
30{
Matt Spinlere2359fb2019-04-05 14:11:33 -050031 AssociationMaps assocMaps;
32 assocMaps.owners = createDefaultOwnerAssociation();
Andrew Geissler271b7dd2019-02-05 11:23:30 -060033
34 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
Matt Spinlere2359fb2019-04-05 14:11:33 -050035 assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060036}
37
38// Verify call when path is not in associated interfaces
39TEST_F(TestAssociations, PathNotInAssocInterfaces)
40{
Matt Spinlere2359fb2019-04-05 14:11:33 -050041 AssociationMaps assocMaps;
Andrew Geissler271b7dd2019-02-05 11:23:30 -060042
Matt Spinlere2359fb2019-04-05 14:11:33 -050043 assocMaps.owners = createDefaultOwnerAssociation();
Andrew Geissler271b7dd2019-02-05 11:23:30 -060044
45 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
Matt Spinlere2359fb2019-04-05 14:11:33 -050046 assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060047
Matt Spinlere2359fb2019-04-05 14:11:33 -050048 EXPECT_TRUE(assocMaps.owners.empty());
Andrew Geissler271b7dd2019-02-05 11:23:30 -060049}
50
51// Verify call when path is in associated interfaces
52TEST_F(TestAssociations, PathIsInAssociatedInterfaces)
53{
54 // Build up these objects so that an associated interface will match
55 // with the associated owner being removed
Matt Spinlere2359fb2019-04-05 14:11:33 -050056 AssociationMaps assocMaps;
57 assocMaps.owners = createDefaultOwnerAssociation();
58 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060059
60 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
Matt Spinlere2359fb2019-04-05 14:11:33 -050061 assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060062
63 // Verify owner association was deleted
Matt Spinlere2359fb2019-04-05 14:11:33 -050064 EXPECT_TRUE(assocMaps.owners.empty());
Andrew Geissler271b7dd2019-02-05 11:23:30 -060065
66 // Verify endpoint was deleted from interface association
67 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -050068 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060069 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -050070 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060071 EXPECT_EQ(intfEndpoints.size(), 0);
72}
73
74// Verify call when path is in associated interfaces, with extra endpoints
75TEST_F(TestAssociations, PathIsInAssociatedInterfacesExtraEndpoints)
76{
77 // Build up these objects so that an associated interface will match
78 // with the associated owner being removed
Matt Spinlere2359fb2019-04-05 14:11:33 -050079 AssociationMaps assocMaps;
80 assocMaps.owners = createDefaultOwnerAssociation();
81 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060082
83 // Add another endpoint to the assoc interfaces
Matt Spinlere2359fb2019-04-05 14:11:33 -050084 addEndpointToInterfaceAssociation(assocMaps.ifaces);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060085
86 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
Matt Spinlere2359fb2019-04-05 14:11:33 -050087 assocMaps);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060088
89 // Verify owner association was deleted
Matt Spinlere2359fb2019-04-05 14:11:33 -050090 EXPECT_TRUE(assocMaps.owners.empty());
Andrew Geissler271b7dd2019-02-05 11:23:30 -060091
92 // Verify all endpoints are deleted since source path was deleted
93 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -050094 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060095 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -050096 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geissler271b7dd2019-02-05 11:23:30 -060097 EXPECT_EQ(intfEndpoints.size(), 0);
98}
Andrew Geisslere4ab6c92019-02-21 15:07:27 -060099
100// Verify no associations or endpoints removed when the change is identical
101TEST_F(TestAssociations, checkAssociationEndpointRemovesNoEpRemove)
102{
103
104 AssociationPaths newAssocPaths = {
105 {DEFAULT_FWD_PATH, {DEFAULT_ENDPOINT}},
106 {DEFAULT_REV_PATH, {DEFAULT_SOURCE_PATH}}};
107
Matt Spinlere2359fb2019-04-05 14:11:33 -0500108 AssociationMaps assocMaps;
109 assocMaps.owners = createDefaultOwnerAssociation();
110 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600111
112 checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500113 newAssocPaths, *server, assocMaps);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600114
115 // Verify endpoints were not deleted because they matche with what was
116 // in the original
117 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500118 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600119 EXPECT_EQ(intfEndpoints.size(), 1);
Matt Spinlere2359fb2019-04-05 14:11:33 -0500120 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600121 EXPECT_EQ(intfEndpoints.size(), 1);
122}
123
124// Verify endpoint is removed when assoc path is different
125TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveApDiff)
126{
127 AssociationPaths newAssocPaths = {{"/different/path", {DEFAULT_ENDPOINT}}};
128
Matt Spinlere2359fb2019-04-05 14:11:33 -0500129 AssociationMaps assocMaps;
130 assocMaps.owners = createDefaultOwnerAssociation();
131 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600132
133 checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500134 newAssocPaths, *server, assocMaps);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600135
136 // Verify initial endpoints were deleted because the new path
137 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500138 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600139 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -0500140 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600141 EXPECT_EQ(intfEndpoints.size(), 0);
142}
143
144// Verify endpoint is removed when endpoint is different
145TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveEpChanged)
146{
147 AssociationPaths newAssocPaths = {
148 {DEFAULT_FWD_PATH, {DEFAULT_ENDPOINT + "/different"}},
149 {DEFAULT_REV_PATH, {DEFAULT_SOURCE_PATH + "/different"}}};
150
Matt Spinlere2359fb2019-04-05 14:11:33 -0500151 AssociationMaps assocMaps;
152 assocMaps.owners = createDefaultOwnerAssociation();
153 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600154
155 checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500156 newAssocPaths, *server, assocMaps);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600157
158 // Verify initial endpoints were deleted because of different endpoints
159 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500160 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600161 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -0500162 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600163 EXPECT_EQ(intfEndpoints.size(), 0);
164}
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600165
166// Verify existing endpoint deleted when empty endpoint is provided
167TEST_F(TestAssociations, associationChangedEmptyEndpoint)
168{
Andrew Geisslereecc1962020-06-10 19:58:35 -0500169 std::vector<Association> associations = {
170 {"inventory_cee", "error_cee", ""}};
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500171 interface_map_type interfaceMap;
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600172
Matt Spinlere2359fb2019-04-05 14:11:33 -0500173 AssociationMaps assocMaps;
174 assocMaps.owners = createDefaultOwnerAssociation();
175 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600176
177 // Empty endpoint will result in deletion of corresponding assocInterface
178 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500179 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600180
Andrew Geissler0a560a52019-03-22 10:59:07 -0500181 // Both of these should be 0 since we have an invalid endpoint
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600182 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500183 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler0a560a52019-03-22 10:59:07 -0500184 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -0500185 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600186 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500187
188 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600189}
190
191// Add a new association with endpoint
192TEST_F(TestAssociations, associationChangedAddNewAssoc)
193{
194 std::vector<Association> associations = {
195 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
196
Matt Spinlere2359fb2019-04-05 14:11:33 -0500197 AssociationMaps assocMaps;
198 assocMaps.owners = createDefaultOwnerAssociation();
199 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600200
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500201 // Make it look like the assoc endpoints are on D-Bus
202 interface_map_type interfaceMap = {
203 {"/new/source/path", {{DEFAULT_DBUS_SVC, {"a"}}}},
204 {"/xyz/openbmc_project/new/endpoint", {{DEFAULT_DBUS_SVC, {"a"}}}}};
205
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600206 associationChanged(*server, associations, "/new/source/path",
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500207 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600208
209 // Two source paths
Matt Spinlere2359fb2019-04-05 14:11:33 -0500210 EXPECT_EQ(assocMaps.owners.size(), 2);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600211
212 // Four interfaces
Matt Spinlere2359fb2019-04-05 14:11:33 -0500213 EXPECT_EQ(assocMaps.ifaces.size(), 4);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600214
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500215 // Nothing pending
216 EXPECT_EQ(assocMaps.pending.size(), 0);
217
Matt Spinlere2359fb2019-04-05 14:11:33 -0500218 // New endpoint so assocMaps.ifaces should be same size
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600219 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500220 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600221 EXPECT_EQ(intfEndpoints.size(), 1);
222}
223
224// Add a new association to empty objects
225TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
226{
227 std::string sourcePath = "/logging/entry/1";
228 std::string owner = "xyz.openbmc_project.Test";
229 std::vector<Association> associations = {
Andrew Geisslereecc1962020-06-10 19:58:35 -0500230 {"inventory_canaeo", "error_canaeo",
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600231 "/xyz/openbmc_project/inventory/system/chassis"}};
232
233 // Empty objects because this test will ensure assocOwners adds the
234 // changed association and interface
Matt Spinlere2359fb2019-04-05 14:11:33 -0500235 AssociationMaps assocMaps;
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600236
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500237 // Make it look like the assoc endpoints are on D-Bus
238 interface_map_type interfaceMap = createDefaultInterfaceMap();
239
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600240 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500241 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600242
243 // New associations so ensure it now contains a single entry
Matt Spinlere2359fb2019-04-05 14:11:33 -0500244 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600245
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500246 // Nothing pending
247 EXPECT_EQ(assocMaps.pending.size(), 0);
248
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600249 // Verify corresponding assoc paths each have one endpoint in assoc
250 // interfaces and that those endpoints match
Matt Spinlere2359fb2019-04-05 14:11:33 -0500251 auto singleOwner = assocMaps.owners[DEFAULT_SOURCE_PATH];
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600252 auto singleIntf = singleOwner[DEFAULT_DBUS_SVC];
253 for (auto i : singleIntf)
254 {
Matt Spinlere2359fb2019-04-05 14:11:33 -0500255 auto intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[i.first]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600256 EXPECT_EQ(intfEndpoints.size(), 1);
257 EXPECT_EQ(intfEndpoints[0], *i.second.begin());
258 }
259}
260
261// Add a new association to same source path but with new owner
262TEST_F(TestAssociations, associationChangedAddNewAssocNewOwner)
263{
264 std::string newOwner = "xyz.openbmc_project.Test2";
265 std::vector<Association> associations = {
Andrew Geisslereecc1962020-06-10 19:58:35 -0500266 {"inventory_canano", "error_canano",
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600267 "/xyz/openbmc_project/inventory/system/chassis"}};
268
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500269 // Make it look like the assoc endpoints are on D-Bus
270 interface_map_type interfaceMap = createDefaultInterfaceMap();
271
Matt Spinlere2359fb2019-04-05 14:11:33 -0500272 AssociationMaps assocMaps;
273 assocMaps.owners = createDefaultOwnerAssociation();
274 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600275
276 associationChanged(*server, associations, DEFAULT_SOURCE_PATH, newOwner,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500277 interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600278
279 // New endpoint so assocOwners should be same size
Matt Spinlere2359fb2019-04-05 14:11:33 -0500280 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600281
282 // Ensure only one endpoint under first path
283 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500284 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600285 EXPECT_EQ(intfEndpoints.size(), 1);
286
287 // Ensure the 2 new association endpoints are under the new owner
Matt Spinlere2359fb2019-04-05 14:11:33 -0500288 auto a = assocMaps.owners.find(DEFAULT_SOURCE_PATH);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600289 auto o = a->second.find(newOwner);
290 EXPECT_EQ(o->second.size(), 2);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500291
292 // Nothing pending
293 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600294}
295
296// Add a new association to existing interface path
297TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
298{
299 std::vector<Association> associations = {
300 {"abc", "error", "/xyz/openbmc_project/inventory/system/chassis"}};
301
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500302 // Make it look like the assoc endpoints are on D-Bus
303 interface_map_type interfaceMap = createDefaultInterfaceMap();
304
Matt Spinlere2359fb2019-04-05 14:11:33 -0500305 AssociationMaps assocMaps;
306 assocMaps.owners = createDefaultOwnerAssociation();
307 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600308
309 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500310 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600311
312 // Should have 3 entries in AssociationInterfaces, one is just missing an
313 // endpoint
Matt Spinlere2359fb2019-04-05 14:11:33 -0500314 EXPECT_EQ(assocMaps.ifaces.size(), 3);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600315
316 // Change to existing interface so it will be removed here
317 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500318 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600319 EXPECT_EQ(intfEndpoints.size(), 0);
320
321 // The new endpoint should exist though in it's place
322 intfEndpoints = std::get<endpointsPos>(
Matt Spinlere2359fb2019-04-05 14:11:33 -0500323 assocMaps.ifaces[DEFAULT_SOURCE_PATH + "/" + "abc"]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600324 EXPECT_EQ(intfEndpoints.size(), 1);
325
326 // Added to an existing owner path so still 1
Matt Spinlere2359fb2019-04-05 14:11:33 -0500327 EXPECT_EQ(assocMaps.owners.size(), 1);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500328
329 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600330}
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500331
332// Add 2 pending associations
333TEST_F(TestAssociations, addPendingAssocs)
334{
335 AssociationMaps assocMaps;
336
337 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
338 "error", DEFAULT_DBUS_SVC, assocMaps);
339
340 EXPECT_TRUE(assocMaps.ifaces.empty());
341 EXPECT_TRUE(assocMaps.owners.empty());
342
343 EXPECT_EQ(assocMaps.pending.size(), 1);
344
345 addPendingAssociation("some/other/path", "inventory", DEFAULT_ENDPOINT,
346 "error", DEFAULT_DBUS_SVC, assocMaps);
347
348 EXPECT_TRUE(assocMaps.ifaces.empty());
349 EXPECT_TRUE(assocMaps.owners.empty());
350
351 EXPECT_EQ(assocMaps.pending.size(), 2);
352}
353
354// Test adding a new endpoint to a pending association
355TEST_F(TestAssociations, addPendingAssocsNewEndpoints)
356{
357 AssociationMaps assocMaps;
358
359 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
360 "error", DEFAULT_DBUS_SVC, assocMaps);
361
362 EXPECT_EQ(assocMaps.pending.size(), 1);
363
364 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory",
365 "some/other/endpoint", "error", DEFAULT_DBUS_SVC,
366 assocMaps);
367
368 // Same pending path, so still just 1 entry
369 EXPECT_EQ(assocMaps.pending.size(), 1);
370
371 auto assoc = assocMaps.pending.find(DEFAULT_SOURCE_PATH);
372 EXPECT_NE(assoc, assocMaps.pending.end());
373
374 auto& endpoints = assoc->second;
375 EXPECT_EQ(endpoints.size(), 2);
376}
377
378// Test adding a new owner to a pending association
379TEST_F(TestAssociations, addPendingAssocsNewOwner)
380{
381 AssociationMaps assocMaps;
382
383 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
384 "error", DEFAULT_DBUS_SVC, assocMaps);
385
386 EXPECT_EQ(assocMaps.pending.size(), 1);
387
388 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
389 "error", "new owner", assocMaps);
390
391 EXPECT_EQ(assocMaps.pending.size(), 1);
392
393 auto assoc = assocMaps.pending.find(DEFAULT_SOURCE_PATH);
394 EXPECT_NE(assoc, assocMaps.pending.end());
395
396 auto& endpoints = assoc->second;
397 EXPECT_EQ(endpoints.size(), 2);
398}
399
400// Add a pending association inside associationChanged
401TEST_F(TestAssociations, associationChangedPending)
402{
403 std::vector<Association> associations = {
404 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
405
406 AssociationMaps assocMaps;
407 interface_map_type interfaceMap;
408
409 associationChanged(*server, associations, "/new/source/path",
410 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
411
412 // No associations were actually added
413 EXPECT_EQ(assocMaps.owners.size(), 0);
414 EXPECT_EQ(assocMaps.ifaces.size(), 0);
415
416 // 1 pending association
417 EXPECT_EQ(assocMaps.pending.size(), 1);
418}
Matt Spinlercb9bcdb2019-04-08 10:58:49 -0500419
420// Test removing pending associations
421TEST_F(TestAssociations, testRemoveFromPendingAssociations)
422{
423 AssociationMaps assocMaps;
424
425 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
426 "error", DEFAULT_DBUS_SVC, assocMaps);
427
428 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory",
429 "some/other/endpoint", "error", DEFAULT_DBUS_SVC,
430 assocMaps);
431
432 EXPECT_EQ(assocMaps.pending.size(), 1);
433
434 removeFromPendingAssociations("some/other/endpoint", assocMaps);
435
436 // Still 1 pending entry, but down to 1 endpoint
437 EXPECT_EQ(assocMaps.pending.size(), 1);
438
439 auto assoc = assocMaps.pending.find(DEFAULT_SOURCE_PATH);
440 EXPECT_NE(assoc, assocMaps.pending.end());
441 auto& endpoints = assoc->second;
442 EXPECT_EQ(endpoints.size(), 1);
443
444 // Now nothing pending
445 removeFromPendingAssociations(DEFAULT_ENDPOINT, assocMaps);
446 EXPECT_EQ(assocMaps.pending.size(), 0);
447}
Matt Spinler11401e22019-04-08 13:13:25 -0500448
449// Test moving a pending association to a real one
450TEST_F(TestAssociations, checkIfPending)
451{
452 AssociationMaps assocMaps;
453 interface_map_type interfaceMap = {
454 {DEFAULT_SOURCE_PATH, {{DEFAULT_DBUS_SVC, {"a"}}}},
455 {DEFAULT_ENDPOINT, {{DEFAULT_DBUS_SVC, {"b"}}}}};
456
Andrew Geisslereecc1962020-06-10 19:58:35 -0500457 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory_cip",
458 DEFAULT_ENDPOINT, "error_cip", DEFAULT_DBUS_SVC,
459 assocMaps);
Matt Spinler11401e22019-04-08 13:13:25 -0500460 EXPECT_EQ(assocMaps.pending.size(), 1);
461
462 // Move the pending association to a real association
463 checkIfPendingAssociation(DEFAULT_SOURCE_PATH, interfaceMap, assocMaps,
464 *server);
465
466 EXPECT_TRUE(assocMaps.pending.empty());
467 EXPECT_EQ(assocMaps.owners.size(), 1);
468 EXPECT_EQ(assocMaps.ifaces.size(), 2);
469
470 // This shouldn't do anything, since /new/path isn't pending
471 checkIfPendingAssociation("/new/path", interfaceMap, assocMaps, *server);
472 EXPECT_TRUE(assocMaps.pending.empty());
473 EXPECT_EQ(assocMaps.owners.size(), 1);
474 EXPECT_EQ(assocMaps.ifaces.size(), 2);
475}
Matt Spinler7f8fd1f2019-04-08 15:21:59 -0500476
477TEST_F(TestAssociations, findAssociations)
478{
479 std::vector<std::tuple<std::string, Association>> associationData;
480 AssociationMaps assocMaps;
481
482 assocMaps.owners = {
483 {"pathA",
484 {{"ownerA",
485 {{"pathA/typeA", {"endpointA", "endpointB"}},
486 {"endpointA/type0", {"pathA"}}}}}},
487
488 {"pathJ",
489 {{"ownerC",
490 {{"pathJ/typeA", {"endpointF"}}, {"endpointF/type0", {"pathJ"}}}}}},
491
492 {"pathX",
493 {{"ownerB",
494 {{"pathX/typeB", {"endpointA"}}, {"endpointA/type1", {"pathX"}}}}}}};
495
496 findAssociations("endpointA", assocMaps, associationData);
497 ASSERT_EQ(associationData.size(), 2);
498
499 {
500 auto ad = std::find_if(
501 associationData.begin(), associationData.end(),
502 [](const auto& ad) { return std::get<0>(ad) == "ownerA"; });
503 ASSERT_NE(ad, associationData.end());
504
505 auto& a = std::get<1>(*ad);
506 ASSERT_EQ(std::get<0>(a), "type0");
507 ASSERT_EQ(std::get<1>(a), "typeA");
508 ASSERT_EQ(std::get<2>(a), "pathA");
509 }
510 {
511 auto ad = std::find_if(
512 associationData.begin(), associationData.end(),
513 [](const auto& ad) { return std::get<0>(ad) == "ownerB"; });
514 ASSERT_NE(ad, associationData.end());
515
516 auto& a = std::get<1>(*ad);
517 ASSERT_EQ(std::get<0>(a), "type1");
518 ASSERT_EQ(std::get<1>(a), "typeB");
519 ASSERT_EQ(std::get<2>(a), "pathX");
520 }
521}
Matt Spinler9c3d2852019-04-08 15:57:19 -0500522
523TEST_F(TestAssociations, moveAssocToPendingNoOp)
524{
525 AssociationMaps assocMaps;
526
527 // Not an association, so it shouldn't do anything
528 moveAssociationToPending(DEFAULT_ENDPOINT, assocMaps, *server);
529
530 EXPECT_TRUE(assocMaps.pending.empty());
531 EXPECT_TRUE(assocMaps.owners.empty());
532 EXPECT_TRUE(assocMaps.ifaces.empty());
533}
534
535TEST_F(TestAssociations, moveAssocToPending)
536{
537 AssociationMaps assocMaps;
538 assocMaps.owners = createDefaultOwnerAssociation();
539 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
540
541 moveAssociationToPending(DEFAULT_ENDPOINT, assocMaps, *server);
542
543 // Check it's now pending
544 EXPECT_EQ(assocMaps.pending.size(), 1);
545 EXPECT_EQ(assocMaps.pending.begin()->first, DEFAULT_ENDPOINT);
546
547 // No more assoc owners
548 EXPECT_TRUE(assocMaps.owners.empty());
549
550 // Check the association interfaces were removed
551 {
552 auto assocs = assocMaps.ifaces.find(DEFAULT_FWD_PATH);
553 auto& iface = std::get<ifacePos>(assocs->second);
554 auto& endpoints = std::get<endpointsPos>(assocs->second);
555
556 EXPECT_EQ(iface.get(), nullptr);
557 EXPECT_TRUE(endpoints.empty());
558 }
559 {
560 auto assocs = assocMaps.ifaces.find(DEFAULT_REV_PATH);
561 auto& iface = std::get<ifacePos>(assocs->second);
562 auto& endpoints = std::get<endpointsPos>(assocs->second);
563
564 EXPECT_EQ(iface.get(), nullptr);
565 EXPECT_TRUE(endpoints.empty());
566 }
567}