blob: ce3c9eb4b665dc9ab544f81a8e5b00145301e277 [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", ""}};
170
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 Spinlere2359fb2019-04-05 14:11:33 -0500177 DEFAULT_DBUS_SVC, 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);
185}
186
187// Add a new association with endpoint
188TEST_F(TestAssociations, associationChangedAddNewAssoc)
189{
190 std::vector<Association> associations = {
191 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
192
Matt Spinlere2359fb2019-04-05 14:11:33 -0500193 AssociationMaps assocMaps;
194 assocMaps.owners = createDefaultOwnerAssociation();
195 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600196
197 associationChanged(*server, associations, "/new/source/path",
Matt Spinlere2359fb2019-04-05 14:11:33 -0500198 DEFAULT_DBUS_SVC, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600199
200 // Two source paths
Matt Spinlere2359fb2019-04-05 14:11:33 -0500201 EXPECT_EQ(assocMaps.owners.size(), 2);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600202
203 // Four interfaces
Matt Spinlere2359fb2019-04-05 14:11:33 -0500204 EXPECT_EQ(assocMaps.ifaces.size(), 4);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600205
Matt Spinlere2359fb2019-04-05 14:11:33 -0500206 // New endpoint so assocMaps.ifaces should be same size
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600207 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500208 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600209 EXPECT_EQ(intfEndpoints.size(), 1);
210}
211
212// Add a new association to empty objects
213TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
214{
215 std::string sourcePath = "/logging/entry/1";
216 std::string owner = "xyz.openbmc_project.Test";
217 std::vector<Association> associations = {
218 {"inventory", "error",
219 "/xyz/openbmc_project/inventory/system/chassis"}};
220
221 // Empty objects because this test will ensure assocOwners adds the
222 // changed association and interface
Matt Spinlere2359fb2019-04-05 14:11:33 -0500223 AssociationMaps assocMaps;
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600224
225 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500226 DEFAULT_DBUS_SVC, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600227
228 // New associations so ensure it now contains a single entry
Matt Spinlere2359fb2019-04-05 14:11:33 -0500229 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600230
231 // Verify corresponding assoc paths each have one endpoint in assoc
232 // interfaces and that those endpoints match
Matt Spinlere2359fb2019-04-05 14:11:33 -0500233 auto singleOwner = assocMaps.owners[DEFAULT_SOURCE_PATH];
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600234 auto singleIntf = singleOwner[DEFAULT_DBUS_SVC];
235 for (auto i : singleIntf)
236 {
Matt Spinlere2359fb2019-04-05 14:11:33 -0500237 auto intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[i.first]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600238 EXPECT_EQ(intfEndpoints.size(), 1);
239 EXPECT_EQ(intfEndpoints[0], *i.second.begin());
240 }
241}
242
243// Add a new association to same source path but with new owner
244TEST_F(TestAssociations, associationChangedAddNewAssocNewOwner)
245{
246 std::string newOwner = "xyz.openbmc_project.Test2";
247 std::vector<Association> associations = {
248 {"inventory", "error",
249 "/xyz/openbmc_project/inventory/system/chassis"}};
250
Matt Spinlere2359fb2019-04-05 14:11:33 -0500251 AssociationMaps assocMaps;
252 assocMaps.owners = createDefaultOwnerAssociation();
253 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600254
255 associationChanged(*server, associations, DEFAULT_SOURCE_PATH, newOwner,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500256 assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600257
258 // New endpoint so assocOwners should be same size
Matt Spinlere2359fb2019-04-05 14:11:33 -0500259 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600260
261 // Ensure only one endpoint under first path
262 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500263 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600264 EXPECT_EQ(intfEndpoints.size(), 1);
265
266 // Ensure the 2 new association endpoints are under the new owner
Matt Spinlere2359fb2019-04-05 14:11:33 -0500267 auto a = assocMaps.owners.find(DEFAULT_SOURCE_PATH);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600268 auto o = a->second.find(newOwner);
269 EXPECT_EQ(o->second.size(), 2);
270}
271
272// Add a new association to existing interface path
273TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
274{
275 std::vector<Association> associations = {
276 {"abc", "error", "/xyz/openbmc_project/inventory/system/chassis"}};
277
Matt Spinlere2359fb2019-04-05 14:11:33 -0500278 AssociationMaps assocMaps;
279 assocMaps.owners = createDefaultOwnerAssociation();
280 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600281
282 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
Matt Spinlere2359fb2019-04-05 14:11:33 -0500283 DEFAULT_DBUS_SVC, assocMaps);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600284
285 // Should have 3 entries in AssociationInterfaces, one is just missing an
286 // endpoint
Matt Spinlere2359fb2019-04-05 14:11:33 -0500287 EXPECT_EQ(assocMaps.ifaces.size(), 3);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600288
289 // Change to existing interface so it will be removed here
290 auto intfEndpoints =
Matt Spinlere2359fb2019-04-05 14:11:33 -0500291 std::get<endpointsPos>(assocMaps.ifaces[DEFAULT_FWD_PATH]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600292 EXPECT_EQ(intfEndpoints.size(), 0);
293
294 // The new endpoint should exist though in it's place
295 intfEndpoints = std::get<endpointsPos>(
Matt Spinlere2359fb2019-04-05 14:11:33 -0500296 assocMaps.ifaces[DEFAULT_SOURCE_PATH + "/" + "abc"]);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600297 EXPECT_EQ(intfEndpoints.size(), 1);
298
299 // Added to an existing owner path so still 1
Matt Spinlere2359fb2019-04-05 14:11:33 -0500300 EXPECT_EQ(assocMaps.owners.size(), 1);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600301}