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:
144     AssocsTest() : ::testing::Test(), bus(sdbusplus::bus::new_default())
145     {}
146 
147     fs::path jsonDir;
148     sdbusplus::bus::bus bus;
149 
150     virtual void SetUp()
151     {
152         char dir[] = {"assocTestXXXXXX"};
153         jsonDir = mkdtemp(dir);
154     }
155 
156     virtual void TearDown()
157     {
158         fs::remove_all(jsonDir);
159     }
160 
161     std::string writeFile(const char* data)
162     {
163         fs::path path = jsonDir / "associations.json";
164 
165         std::ofstream f{path};
166         f << data;
167         f.close();
168 
169         return path;
170     }
171 };
172 
173 TEST_F(AssocsTest, TEST_NO_JSON)
174 {
175     try
176     {
177         Manager m{bus};
178         EXPECT_TRUE(false);
179     }
180     catch (const std::exception& e)
181     {}
182 }
183 
184 TEST_F(AssocsTest, TEST_GOOD_JSON)
185 {
186     auto path = writeFile(goodJson);
187     Manager m(bus, path);
188 
189     const auto& a = m.getAssociationsConfig();
190     EXPECT_EQ(a.size(), 2);
191 
192     {
193         auto x = a.find("/xyz/openbmc_project/inventory/system/PS0");
194         EXPECT_NE(x, a.end());
195 
196         auto& endpoints = x->second;
197         EXPECT_EQ(endpoints.size(), 2);
198 
199         {
200             auto& types = std::get<0>(endpoints[0]);
201             EXPECT_EQ(std::get<0>(types), "sensors");
202             EXPECT_EQ(std::get<1>(types), "inventory");
203 
204             auto& paths = std::get<1>(endpoints[0]);
205             EXPECT_EQ(paths.size(), 4);
206         }
207         {
208             auto& types = std::get<0>(endpoints[1]);
209             EXPECT_EQ(std::get<0>(types), "fans");
210             EXPECT_EQ(std::get<1>(types), "inventory");
211 
212             auto& paths = std::get<1>(endpoints[1]);
213             EXPECT_EQ(paths.size(), 1);
214         }
215     }
216     {
217         auto x = a.find("/xyz/openbmc_project/inventory/system/fan42");
218         EXPECT_NE(x, a.end());
219 
220         auto& endpoints = x->second;
221         EXPECT_EQ(endpoints.size(), 2);
222 
223         {
224             auto& types = std::get<0>(endpoints[0]);
225             EXPECT_EQ(std::get<0>(types), "sensors");
226             EXPECT_EQ(std::get<1>(types), "inventory");
227 
228             auto& paths = std::get<1>(endpoints[0]);
229             EXPECT_EQ(paths.size(), 1);
230         }
231         {
232             auto& types = std::get<0>(endpoints[1]);
233             EXPECT_EQ(std::get<0>(types), "led");
234             EXPECT_EQ(std::get<1>(types), "inventory");
235 
236             auto& paths = std::get<1>(endpoints[1]);
237             EXPECT_EQ(paths.size(), 1);
238         }
239     }
240 }
241 
242 TEST_F(AssocsTest, TEST_BAD_JSON0)
243 {
244     auto path = writeFile(badJson0);
245 
246     try
247     {
248         Manager m(bus, path);
249 
250         EXPECT_TRUE(false);
251     }
252     catch (const std::exception& e)
253     {}
254 }
255 
256 TEST_F(AssocsTest, TEST_BAD_JSON1)
257 {
258     auto path = writeFile(badJson1);
259 
260     try
261     {
262         Manager m(bus, path);
263 
264         EXPECT_TRUE(false);
265     }
266     catch (const std::exception& e)
267     {}
268 }
269 
270 TEST_F(AssocsTest, TEST_BAD_JSON2)
271 {
272     auto path = writeFile(badJson2);
273 
274     try
275     {
276         Manager m(bus, path);
277 
278         EXPECT_TRUE(false);
279     }
280     catch (const std::exception& e)
281     {}
282 }
283 
284 TEST_F(AssocsTest, TEST_BAD_JSON3)
285 {
286     auto path = writeFile(badJson3);
287 
288     try
289     {
290         Manager m(bus, path);
291 
292         EXPECT_TRUE(false);
293     }
294     catch (const std::exception& e)
295     {}
296 }
297