1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright 2019 IBM Corporation
3
4 #include "elog_entry.hpp"
5 #include "extensions/openpower-pels/pel_types.hpp"
6 #include "extensions/openpower-pels/private_header.hpp"
7 #include "extensions/openpower-pels/user_header.hpp"
8 #include "mocks.hpp"
9 #include "pel_utils.hpp"
10
11 #include <gtest/gtest.h>
12
13 using namespace openpower::pels;
14 using ::testing::Return;
15
TEST(UserHeaderTest,SizeTest)16 TEST(UserHeaderTest, SizeTest)
17 {
18 EXPECT_EQ(UserHeader::flattenedSize(), 24);
19 }
20
TEST(UserHeaderTest,UnflattenFlattenTest)21 TEST(UserHeaderTest, UnflattenFlattenTest)
22 {
23 auto data = pelDataFactory(TestPELType::userHeaderSection);
24
25 Stream stream(data);
26 UserHeader uh(stream);
27 EXPECT_EQ(uh.valid(), true);
28
29 EXPECT_EQ(uh.header().id, 0x5548);
30 EXPECT_EQ(uh.header().size, UserHeader::flattenedSize());
31 EXPECT_EQ(uh.header().version, 0x01);
32 EXPECT_EQ(uh.header().subType, 0x0A);
33 EXPECT_EQ(uh.header().componentID, 0x0B0C);
34
35 EXPECT_EQ(uh.subsystem(), 0x10);
36 EXPECT_EQ(uh.scope(), 0x04);
37 EXPECT_EQ(uh.severity(), 0x20);
38 EXPECT_EQ(uh.eventType(), 0x00);
39 EXPECT_EQ(uh.problemDomain(), 0x03);
40 EXPECT_EQ(uh.problemVector(), 0x04);
41 EXPECT_EQ(uh.actionFlags(), 0x80C0);
42
43 // Now flatten into a vector and check that this vector
44 // matches the original one.
45 std::vector<uint8_t> newData;
46 Stream newStream(newData);
47
48 uh.flatten(newStream);
49 EXPECT_EQ(data, newData);
50 }
51
TEST(UserHeaderTest,ShortDataTest)52 TEST(UserHeaderTest, ShortDataTest)
53 {
54 auto data = pelDataFactory(TestPELType::userHeaderSection);
55 data.resize(data.size() - 1);
56
57 Stream stream(data);
58 UserHeader uh(stream);
59
60 EXPECT_EQ(uh.valid(), false);
61 }
62
TEST(UserHeaderTest,CorruptDataTest1)63 TEST(UserHeaderTest, CorruptDataTest1)
64 {
65 auto data = pelDataFactory(TestPELType::userHeaderSection);
66 data.resize(data.size() - 1);
67
68 data.at(0) = 0; // corrupt the section ID
69
70 Stream stream(data);
71 UserHeader uh(stream);
72
73 EXPECT_EQ(uh.valid(), false);
74 }
75
TEST(UserHeaderTest,CorruptDataTest2)76 TEST(UserHeaderTest, CorruptDataTest2)
77 {
78 auto data = pelDataFactory(TestPELType::userHeaderSection);
79
80 data.at(4) = 0x22; // corrupt the version
81
82 Stream stream(data);
83 UserHeader uh(stream);
84
85 EXPECT_EQ(uh.valid(), false);
86 }
87
88 // Construct the User Header from the message registry
TEST(UserHeaderTest,ConstructionTest)89 TEST(UserHeaderTest, ConstructionTest)
90 {
91 using namespace openpower::pels::message;
92 {
93 Entry regEntry;
94
95 regEntry.name = "test";
96 regEntry.subsystem = 5;
97 regEntry.severity = {{"", 0x40}};
98 regEntry.actionFlags = 0xC000;
99 regEntry.eventType = 1;
100 regEntry.eventScope = 2;
101
102 MockDataInterface dataIface;
103 AdditionalData ad;
104
105 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad,
106 dataIface);
107
108 ASSERT_TRUE(uh.valid());
109 EXPECT_EQ(uh.header().id, 0x5548);
110 EXPECT_EQ(uh.header().size, UserHeader::flattenedSize());
111 EXPECT_EQ(uh.header().version, 0x01);
112 EXPECT_EQ(uh.header().subType, 0x00);
113 EXPECT_EQ(uh.header().componentID,
114 static_cast<uint16_t>(ComponentID::phosphorLogging));
115
116 EXPECT_EQ(uh.subsystem(), 5);
117 EXPECT_EQ(uh.severity(), 0x40);
118 EXPECT_EQ(uh.eventType(), 1);
119 EXPECT_EQ(uh.scope(), 2);
120 EXPECT_EQ(uh.problemDomain(), 0);
121 EXPECT_EQ(uh.problemVector(), 0);
122 EXPECT_EQ(uh.actionFlags(), 0xC000);
123
124 {
125 // The same thing, but as if the action flags weren't specified
126 // in the registry so they are a nullopt. The object should
127 // then set them to 0xFFFF.
128 regEntry.actionFlags = std::nullopt;
129
130 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad,
131 dataIface);
132 EXPECT_EQ(uh.actionFlags(), 0xFFFF);
133 }
134 }
135
136 // Test the system type based severity lookups
137 {
138 Entry regEntry;
139
140 regEntry.name = "test";
141 regEntry.subsystem = 5;
142 regEntry.severity = {{"", 0x20}, {"systemB", 0x10}, {"systemA", 0x00}};
143
144 AdditionalData ad;
145
146 MockDataInterface dataIface;
147 std::vector<std::string> names1{"systemA"};
148 std::vector<std::string> names2{"systemB"};
149 std::vector<std::string> names3{"systemC"};
150
151 EXPECT_CALL(dataIface, getSystemNames)
152 .WillOnce(Return(names1))
153 .WillOnce(Return(names2))
154 .WillOnce(Return(names3));
155
156 {
157 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad,
158 dataIface);
159
160 EXPECT_EQ(uh.severity(), 0x00);
161 }
162
163 {
164 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad,
165 dataIface);
166
167 EXPECT_EQ(uh.severity(), 0x10);
168 }
169
170 {
171 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad,
172 dataIface);
173
174 EXPECT_EQ(uh.severity(), 0x20);
175 }
176 }
177 }
178
179 // Test that the severity comes from the event log if not
180 // in the message registry
TEST(UserHeaderTest,UseEventLogSevTest)181 TEST(UserHeaderTest, UseEventLogSevTest)
182 {
183 using namespace openpower::pels::message;
184 Entry regEntry;
185
186 regEntry.name = "test";
187 regEntry.subsystem = 5;
188 regEntry.actionFlags = 0xC000;
189 regEntry.eventType = 1;
190 regEntry.eventScope = 2;
191 // Leave off severity
192
193 MockDataInterface dataIface;
194 AdditionalData ad;
195
196 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad,
197 dataIface);
198 ASSERT_EQ(uh.severity(), 0x40);
199 }
200
201 // Test that the critical severity comes from the event log if not
202 // in the message registry
TEST(UserHeaderTest,UseEventLogSevCritTest)203 TEST(UserHeaderTest, UseEventLogSevCritTest)
204 {
205 using namespace openpower::pels::message;
206 Entry regEntry;
207
208 regEntry.name = "test";
209 regEntry.subsystem = 5;
210 regEntry.actionFlags = 0xC000;
211 regEntry.eventType = 1;
212 regEntry.eventScope = 2;
213 // Leave off severity
214
215 MockDataInterface dataIface;
216 AdditionalData ad;
217
218 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Critical, ad,
219 dataIface);
220 ASSERT_EQ(uh.severity(), 0x50);
221 }
222
223 // Test that the critical severity comes from the event log if not
224 // in the message registry and termination condition is set
TEST(UserHeaderTest,UseEventLogSevCritTermTest)225 TEST(UserHeaderTest, UseEventLogSevCritTermTest)
226 {
227 using namespace openpower::pels::message;
228 Entry regEntry;
229
230 regEntry.name = "test";
231 regEntry.subsystem = 5;
232 regEntry.actionFlags = 0xC000;
233 regEntry.eventType = 1;
234 regEntry.eventScope = 2;
235 // Leave off severity
236
237 MockDataInterface dataIface;
238 std::map<std::string, std::string> adData{
239 {"SEVERITY_DETAIL", "SYSTEM_TERM"}};
240 AdditionalData ad{adData};
241
242 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Critical, ad,
243 dataIface);
244 ASSERT_EQ(uh.severity(), 0x51);
245 }
246
247 // Test that the optional event type & scope fields work
TEST(UserHeaderTest,DefaultEventTypeScopeTest)248 TEST(UserHeaderTest, DefaultEventTypeScopeTest)
249 {
250 using namespace openpower::pels::message;
251 Entry regEntry;
252
253 regEntry.name = "test";
254 regEntry.subsystem = 5;
255 regEntry.severity = {{"", 0x40}};
256 regEntry.actionFlags = 0xC000;
257
258 MockDataInterface dataIface;
259 AdditionalData ad;
260
261 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad,
262 dataIface);
263
264 ASSERT_EQ(uh.eventType(), 0);
265 ASSERT_EQ(uh.scope(), 0x03);
266 }
267
268 // Test that the event severity & action flags override
269 // when QuiesceOnHwError is set
TEST(UserHeaderTest,UseEventLogQuiesceOnErrorTest)270 TEST(UserHeaderTest, UseEventLogQuiesceOnErrorTest)
271 {
272 using namespace openpower::pels::message;
273 Entry regEntry;
274
275 regEntry.name = "test";
276 regEntry.subsystem = 5;
277 regEntry.actionFlags = 0xC000;
278 regEntry.eventType = 1;
279 regEntry.eventScope = 2;
280 regEntry.severity = {{"", 0x40}, {"systemB", 0x10}, {"systemA", 0x00}};
281
282 // set the value for mfg severity and action flags
283 regEntry.mfgSeverity = {{"systemA", 0x20}};
284 regEntry.mfgActionFlags = 0xF000;
285
286 std::vector<std::string> names{"systemA"};
287
288 MockDataInterface dataIface;
289 AdditionalData ad;
290
291 EXPECT_CALL(dataIface, getSystemNames).WillOnce(Return(names));
292 EXPECT_CALL(dataIface, getQuiesceOnError).WillOnce(Return(true));
293
294 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad,
295 dataIface);
296
297 EXPECT_EQ(uh.severity(), 0x20);
298 EXPECT_EQ(uh.actionFlags(), 0xF000);
299 }
300
301 // Test that the PEL Subsystem omes from the event log if any
TEST(UserHeaderTest,UseEventLogPELSubsystem)302 TEST(UserHeaderTest, UseEventLogPELSubsystem)
303 {
304 using namespace openpower::pels::message;
305
306 {
307 Entry regEntry;
308
309 regEntry.name = "test";
310 regEntry.subsystem = 5;
311 regEntry.actionFlags = 0xC000;
312 regEntry.eventType = 1;
313 regEntry.eventScope = 2;
314
315 MockDataInterface dataIface;
316 std::map<std::string, std::string> adData{{"PEL_SUBSYSTEM", "0x25"}};
317 AdditionalData ad{adData};
318
319 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Critical, ad,
320 dataIface);
321 ASSERT_EQ(uh.subsystem(), 0x25);
322 }
323 {
324 // No subsystem in registry, and invalid PEL_SUBSYSTEM
325 Entry regEntry;
326
327 regEntry.name = "test";
328 regEntry.actionFlags = 0xC000;
329 regEntry.eventType = 1;
330 regEntry.eventScope = 2;
331
332 MockDataInterface dataIface;
333 std::map<std::string, std::string> adData{{"PEL_SUBSYSTEM", "0x99"}};
334 AdditionalData ad{adData};
335
336 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Critical, ad,
337 dataIface);
338 ASSERT_EQ(uh.subsystem(), 0x70); // others
339 }
340 {
341 // No subsystem in registry or PEL_SUBSYSTEM
342 Entry regEntry;
343
344 regEntry.name = "test";
345 regEntry.actionFlags = 0xC000;
346 regEntry.eventType = 1;
347 regEntry.eventScope = 2;
348
349 MockDataInterface dataIface;
350 std::map<std::string, std::string> adData;
351 AdditionalData ad{adData};
352
353 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Critical, ad,
354 dataIface);
355 ASSERT_EQ(uh.subsystem(), 0x70); // others
356 }
357 }
358