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