1 #include "src/associations.hpp"
2
3 #include "src/test/util/asio_server_class.hpp"
4 #include "src/test/util/association_objects.hpp"
5 #include "src/test/util/debug_output.hpp"
6
7 #include <sdbusplus/asio/connection.hpp>
8 #include <sdbusplus/asio/object_server.hpp>
9
10 #include <gtest/gtest.h>
11
12 class TestAssociations : public AsioServerClassTest
13 {
14 public:
15 boost::asio::io_context io;
SetUp()16 virtual void SetUp()
17 {
18 io.run();
19 }
20 };
21 sdbusplus::asio::object_server* TestAssociations::AsioServerClassTest::server =
22 nullptr;
23
24 // Verify call when path is not in associated owners
TEST_F(TestAssociations,SourcePathNotInAssociations)25 TEST_F(TestAssociations, SourcePathNotInAssociations)
26 {
27 EXPECT_NE(nullptr, server);
28 std::string sourcePath = "/xyz/openbmc_project/no/association";
29 AssociationMaps assocMaps;
30
31 removeAssociation(io, sourcePath, defaultDbusSvc, *server, assocMaps);
32 }
33
34 // Verify call when owner is not in associated owners
TEST_F(TestAssociations,OwnerNotInAssociations)35 TEST_F(TestAssociations, OwnerNotInAssociations)
36 {
37 AssociationMaps assocMaps;
38 assocMaps.owners = createDefaultOwnerAssociation();
39
40 removeAssociation(io, defaultSourcePath, defaultDbusSvc, *server,
41 assocMaps);
42 }
43
44 // Verify call when path is not in associated interfaces
TEST_F(TestAssociations,PathNotInAssocInterfaces)45 TEST_F(TestAssociations, PathNotInAssocInterfaces)
46 {
47 AssociationMaps assocMaps;
48
49 assocMaps.owners = createDefaultOwnerAssociation();
50
51 removeAssociation(io, defaultSourcePath, defaultDbusSvc, *server,
52 assocMaps);
53
54 EXPECT_TRUE(assocMaps.owners.empty());
55 }
56
57 // Verify call when path is in associated interfaces
TEST_F(TestAssociations,PathIsInAssociatedInterfaces)58 TEST_F(TestAssociations, PathIsInAssociatedInterfaces)
59 {
60 // Build up these objects so that an associated interface will match
61 // with the associated owner being removed
62 AssociationMaps assocMaps;
63 assocMaps.owners = createDefaultOwnerAssociation();
64 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
65
66 removeAssociation(io, defaultSourcePath, defaultDbusSvc, *server,
67 assocMaps);
68
69 // Verify owner association was deleted
70 EXPECT_TRUE(assocMaps.owners.empty());
71
72 // Verify endpoint was deleted from interface association
73 auto intfEndpoints =
74 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
75 EXPECT_EQ(intfEndpoints.size(), 0);
76 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
77 EXPECT_EQ(intfEndpoints.size(), 0);
78 }
79
80 // Verify call when path is in associated interfaces, with extra endpoints
TEST_F(TestAssociations,PathIsInAssociatedInterfacesExtraEndpoints)81 TEST_F(TestAssociations, PathIsInAssociatedInterfacesExtraEndpoints)
82 {
83 // Build up these objects so that an associated interface will match
84 // with the associated owner being removed
85 AssociationMaps assocMaps;
86 assocMaps.owners = createDefaultOwnerAssociation();
87 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
88
89 // Add another endpoint to the assoc interfaces
90 addEndpointToInterfaceAssociation(assocMaps.ifaces);
91
92 removeAssociation(io, defaultSourcePath, defaultDbusSvc, *server,
93 assocMaps);
94
95 // Verify owner association was deleted
96 EXPECT_TRUE(assocMaps.owners.empty());
97
98 // Verify all endpoints are deleted since source path was deleted
99 auto intfEndpoints =
100 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
101 EXPECT_EQ(intfEndpoints.size(), 0);
102 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
103 EXPECT_EQ(intfEndpoints.size(), 0);
104 }
105
106 // Verify no associations or endpoints removed when the change is identical
TEST_F(TestAssociations,checkAssociationEndpointRemovesNoEpRemove)107 TEST_F(TestAssociations, checkAssociationEndpointRemovesNoEpRemove)
108 {
109 AssociationPaths newAssocPaths = {{defaultFwdPath, {defaultEndpoint}},
110 {defaultRevPath, {defaultSourcePath}}};
111
112 AssociationMaps assocMaps;
113 assocMaps.owners = createDefaultOwnerAssociation();
114 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
115
116 checkAssociationEndpointRemoves(io, defaultSourcePath, defaultDbusSvc,
117 newAssocPaths, *server, assocMaps);
118
119 // Verify endpoints were not deleted because they matche with what was
120 // in the original
121 auto intfEndpoints =
122 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
123 EXPECT_EQ(intfEndpoints.size(), 1);
124 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
125 EXPECT_EQ(intfEndpoints.size(), 1);
126 }
127
128 // Verify endpoint is removed when assoc path is different
TEST_F(TestAssociations,checkAssociationEndpointRemovesEpRemoveApDiff)129 TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveApDiff)
130 {
131 AssociationPaths newAssocPaths = {{"/different/path", {defaultEndpoint}}};
132
133 AssociationMaps assocMaps;
134 assocMaps.owners = createDefaultOwnerAssociation();
135 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
136
137 checkAssociationEndpointRemoves(io, defaultSourcePath, defaultDbusSvc,
138 newAssocPaths, *server, assocMaps);
139
140 // Verify initial endpoints were deleted because the new path
141 auto intfEndpoints =
142 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
143 EXPECT_EQ(intfEndpoints.size(), 0);
144 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
145 EXPECT_EQ(intfEndpoints.size(), 0);
146 }
147
148 // Verify endpoint is removed when endpoint is different
TEST_F(TestAssociations,checkAssociationEndpointRemovesEpRemoveEpChanged)149 TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveEpChanged)
150 {
151 AssociationPaths newAssocPaths = {
152 {defaultFwdPath, {defaultEndpoint + "/different"}},
153 {defaultRevPath, {defaultSourcePath + "/different"}}};
154
155 AssociationMaps assocMaps;
156 assocMaps.owners = createDefaultOwnerAssociation();
157 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
158
159 checkAssociationEndpointRemoves(io, defaultSourcePath, defaultDbusSvc,
160 newAssocPaths, *server, assocMaps);
161
162 // Verify initial endpoints were deleted because of different endpoints
163 auto intfEndpoints =
164 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
165 EXPECT_EQ(intfEndpoints.size(), 0);
166 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
167 EXPECT_EQ(intfEndpoints.size(), 0);
168 }
169
170 // Verify existing endpoint deleted when empty endpoint is provided
TEST_F(TestAssociations,associationChangedEmptyEndpoint)171 TEST_F(TestAssociations, associationChangedEmptyEndpoint)
172 {
173 std::vector<Association> associations = {
174 {"inventory_cee", "error_cee", ""}};
175 InterfaceMapType interfaceMap;
176
177 AssociationMaps assocMaps;
178 assocMaps.owners = createDefaultOwnerAssociation();
179 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
180
181 // Empty endpoint will result in deletion of corresponding assocInterface
182 associationChanged(io, *server, associations, defaultSourcePath,
183 defaultDbusSvc, interfaceMap, assocMaps);
184
185 // Both of these should be 0 since we have an invalid endpoint
186 auto intfEndpoints =
187 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
188 EXPECT_EQ(intfEndpoints.size(), 0);
189 intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[defaultRevPath]);
190 EXPECT_EQ(intfEndpoints.size(), 0);
191
192 EXPECT_EQ(assocMaps.pending.size(), 0);
193 }
194
195 // Add a new association with endpoint
TEST_F(TestAssociations,associationChangedAddNewAssoc)196 TEST_F(TestAssociations, associationChangedAddNewAssoc)
197 {
198 std::vector<Association> associations = {
199 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
200
201 AssociationMaps assocMaps;
202 assocMaps.owners = createDefaultOwnerAssociation();
203 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
204
205 // Make it look like the assoc endpoints are on D-Bus
206 InterfaceMapType interfaceMap = {
207 {"/new/source/path", {{defaultDbusSvc, {"a"}}}},
208 {"/xyz/openbmc_project/new/endpoint", {{defaultDbusSvc, {"a"}}}}};
209
210 associationChanged(io, *server, associations, "/new/source/path",
211 defaultDbusSvc, interfaceMap, assocMaps);
212
213 // Two source paths
214 EXPECT_EQ(assocMaps.owners.size(), 2);
215
216 // Four interfaces
217 EXPECT_EQ(assocMaps.ifaces.size(), 4);
218
219 // Nothing pending
220 EXPECT_EQ(assocMaps.pending.size(), 0);
221
222 // New endpoint so assocMaps.ifaces should be same size
223 auto intfEndpoints =
224 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
225 EXPECT_EQ(intfEndpoints.size(), 1);
226 }
227
228 // Add a new association to empty objects
TEST_F(TestAssociations,associationChangedAddNewAssocEmptyObj)229 TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
230 {
231 std::string sourcePath = "/logging/entry/1";
232 std::string owner = "xyz.openbmc_project.Test";
233 std::vector<Association> associations = {
234 {"inventory_canaeo", "error_canaeo",
235 "/xyz/openbmc_project/inventory/system/chassis"}};
236
237 // Empty objects because this test will ensure assocOwners adds the
238 // changed association and interface
239 AssociationMaps assocMaps;
240
241 // Make it look like the assoc endpoints are on D-Bus
242 InterfaceMapType interfaceMap = createDefaultInterfaceMap();
243
244 associationChanged(io, *server, associations, defaultSourcePath,
245 defaultDbusSvc, interfaceMap, assocMaps);
246
247 // New associations so ensure it now contains a single entry
248 EXPECT_EQ(assocMaps.owners.size(), 1);
249
250 // Nothing pending
251 EXPECT_EQ(assocMaps.pending.size(), 0);
252
253 // Verify corresponding assoc paths each have one endpoint in assoc
254 // interfaces and that those endpoints match
255 auto singleOwner = assocMaps.owners[defaultSourcePath];
256 auto singleIntf = singleOwner[defaultDbusSvc];
257 for (auto i : singleIntf)
258 {
259 auto intfEndpoints = std::get<endpointsPos>(assocMaps.ifaces[i.first]);
260 EXPECT_EQ(intfEndpoints.size(), 1);
261 EXPECT_EQ(intfEndpoints[0], *i.second.begin());
262 }
263 }
264
265 // Add a new association to same source path but with new owner
TEST_F(TestAssociations,associationChangedAddNewAssocNewOwner)266 TEST_F(TestAssociations, associationChangedAddNewAssocNewOwner)
267 {
268 std::string newOwner = "xyz.openbmc_project.Test2";
269 std::vector<Association> associations = {
270 {"inventory_canano", "error_canano",
271 "/xyz/openbmc_project/inventory/system/chassis"}};
272
273 // Make it look like the assoc endpoints are on D-Bus
274 InterfaceMapType interfaceMap = createDefaultInterfaceMap();
275
276 AssociationMaps assocMaps;
277 assocMaps.owners = createDefaultOwnerAssociation();
278 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
279
280 associationChanged(io, *server, associations, defaultSourcePath, newOwner,
281 interfaceMap, assocMaps);
282
283 // New endpoint so assocOwners should be same size
284 EXPECT_EQ(assocMaps.owners.size(), 1);
285
286 // Ensure only one endpoint under first path
287 auto intfEndpoints =
288 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
289 EXPECT_EQ(intfEndpoints.size(), 1);
290
291 // Ensure the 2 new association endpoints are under the new owner
292 auto a = assocMaps.owners.find(defaultSourcePath);
293 auto o = a->second.find(newOwner);
294 EXPECT_EQ(o->second.size(), 2);
295
296 // Nothing pending
297 EXPECT_EQ(assocMaps.pending.size(), 0);
298 }
299
300 // Add a new association to existing interface path
TEST_F(TestAssociations,associationChangedAddNewAssocSameInterface)301 TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
302 {
303 std::vector<Association> associations = {
304 {"abc", "error", "/xyz/openbmc_project/inventory/system/chassis"}};
305
306 // Make it look like the assoc endpoints are on D-Bus
307 InterfaceMapType interfaceMap = createDefaultInterfaceMap();
308
309 AssociationMaps assocMaps;
310 assocMaps.owners = createDefaultOwnerAssociation();
311 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
312
313 associationChanged(io, *server, associations, defaultSourcePath,
314 defaultDbusSvc, interfaceMap, assocMaps);
315
316 // Should have 3 entries in AssociationInterfaces, one is just missing an
317 // endpoint
318 EXPECT_EQ(assocMaps.ifaces.size(), 3);
319
320 // Change to existing interface so it will be removed here
321 auto intfEndpoints =
322 std::get<endpointsPos>(assocMaps.ifaces[defaultFwdPath]);
323 EXPECT_EQ(intfEndpoints.size(), 0);
324
325 // The new endpoint should exist though in it's place
326 intfEndpoints = std::get<endpointsPos>(
327 assocMaps.ifaces[defaultSourcePath + "/" + "abc"]);
328 EXPECT_EQ(intfEndpoints.size(), 1);
329
330 // Added to an existing owner path so still 1
331 EXPECT_EQ(assocMaps.owners.size(), 1);
332
333 EXPECT_EQ(assocMaps.pending.size(), 0);
334 }
335
336 // Add 2 pending associations
TEST_F(TestAssociations,addPendingAssocs)337 TEST_F(TestAssociations, addPendingAssocs)
338 {
339 AssociationMaps assocMaps;
340
341 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
342 "error", defaultDbusSvc, assocMaps);
343
344 EXPECT_TRUE(assocMaps.ifaces.empty());
345 EXPECT_TRUE(assocMaps.owners.empty());
346
347 EXPECT_EQ(assocMaps.pending.size(), 1);
348
349 addPendingAssociation("some/other/path", "inventory", defaultEndpoint,
350 "error", defaultDbusSvc, assocMaps);
351
352 EXPECT_TRUE(assocMaps.ifaces.empty());
353 EXPECT_TRUE(assocMaps.owners.empty());
354
355 EXPECT_EQ(assocMaps.pending.size(), 2);
356 }
357
358 // Test adding a new endpoint to a pending association
TEST_F(TestAssociations,addPendingAssocsNewEndpoints)359 TEST_F(TestAssociations, addPendingAssocsNewEndpoints)
360 {
361 AssociationMaps assocMaps;
362
363 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
364 "error", defaultDbusSvc, assocMaps);
365
366 EXPECT_EQ(assocMaps.pending.size(), 1);
367
368 addPendingAssociation(defaultSourcePath, "inventory", "some/other/endpoint",
369 "error", defaultDbusSvc, assocMaps);
370
371 // Same pending path, so still just 1 entry
372 EXPECT_EQ(assocMaps.pending.size(), 1);
373
374 auto assoc = assocMaps.pending.find(defaultSourcePath);
375 EXPECT_NE(assoc, assocMaps.pending.end());
376
377 auto& endpoints = assoc->second;
378 EXPECT_EQ(endpoints.size(), 2);
379 }
380
381 // Test adding a new owner to a pending association
TEST_F(TestAssociations,addPendingAssocsNewOwner)382 TEST_F(TestAssociations, addPendingAssocsNewOwner)
383 {
384 AssociationMaps assocMaps;
385
386 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
387 "error", defaultDbusSvc, assocMaps);
388
389 EXPECT_EQ(assocMaps.pending.size(), 1);
390
391 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
392 "error", "new owner", assocMaps);
393
394 EXPECT_EQ(assocMaps.pending.size(), 1);
395
396 auto assoc = assocMaps.pending.find(defaultSourcePath);
397 EXPECT_NE(assoc, assocMaps.pending.end());
398
399 auto& endpoints = assoc->second;
400 EXPECT_EQ(endpoints.size(), 2);
401 }
402
403 // Add a pending association inside associationChanged
TEST_F(TestAssociations,associationChangedPending)404 TEST_F(TestAssociations, associationChangedPending)
405 {
406 std::vector<Association> associations = {
407 {"abc", "def", "/xyz/openbmc_project/new/endpoint"}};
408
409 AssociationMaps assocMaps;
410 InterfaceMapType interfaceMap;
411
412 associationChanged(io, *server, associations, "/new/source/path",
413 defaultDbusSvc, interfaceMap, assocMaps);
414
415 // No associations were actually added
416 EXPECT_EQ(assocMaps.owners.size(), 0);
417 EXPECT_EQ(assocMaps.ifaces.size(), 0);
418
419 // 1 pending association
420 EXPECT_EQ(assocMaps.pending.size(), 1);
421 }
422
423 // Test removing pending associations
TEST_F(TestAssociations,testRemoveFromPendingAssociations)424 TEST_F(TestAssociations, testRemoveFromPendingAssociations)
425 {
426 AssociationMaps assocMaps;
427
428 addPendingAssociation(defaultSourcePath, "inventory", defaultEndpoint,
429 "error", defaultDbusSvc, assocMaps);
430
431 addPendingAssociation(defaultSourcePath, "inventory", "some/other/endpoint",
432 "error", defaultDbusSvc, assocMaps);
433
434 EXPECT_EQ(assocMaps.pending.size(), 1);
435
436 removeFromPendingAssociations("some/other/endpoint", assocMaps);
437
438 // Still 1 pending entry, but down to 1 endpoint
439 EXPECT_EQ(assocMaps.pending.size(), 1);
440
441 auto assoc = assocMaps.pending.find(defaultSourcePath);
442 EXPECT_NE(assoc, assocMaps.pending.end());
443 auto& endpoints = assoc->second;
444 EXPECT_EQ(endpoints.size(), 1);
445
446 // Now nothing pending
447 removeFromPendingAssociations(defaultEndpoint, assocMaps);
448 EXPECT_EQ(assocMaps.pending.size(), 0);
449 }
450
451 // Test moving a pending association to a real one
TEST_F(TestAssociations,checkIfPending)452 TEST_F(TestAssociations, checkIfPending)
453 {
454 AssociationMaps assocMaps;
455 InterfaceMapType interfaceMap = {
456 {defaultSourcePath, {{defaultDbusSvc, {"a"}}}},
457 {defaultEndpoint, {{defaultDbusSvc, {"b"}}}}};
458
459 addPendingAssociation(defaultSourcePath, "inventory_cip", defaultEndpoint,
460 "error_cip", defaultDbusSvc, assocMaps);
461 EXPECT_EQ(assocMaps.pending.size(), 1);
462
463 // Move the pending association to a real association
464 checkIfPendingAssociation(io, defaultSourcePath, interfaceMap, assocMaps,
465 *server);
466
467 EXPECT_TRUE(assocMaps.pending.empty());
468 EXPECT_EQ(assocMaps.owners.size(), 1);
469 EXPECT_EQ(assocMaps.ifaces.size(), 2);
470
471 // This shouldn't do anything, since /new/path isn't pending
472 checkIfPendingAssociation(io, "/new/path", interfaceMap, assocMaps,
473 *server);
474 EXPECT_TRUE(assocMaps.pending.empty());
475 EXPECT_EQ(assocMaps.owners.size(), 1);
476 EXPECT_EQ(assocMaps.ifaces.size(), 2);
477 }
478
TEST_F(TestAssociations,findAssociations)479 TEST_F(TestAssociations, findAssociations)
480 {
481 std::vector<std::tuple<std::string, Association>> associationData;
482 AssociationMaps assocMaps;
483
484 assocMaps.owners = {
485 {"pathA",
486 {{"ownerA",
487 {{"pathA/typeA", {"endpointA", "endpointB"}},
488 {"endpointA/type0", {"pathA"}}}}}},
489
490 {"pathJ",
491 {{"ownerC",
492 {{"pathJ/typeA", {"endpointF"}}, {"endpointF/type0", {"pathJ"}}}}}},
493
494 {"pathX",
495 {{"ownerB",
496 {{"pathX/typeB", {"endpointA"}}, {"endpointA/type1", {"pathX"}}}}}}};
497
498 findAssociations("endpointA", assocMaps, associationData);
499 ASSERT_EQ(associationData.size(), 2);
500
501 {
502 auto ad = std::find_if(
503 associationData.begin(), associationData.end(),
504 [](const auto& ad) { return std::get<0>(ad) == "ownerA"; });
505 ASSERT_NE(ad, associationData.end());
506
507 auto& a = std::get<1>(*ad);
508 ASSERT_EQ(std::get<0>(a), "type0");
509 ASSERT_EQ(std::get<1>(a), "typeA");
510 ASSERT_EQ(std::get<2>(a), "pathA");
511 }
512 {
513 auto ad = std::find_if(
514 associationData.begin(), associationData.end(),
515 [](const auto& ad) { return std::get<0>(ad) == "ownerB"; });
516 ASSERT_NE(ad, associationData.end());
517
518 auto& a = std::get<1>(*ad);
519 ASSERT_EQ(std::get<0>(a), "type1");
520 ASSERT_EQ(std::get<1>(a), "typeB");
521 ASSERT_EQ(std::get<2>(a), "pathX");
522 }
523 }
524
TEST_F(TestAssociations,moveAssocToPendingNoOp)525 TEST_F(TestAssociations, moveAssocToPendingNoOp)
526 {
527 AssociationMaps assocMaps;
528
529 // Not an association, so it shouldn't do anything
530 moveAssociationToPending(io, defaultEndpoint, assocMaps, *server);
531
532 EXPECT_TRUE(assocMaps.pending.empty());
533 EXPECT_TRUE(assocMaps.owners.empty());
534 EXPECT_TRUE(assocMaps.ifaces.empty());
535 }
536
TEST_F(TestAssociations,moveAssocToPending)537 TEST_F(TestAssociations, moveAssocToPending)
538 {
539 AssociationMaps assocMaps;
540 assocMaps.owners = createDefaultOwnerAssociation();
541 assocMaps.ifaces = createDefaultInterfaceAssociation(server);
542
543 moveAssociationToPending(io, defaultEndpoint, assocMaps, *server);
544
545 // Check it's now pending
546 EXPECT_EQ(assocMaps.pending.size(), 1);
547 EXPECT_EQ(assocMaps.pending.begin()->first, defaultEndpoint);
548
549 // No more assoc owners
550 EXPECT_TRUE(assocMaps.owners.empty());
551
552 // Check the association interfaces were removed
553 {
554 auto assocs = assocMaps.ifaces.find(defaultFwdPath);
555 auto& iface = std::get<ifacePos>(assocs->second);
556 auto& endpoints = std::get<endpointsPos>(assocs->second);
557
558 EXPECT_EQ(iface.get(), nullptr);
559 EXPECT_TRUE(endpoints.empty());
560 }
561 {
562 auto assocs = assocMaps.ifaces.find(defaultRevPath);
563 auto& iface = std::get<ifacePos>(assocs->second);
564 auto& endpoints = std::get<endpointsPos>(assocs->second);
565
566 EXPECT_EQ(iface.get(), nullptr);
567 EXPECT_TRUE(endpoints.empty());
568 }
569 }
570