blob: 6537485ee822861b46ef72045fa494c414acff76 [file] [log] [blame]
Andrew Geisslere4960ee2020-03-30 14:31:52 -05001#include "config.h"
2
3#include "elog_entry.hpp"
4#include "log_manager.hpp"
5
6#include <sdbusplus/bus.hpp>
7#include <sdbusplus/test/sdbus_mock.hpp>
8
9#include <gmock/gmock.h>
10#include <gtest/gtest.h>
11
12namespace phosphor
13{
14namespace logging
15{
16namespace test
17{
18
19class TestQuiesceOnError : public testing::Test
20{
21 public:
22 sdbusplus::SdBusMock sdbusMock;
23 sdbusplus::bus::bus mockedBus = sdbusplus::get_mocked_new(&sdbusMock);
24 phosphor::logging::internal::Manager manager;
25
26 TestQuiesceOnError() : manager(mockedBus, OBJ_INTERNAL)
27 {
28 }
29};
30
31// Test that false is returned when no callout is present in the log
32TEST_F(TestQuiesceOnError, testNoCallout)
33{
34 uint32_t id = 99;
35 uint64_t timestamp{100};
36 std::string message{"test error"};
37 std::string fwLevel{"level42"};
38 std::vector<std::string> testData{"no", "callout"};
39 phosphor::logging::AssociationList associations{};
40
41 Entry elog{mockedBus,
42 std::string(OBJ_ENTRY) + '/' + std::to_string(id),
43 id,
44 timestamp,
45 Entry::Level::Informational,
46 std::move(message),
47 std::move(testData),
48 std::move(associations),
49 fwLevel,
50 manager};
51
52 EXPECT_EQ(manager.isCalloutPresent(elog), false);
53}
54
55// Test that trues is returned when a callout is present in the log
56TEST_F(TestQuiesceOnError, testCallout)
57{
58 uint32_t id = 99;
59 uint64_t timestamp{100};
60 std::string message{"test error"};
61 std::string fwLevel{"level42"};
62 std::vector<std::string> testData{
63 "CALLOUT_INVENTORY_PATH=/xyz/openbmc_project/inventory/system/chassis/"
64 "motherboard/powersupply0/"};
65 phosphor::logging::AssociationList associations{};
66
67 Entry elog{mockedBus,
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 manager};
77
78 EXPECT_EQ(manager.isCalloutPresent(elog), true);
79}
80
Andrew Geissler6a0ef6f2020-04-06 15:06:31 -050081// Test that no blocking errors are created when no callout
82TEST_F(TestQuiesceOnError, testNoBlockingErrorsCreated)
83{
84 uint32_t id = 99;
85 uint64_t timestamp{100};
86 std::string message{"test error"};
87 std::string fwLevel{"level42"};
88 std::vector<std::string> testData{"no", "callout"};
89 phosphor::logging::AssociationList associations{};
90
91 Entry elog{mockedBus,
92 std::string(OBJ_ENTRY) + '/' + std::to_string(id),
93 id,
94 timestamp,
95 Entry::Level::Informational,
96 std::move(message),
97 std::move(testData),
98 std::move(associations),
99 fwLevel,
100 manager};
101
102 manager.checkQuiesceOnError(elog);
103 EXPECT_EQ(manager.getBlockingErrSize(), 0);
104}
105
106// Test that a blocking error is created on entry with callout
107TEST_F(TestQuiesceOnError, testBlockingErrorsCreated)
108{
109 uint32_t id = 100;
110 uint64_t timestamp{100};
111 std::string message{"test error"};
112 std::string fwLevel{"level42"};
113 std::vector<std::string> testData{
114 "CALLOUT_INVENTORY_PATH=/xyz/openbmc_project/inventory/system/chassis/"
115 "motherboard/powersupply0/"};
116 phosphor::logging::AssociationList associations{};
117
118 // Ensure D-Bus object created for this blocking error
119 // First allow any number of sd_bus_emit_object_added calls
120 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(testing::_, testing::_))
121 .Times(testing::AnyNumber());
122 // Second verify the new block100 object is created once
123 EXPECT_CALL(sdbusMock,
124 sd_bus_emit_object_added(
125 testing::_, testing::HasSubstr(
126 "/xyz/openbmc_project/logging/block100")))
127 .Times(1);
128
129 Entry elog{mockedBus,
130 std::string(OBJ_ENTRY) + '/' + std::to_string(id),
131 id,
132 timestamp,
133 Entry::Level::Informational,
134 std::move(message),
135 std::move(testData),
136 std::move(associations),
137 fwLevel,
138 manager};
139
140 manager.checkQuiesceOnError(elog);
141 // Created error with callout so expect a blocking error now
142 EXPECT_EQ(manager.getBlockingErrSize(), 1);
Andrew Geisslerced6e2a2020-04-07 16:15:29 -0500143
144 // Now delete the error and make sure the object and entry go away
145 EXPECT_CALL(sdbusMock, sd_bus_emit_object_removed(testing::_, testing::_))
146 .Times(testing::AnyNumber());
147 EXPECT_CALL(sdbusMock,
148 sd_bus_emit_object_removed(
149 testing::_, testing::HasSubstr(
150 "/xyz/openbmc_project/logging/block100")))
151 .Times(1);
152
153 // Make sure nothing happens within invalid id
154 manager.checkAndRemoveBlockingError(id + 1);
155 EXPECT_EQ(manager.getBlockingErrSize(), 1);
156
157 manager.checkAndRemoveBlockingError(id);
158 EXPECT_EQ(manager.getBlockingErrSize(), 0);
Andrew Geissler6a0ef6f2020-04-06 15:06:31 -0500159}
160
Andrew Geissler7f6d4bc2020-04-16 14:47:34 -0500161// Test that a blocking error is created on entry with callout
162TEST_F(TestQuiesceOnError, testBlockingErrorsResolved)
163{
164 uint32_t id = 101;
165 uint64_t timestamp{100};
166 std::string message{"test error"};
167 std::string fwLevel{"level42"};
168 std::vector<std::string> testData{
169 "CALLOUT_INVENTORY_PATH=/xyz/openbmc_project/inventory/system/chassis/"
170 "motherboard/powersupply0/"};
171 phosphor::logging::AssociationList associations{};
172
173 // Ensure D-Bus object created for this blocking error
174 // First allow any number of sd_bus_emit_object_added calls
175 EXPECT_CALL(sdbusMock, sd_bus_emit_object_added(testing::_, testing::_))
176 .Times(testing::AnyNumber());
177 // Second verify the new block100 object is created once
178 EXPECT_CALL(sdbusMock,
179 sd_bus_emit_object_added(
180 testing::_, testing::HasSubstr(
181 "/xyz/openbmc_project/logging/block101")))
182 .Times(1);
183
184 Entry elog{mockedBus,
185 std::string(OBJ_ENTRY) + '/' + std::to_string(id),
186 id,
187 timestamp,
188 Entry::Level::Informational,
189 std::move(message),
190 std::move(testData),
191 std::move(associations),
192 fwLevel,
193 manager};
194
195 manager.checkQuiesceOnError(elog);
196 // Created error with callout so expect a blocking error now
197 EXPECT_EQ(manager.getBlockingErrSize(), 1);
198 // Also should have a callback create looking for entry to be resolved
199 EXPECT_EQ(manager.getEntryCallbackSize(), 1);
200
201 // Now resolve the error and make sure the object and entry go away
202 EXPECT_CALL(sdbusMock, sd_bus_emit_object_removed(testing::_, testing::_))
203 .Times(testing::AnyNumber());
204 EXPECT_CALL(sdbusMock,
205 sd_bus_emit_object_removed(
206 testing::_, testing::HasSubstr(
207 "/xyz/openbmc_project/logging/block101")))
208 .Times(1);
209
210 elog.resolved(true);
211 // Note that property signal callbacks do not work in unit test so directly
212 // call the interface to find and resolve blocking entries
213 manager.checkAndRemoveBlockingError(101);
214 EXPECT_EQ(manager.getBlockingErrSize(), 0);
215 EXPECT_EQ(manager.getEntryCallbackSize(), 0);
216}
217
Andrew Geisslere4960ee2020-03-30 14:31:52 -0500218} // namespace test
219} // namespace logging
220} // namespace phosphor