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