blob: 20d7ba776dc914c34dda245bbed544a0bba7a795 [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
179 // TODO - This test case found a bug where the endpoint validity
180 // is not checked on the FWD path and is used by default, resulting
181 // in there being a "" endpoint value. Will fix this in next commit
182 // to keep the refactor of the code separate from the fix
183 // (i.e. both of these should be 0 since we have an invalid endpoint)
184 auto intfEndpoints =
185 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
186 EXPECT_EQ(intfEndpoints.size(), 1);
187 intfEndpoints = std::get<endpointsPos>(assocInterfaces[DEFAULT_REV_PATH]);
188 EXPECT_EQ(intfEndpoints.size(), 0);
189}
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
197 auto assocOwners = createDefaultOwnerAssociation();
198 auto assocInterfaces = createDefaultInterfaceAssociation(server);
199
200 associationChanged(*server, associations, "/new/source/path",
201 DEFAULT_DBUS_SVC, assocOwners, assocInterfaces);
202
203 // Two source paths
204 EXPECT_EQ(assocOwners.size(), 2);
205
206 // Four interfaces
207 EXPECT_EQ(assocInterfaces.size(), 4);
208
209 // New endpoint so assocInterfaces should be same size
210 auto intfEndpoints =
211 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
212 EXPECT_EQ(intfEndpoints.size(), 1);
213}
214
215// Add a new association to empty objects
216TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
217{
218 std::string sourcePath = "/logging/entry/1";
219 std::string owner = "xyz.openbmc_project.Test";
220 std::vector<Association> associations = {
221 {"inventory", "error",
222 "/xyz/openbmc_project/inventory/system/chassis"}};
223
224 // Empty objects because this test will ensure assocOwners adds the
225 // changed association and interface
226 AssociationInterfaces assocInterfaces;
227 AssociationOwnersType assocOwners;
228
229 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
230 DEFAULT_DBUS_SVC, assocOwners, assocInterfaces);
231
232 // New associations so ensure it now contains a single entry
233 EXPECT_EQ(assocOwners.size(), 1);
234
235 // Verify corresponding assoc paths each have one endpoint in assoc
236 // interfaces and that those endpoints match
237 auto singleOwner = assocOwners[DEFAULT_SOURCE_PATH];
238 auto singleIntf = singleOwner[DEFAULT_DBUS_SVC];
239 for (auto i : singleIntf)
240 {
241 auto intfEndpoints = std::get<endpointsPos>(assocInterfaces[i.first]);
242 EXPECT_EQ(intfEndpoints.size(), 1);
243 EXPECT_EQ(intfEndpoints[0], *i.second.begin());
244 }
245}
246
247// Add a new association to same source path but with new owner
248TEST_F(TestAssociations, associationChangedAddNewAssocNewOwner)
249{
250 std::string newOwner = "xyz.openbmc_project.Test2";
251 std::vector<Association> associations = {
252 {"inventory", "error",
253 "/xyz/openbmc_project/inventory/system/chassis"}};
254
255 auto assocOwners = createDefaultOwnerAssociation();
256 auto assocInterfaces = createDefaultInterfaceAssociation(server);
257
258 associationChanged(*server, associations, DEFAULT_SOURCE_PATH, newOwner,
259 assocOwners, assocInterfaces);
260
261 // New endpoint so assocOwners should be same size
262 EXPECT_EQ(assocOwners.size(), 1);
263
264 // Ensure only one endpoint under first path
265 auto intfEndpoints =
266 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
267 EXPECT_EQ(intfEndpoints.size(), 1);
268
269 // Ensure the 2 new association endpoints are under the new owner
270 auto a = assocOwners.find(DEFAULT_SOURCE_PATH);
271 auto o = a->second.find(newOwner);
272 EXPECT_EQ(o->second.size(), 2);
273}
274
275// Add a new association to existing interface path
276TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
277{
278 std::vector<Association> associations = {
279 {"abc", "error", "/xyz/openbmc_project/inventory/system/chassis"}};
280
281 auto assocOwners = createDefaultOwnerAssociation();
282 auto assocInterfaces = createDefaultInterfaceAssociation(server);
283
284 associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
285 DEFAULT_DBUS_SVC, assocOwners, assocInterfaces);
286
287 // Should have 3 entries in AssociationInterfaces, one is just missing an
288 // endpoint
289 EXPECT_EQ(assocInterfaces.size(), 3);
290
291 // Change to existing interface so it will be removed here
292 auto intfEndpoints =
293 std::get<endpointsPos>(assocInterfaces[DEFAULT_FWD_PATH]);
294 EXPECT_EQ(intfEndpoints.size(), 0);
295
296 // The new endpoint should exist though in it's place
297 intfEndpoints = std::get<endpointsPos>(
298 assocInterfaces[DEFAULT_SOURCE_PATH + "/" + "abc"]);
299 EXPECT_EQ(intfEndpoints.size(), 1);
300
301 // Added to an existing owner path so still 1
302 EXPECT_EQ(assocOwners.size(), 1);
303}