blob: c0f25783dab70e900c8921887f4e4503e887ad36 [file] [log] [blame]
kasunath37bc0df2022-06-07 12:40:26 -07001#include "rde/external_storer_file.hpp"
2
kasunath3d0cd552022-08-25 20:22:58 -07003#include <boost/asio/io_context.hpp>
kasunatha3b64fb2022-06-15 18:47:18 -07004
kasunath37bc0df2022-06-07 12:40:26 -07005#include <string_view>
6
7#include <gmock/gmock-matchers.h>
8#include <gmock/gmock.h>
9#include <gtest/gtest.h>
10
11namespace bios_bmc_smm_error_logger
12{
13namespace rde
14{
15
16using ::testing::_;
17using ::testing::DoAll;
Brandon Kim41a58d42024-09-06 06:49:42 +000018using ::testing::InSequence;
kasunath37bc0df2022-06-07 12:40:26 -070019using ::testing::Return;
20using ::testing::SaveArg;
21
22class MockFileWriter : public FileHandlerInterface
23{
24 public:
25 MOCK_METHOD(bool, createFolder, (const std::string& path),
26 (const, override));
27 MOCK_METHOD(bool, createFile,
28 (const std::string& path, const nlohmann::json& jsonPdr),
29 (const, override));
Brandon Kim41a58d42024-09-06 06:49:42 +000030 MOCK_METHOD(bool, removeAll, (const std::string& path), (const, override));
kasunath37bc0df2022-06-07 12:40:26 -070031};
32
33class ExternalStorerFileTest : public ::testing::Test
34{
35 public:
36 ExternalStorerFileTest() :
kasunath3d0cd552022-08-25 20:22:58 -070037 conn(std::make_shared<sdbusplus::asio::connection>(io)),
kasunath37bc0df2022-06-07 12:40:26 -070038 mockFileWriter(std::make_unique<MockFileWriter>())
39 {
40 mockFileWriterPtr = dynamic_cast<MockFileWriter*>(mockFileWriter.get());
Brandon Kim41a58d42024-09-06 06:49:42 +000041 // Set the queue of LogEntry to 1 saved entry and 2 non saved entry
kasunath37bc0df2022-06-07 12:40:26 -070042 exStorer = std::make_unique<ExternalStorerFileInterface>(
Brandon Kim41a58d42024-09-06 06:49:42 +000043 conn, rootPath, std::move(mockFileWriter), 1, 2);
kasunath37bc0df2022-06-07 12:40:26 -070044 }
45
46 protected:
kasunath3d0cd552022-08-25 20:22:58 -070047 boost::asio::io_context io;
48 std::shared_ptr<sdbusplus::asio::connection> conn;
49
kasunath37bc0df2022-06-07 12:40:26 -070050 std::unique_ptr<FileHandlerInterface> mockFileWriter;
51 std::unique_ptr<ExternalStorerFileInterface> exStorer;
52 MockFileWriter* mockFileWriterPtr;
53 const std::string rootPath = "/some/path";
54};
55
56TEST_F(ExternalStorerFileTest, InvalidJsonTest)
57{
58 // Try an invalid JSON.
59 std::string jsonStr = "Invalid JSON";
60 EXPECT_THAT(exStorer->publishJson(jsonStr), false);
61}
62
63TEST_F(ExternalStorerFileTest, NoOdataTypeFailureTest)
64{
65 // Try a JSON without @odata.type.
66 std::string jsonStr = R"(
67 {
68 "@odata.id": "/redfish/v1/Systems/system/Memory/dimm0/MemoryMetrics",
69 "Id":"Metrics"
70 }
71 )";
72 EXPECT_THAT(exStorer->publishJson(jsonStr), false);
73}
74
75TEST_F(ExternalStorerFileTest, LogServiceNoOdataIdTest)
76{
77 // Try a LogService without @odata.id.
78 std::string jsonStr = R"(
79 {
80 "@odata.type": "#LogService.v1_1_0.LogService","Id":"6F7-C1A7C"
81 }
82 )";
83 EXPECT_THAT(exStorer->publishJson(jsonStr), false);
84}
85
86TEST_F(ExternalStorerFileTest, LogServiceNoIdTest)
87{
88 // Try a LogService without Id.
89 std::string jsonStr = R"(
90 {
91 "@odata.id": "/redfish/v1/Systems/system/LogServices/6F7-C1A7C",
92 "@odata.type": "#LogService.v1_1_0.LogService"
93 }
94 )";
95 EXPECT_THAT(exStorer->publishJson(jsonStr), false);
96}
97
98TEST_F(ExternalStorerFileTest, LogServiceTest)
99{
100 // A valid LogService test.
101 std::string jsonStr = R"(
102 {
103 "@odata.id": "/redfish/v1/Systems/system/LogServices/6F7-C1A7C",
104 "@odata.type": "#LogService.v1_1_0.LogService","Id":"6F7-C1A7C"
105 }
106 )";
107 std::string exServiceFolder =
108 "/some/path/redfish/v1/Systems/system/LogServices/6F7-C1A7C";
109 std::string exEntriesFolder =
110 "/some/path/redfish/v1/Systems/system/LogServices/6F7-C1A7C/Entries";
111 nlohmann::json exEntriesJson = "{}"_json;
112 nlohmann::json exServiceJson = nlohmann::json::parse(jsonStr);
113 EXPECT_CALL(*mockFileWriterPtr, createFile(exServiceFolder, exServiceJson))
114 .WillOnce(Return(true));
115 EXPECT_CALL(*mockFileWriterPtr, createFile(exEntriesFolder, exEntriesJson))
116 .WillOnce(Return(true));
117 EXPECT_THAT(exStorer->publishJson(jsonStr), true);
118}
119
120TEST_F(ExternalStorerFileTest, LogEntryWithoutLogServiceTest)
121{
122 // Try a LogEntry without sending a LogService first.
123 std::string jsonLogEntry = R"(
124 {
125 "@odata.type": "#LogEntry.v1_13_0.LogEntry"
126 }
127 )";
128 EXPECT_THAT(exStorer->publishJson(jsonLogEntry), false);
129}
130
131TEST_F(ExternalStorerFileTest, LogEntryTest)
132{
Brandon Kim41a58d42024-09-06 06:49:42 +0000133 InSequence s;
kasunath37bc0df2022-06-07 12:40:26 -0700134 // Before sending a LogEntry, first we need to push a LogService.
135 std::string jsonLogSerivce = R"(
136 {
137 "@odata.id": "/redfish/v1/Systems/system/LogServices/6F7-C1A7C",
138 "@odata.type": "#LogService.v1_1_0.LogService","Id":"6F7-C1A7C"
139 }
140 )";
141 std::string exServiceFolder =
142 "/some/path/redfish/v1/Systems/system/LogServices/6F7-C1A7C";
143 std::string exEntriesFolder =
144 "/some/path/redfish/v1/Systems/system/LogServices/6F7-C1A7C/Entries";
145 nlohmann::json exEntriesJson = "{}"_json;
146 nlohmann::json exServiceJson = nlohmann::json::parse(jsonLogSerivce);
147 EXPECT_CALL(*mockFileWriterPtr, createFile(exServiceFolder, exServiceJson))
148 .WillOnce(Return(true));
149 EXPECT_CALL(*mockFileWriterPtr, createFile(exEntriesFolder, exEntriesJson))
150 .WillOnce(Return(true));
151 EXPECT_THAT(exStorer->publishJson(jsonLogSerivce), true);
152
Brandon Kim41a58d42024-09-06 06:49:42 +0000153 // Now send a LogEntry#1, which will not be deleted
kasunath37bc0df2022-06-07 12:40:26 -0700154 std::string jsonLogEntry = R"(
155 {
156 "@odata.id": "/some/odata/id",
157 "@odata.type": "#LogEntry.v1_13_0.LogEntry"
158 }
159 )";
160 nlohmann::json logEntryOut;
Brandon Kim41a58d42024-09-06 06:49:42 +0000161 std::string logPath1;
kasunath37bc0df2022-06-07 12:40:26 -0700162 EXPECT_CALL(*mockFileWriterPtr, createFile(_, _))
Brandon Kim41a58d42024-09-06 06:49:42 +0000163 .WillOnce(DoAll(SaveArg<0>(&logPath1), SaveArg<1>(&logEntryOut),
164 Return(true)));
kasunath37bc0df2022-06-07 12:40:26 -0700165 EXPECT_THAT(exStorer->publishJson(jsonLogEntry), true);
Brandon Kim41a58d42024-09-06 06:49:42 +0000166 EXPECT_FALSE(logPath1.empty());
167 EXPECT_NE(logEntryOut["Id"], nullptr);
168 EXPECT_EQ(logEntryOut["@odata.id"], nullptr);
169
170 // Now send a LogEntry#2, which will be the first to be deleted
171 std::string logPath2;
172 EXPECT_CALL(*mockFileWriterPtr, createFile(_, _))
173 .WillOnce(DoAll(SaveArg<0>(&logPath2), SaveArg<1>(&logEntryOut),
174 Return(true)));
175 EXPECT_THAT(exStorer->publishJson(jsonLogEntry), true);
176 EXPECT_FALSE(logPath2.empty());
177 EXPECT_NE(logEntryOut["Id"], nullptr);
178 EXPECT_EQ(logEntryOut["@odata.id"], nullptr);
179
180 // Now send a LogEntry#3
181 std::string logPath3;
182 EXPECT_CALL(*mockFileWriterPtr, createFile(_, _))
183 .WillOnce(DoAll(SaveArg<0>(&logPath3), SaveArg<1>(&logEntryOut),
184 Return(true)));
185 EXPECT_THAT(exStorer->publishJson(jsonLogEntry), true);
186 EXPECT_FALSE(logPath3.empty());
187 EXPECT_NE(logEntryOut["Id"], nullptr);
188 EXPECT_EQ(logEntryOut["@odata.id"], nullptr);
189
190 // Now send a LogEntry#4, we expect the LogEntry#2 to be deleted
191 std::string logPath4;
192 EXPECT_CALL(*mockFileWriterPtr, removeAll(logPath2)).WillOnce(Return(true));
193 EXPECT_CALL(*mockFileWriterPtr, createFile(_, _))
194 .WillOnce(DoAll(SaveArg<0>(&logPath4), SaveArg<1>(&logEntryOut),
195 Return(true)));
196 EXPECT_THAT(exStorer->publishJson(jsonLogEntry), true);
197 EXPECT_FALSE(logPath4.empty());
198 EXPECT_NE(logEntryOut["Id"], nullptr);
199 EXPECT_EQ(logEntryOut["@odata.id"], nullptr);
200
201 // Now send a LogEntry#5, we expect the LogEntry#3 to be deleted
202 std::string logPath5;
203 EXPECT_CALL(*mockFileWriterPtr, removeAll(logPath3)).WillOnce(Return(true));
204 EXPECT_CALL(*mockFileWriterPtr, createFile(_, _))
205 .WillOnce(DoAll(SaveArg<0>(&logPath5), SaveArg<1>(&logEntryOut),
206 Return(true)));
207 EXPECT_THAT(exStorer->publishJson(jsonLogEntry), true);
208 EXPECT_FALSE(logPath5.empty());
kasunath37bc0df2022-06-07 12:40:26 -0700209 EXPECT_NE(logEntryOut["Id"], nullptr);
210 EXPECT_EQ(logEntryOut["@odata.id"], nullptr);
kasunath37bc0df2022-06-07 12:40:26 -0700211}
212
213TEST_F(ExternalStorerFileTest, OtherSchemaNoOdataIdTest)
214{
215 // Try a another PDRs without @odata.id.
216 std::string jsonStr = R"(
217 {
218 "@odata.type": "#MemoryMetrics.v1_4_1.MemoryMetrics",
219 "Id":"Metrics"
220 }
221 )";
222 EXPECT_THAT(exStorer->publishJson(jsonStr), false);
223}
224
225TEST_F(ExternalStorerFileTest, OtherSchemaTypeTest)
226{
227 // A valid MemoryMetrics PDR.
228 std::string jsonStr = R"(
229 {
230 "@odata.id": "/redfish/v1/Systems/system/Memory/dimm0/MemoryMetrics",
231 "@odata.type": "#MemoryMetrics.v1_4_1.MemoryMetrics",
232 "Id": "Metrics"
233 }
234 )";
235 std::string exFolder =
236 "/some/path/redfish/v1/Systems/system/Memory/dimm0/MemoryMetrics";
237 nlohmann::json exJson = nlohmann::json::parse(jsonStr);
238 EXPECT_CALL(*mockFileWriterPtr, createFile(exFolder, exJson))
239 .WillOnce(Return(true));
240 EXPECT_THAT(exStorer->publishJson(jsonStr), true);
241}
242
243} // namespace rde
244} // namespace bios_bmc_smm_error_logger