1 #include "rde/external_storer_file.hpp"
2 
3 #include <string_view>
4 
5 #include <gmock/gmock-matchers.h>
6 #include <gmock/gmock.h>
7 #include <gtest/gtest.h>
8 
9 namespace bios_bmc_smm_error_logger
10 {
11 namespace rde
12 {
13 
14 using ::testing::_;
15 using ::testing::DoAll;
16 using ::testing::Return;
17 using ::testing::SaveArg;
18 
19 class MockFileWriter : public FileHandlerInterface
20 {
21   public:
22     MOCK_METHOD(bool, createFolder, (const std::string& path),
23                 (const, override));
24     MOCK_METHOD(bool, createFile,
25                 (const std::string& path, const nlohmann::json& jsonPdr),
26                 (const, override));
27 };
28 
29 class ExternalStorerFileTest : public ::testing::Test
30 {
31   public:
32     ExternalStorerFileTest() :
33         mockFileWriter(std::make_unique<MockFileWriter>())
34     {
35         mockFileWriterPtr = dynamic_cast<MockFileWriter*>(mockFileWriter.get());
36         exStorer = std::make_unique<ExternalStorerFileInterface>(
37             rootPath, std::move(mockFileWriter));
38     }
39 
40   protected:
41     std::unique_ptr<FileHandlerInterface> mockFileWriter;
42     std::unique_ptr<ExternalStorerFileInterface> exStorer;
43     MockFileWriter* mockFileWriterPtr;
44     const std::string rootPath = "/some/path";
45 };
46 
47 TEST_F(ExternalStorerFileTest, InvalidJsonTest)
48 {
49     // Try an invalid JSON.
50     std::string jsonStr = "Invalid JSON";
51     EXPECT_THAT(exStorer->publishJson(jsonStr), false);
52 }
53 
54 TEST_F(ExternalStorerFileTest, NoOdataTypeFailureTest)
55 {
56     // Try a JSON without @odata.type.
57     std::string jsonStr = R"(
58       {
59         "@odata.id": "/redfish/v1/Systems/system/Memory/dimm0/MemoryMetrics",
60         "Id":"Metrics"
61       }
62     )";
63     EXPECT_THAT(exStorer->publishJson(jsonStr), false);
64 }
65 
66 TEST_F(ExternalStorerFileTest, LogServiceNoOdataIdTest)
67 {
68     // Try a LogService without @odata.id.
69     std::string jsonStr = R"(
70       {
71         "@odata.type": "#LogService.v1_1_0.LogService","Id":"6F7-C1A7C"
72       }
73     )";
74     EXPECT_THAT(exStorer->publishJson(jsonStr), false);
75 }
76 
77 TEST_F(ExternalStorerFileTest, LogServiceNoIdTest)
78 {
79     // Try a LogService without Id.
80     std::string jsonStr = R"(
81       {
82         "@odata.id": "/redfish/v1/Systems/system/LogServices/6F7-C1A7C",
83         "@odata.type": "#LogService.v1_1_0.LogService"
84       }
85     )";
86     EXPECT_THAT(exStorer->publishJson(jsonStr), false);
87 }
88 
89 TEST_F(ExternalStorerFileTest, LogServiceTest)
90 {
91     // A valid LogService test.
92     std::string jsonStr = R"(
93       {
94         "@odata.id": "/redfish/v1/Systems/system/LogServices/6F7-C1A7C",
95         "@odata.type": "#LogService.v1_1_0.LogService","Id":"6F7-C1A7C"
96         }
97       )";
98     std::string exServiceFolder =
99         "/some/path/redfish/v1/Systems/system/LogServices/6F7-C1A7C";
100     std::string exEntriesFolder =
101         "/some/path/redfish/v1/Systems/system/LogServices/6F7-C1A7C/Entries";
102     nlohmann::json exEntriesJson = "{}"_json;
103     nlohmann::json exServiceJson = nlohmann::json::parse(jsonStr);
104     EXPECT_CALL(*mockFileWriterPtr, createFile(exServiceFolder, exServiceJson))
105         .WillOnce(Return(true));
106     EXPECT_CALL(*mockFileWriterPtr, createFile(exEntriesFolder, exEntriesJson))
107         .WillOnce(Return(true));
108     EXPECT_THAT(exStorer->publishJson(jsonStr), true);
109 }
110 
111 TEST_F(ExternalStorerFileTest, LogEntryWithoutLogServiceTest)
112 {
113     // Try a LogEntry without sending a LogService first.
114     std::string jsonLogEntry = R"(
115       {
116         "@odata.type": "#LogEntry.v1_13_0.LogEntry"
117       }
118     )";
119     EXPECT_THAT(exStorer->publishJson(jsonLogEntry), false);
120 }
121 
122 TEST_F(ExternalStorerFileTest, LogEntryTest)
123 {
124     // Before sending a LogEntry, first we need to push a LogService.
125     std::string jsonLogSerivce = R"(
126       {
127         "@odata.id": "/redfish/v1/Systems/system/LogServices/6F7-C1A7C",
128         "@odata.type": "#LogService.v1_1_0.LogService","Id":"6F7-C1A7C"
129       }
130     )";
131     std::string exServiceFolder =
132         "/some/path/redfish/v1/Systems/system/LogServices/6F7-C1A7C";
133     std::string exEntriesFolder =
134         "/some/path/redfish/v1/Systems/system/LogServices/6F7-C1A7C/Entries";
135     nlohmann::json exEntriesJson = "{}"_json;
136     nlohmann::json exServiceJson = nlohmann::json::parse(jsonLogSerivce);
137     EXPECT_CALL(*mockFileWriterPtr, createFile(exServiceFolder, exServiceJson))
138         .WillOnce(Return(true));
139     EXPECT_CALL(*mockFileWriterPtr, createFile(exEntriesFolder, exEntriesJson))
140         .WillOnce(Return(true));
141     EXPECT_THAT(exStorer->publishJson(jsonLogSerivce), true);
142 
143     // Now send a LogEntry
144     std::string jsonLogEntry = R"(
145       {
146         "@odata.id": "/some/odata/id",
147         "@odata.type": "#LogEntry.v1_13_0.LogEntry"
148       }
149     )";
150     nlohmann::json logEntryOut;
151     EXPECT_CALL(*mockFileWriterPtr, createFile(_, _))
152         .WillOnce(DoAll(SaveArg<1>(&logEntryOut), Return(true)));
153     EXPECT_THAT(exStorer->publishJson(jsonLogEntry), true);
154     EXPECT_NE(logEntryOut["Id"], nullptr);
155     EXPECT_EQ(logEntryOut["@odata.id"], nullptr);
156 }
157 
158 TEST_F(ExternalStorerFileTest, OtherSchemaNoOdataIdTest)
159 {
160     // Try a another PDRs without @odata.id.
161     std::string jsonStr = R"(
162       {
163         "@odata.type": "#MemoryMetrics.v1_4_1.MemoryMetrics",
164         "Id":"Metrics"
165       }
166     )";
167     EXPECT_THAT(exStorer->publishJson(jsonStr), false);
168 }
169 
170 TEST_F(ExternalStorerFileTest, OtherSchemaTypeTest)
171 {
172     // A valid MemoryMetrics PDR.
173     std::string jsonStr = R"(
174       {
175         "@odata.id": "/redfish/v1/Systems/system/Memory/dimm0/MemoryMetrics",
176         "@odata.type": "#MemoryMetrics.v1_4_1.MemoryMetrics",
177         "Id": "Metrics"
178       }
179     )";
180     std::string exFolder =
181         "/some/path/redfish/v1/Systems/system/Memory/dimm0/MemoryMetrics";
182     nlohmann::json exJson = nlohmann::json::parse(jsonStr);
183     EXPECT_CALL(*mockFileWriterPtr, createFile(exFolder, exJson))
184         .WillOnce(Return(true));
185     EXPECT_THAT(exStorer->publishJson(jsonStr), true);
186 }
187 
188 } // namespace rde
189 } // namespace bios_bmc_smm_error_logger
190