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