| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 1 | #include "extensions/openpower-pels/manager.hpp" | 
|  | 2 | #include "log_manager.hpp" | 
|  | 3 | #include "pel_utils.hpp" | 
|  | 4 |  | 
|  | 5 | #include <fstream> | 
|  | 6 | #include <regex> | 
|  | 7 |  | 
|  | 8 | #include <gtest/gtest.h> | 
|  | 9 |  | 
|  | 10 | using namespace openpower::pels; | 
|  | 11 | namespace fs = std::filesystem; | 
|  | 12 |  | 
|  | 13 | class ManagerTest : public CleanPELFiles | 
|  | 14 | { | 
|  | 15 | }; | 
|  | 16 |  | 
|  | 17 | fs::path makeTempDir() | 
|  | 18 | { | 
|  | 19 | char path[] = "/tmp/tempnameXXXXXX"; | 
|  | 20 | std::filesystem::path dir = mkdtemp(path); | 
|  | 21 | return dir; | 
|  | 22 | } | 
|  | 23 |  | 
| Matt Spinler | 67456c2 | 2019-10-21 12:22:49 -0500 | [diff] [blame] | 24 | std::optional<fs::path> findAnyPELInRepo() | 
|  | 25 | { | 
|  | 26 | // PELs are named <timestamp>_<ID> | 
|  | 27 | std::regex expr{"\\d+_\\d+"}; | 
|  | 28 |  | 
|  | 29 | for (auto& f : fs::directory_iterator(getPELRepoPath() / "logs")) | 
|  | 30 | { | 
|  | 31 | if (std::regex_search(f.path().string(), expr)) | 
|  | 32 | { | 
|  | 33 | return f.path(); | 
|  | 34 | } | 
|  | 35 | } | 
|  | 36 | return std::nullopt; | 
|  | 37 | } | 
|  | 38 |  | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 39 | // Test that using the RAWPEL=<file> with the Manager::create() call gets | 
|  | 40 | // a PEL saved in the repository. | 
|  | 41 | TEST_F(ManagerTest, TestCreateWithPEL) | 
|  | 42 | { | 
|  | 43 | auto bus = sdbusplus::bus::new_default(); | 
|  | 44 | phosphor::logging::internal::Manager logManager(bus, "logging_path"); | 
| Matt Spinler | c8705e2 | 2019-09-11 12:36:07 -0500 | [diff] [blame] | 45 | std::unique_ptr<DataInterfaceBase> dataIface = | 
|  | 46 | std::make_unique<DataInterface>(bus); | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 47 |  | 
| Matt Spinler | c8705e2 | 2019-09-11 12:36:07 -0500 | [diff] [blame] | 48 | openpower::pels::Manager manager{logManager, std::move(dataIface)}; | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 49 |  | 
|  | 50 | // Create a PEL, write it to a file, and pass that filename into | 
|  | 51 | // the create function. | 
| Matt Spinler | 42828bd | 2019-10-11 10:39:30 -0500 | [diff] [blame] | 52 | auto data = pelDataFactory(TestPELType::pelSimple); | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 53 |  | 
|  | 54 | fs::path pelFilename = makeTempDir() / "rawpel"; | 
|  | 55 | std::ofstream pelFile{pelFilename}; | 
| Matt Spinler | 42828bd | 2019-10-11 10:39:30 -0500 | [diff] [blame] | 56 | pelFile.write(reinterpret_cast<const char*>(data.data()), data.size()); | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 57 | pelFile.close(); | 
|  | 58 |  | 
|  | 59 | std::string adItem = "RAWPEL=" + pelFilename.string(); | 
|  | 60 | std::vector<std::string> additionalData{adItem}; | 
|  | 61 | std::vector<std::string> associations; | 
|  | 62 |  | 
| Matt Spinler | 367144c | 2019-09-19 15:33:52 -0500 | [diff] [blame] | 63 | manager.create("error message", 42, 0, | 
|  | 64 | phosphor::logging::Entry::Level::Error, additionalData, | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 65 | associations); | 
|  | 66 |  | 
| Matt Spinler | 67456c2 | 2019-10-21 12:22:49 -0500 | [diff] [blame] | 67 | // Find the file in the PEL repository directory | 
|  | 68 | auto pelPathInRepo = findAnyPELInRepo(); | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 69 |  | 
| Matt Spinler | 67456c2 | 2019-10-21 12:22:49 -0500 | [diff] [blame] | 70 | EXPECT_TRUE(pelPathInRepo); | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 71 |  | 
| Matt Spinler | 475e574 | 2019-07-18 16:09:49 -0500 | [diff] [blame] | 72 | // Now remove it based on its OpenBMC event log ID | 
|  | 73 | manager.erase(42); | 
|  | 74 |  | 
| Matt Spinler | 67456c2 | 2019-10-21 12:22:49 -0500 | [diff] [blame] | 75 | pelPathInRepo = findAnyPELInRepo(); | 
| Matt Spinler | 475e574 | 2019-07-18 16:09:49 -0500 | [diff] [blame] | 76 |  | 
| Matt Spinler | 67456c2 | 2019-10-21 12:22:49 -0500 | [diff] [blame] | 77 | EXPECT_FALSE(pelPathInRepo); | 
| Matt Spinler | 475e574 | 2019-07-18 16:09:49 -0500 | [diff] [blame] | 78 |  | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 79 | fs::remove_all(pelFilename.parent_path()); | 
|  | 80 | } | 
| Matt Spinler | 67456c2 | 2019-10-21 12:22:49 -0500 | [diff] [blame] | 81 |  | 
|  | 82 | // Test that the message registry can be used to build a PEL. | 
|  | 83 | TEST_F(ManagerTest, TestCreateWithMessageRegistry) | 
|  | 84 | { | 
|  | 85 | const auto registry = R"( | 
|  | 86 | { | 
|  | 87 | "PELs": | 
|  | 88 | [ | 
|  | 89 | { | 
|  | 90 | "Name": "xyz.openbmc_project.Error.Test", | 
|  | 91 | "Subsystem": "power_supply", | 
|  | 92 | "ActionFlags": ["service_action", "report"], | 
|  | 93 | "SRC": | 
|  | 94 | { | 
|  | 95 | "ReasonCode": "0x2030" | 
|  | 96 | } | 
|  | 97 | } | 
|  | 98 | ] | 
|  | 99 | } | 
|  | 100 | )"; | 
|  | 101 |  | 
|  | 102 | fs::path path = getMessageRegistryPath() / "message_registry.json"; | 
|  | 103 | std::ofstream registryFile{path}; | 
|  | 104 | registryFile << registry; | 
|  | 105 | registryFile.close(); | 
|  | 106 |  | 
|  | 107 | auto bus = sdbusplus::bus::new_default(); | 
|  | 108 | phosphor::logging::internal::Manager logManager(bus, "logging_path"); | 
|  | 109 |  | 
|  | 110 | std::unique_ptr<DataInterfaceBase> dataIface = | 
|  | 111 | std::make_unique<DataInterface>(logManager.getBus()); | 
|  | 112 |  | 
|  | 113 | openpower::pels::Manager manager{logManager, std::move(dataIface)}; | 
|  | 114 |  | 
|  | 115 | std::vector<std::string> additionalData; | 
|  | 116 | std::vector<std::string> associations; | 
|  | 117 |  | 
|  | 118 | // Create the event log to create the PEL from. | 
|  | 119 | manager.create("xyz.openbmc_project.Error.Test", 33, 0, | 
|  | 120 | phosphor::logging::Entry::Level::Error, additionalData, | 
|  | 121 | associations); | 
|  | 122 |  | 
|  | 123 | // Ensure a PEL was created in the repository | 
|  | 124 | auto pelFile = findAnyPELInRepo(); | 
|  | 125 | ASSERT_TRUE(pelFile); | 
|  | 126 |  | 
|  | 127 | auto data = readPELFile(*pelFile); | 
|  | 128 | PEL pel(*data); | 
|  | 129 |  | 
|  | 130 | // Spot check it.  Other testcases cover the details. | 
|  | 131 | EXPECT_TRUE(pel.valid()); | 
|  | 132 | EXPECT_EQ(pel.obmcLogID(), 33); | 
|  | 133 | EXPECT_EQ(pel.primarySRC().value()->asciiString(), | 
|  | 134 | "BD612030                        "); | 
|  | 135 |  | 
|  | 136 | // Remove it | 
|  | 137 | manager.erase(33); | 
|  | 138 | pelFile = findAnyPELInRepo(); | 
|  | 139 | EXPECT_FALSE(pelFile); | 
|  | 140 |  | 
|  | 141 | // Create an event log that can't be found in the registry. | 
|  | 142 | manager.create("xyz.openbmc_project.Error.Foo", 33, 0, | 
|  | 143 | phosphor::logging::Entry::Level::Error, additionalData, | 
|  | 144 | associations); | 
|  | 145 |  | 
|  | 146 | // Currently, no PEL should be created.  Eventually, a 'missing registry | 
|  | 147 | // entry' PEL will be there. | 
|  | 148 | pelFile = findAnyPELInRepo(); | 
|  | 149 | EXPECT_FALSE(pelFile); | 
|  | 150 | } |