1 // Copyright 2021 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "general_systemd.hpp"
16 #include "log_handlers_builder.hpp"
17 #include "skip_action.hpp"
18 
19 #include <nlohmann/json.hpp>
20 
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 
24 namespace ipmi_flash
25 {
26 namespace
27 {
28 using ::testing::IsEmpty;
29 
30 using json = nlohmann::json;
31 
TEST(LogJsonTest,ValidConfigurationNoLogHandler)32 TEST(LogJsonTest, ValidConfigurationNoLogHandler)
33 {
34     auto j2 = R"(
35         [{
36             "blob" : "/flash/sink_seq",
37             "log":{
38                 "handler": {
39                    "type" : "file",
40                    "path" : "/tmp/log_info"
41                  },
42                 "actions":{
43                     "open" :{
44                     "type" : "systemd",
45                     "unit" : "absolute"
46                     }
47                  }
48             }
49          }]
50     )"_json;
51     auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
52     ASSERT_THAT(h, ::testing::SizeIs(1));
53     EXPECT_THAT(h[0].blobId, "/log/sink_seq");
54     EXPECT_FALSE(h[0].actions == nullptr);
55     EXPECT_FALSE(h[0].handler == nullptr);
56 }
57 
TEST(LogJsonTest,ValidConfigurationLogBlobName)58 TEST(LogJsonTest, ValidConfigurationLogBlobName)
59 {
60     auto j2 = R"(
61         [{
62             "blob" : "/log/sink_seq",
63             "log":{
64                 "handler": {
65                    "type" : "file",
66                    "path" : "/tmp/log_info"
67                  },
68                 "actions": {
69                     "open" : {
70                     "type" : "systemd",
71                     "unit" : "phosphor-ipmi-flash-log-sink-sequencer.target"
72                     }
73                  }
74             }
75          }]
76     )"_json;
77     auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
78     ASSERT_THAT(h, ::testing::SizeIs(1));
79     EXPECT_THAT(h[0].blobId, "/log/sink_seq");
80     EXPECT_FALSE(h[0].actions == nullptr);
81     EXPECT_FALSE(h[0].handler == nullptr);
82 }
83 
TEST(LogJsonTest,MissingHandlerType)84 TEST(LogJsonTest, MissingHandlerType)
85 {
86     auto j2 = R"(
87         [{
88             "blob" : "/flash/image",
89             "log":{
90                 "handler": {
91                    "path" : "/tmp/log_info"
92                  },
93                 "actions": {
94                   "open" : {
95                   "type" : "systemd",
96                   "unit" : "absolute"}
97                  }
98             }
99          }]
100     )"_json;
101     EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
102 }
103 
TEST(LogJsonTest,BadBlobName)104 TEST(LogJsonTest, BadBlobName)
105 {
106     auto j2 = R"(
107         [{
108             "blob" : "/bad/image",
109             "log":{
110                 "handler": {
111                    "type" : "file",
112                    "path" : "/tmp/log_info"
113                  },
114                 "actions": {
115                   "open" : {
116                   "type" : "systemd",
117                   "unit" : "absolute"}
118                  }
119             }
120          }]
121     )"_json;
122     EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
123 }
124 
TEST(LogJsonTest,MissingActions)125 TEST(LogJsonTest, MissingActions)
126 {
127     auto j2 = R"(
128         [{
129             "blob" : "/flash/image",
130             "log":{
131                 "handler": {
132                    "type" : "file",
133                    "path" : "/tmp/log_info"
134                  }
135             }
136          }]
137     )"_json;
138     EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
139 }
140 
TEST(LogJsonTest,MissingOpenAction)141 TEST(LogJsonTest, MissingOpenAction)
142 {
143     auto j2 = R"(
144         [{
145             "blob" : "/flash/image",
146             "log":{
147                 "handler": {
148                    "type" : "file",
149                    "path" : "/tmp/log_info"
150                  },
151                 "actions": {}
152             }
153          }]
154     )"_json;
155     EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
156 }
157 
TEST(LogJsonTest,OneInvalidTwoValidSucceeds)158 TEST(LogJsonTest, OneInvalidTwoValidSucceeds)
159 {
160     auto j2 = R"(
161         [{
162             "blob" : "/flash/sink_seq0",
163             "log":{
164                 "handler": {
165                    "type" : "file",
166                    "path" : "/tmp/log_info"
167                  },
168                 "actions":{
169                     "open" :{
170                     "type" : "systemd",
171                     "unit" : "absolute"
172                     }
173                  }
174             }
175          },
176          {
177             "blob" : "/log/sink_seq1",
178             "log":{
179                 "handler": {
180                    "type" : "file",
181                    "path" : "/tmp/log_info"
182                  },
183                 "actions":{
184                     "open" :{
185                     "type" : "systemd",
186                     "unit" : "absolute"
187                     }
188                  }
189             }
190          },
191          {
192             "blob" : "/bad/sink_seq",
193             "log":{
194                 "handler": {
195                    "type" : "file",
196                    "path" : "/tmp/log_info"
197                  },
198                 "actions":{
199                     "open" :{
200                     "type" : "systemd",
201                     "unit" : "absolute"
202                     }
203                  }
204             }
205          }
206          ]
207     )"_json;
208     auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
209     ASSERT_THAT(h, ::testing::SizeIs(2));
210     EXPECT_THAT(h[0].blobId, "/log/sink_seq0");
211     EXPECT_THAT(h[1].blobId, "/log/sink_seq1");
212 }
213 
TEST(LogJsonTest,BlobNameIsTooShort)214 TEST(LogJsonTest, BlobNameIsTooShort)
215 {
216     auto j2 = R"(
217         [{
218             "blob" : "/flash/",
219             "log":{
220                 "handler": {
221                    "type" : "file",
222                    "path" : "/tmp/log_info"
223                  },
224                 "actions":{
225                     "open" :{
226                     "type" : "systemd",
227                     "unit" : "absolute"
228                     }
229                  }
230             }
231          }]
232     )"_json;
233     EXPECT_THAT(LogHandlersBuilder().buildHandlerFromJson(j2), IsEmpty());
234 }
235 
TEST(LogJsonTest,OpenSkipAction)236 TEST(LogJsonTest, OpenSkipAction)
237 {
238     auto j2 = R"(
239         [{
240             "blob" : "/flash/sink_seqs",
241             "log":{
242                 "handler": {
243                    "type" : "file",
244                    "path" : "/tmp/log_info"
245                  },
246                 "actions":{
247                     "open" :{
248                     "type" : "skip"
249                     }
250                  }
251             }
252          }]
253     )"_json;
254     auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
255     EXPECT_THAT(h, ::testing::SizeIs(1));
256     EXPECT_TRUE(h[0].blobId == "/log/sink_seqs");
257     ASSERT_FALSE(h[0].actions == nullptr);
258     EXPECT_FALSE(h[0].actions->onOpen == nullptr);
259 }
260 
TEST(LogJsonTest,OpenActionsWithDifferentModes)261 TEST(LogJsonTest, OpenActionsWithDifferentModes)
262 {
263     auto j2 = R"(
264         [{
265             "blob" : "/flash/blob1",
266             "log":{
267                 "handler": {
268                    "type" : "file",
269                    "path" : "/tmp/log_info"
270                  },
271                 "actions":{
272                     "open" :{
273                     "type" : "systemd",
274                     "unit" : "absolute",
275                     "mode" : "replace-nope"
276                     }
277                  }
278             }
279          },
280          {
281             "blob" : "/flash/blob2",
282             "log":{
283                 "handler": {
284                    "type" : "file",
285                    "path" : "/tmp/log_info"
286                  },
287                 "actions":{
288                     "open" :{
289                     "type" : "systemd",
290                     "unit" : "absolute",
291                     "mode" : "replace-fake"
292                     }
293                  }
294             }
295          }
296          ]
297     )"_json;
298     auto h = LogHandlersBuilder().buildHandlerFromJson(j2);
299     ASSERT_THAT(h, ::testing::SizeIs(2));
300 
301     EXPECT_FALSE(h[0].handler == nullptr);
302     EXPECT_FALSE(h[0].actions == nullptr);
303     EXPECT_THAT(h[0].blobId, "/log/blob1");
304     auto onOpen0 = reinterpret_cast<SystemdNoFile*>(h[0].actions->onOpen.get());
305     EXPECT_THAT(onOpen0->getMode(), "replace-nope");
306 
307     EXPECT_FALSE(h[1].handler == nullptr);
308     EXPECT_FALSE(h[1].actions == nullptr);
309     EXPECT_THAT(h[1].blobId, "/log/blob2");
310     auto onOpen1 = reinterpret_cast<SystemdNoFile*>(h[1].actions->onOpen.get());
311     EXPECT_THAT(onOpen1->getMode(), "replace-fake");
312 }
313 } // namespace
314 } // namespace ipmi_flash
315