1 /** 2 * Copyright © 2019 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 "extensions/openpower-pels/manager.hpp" 17 #include "log_manager.hpp" 18 #include "pel_utils.hpp" 19 20 #include <fstream> 21 #include <regex> 22 #include <xyz/openbmc_project/Common/error.hpp> 23 24 #include <gtest/gtest.h> 25 26 using namespace openpower::pels; 27 namespace fs = std::filesystem; 28 29 class TestLogger 30 { 31 public: 32 void log(const std::string& name, phosphor::logging::Entry::Level level, 33 const EventLogger::ADMap& additionalData) 34 { 35 errName = name; 36 errLevel = level; 37 ad = additionalData; 38 } 39 40 std::string errName; 41 phosphor::logging::Entry::Level errLevel; 42 EventLogger::ADMap ad; 43 }; 44 45 class ManagerTest : public CleanPELFiles 46 { 47 public: 48 ManagerTest() : logManager(bus, "logging_path") 49 { 50 sd_event_default(&sdEvent); 51 bus.attach_event(sdEvent, SD_EVENT_PRIORITY_NORMAL); 52 } 53 54 ~ManagerTest() 55 { 56 sd_event_unref(sdEvent); 57 } 58 59 sdbusplus::bus::bus bus = sdbusplus::bus::new_default(); 60 phosphor::logging::internal::Manager logManager; 61 sd_event* sdEvent; 62 TestLogger logger; 63 }; 64 65 fs::path makeTempDir() 66 { 67 char path[] = "/tmp/tempnameXXXXXX"; 68 std::filesystem::path dir = mkdtemp(path); 69 return dir; 70 } 71 72 std::optional<fs::path> findAnyPELInRepo() 73 { 74 // PELs are named <timestamp>_<ID> 75 std::regex expr{"\\d+_\\d+"}; 76 77 for (auto& f : fs::directory_iterator(getPELRepoPath() / "logs")) 78 { 79 if (std::regex_search(f.path().string(), expr)) 80 { 81 return f.path(); 82 } 83 } 84 return std::nullopt; 85 } 86 87 // Test that using the RAWPEL=<file> with the Manager::create() call gets 88 // a PEL saved in the repository. 89 TEST_F(ManagerTest, TestCreateWithPEL) 90 { 91 std::unique_ptr<DataInterfaceBase> dataIface = 92 std::make_unique<DataInterface>(bus); 93 94 openpower::pels::Manager manager{ 95 logManager, std::move(dataIface), 96 std::bind(std::mem_fn(&TestLogger::log), &logger, std::placeholders::_1, 97 std::placeholders::_2, std::placeholders::_3)}; 98 99 // Create a PEL, write it to a file, and pass that filename into 100 // the create function. 101 auto data = pelDataFactory(TestPELType::pelSimple); 102 103 fs::path pelFilename = makeTempDir() / "rawpel"; 104 std::ofstream pelFile{pelFilename}; 105 pelFile.write(reinterpret_cast<const char*>(data.data()), data.size()); 106 pelFile.close(); 107 108 std::string adItem = "RAWPEL=" + pelFilename.string(); 109 std::vector<std::string> additionalData{adItem}; 110 std::vector<std::string> associations; 111 112 manager.create("error message", 42, 0, 113 phosphor::logging::Entry::Level::Error, additionalData, 114 associations); 115 116 // Find the file in the PEL repository directory 117 auto pelPathInRepo = findAnyPELInRepo(); 118 119 EXPECT_TRUE(pelPathInRepo); 120 121 // Now remove it based on its OpenBMC event log ID 122 manager.erase(42); 123 124 pelPathInRepo = findAnyPELInRepo(); 125 126 EXPECT_FALSE(pelPathInRepo); 127 128 fs::remove_all(pelFilename.parent_path()); 129 } 130 131 TEST_F(ManagerTest, TestCreateWithInvalidPEL) 132 { 133 std::unique_ptr<DataInterfaceBase> dataIface = 134 std::make_unique<DataInterface>(bus); 135 136 openpower::pels::Manager manager{ 137 logManager, std::move(dataIface), 138 std::bind(std::mem_fn(&TestLogger::log), &logger, std::placeholders::_1, 139 std::placeholders::_2, std::placeholders::_3)}; 140 141 // Create a PEL, write it to a file, and pass that filename into 142 // the create function. 143 auto data = pelDataFactory(TestPELType::pelSimple); 144 145 // Truncate it to make it invalid. 146 data.resize(200); 147 148 fs::path pelFilename = makeTempDir() / "rawpel"; 149 std::ofstream pelFile{pelFilename}; 150 pelFile.write(reinterpret_cast<const char*>(data.data()), data.size()); 151 pelFile.close(); 152 153 std::string adItem = "RAWPEL=" + pelFilename.string(); 154 std::vector<std::string> additionalData{adItem}; 155 std::vector<std::string> associations; 156 157 manager.create("error message", 42, 0, 158 phosphor::logging::Entry::Level::Error, additionalData, 159 associations); 160 161 // Run the event loop to log the bad PEL event 162 sdeventplus::Event e{sdEvent}; 163 e.run(std::chrono::milliseconds(1)); 164 165 PEL invalidPEL{data}; 166 EXPECT_EQ(logger.errName, "org.open_power.Logging.Error.BadHostPEL"); 167 EXPECT_EQ(logger.errLevel, phosphor::logging::Entry::Level::Error); 168 EXPECT_EQ(std::stoi(logger.ad["PLID"], nullptr, 16), invalidPEL.plid()); 169 EXPECT_EQ(logger.ad["OBMC_LOG_ID"], "42"); 170 EXPECT_EQ(logger.ad["SRC"], (*invalidPEL.primarySRC())->asciiString()); 171 EXPECT_EQ(logger.ad["PEL_SIZE"], std::to_string(data.size())); 172 173 fs::remove_all(pelFilename.parent_path()); 174 } 175 176 // Test that the message registry can be used to build a PEL. 177 TEST_F(ManagerTest, TestCreateWithMessageRegistry) 178 { 179 const auto registry = R"( 180 { 181 "PELs": 182 [ 183 { 184 "Name": "xyz.openbmc_project.Error.Test", 185 "Subsystem": "power_supply", 186 "ActionFlags": ["service_action", "report"], 187 "SRC": 188 { 189 "ReasonCode": "0x2030" 190 }, 191 "Documentation": 192 { 193 "Description": "A PGOOD Fault", 194 "Message": "PS had a PGOOD Fault" 195 } 196 } 197 ] 198 } 199 )"; 200 201 auto path = getMessageRegistryPath(); 202 fs::create_directories(path); 203 path /= "message_registry.json"; 204 205 std::ofstream registryFile{path}; 206 registryFile << registry; 207 registryFile.close(); 208 209 std::unique_ptr<DataInterfaceBase> dataIface = 210 std::make_unique<DataInterface>(logManager.getBus()); 211 212 openpower::pels::Manager manager{ 213 logManager, std::move(dataIface), 214 std::bind(std::mem_fn(&TestLogger::log), &logger, std::placeholders::_1, 215 std::placeholders::_2, std::placeholders::_3)}; 216 217 std::vector<std::string> additionalData; 218 std::vector<std::string> associations; 219 220 // Create the event log to create the PEL from. 221 manager.create("xyz.openbmc_project.Error.Test", 33, 0, 222 phosphor::logging::Entry::Level::Error, additionalData, 223 associations); 224 225 // Ensure a PEL was created in the repository 226 auto pelFile = findAnyPELInRepo(); 227 ASSERT_TRUE(pelFile); 228 229 auto data = readPELFile(*pelFile); 230 PEL pel(*data); 231 232 // Spot check it. Other testcases cover the details. 233 EXPECT_TRUE(pel.valid()); 234 EXPECT_EQ(pel.obmcLogID(), 33); 235 EXPECT_EQ(pel.primarySRC().value()->asciiString(), 236 "BD612030 "); 237 238 // Remove it 239 manager.erase(33); 240 pelFile = findAnyPELInRepo(); 241 EXPECT_FALSE(pelFile); 242 243 // Create an event log that can't be found in the registry. 244 manager.create("xyz.openbmc_project.Error.Foo", 33, 0, 245 phosphor::logging::Entry::Level::Error, additionalData, 246 associations); 247 248 // Currently, no PEL should be created. Eventually, a 'missing registry 249 // entry' PEL will be there. 250 pelFile = findAnyPELInRepo(); 251 EXPECT_FALSE(pelFile); 252 } 253 254 TEST_F(ManagerTest, TestDBusMethods) 255 { 256 std::unique_ptr<DataInterfaceBase> dataIface = 257 std::make_unique<DataInterface>(bus); 258 259 Manager manager{logManager, std::move(dataIface), 260 std::bind(std::mem_fn(&TestLogger::log), &logger, 261 std::placeholders::_1, std::placeholders::_2, 262 std::placeholders::_3)}; 263 264 // Create a PEL, write it to a file, and pass that filename into 265 // the create function so there's one in the repo. 266 auto data = pelDataFactory(TestPELType::pelSimple); 267 268 fs::path pelFilename = makeTempDir() / "rawpel"; 269 std::ofstream pelFile{pelFilename}; 270 pelFile.write(reinterpret_cast<const char*>(data.data()), data.size()); 271 pelFile.close(); 272 273 std::string adItem = "RAWPEL=" + pelFilename.string(); 274 std::vector<std::string> additionalData{adItem}; 275 std::vector<std::string> associations; 276 277 manager.create("error message", 42, 0, 278 phosphor::logging::Entry::Level::Error, additionalData, 279 associations); 280 281 // getPELFromOBMCID 282 auto newData = manager.getPELFromOBMCID(42); 283 EXPECT_EQ(newData.size(), data.size()); 284 285 // Read the PEL to get the ID for later 286 PEL pel{newData}; 287 auto id = pel.id(); 288 289 EXPECT_THROW( 290 manager.getPELFromOBMCID(id + 1), 291 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 292 293 // getPEL 294 auto unixfd = manager.getPEL(id); 295 296 // Get the size 297 struct stat s; 298 int r = fstat(unixfd, &s); 299 ASSERT_EQ(r, 0); 300 auto size = s.st_size; 301 302 // Open the FD and check the contents 303 FILE* fp = fdopen(unixfd, "r"); 304 ASSERT_NE(fp, nullptr); 305 306 std::vector<uint8_t> fdData; 307 fdData.resize(size); 308 r = fread(fdData.data(), 1, size, fp); 309 EXPECT_EQ(r, size); 310 311 EXPECT_EQ(newData, fdData); 312 313 fclose(fp); 314 315 // Run the event loop to close the FD 316 sdeventplus::Event e{sdEvent}; 317 e.run(std::chrono::milliseconds(1)); 318 319 EXPECT_THROW( 320 manager.getPEL(id + 1), 321 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 322 323 // hostAck 324 manager.hostAck(id); 325 326 EXPECT_THROW( 327 manager.hostAck(id + 1), 328 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 329 330 // hostReject 331 manager.hostReject(id, Manager::RejectionReason::BadPEL); 332 333 // Run the event loop to log the bad PEL event 334 e.run(std::chrono::milliseconds(1)); 335 336 EXPECT_EQ(logger.errName, "org.open_power.Logging.Error.SentBadPELToHost"); 337 EXPECT_EQ(id, std::stoi(logger.ad["BAD_ID"], nullptr, 16)); 338 339 manager.hostReject(id, Manager::RejectionReason::HostFull); 340 341 EXPECT_THROW( 342 manager.hostReject(id + 1, Manager::RejectionReason::BadPEL), 343 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 344 345 fs::remove_all(pelFilename.parent_path()); 346 } 347 348 // An ESEL from the wild 349 const std::string esel{ 350 "00 00 df 00 00 00 00 20 00 04 12 01 6f aa 00 00 " 351 "50 48 00 30 01 00 33 00 00 00 00 07 5c 69 cc 0d 00 00 00 07 5c d5 50 db " 352 "42 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 90 00 00 4e 90 00 00 4e " 353 "55 48 00 18 01 00 09 00 8a 03 40 00 00 00 00 00 ff ff 00 00 00 00 00 00 " 354 "50 53 00 50 01 01 00 00 02 00 00 09 33 2d 00 48 00 00 00 e0 00 00 10 00 " 355 "00 00 00 00 00 20 00 00 00 0c 00 02 00 00 00 fa 00 00 0c e4 00 00 00 12 " 356 "42 43 38 41 33 33 32 44 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 " 357 "20 20 20 20 20 20 20 20 55 44 00 1c 01 06 01 00 02 54 41 4b 00 00 00 06 " 358 "00 00 00 55 00 01 f9 20 00 00 00 00 55 44 00 24 01 06 01 00 01 54 41 4b " 359 "00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 23 01 00 02 00 05 00 00 " 360 "55 44 00 0c 01 0b 01 00 0f 01 00 00 55 44 00 10 01 04 01 00 0f 9f de 6a " 361 "00 01 00 00 55 44 00 7c 00 0c 01 00 00 13 0c 02 00 fa 0c e4 16 00 01 2c " 362 "0c 1c 16 00 00 fa 0a f0 14 00 00 fa 0b b8 14 00 00 be 09 60 12 00 01 2c " 363 "0d 7a 12 00 00 fa 0c 4e 10 00 00 fa 0c e4 10 00 00 be 0a 8c 16 00 01 2c " 364 "0c 1c 16 00 01 09 09 f6 16 00 00 fa 09 f6 14 00 00 fa 0b b8 14 00 00 fa " 365 "0a f0 14 00 00 be 08 ca 12 00 01 2c 0c e4 12 00 00 fa 0b 54 10 00 00 fa " 366 "0c 2d 10 00 00 be 08 ca 55 44 00 58 01 03 01 00 00 00 00 00 00 05 31 64 " 367 "00 00 00 00 00 05 0d d4 00 00 00 00 40 5f 06 e0 00 00 00 00 40 5d d2 00 " 368 "00 00 00 00 40 57 d3 d0 00 00 00 00 40 58 f6 a0 00 00 00 00 40 54 c9 34 " 369 "00 00 00 00 40 55 9a 10 00 00 00 00 40 4c 0a 80 00 00 00 00 00 00 27 14 " 370 "55 44 01 84 01 01 01 00 48 6f 73 74 62 6f 6f 74 20 42 75 69 6c 64 20 49 " 371 "44 3a 20 68 6f 73 74 62 6f 6f 74 2d 66 65 63 37 34 64 66 2d 70 30 61 38 " 372 "37 64 63 34 2f 68 62 69 63 6f 72 65 2e 62 69 6e 00 49 42 4d 2d 77 69 74 " 373 "68 65 72 73 70 6f 6f 6e 2d 4f 50 39 2d 76 32 2e 34 2d 39 2e 32 33 34 0a " 374 "09 6f 70 2d 62 75 69 6c 64 2d 38 32 66 34 63 66 30 0a 09 62 75 69 6c 64 " 375 "72 6f 6f 74 2d 32 30 31 39 2e 30 35 2e 32 2d 31 30 2d 67 38 39 35 39 31 " 376 "31 34 0a 09 73 6b 69 62 6f 6f 74 2d 76 36 2e 35 2d 31 38 2d 67 34 37 30 " 377 "66 66 62 35 66 32 39 64 37 0a 09 68 6f 73 74 62 6f 6f 74 2d 66 65 63 37 " 378 "34 64 66 2d 70 30 61 38 37 64 63 34 0a 09 6f 63 63 2d 65 34 35 39 37 61 " 379 "62 0a 09 6c 69 6e 75 78 2d 35 2e 32 2e 31 37 2d 6f 70 65 6e 70 6f 77 65 " 380 "72 31 2d 70 64 64 63 63 30 33 33 0a 09 70 65 74 69 74 62 6f 6f 74 2d 76 " 381 "31 2e 31 30 2e 34 0a 09 6d 61 63 68 69 6e 65 2d 78 6d 6c 2d 63 36 32 32 " 382 "63 62 35 2d 70 37 65 63 61 62 33 64 0a 09 68 6f 73 74 62 6f 6f 74 2d 62 " 383 "69 6e 61 72 69 65 73 2d 36 36 65 39 61 36 30 0a 09 63 61 70 70 2d 75 63 " 384 "6f 64 65 2d 70 39 2d 64 64 32 2d 76 34 0a 09 73 62 65 2d 36 30 33 33 30 " 385 "65 30 0a 09 68 63 6f 64 65 2d 68 77 30 39 32 31 31 39 61 2e 6f 70 6d 73 " 386 "74 0a 00 00 55 44 00 70 01 04 01 00 0f 9f de 6a 00 05 00 00 07 5f 1d f4 " 387 "30 32 43 59 34 37 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " 388 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " 389 "0b ac 54 02 59 41 31 39 33 34 36 39 37 30 35 38 00 00 00 00 00 00 05 22 " 390 "a1 58 01 8a 00 58 40 20 17 18 4d 2c 00 00 00 fc 01 a1 00 00 55 44 00 14 " 391 "01 08 01 00 00 00 00 01 00 00 00 5a 00 00 00 05 55 44 03 fc 01 15 31 00 " 392 "01 28 00 42 46 41 50 49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 f4 " 393 "00 00 00 00 00 00 03 f4 00 00 00 0b 00 00 00 00 00 00 00 3d 2c 9b c2 84 " 394 "00 00 01 e4 00 48 43 4f fb ed 70 b1 00 00 02 01 00 00 00 00 00 00 00 09 " 395 "00 00 00 00 00 11 bd 20 00 00 00 00 00 01 f8 80 00 00 00 00 00 00 00 01 " 396 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 00 00 00 00 00 00 01 2c " 397 "00 00 00 00 00 00 07 d0 00 00 00 00 00 00 0c 1c 00 00 00 64 00 00 00 3d " 398 "2c 9b d1 11 00 00 01 e4 00 48 43 4f fb ed 70 b1 00 00 02 01 00 00 00 00 " 399 "00 00 00 0a 00 00 00 00 00 13 b5 a0 00 00 00 00 00 01 f8 80 00 00 00 00 " 400 "00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 " 401 "00 00 00 be 00 00 00 00 00 00 07 d0 00 00 00 00 00 00 0a 8c 00 00 00 64 " 402 "00 00 00 3d 2c 9b df 98 00 00 01 e4 00 48 43 4f fb ed 70 b1 00 00 02 01 " 403 "00 00 00 00 00 00 00 0b 00 00 00 00 00 15 ae 20 00 00 00 00 00 01 f8 80 " 404 "00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 " 405 "00 00 00 00 00 00 00 fa 00 00 00 00 00 00 07 d0 00 00 00 00 00 00 0c e4 " 406 "00 00 00 64 00 00 00 3d 2c 9b ea b7 00 00 01 e4 00 48 43 4f fb ed 70 b1 " 407 "00 00 02 01 00 00 00 00 00 00 00 0c 00 00 00 00 00 17 a6 a0 00 00 00 00 " 408 "00 01 f8 80 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 " 409 "00 00 00 12 00 00 00 00 00 00 00 fa 00 00 00 00 00 00 07 d0 00 00 00 00 " 410 "00 00 0c 4e 00 00 00 64 00 00 00 3d 2c 9b f6 27 00 00 01 e4 00 48 43 4f " 411 "fb ed 70 b1 00 00 02 01 00 00 00 00 00 00 00 0d 00 00 00 00 00 19 9f 20 " 412 "00 00 00 00 00 01 f8 80 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 " 413 "00 00 00 00 00 00 00 12 00 00 00 00 00 00 01 2c 00 00 00 00 00 00 07 d0 " 414 "00 00 00 00 00 00 0d 7a 00 00 00 64 00 00 00 3d 2c 9c 05 75 00 00 01 e4 " 415 "00 48 43 4f fb ed 70 b1 00 00 02 01 00 00 00 00 00 00 00 0e 00 00 00 00 " 416 "00 1b 97 a0 00 00 00 00 00 01 f8 80 00 00 00 00 00 00 00 01 00 00 00 00 " 417 "00 00 00 00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 be 00 00 00 00 " 418 "00 00 07 d0 00 00 00 00 00 00 09 60 00 00 00 64 00 00 00 3d 2c 9c 11 29 " 419 "00 00 01 e4 00 48 43 4f fb ed 70 b1 00 00 02 01 00 00 00 00 00 00 00 0f " 420 "00 00 00 00 00 1d 90 20 00 00 00 00 00 01 f8 80 00 00 00 00 00 00 00 01 " 421 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 fa " 422 "00 00 00 00 00 00 07 d0 00 00 00 00 00 00 0b b8 00 00 00 64 00 00 00 3d " 423 "2c 9c 1c 45 00 00 01 e4 00 48 43 4f fb ed 70 b1 00 00 02 01 00 00 00 00 " 424 "00 00 00 10 00 00 00 00 00 1f 88 a0 00 00 00 00 00 01 f8 80 00 00 00 00 " 425 "00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 00 00 00 00 " 426 "00 00 00 fa 00 00 00 00 00 00 07 d0 00 00 00 00 00 00 0a f0 00 00 00 64 " 427 "00 00 00 3d 2c 9c 2b 14 00 00 01 e4 00 48 43 4f fb ed 70 b1 00 00 02 01 " 428 "00 00 00 00 00 00 00 11 00 00 00 00 00 21 81 20 00 00 00 00 00 01 f8 80 " 429 "00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 " 430 "00 00 00 00 00 00 01 2c 00 00 00 00 00 00 07 d0 00 00 00 00 00 00 0c 1c " 431 "00 00 00 64 00 00 00 3d 2d 6d 8f 9e 00 00 01 e4 00 00 43 4f 52 d7 9c 36 " 432 "00 00 04 73 00 00 00 1c 00 00 00 3d 2d 6d 99 ac 00 00 01 e4 00 10 43 4f " 433 "3f f2 02 3d 00 00 05 58 00 00 00 00 02 00 00 01 00 00 00 00 00 00 00 40 " 434 "00 00 00 2c 55 44 00 30 01 15 31 00 01 28 00 42 46 41 50 49 5f 44 42 47 " 435 "00 00 00 00 00 00 00 00 00 00 00 28 00 00 00 00 00 00 00 28 00 00 00 00 " 436 "00 00 00 00 55 44 01 74 01 15 31 00 01 28 00 42 46 41 50 49 5f 49 00 00 " 437 "00 00 00 00 00 00 00 00 00 00 01 6c 00 00 00 00 00 00 01 6c 00 00 00 0b " 438 "00 00 00 00 00 00 00 3c 0d 52 18 5e 00 00 01 e4 00 08 43 4f 46 79 94 13 " 439 "00 00 0a 5b 00 00 00 00 00 00 2c 00 00 00 00 24 00 00 00 3c 0d 6b 26 6c " 440 "00 00 01 e4 00 00 43 4f 4e 9b 18 74 00 00 01 03 00 00 00 1c 00 00 00 3c " 441 "12 b9 2d 13 00 00 01 e4 00 00 43 4f ea 31 ed d4 00 00 05 c4 00 00 00 1c " 442 "00 00 00 3c 13 02 73 53 00 00 01 e4 00 00 43 4f ea 31 ed d4 00 00 05 c4 " 443 "00 00 00 1c 00 00 00 3c 13 04 7c 94 00 00 01 e4 00 00 43 4f ea 31 ed d4 " 444 "00 00 05 c4 00 00 00 1c 00 00 00 3c 13 06 ad e1 00 00 01 e4 00 00 43 4f " 445 "ea 31 ed d4 00 00 05 c4 00 00 00 1c 00 00 00 3c 13 07 3f 77 00 00 01 e4 " 446 "00 00 43 4f 5e 4a 55 32 00 00 10 f2 00 00 00 1c 00 00 00 3c 13 07 4e e4 " 447 "00 00 01 e4 00 00 43 4f 5e 4a 55 32 00 00 0d 68 00 00 00 1c 00 00 00 3c " 448 "13 36 79 18 00 00 01 e4 00 00 43 4f ea 31 ed d4 00 00 05 c4 00 00 00 1c " 449 "00 00 00 3d 2c 9c 36 70 00 00 01 e4 00 00 43 4f 23 45 90 97 00 00 02 47 " 450 "00 00 00 1c 00 00 00 3d 2d 6d a3 ed 00 00 01 e4 00 08 43 4f 74 3a 5b 1a " 451 "00 00 04 cc 00 00 00 00 02 00 00 01 00 00 00 24 55 44 00 30 01 15 31 00 " 452 "01 28 00 42 53 43 41 4e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 28 " 453 "00 00 00 00 00 00 00 28 00 00 00 00 00 00 00 00"}; 454 455 TEST_F(ManagerTest, TestESELToRawData) 456 { 457 auto data = Manager::eselToRawData(esel); 458 459 EXPECT_EQ(data.size(), 2464); 460 461 PEL pel{data}; 462 EXPECT_TRUE(pel.valid()); 463 } 464 465 TEST_F(ManagerTest, TestCreateWithESEL) 466 { 467 std::unique_ptr<DataInterfaceBase> dataIface = 468 std::make_unique<DataInterface>(bus); 469 470 openpower::pels::Manager manager{ 471 logManager, std::move(dataIface), 472 std::bind(std::mem_fn(&TestLogger::log), &logger, std::placeholders::_1, 473 std::placeholders::_2, std::placeholders::_3)}; 474 475 { 476 std::string adItem = "ESEL=" + esel; 477 std::vector<std::string> additionalData{adItem}; 478 std::vector<std::string> associations; 479 480 manager.create("error message", 37, 0, 481 phosphor::logging::Entry::Level::Error, additionalData, 482 associations); 483 484 auto data = manager.getPELFromOBMCID(37); 485 PEL pel{data}; 486 EXPECT_TRUE(pel.valid()); 487 } 488 489 // Now an invalid one 490 { 491 std::string adItem = "ESEL=" + esel; 492 493 // Crop it 494 adItem.resize(adItem.size() - 300); 495 496 std::vector<std::string> additionalData{adItem}; 497 std::vector<std::string> associations; 498 499 manager.create("error message", 38, 0, 500 phosphor::logging::Entry::Level::Error, additionalData, 501 associations); 502 503 EXPECT_THROW( 504 manager.getPELFromOBMCID(38), 505 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 506 507 // Run the event loop to log the bad PEL event 508 sdeventplus::Event e{sdEvent}; 509 e.run(std::chrono::milliseconds(1)); 510 511 EXPECT_EQ(logger.errName, "org.open_power.Logging.Error.BadHostPEL"); 512 EXPECT_EQ(logger.errLevel, phosphor::logging::Entry::Level::Error); 513 } 514 } 515