blob: 1b6a348efb97557bf9a50d518e900c080b8e8ecf [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";
23 AssociationOwnersType assocOwners;
24 AssociationInterfaces assocInterfaces;
25
26 removeAssociation(sourcePath, DEFAULT_DBUS_SVC, *server, assocOwners,
27 assocInterfaces);
28}
29
30// Verify call when owner is not in associated owners
31TEST_F(TestAssociations, OwnerNotInAssociations)
32{
33 AssociationInterfaces assocInterfaces;
34
35 auto assocOwners = createDefaultOwnerAssociation();
36
37 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
38 assocOwners, assocInterfaces);
39}
40
41// Verify call when path is not in associated interfaces
42TEST_F(TestAssociations, PathNotInAssocInterfaces)
43{
44 AssociationInterfaces assocInterfaces;
45
46 auto assocOwners = createDefaultOwnerAssociation();
47
48 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
49 assocOwners, assocInterfaces);
50
51 EXPECT_TRUE(assocOwners.empty());
52}
53
54// Verify call when path is in associated interfaces
55TEST_F(TestAssociations, PathIsInAssociatedInterfaces)
56{
57 // Build up these objects so that an associated interface will match
58 // with the associated owner being removed
59 auto assocOwners = createDefaultOwnerAssociation();
60 auto assocInterfaces = createDefaultInterfaceAssociation(server);
61
62 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
63 assocOwners, assocInterfaces);
64
65 // Verify owner association was deleted
66 EXPECT_TRUE(assocOwners.empty());
67
68 // Verify endpoint was deleted from interface association
69 auto intfEndpoints =
70 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
71 EXPECT_EQ(intfEndpoints.size(), 0);
72 intfEndpoints = std::get<endpointsPos>(assocInterfaces[DEFAULT_REV_PATH]);
73 EXPECT_EQ(intfEndpoints.size(), 0);
74}
75
76// Verify call when path is in associated interfaces, with extra endpoints
77TEST_F(TestAssociations, PathIsInAssociatedInterfacesExtraEndpoints)
78{
79 // Build up these objects so that an associated interface will match
80 // with the associated owner being removed
81 auto assocOwners = createDefaultOwnerAssociation();
82 auto assocInterfaces = createDefaultInterfaceAssociation(server);
83
84 // Add another endpoint to the assoc interfaces
85 addEndpointToInterfaceAssociation(assocInterfaces);
86
87 removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
88 assocOwners, assocInterfaces);
89
90 // Verify owner association was deleted
91 EXPECT_TRUE(assocOwners.empty());
92
93 // Verify all endpoints are deleted since source path was deleted
94 auto intfEndpoints =
95 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
96 EXPECT_EQ(intfEndpoints.size(), 0);
97 intfEndpoints = std::get<endpointsPos>(assocInterfaces[DEFAULT_REV_PATH]);
98 EXPECT_EQ(intfEndpoints.size(), 0);
99}
Andrew Geisslere4ab6c92019-02-21 15:07:27 -0600100
101// Verify no associations or endpoints removed when the change is identical
102TEST_F(TestAssociations, checkAssociationEndpointRemovesNoEpRemove)
103{
104
105 AssociationPaths newAssocPaths = {
106 {DEFAULT_FWD_PATH, {DEFAULT_ENDPOINT}},
107 {DEFAULT_REV_PATH, {DEFAULT_SOURCE_PATH}}};
108
109 auto assocOwners = createDefaultOwnerAssociation();
110 auto assocInterfaces = createDefaultInterfaceAssociation(server);
111
112 checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
113 newAssocPaths, *server, assocOwners,
114 assocInterfaces);
115
116 // Verify endpoints were not deleted because they matche with what was
117 // in the original
118 auto intfEndpoints =
119 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
120 EXPECT_EQ(intfEndpoints.size(), 1);
121 intfEndpoints = std::get<endpointsPos>(assocInterfaces[DEFAULT_REV_PATH]);
122 EXPECT_EQ(intfEndpoints.size(), 1);
123}
124
125// Verify endpoint is removed when assoc path is different
126TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveApDiff)
127{
128 AssociationPaths newAssocPaths = {{"/different/path", {DEFAULT_ENDPOINT}}};
129
130 auto assocOwners = createDefaultOwnerAssociation();
131 auto assocInterfaces = createDefaultInterfaceAssociation(server);
132
133 checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
134 newAssocPaths, *server, assocOwners,
135 assocInterfaces);
136
137 // Verify initial endpoints were deleted because the new path
138 auto intfEndpoints =
139 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
140 EXPECT_EQ(intfEndpoints.size(), 0);
141 intfEndpoints = std::get<endpointsPos>(assocInterfaces[DEFAULT_REV_PATH]);
142 EXPECT_EQ(intfEndpoints.size(), 0);
143}
144
145// Verify endpoint is removed when endpoint is different
146TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveEpChanged)
147{
148 AssociationPaths newAssocPaths = {
149 {DEFAULT_FWD_PATH, {DEFAULT_ENDPOINT + "/different"}},
150 {DEFAULT_REV_PATH, {DEFAULT_SOURCE_PATH + "/different"}}};
151
152 auto assocOwners = createDefaultOwnerAssociation();
153 auto assocInterfaces = createDefaultInterfaceAssociation(server);
154
155 checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
156 newAssocPaths, *server, assocOwners,
157 assocInterfaces);
158
159 // Verify initial endpoints were deleted because of different endpoints
160 auto intfEndpoints =
161 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
162 EXPECT_EQ(intfEndpoints.size(), 0);
163 intfEndpoints = std::get<endpointsPos>(assocInterfaces[DEFAULT_REV_PATH]);
164 EXPECT_EQ(intfEndpoints.size(), 0);
165}
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600166
167// Verify existing endpoint deleted when empty endpoint is provided
168TEST_F(TestAssociations, associationChangedEmptyEndpoint)
169{
170 std::vector<Association> associations = {{"inventory", "error", ""}};
171
172 auto assocOwners = createDefaultOwnerAssociation();
173 auto assocInterfaces = createDefaultInterfaceAssociation(server);
174
175 // Empty endpoint will result in deletion of corresponding assocInterface
176 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
177 DEFAULT_DBUS_SVC, assocOwners, assocInterfaces);
178
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 =
181 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
Andrew Geissler0a560a52019-03-22 10:59:07 -0500182 EXPECT_EQ(intfEndpoints.size(), 0);
Andrew Geissler491f9ac2019-02-22 15:23:33 -0600183 intfEndpoints = std::get<endpointsPos>(assocInterfaces[DEFAULT_REV_PATH]);
184 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
193 auto assocOwners = createDefaultOwnerAssociation();
194 auto assocInterfaces = createDefaultInterfaceAssociation(server);
195
196 associationChanged(*server, associations, "/new/source/path",
197 DEFAULT_DBUS_SVC, assocOwners, assocInterfaces);
198
199 // Two source paths
200 EXPECT_EQ(assocOwners.size(), 2);
201
202 // Four interfaces
203 EXPECT_EQ(assocInterfaces.size(), 4);
204
205 // New endpoint so assocInterfaces should be same size
206 auto intfEndpoints =
207 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
208 EXPECT_EQ(intfEndpoints.size(), 1);
209}
210
211// Add a new association to empty objects
212TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
213{
214 std::string sourcePath = "/logging/entry/1";
215 std::string owner = "xyz.openbmc_project.Test";
216 std::vector<Association> associations = {
217 {"inventory", "error",
218 "/xyz/openbmc_project/inventory/system/chassis"}};
219
220 // Empty objects because this test will ensure assocOwners adds the
221 // changed association and interface
222 AssociationInterfaces assocInterfaces;
223 AssociationOwnersType assocOwners;
224
225 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
226 DEFAULT_DBUS_SVC, assocOwners, assocInterfaces);
227
228 // New associations so ensure it now contains a single entry
229 EXPECT_EQ(assocOwners.size(), 1);
230
231 // Verify corresponding assoc paths each have one endpoint in assoc
232 // interfaces and that those endpoints match
233 auto singleOwner = assocOwners[DEFAULT_SOURCE_PATH];
234 auto singleIntf = singleOwner[DEFAULT_DBUS_SVC];
235 for (auto i : singleIntf)
236 {
237 auto intfEndpoints = std::get<endpointsPos>(assocInterfaces[i.first]);
238 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
251 auto assocOwners = createDefaultOwnerAssociation();
252 auto assocInterfaces = createDefaultInterfaceAssociation(server);
253
254 associationChanged(*server, associations, DEFAULT_SOURCE_PATH, newOwner,
255 assocOwners, assocInterfaces);
256
257 // New endpoint so assocOwners should be same size
258 EXPECT_EQ(assocOwners.size(), 1);
259
260 // Ensure only one endpoint under first path
261 auto intfEndpoints =
262 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
263 EXPECT_EQ(intfEndpoints.size(), 1);
264
265 // Ensure the 2 new association endpoints are under the new owner
266 auto a = assocOwners.find(DEFAULT_SOURCE_PATH);
267 auto o = a->second.find(newOwner);
268 EXPECT_EQ(o->second.size(), 2);
269}
270
271// Add a new association to existing interface path
272TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
273{
274 std::vector<Association> associations = {
275 {"abc", "error", "/xyz/openbmc_project/inventory/system/chassis"}};
276
277 auto assocOwners = createDefaultOwnerAssociation();
278 auto assocInterfaces = createDefaultInterfaceAssociation(server);
279
280 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
281 DEFAULT_DBUS_SVC, assocOwners, assocInterfaces);
282
283 // Should have 3 entries in AssociationInterfaces, one is just missing an
284 // endpoint
285 EXPECT_EQ(assocInterfaces.size(), 3);
286
287 // Change to existing interface so it will be removed here
288 auto intfEndpoints =
289 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
290 EXPECT_EQ(intfEndpoints.size(), 0);
291
292 // The new endpoint should exist though in it's place
293 intfEndpoints = std::get<endpointsPos>(
294 assocInterfaces[DEFAULT_SOURCE_PATH + "/" + "abc"]);
295 EXPECT_EQ(intfEndpoints.size(), 1);
296
297 // Added to an existing owner path so still 1
298 EXPECT_EQ(assocOwners.size(), 1);
299}