xref: /openbmc/ibm-logging/test/test_policy.cpp (revision 62011e26)
1 /**
2  * Copyright © 2018 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <fstream>
17 #include <gtest/gtest.h>
18 #include <experimental/filesystem>
19 #include "policy_table.hpp"
20 #include "policy_find.hpp"
21 
22 using namespace ibm::logging;
23 namespace fs = std::experimental::filesystem;
24 
25 static constexpr auto json = R"(
26 [
27     {
28     "dtls":[
29       {
30         "CEID":"ABCD1234",
31         "mod":"",
32         "msg":"Error ABCD1234"
33       }
34     ],
35     "err":"xyz.openbmc_project.Error.Test1"
36     },
37 
38     {
39     "dtls":[
40       {
41         "CEID":"XYZ222",
42         "mod":"",
43         "msg":"Error XYZ222"
44       }
45     ],
46     "err":"xyz.openbmc_project.Error.Test2"
47     },
48 
49     {
50     "dtls":[
51       {
52         "CEID":"AAAAAA",
53         "mod":"mod1",
54         "msg":"Error AAAAAA"
55       },
56       {
57         "CEID":"BBBBBB",
58         "mod":"mod2",
59         "msg":"Error BBBBBB"
60       },
61       {
62         "CEID":"CCCCCC",
63         "mod":"mod3",
64         "msg":"Error CCCCCC"
65       }
66     ],
67     "err":"xyz.openbmc_project.Error.Test3"
68     },
69 
70     {
71     "dtls":[
72       {
73         "CEID":"DDDDDDDD",
74         "mod":"I2C",
75         "msg":"Error DDDDDDDD"
76       },
77       {
78         "CEID":"EEEEEEEE",
79         "mod":"FSI",
80         "msg":"Error EEEEEEEE"
81       }
82     ],
83     "err":"xyz.openbmc_project.Error.Test4"
84     },
85 
86     {
87     "dtls":[
88       {
89         "CEID":"FFFFFFFF",
90         "mod":"6D",
91         "msg":"Error FFFFFFFF"
92       }
93     ],
94 
95     "err":"xyz.openbmc_project.Error.Test5"
96     },
97     {
98     "dtls":[
99       {
100         "CEID":"GGGGGGGG",
101         "mod":"RAIL_5",
102         "msg":"Error GGGGGGGG"
103       }
104     ],
105 
106     "err":"xyz.openbmc_project.Error.Test6"
107     },
108     {
109     "dtls":[
110       {
111         "CEID":"HHHHHHHH",
112         "mod":"INPUT_42",
113         "msg":"Error HHHHHHHH"
114       }
115     ],
116     "err":"xyz.openbmc_project.Error.Test7"
117     }
118 ])";
119 
120 
121 /**
122  * Helper class to write the above json to a file and then
123  * remove it when the tests are over.
124  */
125 class PolicyTableTest : public ::testing::Test
126 {
127     protected:
128 
129         virtual void SetUp()
130         {
131             char dir[] = {"./jsonTestXXXXXX"};
132 
133             jsonDir = mkdtemp(dir);
134             jsonFile = jsonDir / "policy.json";
135 
136             std::ofstream f{jsonFile};
137             f << json;
138         }
139 
140         virtual void TearDown()
141         {
142             fs::remove_all(jsonDir);
143         }
144 
145         fs::path jsonDir;
146         fs::path jsonFile;
147 };
148 
149 
150 /**
151  * Test finding entries in the policy table
152  */
153 TEST_F(PolicyTableTest, TestTable)
154 {
155     policy::Table policy{jsonFile};
156     ASSERT_EQ(policy.isLoaded(), true);
157 
158     ////////////////////////////////////
159     //Basic search, no modifier
160     std::string err{"xyz.openbmc_project.Error.Test2"};
161     std::string mod;
162 
163     auto details = policy.find(err, mod);
164     ASSERT_EQ(static_cast<bool>(details), true);
165     if (details)
166     {
167         ASSERT_EQ((*details).get().ceid, "XYZ222");
168         ASSERT_EQ((*details).get().msg, "Error XYZ222");
169     }
170 
171     /////////////////////////////////////
172     //Not found
173     err = "foo";
174     details = policy.find(err, mod);
175     ASSERT_EQ(static_cast<bool>(details), false);
176 
177     /////////////////////////////////////
178     //Test with a modifier
179     err = "xyz.openbmc_project.Error.Test3";
180     mod = "mod3";
181 
182     details = policy.find(err, mod);
183     ASSERT_EQ(static_cast<bool>(details), true);
184     if (details)
185     {
186         ASSERT_EQ((*details).get().ceid, "CCCCCC");
187         ASSERT_EQ((*details).get().msg, "Error CCCCCC");
188     }
189 }
190 
191 /**
192  * Test policy::find() that uses the data from a property
193  * map to find entries in the policy table.
194  */
195 TEST_F(PolicyTableTest, TestFinder)
196 {
197     using namespace std::literals::string_literals;
198 
199     policy::Table policy{jsonFile};
200     ASSERT_EQ(policy.isLoaded(), true);
201 
202     //A basic search with no modifier
203     {
204         DbusPropertyMap testProperties
205         {
206             {"Message"s, Value{"xyz.openbmc_project.Error.Test1"s}}
207         };
208 
209         auto values = policy::find(policy, testProperties);
210         ASSERT_EQ(std::get<policy::EIDField>(values), "ABCD1234");
211         ASSERT_EQ(std::get<policy::MsgField>(values), "Error ABCD1234");
212     }
213 
214     //Use CALLOUT_INVENTORY_PATH from the AdditionalData property
215     {
216         std::vector<std::string> ad{
217                 "FOO=BAR"s,
218                 "CALLOUT_INVENTORY_PATH=mod2"s};
219         DbusPropertyMap testProperties
220         {
221             {"Message"s, Value{"xyz.openbmc_project.Error.Test3"s}},
222             {"AdditionalData"s, ad}
223         };
224 
225         auto values = policy::find(policy, testProperties);
226         ASSERT_EQ(std::get<policy::EIDField>(values), "BBBBBB");
227         ASSERT_EQ(std::get<policy::MsgField>(values), "Error BBBBBB");
228     }
229 
230     //Use an I2C DEVICE_PATH from the AdditionalData property
231     {
232         std::vector<std::string> ad{
233                 "FOO=BAR"s,
234                 "CALLOUT_DEVICE_PATH=/some/i2c/path"s};
235         DbusPropertyMap testProperties
236         {
237             {"Message"s, Value{"xyz.openbmc_project.Error.Test4"s}},
238             {"AdditionalData"s, ad}
239         };
240 
241         auto values = policy::find(policy, testProperties);
242         ASSERT_EQ(std::get<policy::EIDField>(values), "DDDDDDDD");
243         ASSERT_EQ(std::get<policy::MsgField>(values), "Error DDDDDDDD");
244     }
245 
246     //Use an FSI DEVICE_PATH from the AdditionalData property
247     {
248         std::vector<std::string> ad{
249                 "FOO=BAR"s,
250                 "CALLOUT_DEVICE_PATH=/some/fsi/path"s};
251         DbusPropertyMap testProperties
252         {
253             {"Message"s, Value{"xyz.openbmc_project.Error.Test4"s}},
254             {"AdditionalData"s, ad}
255         };
256 
257         auto values = policy::find(policy, testProperties);
258         ASSERT_EQ(std::get<policy::EIDField>(values), "EEEEEEEE");
259         ASSERT_EQ(std::get<policy::MsgField>(values), "Error EEEEEEEE");
260     }
261 
262     //Use PROCEDURE from the AdditionalData property
263     {
264         std::vector<std::string> ad{
265                 "FOO=BAR"s,
266                 "PROCEDURE=109"s};
267         DbusPropertyMap testProperties
268         {
269             {"Message"s, Value{"xyz.openbmc_project.Error.Test5"s}},
270             {"AdditionalData"s, ad}
271         };
272 
273         auto values = policy::find(policy, testProperties);
274         ASSERT_EQ(std::get<policy::EIDField>(values), "FFFFFFFF");
275         ASSERT_EQ(std::get<policy::MsgField>(values), "Error FFFFFFFF");
276     }
277 
278     //Use RAIL_NAME from the AdditionalData property
279     {
280         std::vector<std::string> ad{
281                 "FOO=BAR"s,
282                 "RAIL_NAME=RAIL_5"s};
283         DbusPropertyMap testProperties
284         {
285             {"Message"s, Value{"xyz.openbmc_project.Error.Test6"s}},
286             {"AdditionalData"s, ad}
287         };
288 
289         auto values = policy::find(policy, testProperties);
290         ASSERT_EQ(std::get<policy::EIDField>(values), "GGGGGGGG");
291         ASSERT_EQ(std::get<policy::MsgField>(values), "Error GGGGGGGG");
292     }
293 
294     //Use INPUT_NAME from the AdditionalData property
295     {
296         std::vector<std::string> ad{
297                 "FOO=BAR"s,
298                 "INPUT_NAME=INPUT_42"s};
299         DbusPropertyMap testProperties
300         {
301             {"Message"s, Value{"xyz.openbmc_project.Error.Test7"s}},
302             {"AdditionalData"s, ad}
303         };
304 
305         auto values = policy::find(policy, testProperties);
306         ASSERT_EQ(std::get<policy::EIDField>(values), "HHHHHHHH");
307         ASSERT_EQ(std::get<policy::MsgField>(values), "Error HHHHHHHH");
308     }
309 
310     //Test not finding an entry.
311     {
312         DbusPropertyMap testProperties
313         {
314             {"Message"s, Value{"hello world"s}}
315         };
316 
317         auto values = policy::find(policy, testProperties);
318         ASSERT_EQ(std::get<policy::EIDField>(values), policy.defaultEID());
319         ASSERT_EQ(std::get<policy::MsgField>(values), policy.defaultMsg());
320     }
321 
322     // Test that strange AdditionalData values don't break anything
323     {
324         std::vector<std::string> ad{
325                 "FOO"s,
326                 "INPUT_NAME="s};
327         DbusPropertyMap testProperties
328         {
329             {"Message"s, Value{"xyz.openbmc_project.Error.Test7"s}},
330             {"AdditionalData"s, ad}
331         };
332 
333         auto values = policy::find(policy, testProperties);
334         ASSERT_EQ(std::get<policy::EIDField>(values), policy.defaultEID());
335         ASSERT_EQ(std::get<policy::MsgField>(values), policy.defaultMsg());
336     }
337 }
338 
339