blob: 693ab210a69981fd41b00f3109762ba6c24fa8f2 [file] [log] [blame]
Willy Tuaba14d32023-01-31 14:19:59 -08001#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
14using ::testing::ElementsAre;
15
16class 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
38TEST_F(TestHandler, AddObjectMapResult)
39{
40 std::vector<InterfaceMapType::value_type> interfaceMaps;
41 addObjectMapResult(interfaceMaps, "test_object_path",
42 std::pair<std::string, InterfaceNames>(
43 "test_object_connection_0", {
44 "test_interface_0",
45 "test_interface_1",
46 }));
47
48 addObjectMapResult(interfaceMaps, "test_object_path",
49 std::pair<std::string, InterfaceNames>(
50 "test_object_connection_1", {
51 "test_interface_0",
52 "test_interface_1",
53 }));
54 ASSERT_EQ(interfaceMaps.size(), 1);
55
56 auto entry = std::find_if(
57 interfaceMaps.begin(), interfaceMaps.end(),
58 [](const auto& i) { return "test_object_path" == i.first; });
59 ASSERT_NE(entry, interfaceMap.end());
60 for (const auto& [_, interfaces] : entry->second)
61 {
62 ASSERT_THAT(interfaces,
63 ElementsAre("test_interface_0", "test_interface_1"));
64 }
65
66 // Change the interface, but expect it to be unchanged
67 addObjectMapResult(interfaceMaps, "test_object_path",
68 std::pair<std::string, InterfaceNames>(
69 "test_object_connection_0", {"test_interface_2"}));
70 addObjectMapResult(interfaceMaps, "test_object_path",
71 std::pair<std::string, InterfaceNames>(
72 "test_object_connection_1", {"test_interface_2"}));
73 entry = std::find_if(
74 interfaceMaps.begin(), interfaceMaps.end(),
75 [](const auto& i) { return "test_object_path" == i.first; });
76 ASSERT_NE(entry, interfaceMaps.end());
77 for (const auto& [_, interfaces] : entry->second)
78 {
79 ASSERT_THAT(interfaces,
80 ElementsAre("test_interface_0", "test_interface_1"));
81 }
82}
83
84TEST_F(TestHandler, getAncestorsBad)
85{
86 std::string path = "/test/object_path_0/child/grandchild";
87 std::vector<std::string> interfaces = {"bad_interface"};
88 std::vector<InterfaceMapType::value_type> ancestors =
89 getAncestors(interfaceMap, path, interfaces);
90 ASSERT_TRUE(ancestors.empty());
91
92 path = "/invalid_path";
93 EXPECT_THROW(
94 getAncestors(interfaceMap, path, interfaces),
95 sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
96}
97
98TEST_F(TestHandler, getAncestorsGood)
99{
100 std::string path = "/test/object_path_0/child/grandchild";
101 std::vector<std::string> interfaces = {"test_interface_0",
102 "test_interface_1"};
103 std::vector<InterfaceMapType::value_type> ancestors =
104 getAncestors(interfaceMap, path, interfaces);
105 ASSERT_EQ(ancestors.size(), 2);
106
107 // Grand Parent
108 EXPECT_EQ(ancestors[0].first, "/test/object_path_0");
109 ASSERT_EQ(ancestors[0].second.size(), 1);
110 auto grandParent = ancestors[0].second.find("test_object_connection_0");
111 ASSERT_NE(grandParent, ancestors[0].second.end());
112 ASSERT_THAT(grandParent->second, ElementsAre("test_interface_0"));
113
114 // Parent
115 ASSERT_EQ(ancestors[1].first, "/test/object_path_0/child");
116 ASSERT_EQ(ancestors[1].second.size(), 1);
117 auto parent = ancestors[1].second.find("test_object_connection_1");
118 ASSERT_NE(parent, ancestors[1].second.end());
119 ASSERT_THAT(parent->second, ElementsAre("test_interface_1"));
120}
121
122TEST_F(TestHandler, getObjectBad)
123{
124 std::string path = "/test/object_path_0";
125 std::vector<std::string> interfaces = {"bad_interface"};
126 EXPECT_THROW(
127 getObject(interfaceMap, path, interfaces),
128 sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
129
130 path = "/invalid_path";
131 EXPECT_THROW(
132 getObject(interfaceMap, path, interfaces),
133 sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
134
135 path = "/";
136 EXPECT_THROW(
137 getObject(interfaceMap, path, interfaces),
138 sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
139}
140
141TEST_F(TestHandler, getObjectGood)
142{
143 std::string path = "/test/object_path_0";
144 std::vector<std::string> interfaces = {"test_interface_0",
145 "test_interface_1"};
146 ConnectionNames connection = getObject(interfaceMap, path, interfaces);
147 auto object = connection.find("test_object_connection_0");
148 ASSERT_NE(object, connection.end());
149 ASSERT_THAT(object->second, ElementsAre("test_interface_0"));
150
151 path = "/test/object_path_0/child";
152 connection = getObject(interfaceMap, path, interfaces);
153 object = connection.find("test_object_connection_1");
154 ASSERT_NE(object, connection.end());
155 ASSERT_THAT(object->second, ElementsAre("test_interface_1"));
156}
157
158TEST_F(TestHandler, getSubTreeBad)
159{
160 std::string path = "/test/object_path_0";
161 std::vector<std::string> interfaces = {"bad_interface"};
162 std::vector<InterfaceMapType::value_type> subtree =
163 getSubTree(interfaceMap, path, 0, interfaces);
164 ASSERT_TRUE(subtree.empty());
165
166 path = "/invalid_path";
167 EXPECT_THROW(
168 getSubTree(interfaceMap, path, 0, interfaces),
169 sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
170}
171
172void verifySubtree(std::span<InterfaceMapType::value_type> subtree)
173{
174 ASSERT_EQ(subtree.size(), 2);
175 ConnectionNames connection = subtree[0].second;
176 auto object = connection.find("test_object_connection_1");
177 ASSERT_NE(object, connection.end());
178 ASSERT_THAT(object->second, ElementsAre("test_interface_1"));
179
180 connection = subtree[1].second;
181 object = connection.find("test_object_connection_3");
182 ASSERT_NE(object, connection.end());
183 ASSERT_THAT(object->second, ElementsAre("test_interface_3"));
184}
185
186TEST_F(TestHandler, getSubTreeGood)
187{
188 std::string path0 = "/test/object_path_0";
189 std::string path1 = "/test/object_path_0/child/grandchild";
190 std::vector<std::string> interfaces = {"test_interface_1",
191 "test_interface_3"};
192 // Root
193 std::vector<InterfaceMapType::value_type> subtree =
194 getSubTree(interfaceMap, "/", 0, interfaces);
195 verifySubtree(subtree);
196
197 // Path0
198 subtree = getSubTree(interfaceMap, path0, 0, interfaces);
199 verifySubtree(subtree);
200
201 // Path0 with Depth path of 1
202 subtree = getSubTree(interfaceMap, path0, 1, interfaces);
203 ASSERT_EQ(subtree.size(), 1);
204 ConnectionNames connection = subtree[0].second;
205 auto object = connection.find("test_object_connection_1");
206 ASSERT_NE(object, connection.end());
207 ASSERT_THAT(object->second, ElementsAre("test_interface_1"));
208
209 // Path1
210 subtree = getSubTree(interfaceMap, path1, 0, interfaces);
211 ASSERT_EQ(subtree.size(), 1);
212 connection = subtree[0].second;
213 object = connection.find("test_object_connection_3");
214 ASSERT_NE(object, connection.end());
215 ASSERT_THAT(object->second, ElementsAre("test_interface_3"));
216}
217
218TEST_F(TestHandler, getSubTreePathsBad)
219{
220 std::string path = "/test/object_path_0";
221 std::vector<std::string> interfaces = {"bad_interface"};
222 std::vector<std::string> subtreePath =
223 getSubTreePaths(interfaceMap, path, 0, interfaces);
224 ASSERT_TRUE(subtreePath.empty());
225
226 path = "/invalid_path";
227 EXPECT_THROW(
228 getSubTreePaths(interfaceMap, path, 0, interfaces),
229 sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound);
230}
231
232TEST_F(TestHandler, getSubTreePathsGood)
233{
234 std::string path0 = "/test/object_path_0";
235 std::string path1 = "/test/object_path_0/child/grandchild";
236 std::vector<std::string> interfaces = {"test_interface_1",
237 "test_interface_3"};
238 // Root
239 std::vector<std::string> subtreePath =
240 getSubTreePaths(interfaceMap, "/", 0, interfaces);
241 ASSERT_THAT(subtreePath,
242 ElementsAre("/test/object_path_0/child",
243 "/test/object_path_0/child/grandchild/dog"));
244
245 // Path0
246 subtreePath = getSubTreePaths(interfaceMap, path0, 0, interfaces);
247 ASSERT_THAT(subtreePath,
248 ElementsAre("/test/object_path_0/child",
249 "/test/object_path_0/child/grandchild/dog"));
250
251 // Path0 + Depth path of 1
252 subtreePath = getSubTreePaths(interfaceMap, path0, 1, interfaces);
253 ASSERT_THAT(subtreePath, ElementsAre("/test/object_path_0/child"));
254
255 // Path1
256 subtreePath = getSubTreePaths(interfaceMap, path1, 0, interfaces);
257 ASSERT_THAT(subtreePath,
258 ElementsAre("/test/object_path_0/child/grandchild/dog"));
259}