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 28 TEST(UserHeaderTest, SizeTest) 29 { 30 EXPECT_EQ(UserHeader::flattenedSize(), 24); 31 } 32 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 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 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 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 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 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 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 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::vector<std::string> adData{"SEVERITY_DETAIL=SYSTEM_TERM"}; 251 AdditionalData ad{adData}; 252 253 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Critical, ad, 254 dataIface); 255 ASSERT_EQ(uh.severity(), 0x51); 256 } 257 258 // Test that the optional event type & scope fields work 259 TEST(UserHeaderTest, DefaultEventTypeScopeTest) 260 { 261 using namespace openpower::pels::message; 262 Entry regEntry; 263 264 regEntry.name = "test"; 265 regEntry.subsystem = 5; 266 regEntry.severity = {{"", 0x40}}; 267 regEntry.actionFlags = 0xC000; 268 269 MockDataInterface dataIface; 270 AdditionalData ad; 271 272 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad, 273 dataIface); 274 275 ASSERT_EQ(uh.eventType(), 0); 276 ASSERT_EQ(uh.scope(), 0x03); 277 } 278 279 // Test that the event severity & action flags override 280 // when QuiesceOnHwError is set 281 TEST(UserHeaderTest, UseEventLogQuiesceOnErrorTest) 282 { 283 using namespace openpower::pels::message; 284 Entry regEntry; 285 286 regEntry.name = "test"; 287 regEntry.subsystem = 5; 288 regEntry.actionFlags = 0xC000; 289 regEntry.eventType = 1; 290 regEntry.eventScope = 2; 291 regEntry.severity = {{"", 0x40}, {"systemB", 0x10}, {"systemA", 0x00}}; 292 293 // set the value for mfg severity and action flags 294 regEntry.mfgSeverity = {{"systemA", 0x20}}; 295 regEntry.mfgActionFlags = 0xF000; 296 297 std::vector<std::string> names{"systemA"}; 298 299 MockDataInterface dataIface; 300 AdditionalData ad; 301 302 EXPECT_CALL(dataIface, getSystemNames).WillOnce(Return(names)); 303 EXPECT_CALL(dataIface, getQuiesceOnError).WillOnce(Return(true)); 304 305 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Error, ad, 306 dataIface); 307 308 EXPECT_EQ(uh.severity(), 0x20); 309 EXPECT_EQ(uh.actionFlags(), 0xF000); 310 } 311 312 // Test that the PEL Subsystem omes from the event log if any 313 TEST(UserHeaderTest, UseEventLogPELSubsystem) 314 { 315 using namespace openpower::pels::message; 316 317 { 318 Entry regEntry; 319 320 regEntry.name = "test"; 321 regEntry.subsystem = 5; 322 regEntry.actionFlags = 0xC000; 323 regEntry.eventType = 1; 324 regEntry.eventScope = 2; 325 326 MockDataInterface dataIface; 327 std::vector<std::string> adData{"PEL_SUBSYSTEM=0x25"}; 328 AdditionalData ad{adData}; 329 330 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Critical, ad, 331 dataIface); 332 ASSERT_EQ(uh.subsystem(), 0x25); 333 } 334 { 335 // No subsystem in registry, and invalid PEL_SUBSYSTEM 336 Entry regEntry; 337 338 regEntry.name = "test"; 339 regEntry.actionFlags = 0xC000; 340 regEntry.eventType = 1; 341 regEntry.eventScope = 2; 342 343 MockDataInterface dataIface; 344 std::vector<std::string> adData{"PEL_SUBSYSTEM=0x99"}; 345 AdditionalData ad{adData}; 346 347 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Critical, ad, 348 dataIface); 349 ASSERT_EQ(uh.subsystem(), 0x70); // others 350 } 351 { 352 // No subsystem in registry or PEL_SUBSYSTEM 353 Entry regEntry; 354 355 regEntry.name = "test"; 356 regEntry.actionFlags = 0xC000; 357 regEntry.eventType = 1; 358 regEntry.eventScope = 2; 359 360 MockDataInterface dataIface; 361 std::vector<std::string> adData; 362 AdditionalData ad{adData}; 363 364 UserHeader uh(regEntry, phosphor::logging::Entry::Level::Critical, ad, 365 dataIface); 366 ASSERT_EQ(uh.subsystem(), 0x70); // others 367 } 368 } 369