1 #include "association_manager.hpp"
2 
3 #include <filesystem>
4 #include <fstream>
5 
6 #include <gtest/gtest.h>
7 
8 using namespace phosphor::inventory::manager::associations;
9 namespace fs = std::filesystem;
10 
11 static const auto goodJson = R"(
12 [
13     {
14         "path": "system/PS0",
15         "endpoints":
16         [
17             {
18                 "types":
19                 {
20                     "rType": "inventory",
21                     "fType": "sensors"
22                 },
23                 "paths":
24                 [
25                     "power/ps0_input_power",
26                     "voltage/ps0_input_voltage",
27                     "current/ps0_output_current",
28                     "voltage/ps0_output_voltage"
29                 ]
30             },
31             {
32                 "types":
33                 {
34                     "rType": "inventory",
35                     "fType": "fans"
36                 },
37                 "paths":
38                 [
39                     "fan_tach/ps0_fan"
40                 ]
41             }
42         ]
43     },
44     {
45         "path": "system/fan42",
46         "endpoints":
47         [
48             {
49                 "types":
50                 {
51                     "rType": "inventory",
52                     "fType": "sensors"
53                 },
54                 "paths":
55                 [
56                     "fan_tach/fan42"
57                 ]
58             },
59             {
60                 "types":
61                 {
62                     "rType": "inventory",
63                     "fType": "led"
64                 },
65                 "paths":
66                 [
67                     "led/fan42"
68                 ]
69             }
70         ]
71     }
72 ])";
73 
74 // Malformed JSON
75 static const auto badJson0 = R"(
76     "hello": world
77 })";
78 
79 // Uses 'blah' instead of 'paths'
80 static const auto badJson1 = R"(
81 [
82     {
83         "blah": "system/PS0",
84         "endpoints":
85         [
86             {
87                 "types":
88                 {
89                     "fType": "inventory",
90                     "rType": "sensors"
91                 },
92                 "paths":
93                 [
94                     "ps0_input_power",
95                 ]
96             }
97         ]
98     }
99 ])";
100 
101 // Uses 'blah' instead of 'rType'
102 static const auto badJson2 = R"(
103 [
104     {
105         "paths": "system/PS0",
106         "endpoints":
107         [
108             {
109                 "types":
110                 {
111                     "blah": "inventory",
112                     "fType": "sensors"
113                 },
114                 "paths":
115                 [
116                     "ps0_input_power",
117                 ]
118             }
119         ]
120     }
121 ])";
122 
123 // Missing the endpoints/paths array
124 static const auto badJson3 = R"(
125 [
126     {
127         "paths": "system/PS0",
128         "endpoints":
129         [
130             {
131                 "types":
132                 {
133                     "rType": "inventory",
134                     "fType": "sensors"
135                 }
136             }
137         ]
138     }
139 ])";
140 
141 class AssocsTest : public ::testing::Test
142 {
143   protected:
AssocsTest()144     AssocsTest() : ::testing::Test(), bus(sdbusplus::bus::new_default()) {}
145 
146     fs::path jsonDir;
147     sdbusplus::bus_t bus;
148 
SetUp()149     virtual void SetUp()
150     {
151         char dir[] = {"assocTestXXXXXX"};
152         jsonDir = mkdtemp(dir);
153     }
154 
TearDown()155     virtual void TearDown()
156     {
157         fs::remove_all(jsonDir);
158     }
159 
writeFile(const char * data)160     std::string writeFile(const char* data)
161     {
162         fs::path path = jsonDir / "associations.json";
163 
164         std::ofstream f{path};
165         f << data;
166         f.close();
167 
168         return path;
169     }
170 };
171 
TEST_F(AssocsTest,TEST_NO_JSON)172 TEST_F(AssocsTest, TEST_NO_JSON)
173 {
174     try
175     {
176         Manager m{bus};
177         EXPECT_TRUE(false);
178     }
179     catch (const std::exception& e)
180     {}
181 }
182 
TEST_F(AssocsTest,TEST_GOOD_JSON)183 TEST_F(AssocsTest, TEST_GOOD_JSON)
184 {
185     auto path = writeFile(goodJson);
186     Manager m(bus, path);
187 
188     const auto& a = m.getAssociationsConfig();
189     EXPECT_EQ(a.size(), 2);
190 
191     {
192         auto x = a.find("/xyz/openbmc_project/inventory/system/PS0");
193         EXPECT_NE(x, a.end());
194 
195         auto& endpoints = x->second;
196         EXPECT_EQ(endpoints.size(), 2);
197 
198         {
199             auto& types = std::get<0>(endpoints[0]);
200             EXPECT_EQ(std::get<0>(types), "sensors");
201             EXPECT_EQ(std::get<1>(types), "inventory");
202 
203             auto& paths = std::get<1>(endpoints[0]);
204             EXPECT_EQ(paths.size(), 4);
205         }
206         {
207             auto& types = std::get<0>(endpoints[1]);
208             EXPECT_EQ(std::get<0>(types), "fans");
209             EXPECT_EQ(std::get<1>(types), "inventory");
210 
211             auto& paths = std::get<1>(endpoints[1]);
212             EXPECT_EQ(paths.size(), 1);
213         }
214     }
215     {
216         auto x = a.find("/xyz/openbmc_project/inventory/system/fan42");
217         EXPECT_NE(x, a.end());
218 
219         auto& endpoints = x->second;
220         EXPECT_EQ(endpoints.size(), 2);
221 
222         {
223             auto& types = std::get<0>(endpoints[0]);
224             EXPECT_EQ(std::get<0>(types), "sensors");
225             EXPECT_EQ(std::get<1>(types), "inventory");
226 
227             auto& paths = std::get<1>(endpoints[0]);
228             EXPECT_EQ(paths.size(), 1);
229         }
230         {
231             auto& types = std::get<0>(endpoints[1]);
232             EXPECT_EQ(std::get<0>(types), "led");
233             EXPECT_EQ(std::get<1>(types), "inventory");
234 
235             auto& paths = std::get<1>(endpoints[1]);
236             EXPECT_EQ(paths.size(), 1);
237         }
238     }
239 }
240 
TEST_F(AssocsTest,TEST_BAD_JSON0)241 TEST_F(AssocsTest, TEST_BAD_JSON0)
242 {
243     auto path = writeFile(badJson0);
244 
245     try
246     {
247         Manager m(bus, path);
248 
249         EXPECT_TRUE(false);
250     }
251     catch (const std::exception& e)
252     {}
253 }
254 
TEST_F(AssocsTest,TEST_BAD_JSON1)255 TEST_F(AssocsTest, TEST_BAD_JSON1)
256 {
257     auto path = writeFile(badJson1);
258 
259     try
260     {
261         Manager m(bus, path);
262 
263         EXPECT_TRUE(false);
264     }
265     catch (const std::exception& e)
266     {}
267 }
268 
TEST_F(AssocsTest,TEST_BAD_JSON2)269 TEST_F(AssocsTest, TEST_BAD_JSON2)
270 {
271     auto path = writeFile(badJson2);
272 
273     try
274     {
275         Manager m(bus, path);
276 
277         EXPECT_TRUE(false);
278     }
279     catch (const std::exception& e)
280     {}
281 }
282 
TEST_F(AssocsTest,TEST_BAD_JSON3)283 TEST_F(AssocsTest, TEST_BAD_JSON3)
284 {
285     auto path = writeFile(badJson3);
286 
287     try
288     {
289         Manager m(bus, path);
290 
291         EXPECT_TRUE(false);
292     }
293     catch (const std::exception& e)
294     {}
295 }
296