1 #include "src/handler.hpp"
2 
3 #include "src/types.hpp"
4 
5 #include <xyz/openbmc_project/Common/error.hpp>
6 
7 #include <span>
8 #include <utility>
9 #include <vector>
10 
11 #include <gmock/gmock.h>
12 #include <gtest/gtest.h>
13 
14 using ::testing::ElementsAre;
15 
16 class TestHandler : public testing::Test
17 {
18   protected:
19     InterfaceMapType interfaceMap = {
20         {
21             "/test/object_path_0",
22             {{"test_object_connection_0", {"test_interface_0"}}},
23         },
24         {
25             "/test/object_path_0/child",
26             {{"test_object_connection_1", {"test_interface_1"}}},
27         },
28         {
29             "/test/object_path_0/child/grandchild",
30             {{"test_object_connection_2", {"test_interface_2"}}},
31         },
32         {
33             "/test/object_path_0/child/grandchild/dog",
34             {{"test_object_connection_3", {"test_interface_3"}}},
35         },
36         {
37             "/test/object_path_0/child1",
38             {{"test_object_connection_4", {"test_interface_4"}}},
39         },
40         {
41             "/test/object_path_0/grandchild/child1",
42             {{"test_object_connection_5", {"test_interface_5"}}},
43         },
44     };
45 
46     AssociationMaps associationMap = {
47         .ifaces =
48             {
49                 {
50                     "/test/object_path_0/descendent",
51                     {
52                         std::shared_ptr<sdbusplus::asio::dbus_interface>(),
53                         {
54                             "/test/object_path_0/child",
55                             "/test/object_path_0/child/grandchild",
56                         },
57                     },
58                 },
59                 {
60                     "/test/object_path_0/child/descendent",
61                     {
62                         std::shared_ptr<sdbusplus::asio::dbus_interface>(),
63                         {
64                             "/test/object_path_0/child/grandchild",
65                         },
66                     },
67                 },
68                 {
69                     "/test/object_path_0/grandchild/child1/descendent",
70                     {
71                         std::shared_ptr<sdbusplus::asio::dbus_interface>(),
72                         {
73                             "/test/object_path_0/child",
74                         },
75                     },
76                 },
77                 {
78                     "/test/object_path_0/child1/descendent",
79                     {
80                         std::shared_ptr<sdbusplus::asio::dbus_interface>(),
81                         {
82                             "/test/object_path_0/child1",
83                             "/test/object_path_0/child1/grandchild",
84                         },
85                     },
86                 },
87             },
88         .owners = {},
89         .pending = {},
90     };
91 };
92 
TEST_F(TestHandler,AddObjectMapResult)93 TEST_F(TestHandler, AddObjectMapResult)
94 {
95     std::vector<InterfaceMapType::value_type> interfaceMaps;
96     addObjectMapResult(interfaceMaps, "test_object_path",
97                        std::pair<std::string, InterfaceNames>(
98                            "test_object_connection_0", {
99                                                            "test_interface_0",
100                                                            "test_interface_1",
101                                                        }));
102 
103     addObjectMapResult(interfaceMaps, "test_object_path",
104                        std::pair<std::string, InterfaceNames>(
105                            "test_object_connection_1", {
106                                                            "test_interface_0",
107                                                            "test_interface_1",
108                                                        }));
109     ASSERT_EQ(interfaceMaps.size(), 1);
110     auto entry = std::find_if(
111         interfaceMaps.begin(), interfaceMaps.end(),
112         [](const auto& i) { return "test_object_path" == i.first; });
113     ASSERT_NE(entry, interfaceMap.end());
114     for (const auto& [_, interfaces] : entry->second)
115     {
116         ASSERT_THAT(interfaces,
117                     ElementsAre("test_interface_0", "test_interface_1"));
118     }
119 
120     // Change the interface, but expect it to be unchanged
121     addObjectMapResult(interfaceMaps, "test_object_path",
122                        std::pair<std::string, InterfaceNames>(
123                            "test_object_connection_0", {"test_interface_2"}));
124     addObjectMapResult(interfaceMaps, "test_object_path",
125                        std::pair<std::string, InterfaceNames>(
126                            "test_object_connection_1", {"test_interface_2"}));
127     entry = std::find_if(
128         interfaceMaps.begin(), interfaceMaps.end(),
129         [](const auto& i) { return "test_object_path" == i.first; });
130     ASSERT_NE(entry, interfaceMaps.end());
131     for (const auto& [_, interfaces] : entry->second)
132     {
133         ASSERT_THAT(interfaces,
134                     ElementsAre("test_interface_0", "test_interface_1"));
135     }
136 }
137 
TEST_F(TestHandler,getAncestorsBad)138 TEST_F(TestHandler, getAncestorsBad)
139 {
140     std::string path = "/test/object_path_0/child/grandchild";
141     std::vector<std::string> interfaces = {"bad_interface"};
142     std::vector<InterfaceMapType::value_type> ancestors =
143         getAncestors(interfaceMap, path, interfaces);
144     ASSERT_TRUE(ancestors.empty());
145 
146     path = "/invalid_path";
147     EXPECT_THROW(
148         getAncestors(interfaceMap, path, interfaces),
149         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
150 }
151 
TEST_F(TestHandler,getAncestorsGood)152 TEST_F(TestHandler, getAncestorsGood)
153 {
154     std::string path = "/test/object_path_0/child/grandchild";
155     std::vector<std::string> interfaces = {"test_interface_0",
156                                            "test_interface_1"};
157     std::vector<InterfaceMapType::value_type> ancestors =
158         getAncestors(interfaceMap, path, interfaces);
159     ASSERT_EQ(ancestors.size(), 2);
160 
161     // Grand Parent
162     EXPECT_EQ(ancestors[0].first, "/test/object_path_0");
163     ASSERT_EQ(ancestors[0].second.size(), 1);
164     auto grandParent = ancestors[0].second.find("test_object_connection_0");
165     ASSERT_NE(grandParent, ancestors[0].second.end());
166     ASSERT_THAT(grandParent->second, ElementsAre("test_interface_0"));
167 
168     // Parent
169     ASSERT_EQ(ancestors[1].first, "/test/object_path_0/child");
170     ASSERT_EQ(ancestors[1].second.size(), 1);
171     auto parent = ancestors[1].second.find("test_object_connection_1");
172     ASSERT_NE(parent, ancestors[1].second.end());
173     ASSERT_THAT(parent->second, ElementsAre("test_interface_1"));
174 }
175 
TEST_F(TestHandler,getObjectBad)176 TEST_F(TestHandler, getObjectBad)
177 {
178     std::string path = "/test/object_path_0";
179     std::vector<std::string> interfaces = {"bad_interface"};
180     EXPECT_THROW(
181         getObject(interfaceMap, path, interfaces),
182         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
183 
184     path = "/invalid_path";
185     EXPECT_THROW(
186         getObject(interfaceMap, path, interfaces),
187         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
188 
189     path = "/";
190     EXPECT_THROW(
191         getObject(interfaceMap, path, interfaces),
192         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
193 }
194 
TEST_F(TestHandler,getObjectGood)195 TEST_F(TestHandler, getObjectGood)
196 {
197     std::string path = "/test/object_path_0";
198     std::vector<std::string> interfaces = {"test_interface_0",
199                                            "test_interface_1"};
200     ConnectionNames connection = getObject(interfaceMap, path, interfaces);
201     auto object = connection.find("test_object_connection_0");
202     ASSERT_NE(object, connection.end());
203     ASSERT_THAT(object->second, ElementsAre("test_interface_0"));
204 
205     path = "/test/object_path_0/child";
206     connection = getObject(interfaceMap, path, interfaces);
207     object = connection.find("test_object_connection_1");
208     ASSERT_NE(object, connection.end());
209     ASSERT_THAT(object->second, ElementsAre("test_interface_1"));
210 }
211 
TEST_F(TestHandler,getSubTreeBad)212 TEST_F(TestHandler, getSubTreeBad)
213 {
214     std::string path = "/test/object_path_0";
215     std::vector<std::string> interfaces = {"bad_interface"};
216     std::vector<InterfaceMapType::value_type> subtree =
217         getSubTree(interfaceMap, path, 0, interfaces);
218     ASSERT_TRUE(subtree.empty());
219 
220     path = "/invalid_path";
221     EXPECT_THROW(
222         getSubTree(interfaceMap, path, 0, interfaces),
223         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
224 }
225 
verifySubtree(std::span<InterfaceMapType::value_type> subtree)226 void verifySubtree(std::span<InterfaceMapType::value_type> subtree)
227 {
228     ASSERT_EQ(subtree.size(), 2);
229     ConnectionNames connection = subtree[0].second;
230     auto object = connection.find("test_object_connection_1");
231     ASSERT_NE(object, connection.end());
232     ASSERT_THAT(object->second, ElementsAre("test_interface_1"));
233 
234     connection = subtree[1].second;
235     object = connection.find("test_object_connection_3");
236     ASSERT_NE(object, connection.end());
237     ASSERT_THAT(object->second, ElementsAre("test_interface_3"));
238 }
239 
TEST_F(TestHandler,getSubTreeGood)240 TEST_F(TestHandler, getSubTreeGood)
241 {
242     std::string path0 = "/test/object_path_0";
243     std::string path1 = "/test/object_path_0/child/grandchild";
244     std::vector<std::string> interfaces = {"test_interface_1",
245                                            "test_interface_3"};
246     // Root
247     std::vector<InterfaceMapType::value_type> subtree =
248         getSubTree(interfaceMap, "/", 0, interfaces);
249     verifySubtree(subtree);
250 
251     // Path0
252     subtree = getSubTree(interfaceMap, path0, 0, interfaces);
253     verifySubtree(subtree);
254 
255     // Path0 with Depth path of 1
256     subtree = getSubTree(interfaceMap, path0, 1, interfaces);
257     ASSERT_EQ(subtree.size(), 1);
258     ConnectionNames connection = subtree[0].second;
259     auto object = connection.find("test_object_connection_1");
260     ASSERT_NE(object, connection.end());
261     ASSERT_THAT(object->second, ElementsAre("test_interface_1"));
262 
263     // Path1
264     subtree = getSubTree(interfaceMap, path1, 0, interfaces);
265     ASSERT_EQ(subtree.size(), 1);
266     connection = subtree[0].second;
267     object = connection.find("test_object_connection_3");
268     ASSERT_NE(object, connection.end());
269     ASSERT_THAT(object->second, ElementsAre("test_interface_3"));
270 }
271 
TEST_F(TestHandler,getSubTreePathsBad)272 TEST_F(TestHandler, getSubTreePathsBad)
273 {
274     std::string path = "/test/object_path_0";
275     std::vector<std::string> interfaces = {"bad_interface"};
276     std::vector<std::string> subtreePath =
277         getSubTreePaths(interfaceMap, path, 0, interfaces);
278     ASSERT_TRUE(subtreePath.empty());
279 
280     path = "/invalid_path";
281     EXPECT_THROW(
282         getSubTreePaths(interfaceMap, path, 0, interfaces),
283         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
284 }
285 
TEST_F(TestHandler,getSubTreePathsGood)286 TEST_F(TestHandler, getSubTreePathsGood)
287 {
288     std::string path0 = "/test/object_path_0";
289     std::string path1 = "/test/object_path_0/child/grandchild";
290     std::vector<std::string> interfaces = {"test_interface_1",
291                                            "test_interface_3"};
292     // Root
293     std::vector<std::string> subtreePath =
294         getSubTreePaths(interfaceMap, "/", 0, interfaces);
295     ASSERT_THAT(subtreePath,
296                 ElementsAre("/test/object_path_0/child",
297                             "/test/object_path_0/child/grandchild/dog"));
298 
299     // Path0
300     subtreePath = getSubTreePaths(interfaceMap, path0, 0, interfaces);
301     ASSERT_THAT(subtreePath,
302                 ElementsAre("/test/object_path_0/child",
303                             "/test/object_path_0/child/grandchild/dog"));
304 
305     // Path0 + Depth path of 1
306     subtreePath = getSubTreePaths(interfaceMap, path0, 1, interfaces);
307     ASSERT_THAT(subtreePath, ElementsAre("/test/object_path_0/child"));
308 
309     // Path1
310     subtreePath = getSubTreePaths(interfaceMap, path1, 0, interfaces);
311     ASSERT_THAT(subtreePath,
312                 ElementsAre("/test/object_path_0/child/grandchild/dog"));
313 }
314 
TEST_F(TestHandler,getAssociatedSubTreeBad)315 TEST_F(TestHandler, getAssociatedSubTreeBad)
316 {
317     sdbusplus::message::object_path path("/test/object_path_0");
318     sdbusplus::message::object_path validAssociatedPath = path / "descendent";
319     std::vector<std::string> invalidInterfaces = {"test_interface_3"};
320     std::vector<std::string> validInterfaces = {"test_interface_1",
321                                                 "test_interface_2"};
322     // Associated path, but invalid interface
323     ASSERT_TRUE(
324         getAssociatedSubTree(interfaceMap, associationMap, validAssociatedPath,
325                              path, 0, invalidInterfaces)
326             .empty());
327 
328     // Valid interface, not associated
329     ASSERT_TRUE(getAssociatedSubTree(interfaceMap, associationMap, path / "dog",
330                                      path, 0, validInterfaces)
331                     .empty());
332 
333     // Invalid path, with valid association
334     path = sdbusplus::message::object_path("/invalid_path");
335     EXPECT_THROW(
336         getAssociatedSubTree(interfaceMap, associationMap, validAssociatedPath,
337                              path, 0, validInterfaces),
338         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
339 }
340 
TEST_F(TestHandler,getAssociatedSubTreeGood)341 TEST_F(TestHandler, getAssociatedSubTreeGood)
342 {
343     sdbusplus::message::object_path path0("/test/object_path_0");
344     sdbusplus::message::object_path path1("/test/object_path_0/child");
345     sdbusplus::message::object_path associatedPath = path0 / "descendent";
346     std::vector<std::string> interfaces = {
347         "test_interface_1", "test_interface_2",
348         // Not associated to path
349         "test_interface_3"};
350 
351     // Path0
352     std::vector<InterfaceMapType::value_type> subtree = getAssociatedSubTree(
353         interfaceMap, associationMap, associatedPath, path0, 0, interfaces);
354     ASSERT_EQ(subtree.size(), 2);
355     ConnectionNames connection = subtree[0].second;
356     auto object = connection.find("test_object_connection_1");
357     ASSERT_NE(object, connection.end());
358     ASSERT_THAT(object->second, ElementsAre("test_interface_1"));
359 
360     connection = subtree[1].second;
361     object = connection.find("test_object_connection_2");
362     ASSERT_NE(object, connection.end());
363     ASSERT_THAT(object->second, ElementsAre("test_interface_2"));
364 
365     // Path0 with Depth path of 1
366     subtree = getAssociatedSubTree(interfaceMap, associationMap, associatedPath,
367                                    path0, 1, interfaces);
368     ASSERT_EQ(subtree.size(), 1);
369     connection = subtree[0].second;
370     object = connection.find("test_object_connection_1");
371     ASSERT_NE(object, connection.end());
372     ASSERT_THAT(object->second, ElementsAre("test_interface_1"));
373 
374     // Path1
375     subtree = getAssociatedSubTree(interfaceMap, associationMap,
376                                    path1 / "descendent", path1, 0, interfaces);
377     ASSERT_EQ(subtree.size(), 1);
378     connection = subtree[0].second;
379     object = connection.find("test_object_connection_2");
380     ASSERT_NE(object, connection.end());
381     ASSERT_THAT(object->second, ElementsAre("test_interface_2"));
382 }
383 
TEST_F(TestHandler,getAssociatedSubTreePathsBad)384 TEST_F(TestHandler, getAssociatedSubTreePathsBad)
385 {
386     sdbusplus::message::object_path path("/test/object_path_0");
387     sdbusplus::message::object_path validAssociatedPath = path / "descendent";
388     std::vector<std::string> invalidInterfaces = {"test_interface_3"};
389     std::vector<std::string> validInterfaces = {"test_interface_1",
390                                                 "test_interface_2"};
391     // Associated path, but invalid interface
392     ASSERT_TRUE(getAssociatedSubTreePaths(interfaceMap, associationMap,
393                                           validAssociatedPath, path, 0,
394                                           invalidInterfaces)
395                     .empty());
396 
397     // Valid interface, not associated
398     ASSERT_TRUE(
399         getAssociatedSubTreePaths(interfaceMap, associationMap, path / "dog",
400                                   path, 0, validInterfaces)
401             .empty());
402 
403     // Invalid path, with valid association
404     path = sdbusplus::message::object_path("/invalid_path");
405     EXPECT_THROW(
406         getAssociatedSubTreePaths(interfaceMap, associationMap,
407                                   validAssociatedPath, path, 0,
408                                   validInterfaces),
409         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
410 }
411 
TEST_F(TestHandler,getAssociatedSubTreePathsGood)412 TEST_F(TestHandler, getAssociatedSubTreePathsGood)
413 {
414     sdbusplus::message::object_path path0("/test/object_path_0");
415     sdbusplus::message::object_path path1("/test/object_path_0/child");
416     sdbusplus::message::object_path associatedPath = path0 / "descendent";
417     std::vector<std::string> interfaces = {
418         "test_interface_1", "test_interface_2",
419         // Not associated to path
420         "test_interface_3"};
421 
422     // Path0
423     std::vector<std::string> subtreePath = getAssociatedSubTreePaths(
424         interfaceMap, associationMap, associatedPath, path0, 0, interfaces);
425     ASSERT_THAT(subtreePath,
426                 ElementsAre("/test/object_path_0/child",
427                             "/test/object_path_0/child/grandchild"));
428 
429     // Path0 with Depth path of 1
430     subtreePath = getAssociatedSubTreePaths(
431         interfaceMap, associationMap, associatedPath, path0, 1, interfaces);
432     ASSERT_THAT(subtreePath, ElementsAre("/test/object_path_0/child"));
433 
434     // Path1
435     subtreePath =
436         getAssociatedSubTreePaths(interfaceMap, associationMap,
437                                   path1 / "descendent", path1, 0, interfaces);
438     ASSERT_THAT(subtreePath,
439                 ElementsAre("/test/object_path_0/child/grandchild"));
440 }
441 
TEST_F(TestHandler,getAssociatedSubTreeByIdBad)442 TEST_F(TestHandler, getAssociatedSubTreeByIdBad)
443 {
444     sdbusplus::message::object_path path("/test/object_path_0");
445     std::vector<std::string> subtreeInterfaces = {"test_interface_1",
446                                                   "test_interface_3"};
447     std::vector<std::string> badsubtreeInterfaces = {"bad_interface"};
448     std::vector<std::string> endpointinvalidInterfaces = {"test_interface_3"};
449     std::vector<std::string> endpointvalidInterfaces = {"test_interface_1",
450                                                         "test_interface_2"};
451     // invalid id
452     ASSERT_TRUE(getAssociatedSubTreeById(interfaceMap, associationMap, "childx",
453                                          path, subtreeInterfaces, "descendent",
454                                          endpointvalidInterfaces)
455                     .empty());
456 
457     // invalid subtreeInterfaces
458     ASSERT_TRUE(getAssociatedSubTreeById(interfaceMap, associationMap, "child",
459                                          path, badsubtreeInterfaces,
460                                          "descendent", endpointvalidInterfaces)
461                     .empty());
462 
463     // invalid endpointinterface
464     ASSERT_TRUE(getAssociatedSubTreeById(interfaceMap, associationMap, "child",
465                                          path, subtreeInterfaces, "descendent",
466                                          endpointinvalidInterfaces)
467                     .empty());
468     // valid id, but doesn't have specified interface
469     ASSERT_TRUE(getAssociatedSubTreeById(interfaceMap, associationMap,
470                                          "grandchild", path, subtreeInterfaces,
471                                          "descendent", endpointvalidInterfaces)
472                     .empty());
473 
474     // invalid association
475     ASSERT_TRUE(getAssociatedSubTreeById(interfaceMap, associationMap, "child",
476                                          path, subtreeInterfaces, "dog",
477                                          endpointinvalidInterfaces)
478                     .empty());
479 
480     // Invalid path
481     path = sdbusplus::message::object_path("/invalid_path");
482     EXPECT_THROW(
483         getAssociatedSubTreeById(interfaceMap, associationMap, "child", path,
484                                  subtreeInterfaces, "descendent",
485                                  endpointvalidInterfaces),
486         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
487 }
488 
TEST_F(TestHandler,getAssociatedSubTreeByIdGood)489 TEST_F(TestHandler, getAssociatedSubTreeByIdGood)
490 {
491     sdbusplus::message::object_path path0("/test/object_path_0");
492     std::vector<std::string> interfaces = {
493         "test_interface_1", "test_interface_2", "test_interface_3"};
494 
495     // Path0
496     std::vector<InterfaceMapType::value_type> subtree =
497         getAssociatedSubTreeById(interfaceMap, associationMap, "child", path0,
498                                  interfaces, "descendent", interfaces);
499     ASSERT_EQ(subtree.size(), 1);
500     ConnectionNames connection = subtree[0].second;
501     auto object = connection.find("test_object_connection_2");
502     ASSERT_NE(object, connection.end());
503     ASSERT_THAT(object->second, ElementsAre("test_interface_2"));
504 
505     std::vector<std::string> interfaces1 = {
506         "test_interface_1", "test_interface_4", "test_interface_5"};
507     // Path0 with Depth path of 0
508     subtree =
509         getAssociatedSubTreeById(interfaceMap, associationMap, "child1", path0,
510                                  interfaces1, "descendent", interfaces1);
511     ASSERT_EQ(subtree.size(), 2);
512 }
513 
TEST_F(TestHandler,getAssociatedSubTreePathsByIdBad)514 TEST_F(TestHandler, getAssociatedSubTreePathsByIdBad)
515 {
516     sdbusplus::message::object_path path("/test/object_path_0");
517     std::vector<std::string> subtreeInterfaces = {"test_interface_1",
518                                                   "test_interface_3"};
519     std::vector<std::string> badsubtreeInterfaces = {"bad_interface"};
520     std::vector<std::string> endpointinvalidInterfaces = {"test_interface_3"};
521     std::vector<std::string> endpointvalidInterfaces = {"test_interface_1",
522                                                         "test_interface_2"};
523     // invalid id
524     ASSERT_TRUE(getAssociatedSubTreePathsById(
525                     interfaceMap, associationMap, "childx", path,
526                     subtreeInterfaces, "descendent", endpointvalidInterfaces)
527                     .empty());
528 
529     // invalid subtreeInterfaces
530     ASSERT_TRUE(getAssociatedSubTreePathsById(
531                     interfaceMap, associationMap, "child", path,
532                     badsubtreeInterfaces, "descendent", endpointvalidInterfaces)
533                     .empty());
534 
535     // invalid endpointinterface
536     ASSERT_TRUE(getAssociatedSubTreePathsById(
537                     interfaceMap, associationMap, "child", path,
538                     subtreeInterfaces, "descendent", endpointinvalidInterfaces)
539                     .empty());
540     // valid id, but doesn't have specified interface
541     ASSERT_TRUE(getAssociatedSubTreePathsById(
542                     interfaceMap, associationMap, "grandchild", path,
543                     subtreeInterfaces, "descendent", endpointvalidInterfaces)
544                     .empty());
545 
546     // invalid association
547     ASSERT_TRUE(getAssociatedSubTreePathsById(interfaceMap, associationMap,
548                                               "child", path, subtreeInterfaces,
549                                               "dog", endpointinvalidInterfaces)
550                     .empty());
551 
552     // Invalid path
553     path = sdbusplus::message::object_path("/invalid_path");
554     EXPECT_THROW(
555         getAssociatedSubTreePathsById(interfaceMap, associationMap, "child",
556                                       path, subtreeInterfaces, "descendent",
557                                       endpointvalidInterfaces),
558         sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
559 }
560 
TEST_F(TestHandler,getAssociatedSubTreePathsByIdGood)561 TEST_F(TestHandler, getAssociatedSubTreePathsByIdGood)
562 {
563     sdbusplus::message::object_path path0("/test/object_path_0");
564     std::vector<std::string> interfaces = {
565         "test_interface_1", "test_interface_2", "test_interface_3"};
566 
567     // Path0
568     std::vector<std::string> subtreePath = getAssociatedSubTreePathsById(
569         interfaceMap, associationMap, "child", path0, interfaces, "descendent",
570         interfaces);
571     ASSERT_THAT(subtreePath,
572                 ElementsAre("/test/object_path_0/child/grandchild"));
573 
574     std::vector<std::string> interfaces1 = {
575         "test_interface_1", "test_interface_4", "test_interface_5"};
576     // Path0 with Depth path of 0
577     subtreePath = getAssociatedSubTreePathsById(
578         interfaceMap, associationMap, "child1", path0, interfaces1,
579         "descendent", interfaces1);
580     ASSERT_THAT(subtreePath, ElementsAre("/test/object_path_0/child1",
581                                          "/test/object_path_0/child"));
582 }
583