xref: /openbmc/phosphor-logging/test/openpower-pels/user_header_test.cpp (revision 40fb54935ce7367636a7156039396ee91cc4d5e2)
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