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