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 auto persist_path = phosphor::logging::paths::error(); 106 107 // Setting resolved will serialize, so need this directory. 108 fs::create_directories(persist_path); 109 110 if (!fs::exists(persist_path)) 111 { 112 ADD_FAILURE() << "Could not create " 113 << phosphor::logging::paths::error() << "\n"; 114 exit(1); 115 } 116 117 auto bus = sdbusplus::bus::new_default(); 118 phosphor::logging::internal::Manager manager(bus, OBJ_INTERNAL); 119 120 // Use a random number for the ID to avoid other CI 121 // testcases running in parallel. 122 std::srand(std::time(nullptr)); 123 uint32_t id = std::rand(); 124 125 if (fs::exists(persist_path / std::to_string(id))) 126 { 127 std::cerr << "Another testcase is using ID " << id << "\n"; 128 id = std::rand(); 129 } 130 131 uint64_t timestamp{100}; 132 std::string message{"test error"}; 133 std::string fwLevel{"level42"}; 134 std::string path{"/tmp/99"}; 135 std::vector<std::string> testData{"additional", "data"}; 136 phosphor::logging::AssociationList associations{}; 137 138 Entry elog{bus, 139 std::string(OBJ_ENTRY) + '/' + std::to_string(id), 140 id, 141 timestamp, 142 Entry::Level::Informational, 143 std::move(message), 144 std::move(testData), 145 std::move(associations), 146 fwLevel, 147 path, 148 manager}; 149 150 Extensions ext{deleteIsProhibitedMock}; 151 152 EXPECT_THROW(elog.resolved(true), 153 sdbusplus::xyz::openbmc_project::Common::Error::Unavailable); 154 155 Extensions::getDeleteProhibitedFunctions().clear(); 156 157 Extensions e{deleteIsNotProhibitedMock}; 158 159 EXPECT_NO_THROW(elog.resolved(true)); 160 EXPECT_EQ(elog.resolved(), true); 161 162 // Leave the directory in case other CI instances are running 163 fs::remove(persist_path / std::to_string(id)); 164 } 165 } // namespace test 166 } // namespace logging 167 } // namespace phosphor 168