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