blob: 50706d78e797ca171b33d39ce70c196ef08248bb [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{
169 std::vector<Association> associations = {{"inventory", "error", ""}};
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500170 interface_map_type interfaceMap;
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600171
Matt Spinlere2359fb2019-04-05 14:11:33 -0500172 AssociationMaps assocMaps;
173 assocMaps.owners = createDefaultOwnerAssociation();
174 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600175
176 // Empty endpoint will result in deletion of corresponding assocInterface
177 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500178 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600179
Andrew Geissler0a560a52019-03-22 10:59:07 -0500180 // Both of these should be 0 since we have an invalid endpoint
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600181 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500182 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler0a560a52019-03-22 10:59:07 -0500183 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere2359fb2019-04-05 14:11:33 -0500184 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_REV_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600185 EXPECT_EQ(intfEndpoints.size(), 0);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500186
187 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600188}
189
190// Add a new association with endpoint
191TEST_F(TestAssociations, associationChangedAddNewAssoc)
192{
193 std::vector<Association> associations = {
194 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
195
Matt Spinlere2359fb2019-04-05 14:11:33 -0500196 AssociationMaps assocMaps;
197 assocMaps.owners = createDefaultOwnerAssociation();
198 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600199
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500200 // Make it look like the assoc endpoints are on D-Bus
201 interface_map_type interfaceMap = {
202 {"/new/source/path", {{DEFAULT_DBUS_SVC, {"a"}}}},
203 {"/xyz/openbmc_project/new/endpoint", {{DEFAULT_DBUS_SVC, {"a"}}}}};
204
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600205 associationChanged(*server, associations, "/new/source/path",
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500206 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600207
208 // Two source paths
Matt Spinlere2359fb2019-04-05 14:11:33 -0500209 EXPECT_EQ(assocMaps.owners.size(), 2);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600210
211 // Four interfaces
Matt Spinlere2359fb2019-04-05 14:11:33 -0500212 EXPECT_EQ(assocMaps.ifaces.size(), 4);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600213
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500214 // Nothing pending
215 EXPECT_EQ(assocMaps.pending.size(), 0);
216
Matt Spinlere2359fb2019-04-05 14:11:33 -0500217 // New endpoint so assocMaps.ifaces should be same size
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600218 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500219 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600220 EXPECT_EQ(intfEndpoints.size(), 1);
221}
222
223// Add a new association to empty objects
224TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
225{
226 std::string sourcePath = "/logging/entry/1";
227 std::string owner = "xyz.openbmc_project.Test";
228 std::vector<Association> associations = {
229 {"inventory", "error",
230 "/xyz/openbmc_project/inventory/system/chassis"}};
231
232 // Empty objects because this test will ensure assocOwners adds the
233 // changed association and interface
Matt Spinlere2359fb2019-04-05 14:11:33 -0500234 AssociationMaps assocMaps;
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600235
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500236 // Make it look like the assoc endpoints are on D-Bus
237 interface_map_type interfaceMap = createDefaultInterfaceMap();
238
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600239 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500240 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600241
242 // New associations so ensure it now contains a single entry
Matt Spinlere2359fb2019-04-05 14:11:33 -0500243 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600244
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500245 // Nothing pending
246 EXPECT_EQ(assocMaps.pending.size(), 0);
247
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600248 // Verify corresponding assoc paths each have one endpoint in assoc
249 // interfaces and that those endpoints match
Matt Spinlere2359fb2019-04-05 14:11:33 -0500250 auto singleOwner = assocMaps.owners[DEFAULT_SOURCE_PATH];
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600251 auto singleIntf = singleOwner[DEFAULT_DBUS_SVC];
252 for (auto i : singleIntf)
253 {
Matt Spinlere2359fb2019-04-05 14:11:33 -0500254 auto intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[i.first]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600255 EXPECT_EQ(intfEndpoints.size(), 1);
256 EXPECT_EQ(intfEndpoints[0], *i.second.begin());
257 }
258}
259
260// Add a new association to same source path but with new owner
261TEST_F(TestAssociations, associationChangedAddNewAssocNewOwner)
262{
263 std::string newOwner = "xyz.openbmc_project.Test2";
264 std::vector<Association> associations = {
265 {"inventory", "error",
266 "/xyz/openbmc_project/inventory/system/chassis"}};
267
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500268 // Make it look like the assoc endpoints are on D-Bus
269 interface_map_type interfaceMap = createDefaultInterfaceMap();
270
Matt Spinlere2359fb2019-04-05 14:11:33 -0500271 AssociationMaps assocMaps;
272 assocMaps.owners = createDefaultOwnerAssociation();
273 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600274
275 associationChanged(*server, associations, DEFAULT_SOURCE_PATH, newOwner,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500276 interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600277
278 // New endpoint so assocOwners should be same size
Matt Spinlere2359fb2019-04-05 14:11:33 -0500279 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600280
281 // Ensure only one endpoint under first path
282 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500283 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600284 EXPECT_EQ(intfEndpoints.size(), 1);
285
286 // Ensure the 2 new association endpoints are under the new owner
Matt Spinlere2359fb2019-04-05 14:11:33 -0500287 auto a = assocMaps.owners.find(DEFAULT_SOURCE_PATH);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600288 auto o = a->second.find(newOwner);
289 EXPECT_EQ(o->second.size(), 2);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500290
291 // Nothing pending
292 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600293}
294
295// Add a new association to existing interface path
296TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
297{
298 std::vector<Association> associations = {
299 {"abc", "error", "/xyz/openbmc_project/inventory/system/chassis"}};
300
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500301 // Make it look like the assoc endpoints are on D-Bus
302 interface_map_type interfaceMap = createDefaultInterfaceMap();
303
Matt Spinlere2359fb2019-04-05 14:11:33 -0500304 AssociationMaps assocMaps;
305 assocMaps.owners = createDefaultOwnerAssociation();
306 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600307
308 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500309 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600310
311 // Should have 3 entries in AssociationInterfaces, one is just missing an
312 // endpoint
Matt Spinlere2359fb2019-04-05 14:11:33 -0500313 EXPECT_EQ(assocMaps.ifaces.size(), 3);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600314
315 // Change to existing interface so it will be removed here
316 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500317 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600318 EXPECT_EQ(intfEndpoints.size(), 0);
319
320 // The new endpoint should exist though in it's place
321 intfEndpoints = std::get<endpointsPos>(
Matt Spinlere2359fb2019-04-05 14:11:33 -0500322 assocMaps.ifaces[DEFAULT_SOURCE_PATH + "/" + "abc"]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600323 EXPECT_EQ(intfEndpoints.size(), 1);
324
325 // Added to an existing owner path so still 1
Matt Spinlere2359fb2019-04-05 14:11:33 -0500326 EXPECT_EQ(assocMaps.owners.size(), 1);
Matt Spinlere0b0e3a2019-04-08 10:39:23 -0500327
328 EXPECT_EQ(assocMaps.pending.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600329}
Matt Spinler9f1adbc2019-04-08 10:47:19 -0500330
331// Add 2 pending associations
332TEST_F(TestAssociations, addPendingAssocs)
333{
334 AssociationMaps assocMaps;
335
336 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
337 "error", DEFAULT_DBUS_SVC, assocMaps);
338
339 EXPECT_TRUE(assocMaps.ifaces.empty());
340 EXPECT_TRUE(assocMaps.owners.empty());
341
342 EXPECT_EQ(assocMaps.pending.size(), 1);
343
344 addPendingAssociation("some/other/path", "inventory", DEFAULT_ENDPOINT,
345 "error", DEFAULT_DBUS_SVC, assocMaps);
346
347 EXPECT_TRUE(assocMaps.ifaces.empty());
348 EXPECT_TRUE(assocMaps.owners.empty());
349
350 EXPECT_EQ(assocMaps.pending.size(), 2);
351}
352
353// Test adding a new endpoint to a pending association
354TEST_F(TestAssociations, addPendingAssocsNewEndpoints)
355{
356 AssociationMaps assocMaps;
357
358 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
359 "error", DEFAULT_DBUS_SVC, assocMaps);
360
361 EXPECT_EQ(assocMaps.pending.size(), 1);
362
363 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory",
364 "some/other/endpoint", "error", DEFAULT_DBUS_SVC,
365 assocMaps);
366
367 // Same pending path, so still just 1 entry
368 EXPECT_EQ(assocMaps.pending.size(), 1);
369
370 auto assoc = assocMaps.pending.find(DEFAULT_SOURCE_PATH);
371 EXPECT_NE(assoc, assocMaps.pending.end());
372
373 auto& endpoints = assoc->second;
374 EXPECT_EQ(endpoints.size(), 2);
375}
376
377// Test adding a new owner to a pending association
378TEST_F(TestAssociations, addPendingAssocsNewOwner)
379{
380 AssociationMaps assocMaps;
381
382 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
383 "error", DEFAULT_DBUS_SVC, assocMaps);
384
385 EXPECT_EQ(assocMaps.pending.size(), 1);
386
387 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
388 "error", "new owner", assocMaps);
389
390 EXPECT_EQ(assocMaps.pending.size(), 1);
391
392 auto assoc = assocMaps.pending.find(DEFAULT_SOURCE_PATH);
393 EXPECT_NE(assoc, assocMaps.pending.end());
394
395 auto& endpoints = assoc->second;
396 EXPECT_EQ(endpoints.size(), 2);
397}
398
399// Add a pending association inside associationChanged
400TEST_F(TestAssociations, associationChangedPending)
401{
402 std::vector<Association> associations = {
403 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
404
405 AssociationMaps assocMaps;
406 interface_map_type interfaceMap;
407
408 associationChanged(*server, associations, "/new/source/path",
409 DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
410
411 // No associations were actually added
412 EXPECT_EQ(assocMaps.owners.size(), 0);
413 EXPECT_EQ(assocMaps.ifaces.size(), 0);
414
415 // 1 pending association
416 EXPECT_EQ(assocMaps.pending.size(), 1);
417}
Matt Spinlercb9bcdb2019-04-08 10:58:49 -0500418
419// Test removing pending associations
420TEST_F(TestAssociations, testRemoveFromPendingAssociations)
421{
422 AssociationMaps assocMaps;
423
424 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
425 "error", DEFAULT_DBUS_SVC, assocMaps);
426
427 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory",
428 "some/other/endpoint", "error", DEFAULT_DBUS_SVC,
429 assocMaps);
430
431 EXPECT_EQ(assocMaps.pending.size(), 1);
432
433 removeFromPendingAssociations("some/other/endpoint", assocMaps);
434
435 // Still 1 pending entry, but down to 1 endpoint
436 EXPECT_EQ(assocMaps.pending.size(), 1);
437
438 auto assoc = assocMaps.pending.find(DEFAULT_SOURCE_PATH);
439 EXPECT_NE(assoc, assocMaps.pending.end());
440 auto& endpoints = assoc->second;
441 EXPECT_EQ(endpoints.size(), 1);
442
443 // Now nothing pending
444 removeFromPendingAssociations(DEFAULT_ENDPOINT, assocMaps);
445 EXPECT_EQ(assocMaps.pending.size(), 0);
446}
Matt Spinler11401e22019-04-08 13:13:25 -0500447
448// Test moving a pending association to a real one
449TEST_F(TestAssociations, checkIfPending)
450{
451 AssociationMaps assocMaps;
452 interface_map_type interfaceMap = {
453 {DEFAULT_SOURCE_PATH, {{DEFAULT_DBUS_SVC, {"a"}}}},
454 {DEFAULT_ENDPOINT, {{DEFAULT_DBUS_SVC, {"b"}}}}};
455
456 addPendingAssociation(DEFAULT_SOURCE_PATH, "inventory", DEFAULT_ENDPOINT,
457 "error", DEFAULT_DBUS_SVC, assocMaps);
458 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}