1 #include "config.h" 2 3 #include "elog_entry.hpp" 4 #include "elog_serialize.hpp" 5 #include "extensions.hpp" 6 #include "log_manager.hpp" 7 #include "paths.hpp" 8 9 #include <filesystem> 10 #include <thread> 11 12 #include <gtest/gtest.h> 13 14 namespace phosphor 15 { 16 namespace logging 17 { 18 namespace test 19 { 20 21 using namespace std::chrono_literals; 22 namespace fs = std::filesystem; 23 24 void deleteIsProhibitedMock(uint32_t /*id*/, bool& prohibited) 25 { 26 prohibited = true; 27 } 28 29 void deleteIsNotProhibitedMock(uint32_t /*id*/, bool& prohibited) 30 { 31 prohibited = false; 32 } 33 34 // Test that the update timestamp changes when the resolved property changes 35 TEST(TestUpdateTS, testChangeResolved) 36 { 37 // Setting resolved will serialize, so need this directory. 38 fs::create_directories(paths::error()); 39 40 if (!fs::exists(paths::error())) 41 { 42 ADD_FAILURE() << "Could not create " << paths::error() << "\n"; 43 exit(1); 44 } 45 46 auto bus = sdbusplus::bus::new_default(); 47 phosphor::logging::internal::Manager manager(bus, OBJ_INTERNAL); 48 49 // Use a random number for the ID to avoid other CI 50 // testcases running in parallel. 51 std::srand(std::time(nullptr)); 52 uint32_t id = std::rand(); 53 54 if (fs::exists(fs::path{paths::error()} / std::to_string(id))) 55 { 56 std::cerr << "Another testcase is using ID " << id << "\n"; 57 id = std::rand(); 58 } 59 60 uint64_t timestamp{100}; 61 std::string message{"test error"}; 62 std::string fwLevel{"level42"}; 63 std::string path{"/tmp/99"}; 64 std::vector<std::string> testData{"additional", "data"}; 65 phosphor::logging::AssociationList associations{}; 66 67 Entry elog{bus, 68 std::string(OBJ_ENTRY) + '/' + std::to_string(id), 69 id, 70 timestamp, 71 Entry::Level::Informational, 72 std::move(message), 73 std::move(testData), 74 std::move(associations), 75 fwLevel, 76 path, 77 manager}; 78 79 EXPECT_EQ(elog.timestamp(), elog.updateTimestamp()); 80 81 std::this_thread::sleep_for(1ms); 82 83 elog.resolved(true); 84 auto updateTS = elog.updateTimestamp(); 85 EXPECT_NE(updateTS, elog.timestamp()); 86 87 std::this_thread::sleep_for(1ms); 88 89 elog.resolved(false); 90 EXPECT_NE(updateTS, elog.updateTimestamp()); 91 updateTS = elog.updateTimestamp(); 92 93 std::this_thread::sleep_for(1ms); 94 95 // No change 96 elog.resolved(false); 97 EXPECT_EQ(updateTS, elog.updateTimestamp()); 98 99 // Leave the directory in case other CI instances are running 100 fs::remove(fs::path{paths::error()} / std::to_string(id)); 101 } 102 103 TEST(TestResolveProhibited, testResolveFlagChange) 104 { 105 // Setting resolved will serialize, so need this directory. 106 fs::create_directory(ERRLOG_PERSIST_PATH); 107 108 if (!fs::exists(ERRLOG_PERSIST_PATH)) 109 { 110 ADD_FAILURE() << "Could not create " << ERRLOG_PERSIST_PATH << "\n"; 111 exit(1); 112 } 113 114 auto bus = sdbusplus::bus::new_default(); 115 phosphor::logging::internal::Manager manager(bus, OBJ_INTERNAL); 116 117 // Use a random number for the ID to avoid other CI 118 // testcases running in parallel. 119 std::srand(std::time(nullptr)); 120 uint32_t id = std::rand(); 121 122 if (fs::exists(fs::path{ERRLOG_PERSIST_PATH} / std::to_string(id))) 123 { 124 std::cerr << "Another testcase is using ID " << id << "\n"; 125 id = std::rand(); 126 } 127 128 uint64_t timestamp{100}; 129 std::string message{"test error"}; 130 std::string fwLevel{"level42"}; 131 std::string path{"/tmp/99"}; 132 std::vector<std::string> testData{"additional", "data"}; 133 phosphor::logging::AssociationList associations{}; 134 135 Entry elog{bus, 136 std::string(OBJ_ENTRY) + '/' + std::to_string(id), 137 id, 138 timestamp, 139 Entry::Level::Informational, 140 std::move(message), 141 std::move(testData), 142 std::move(associations), 143 fwLevel, 144 path, 145 manager}; 146 147 Extensions ext{deleteIsProhibitedMock}; 148 149 EXPECT_THROW(elog.resolved(true), 150 sdbusplus::xyz::openbmc_project::Common::Error::Unavailable); 151 152 Extensions::getDeleteProhibitedFunctions().clear(); 153 154 Extensions e{deleteIsNotProhibitedMock}; 155 156 EXPECT_NO_THROW(elog.resolved(true)); 157 EXPECT_EQ(elog.resolved(), true); 158 159 // Leave the directory in case other CI instances are running 160 fs::remove(fs::path{ERRLOG_PERSIST_PATH} / std::to_string(id)); 161 } 162 } // namespace test 163 } // namespace logging 164 } // namespace phosphor 165