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
deleteIsProhibitedMock(uint32_t,bool & prohibited)24 void deleteIsProhibitedMock(uint32_t /*id*/, bool& prohibited)
25 {
26 prohibited = true;
27 }
28
deleteIsNotProhibitedMock(uint32_t,bool & prohibited)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
TEST(TestUpdateTS,testChangeResolved)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::map<std::string, 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
TEST(TestResolveProhibited,testResolveFlagChange)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::map<std::string, 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