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 "extensions/openpower-pels/registry.hpp" 17 18 #include <nlohmann/json.hpp> 19 20 #include <filesystem> 21 #include <fstream> 22 23 #include <gtest/gtest.h> 24 25 using namespace openpower::pels::message; 26 using namespace openpower::pels; 27 namespace fs = std::filesystem; 28 29 const auto registryData = R"( 30 { 31 "PELs": 32 [ 33 { 34 "Name": "xyz.openbmc_project.Power.Fault", 35 "Subsystem": "power_supply", 36 37 "SRC": 38 { 39 "ReasonCode": "0x2030" 40 }, 41 42 "Documentation": 43 { 44 "Description": "A PGOOD Fault", 45 "Message": "PS had a PGOOD Fault" 46 } 47 }, 48 49 { 50 "Name": "xyz.openbmc_project.Power.OverVoltage", 51 "Subsystem": "power_control_hw", 52 "Severity": 53 [ 54 { 55 "System": "systemA", 56 "SevValue": "unrecoverable" 57 }, 58 { 59 "System": "systemB", 60 "SevValue": "recovered" 61 }, 62 { 63 "SevValue": "predictive" 64 } 65 ], 66 "MfgSeverity": "non_error", 67 "ActionFlags": ["service_action", "report", "call_home"], 68 "MfgActionFlags": ["hidden"], 69 70 "SRC": 71 { 72 "ReasonCode": "0x2333", 73 "Type": "BD", 74 "SymptomIDFields": ["SRCWord5", "SRCWord6", "SRCWord7"], 75 "Words6To9": 76 { 77 "6": 78 { 79 "Description": "Failing unit number", 80 "AdditionalDataPropSource": "PS_NUM" 81 }, 82 83 "7": 84 { 85 "Description": "bad voltage", 86 "AdditionalDataPropSource": "VOLTAGE" 87 } 88 } 89 }, 90 91 "Documentation": 92 { 93 "Description": "A PGOOD Fault", 94 "Message": "PS %1 had a PGOOD Fault", 95 "MessageArgSources": 96 [ 97 "SRCWord6" 98 ], 99 "Notes": [ 100 "In the UserData section there is a JSON", 101 "dump that provides debug information." 102 ] 103 }, 104 105 "JournalCapture": 106 { 107 "NumLines": 7 108 } 109 }, 110 111 { 112 "Name": "xyz.openbmc_project.Common.Error.Timeout", 113 "PossibleSubsystems": ["processor", "memory"], 114 115 "SRC": 116 { 117 "ReasonCode": "0x2030" 118 }, 119 "Documentation": 120 { 121 "Description": "A PGOOD Fault", 122 "Message": "PS had a PGOOD Fault" 123 } 124 }, 125 126 { 127 "Name": "xyz.openbmc_project.Journal.Capture", 128 "Subsystem": "power_supply", 129 130 "SRC": 131 { 132 "ReasonCode": "0x2030" 133 }, 134 135 "Documentation": 136 { 137 "Description": "journal capture test", 138 "Message": "journal capture test" 139 }, 140 141 "JournalCapture": 142 { 143 "Sections": [ 144 { 145 "NumLines": 5, 146 "SyslogID": "test1" 147 }, 148 { 149 "NumLines": 6, 150 "SyslogID": "test2" 151 } 152 ] 153 } 154 } 155 ] 156 } 157 )"; 158 159 class RegistryTest : public ::testing::Test 160 { 161 protected: 162 static void SetUpTestCase() 163 { 164 char path[] = "/tmp/regtestXXXXXX"; 165 regDir = mkdtemp(path); 166 } 167 168 static void TearDownTestCase() 169 { 170 fs::remove_all(regDir); 171 } 172 173 static std::string writeData(const char* data) 174 { 175 fs::path path = regDir / "registry.json"; 176 std::ofstream stream{path}; 177 stream << data; 178 return path; 179 } 180 181 static fs::path regDir; 182 }; 183 184 fs::path RegistryTest::regDir{}; 185 186 TEST_F(RegistryTest, TestNoEntry) 187 { 188 auto path = RegistryTest::writeData(registryData); 189 Registry registry{path}; 190 191 auto entry = registry.lookup("foo", LookupType::name); 192 EXPECT_FALSE(entry); 193 } 194 195 TEST_F(RegistryTest, TestFindEntry) 196 { 197 auto path = RegistryTest::writeData(registryData); 198 Registry registry{path}; 199 200 auto entry = registry.lookup("xyz.openbmc_project.Power.OverVoltage", 201 LookupType::name); 202 ASSERT_TRUE(entry); 203 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage"); 204 EXPECT_EQ(entry->subsystem, 0x62); 205 206 ASSERT_EQ(entry->severity->size(), 3); 207 EXPECT_EQ((*entry->severity)[0].severity, 0x40); 208 EXPECT_EQ((*entry->severity)[0].system, "systemA"); 209 EXPECT_EQ((*entry->severity)[1].severity, 0x10); 210 EXPECT_EQ((*entry->severity)[1].system, "systemB"); 211 EXPECT_EQ((*entry->severity)[2].severity, 0x20); 212 EXPECT_EQ((*entry->severity)[2].system, ""); 213 214 EXPECT_EQ(entry->mfgSeverity->size(), 1); 215 EXPECT_EQ((*entry->mfgSeverity)[0].severity, 0x00); 216 217 EXPECT_EQ(*(entry->actionFlags), 0xA800); 218 EXPECT_EQ(*(entry->mfgActionFlags), 0x4000); 219 EXPECT_EQ(entry->componentID, 0x2300); 220 EXPECT_FALSE(entry->eventType); 221 EXPECT_FALSE(entry->eventScope); 222 223 EXPECT_EQ(entry->src.type, 0xBD); 224 EXPECT_EQ(entry->src.reasonCode, 0x2333); 225 226 auto& hexwords = entry->src.hexwordADFields; 227 EXPECT_TRUE(hexwords); 228 EXPECT_EQ((*hexwords).size(), 2); 229 230 auto word = (*hexwords).find(6); 231 EXPECT_NE(word, (*hexwords).end()); 232 EXPECT_EQ(std::get<0>(word->second), "PS_NUM"); 233 234 word = (*hexwords).find(7); 235 EXPECT_NE(word, (*hexwords).end()); 236 EXPECT_EQ(std::get<0>(word->second), "VOLTAGE"); 237 238 auto& sid = entry->src.symptomID; 239 EXPECT_TRUE(sid); 240 EXPECT_EQ((*sid).size(), 3); 241 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 5), (*sid).end()); 242 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 6), (*sid).end()); 243 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 7), (*sid).end()); 244 245 EXPECT_EQ(entry->doc.description, "A PGOOD Fault"); 246 EXPECT_EQ(entry->doc.message, "PS %1 had a PGOOD Fault"); 247 auto& hexwordSource = entry->doc.messageArgSources; 248 EXPECT_TRUE(hexwordSource); 249 EXPECT_EQ((*hexwordSource).size(), 1); 250 EXPECT_EQ((*hexwordSource).front(), "SRCWord6"); 251 252 const auto& jc = entry->journalCapture; 253 ASSERT_TRUE(jc); 254 ASSERT_TRUE(std::holds_alternative<size_t>(*jc)); 255 EXPECT_EQ(std::get<size_t>(*jc), 7); 256 257 entry = registry.lookup("0x2333", LookupType::reasonCode); 258 ASSERT_TRUE(entry); 259 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage"); 260 } 261 262 // Check the entry that mostly uses defaults 263 TEST_F(RegistryTest, TestFindEntryMinimal) 264 { 265 auto path = RegistryTest::writeData(registryData); 266 Registry registry{path}; 267 268 auto entry = registry.lookup("xyz.openbmc_project.Power.Fault", 269 LookupType::name); 270 ASSERT_TRUE(entry); 271 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.Fault"); 272 EXPECT_EQ(entry->subsystem, 0x61); 273 EXPECT_FALSE(entry->severity); 274 EXPECT_FALSE(entry->mfgSeverity); 275 EXPECT_FALSE(entry->mfgActionFlags); 276 EXPECT_FALSE(entry->actionFlags); 277 EXPECT_EQ(entry->componentID, 0x2000); 278 EXPECT_FALSE(entry->eventType); 279 EXPECT_FALSE(entry->eventScope); 280 281 EXPECT_EQ(entry->src.reasonCode, 0x2030); 282 EXPECT_EQ(entry->src.type, 0xBD); 283 EXPECT_FALSE(entry->src.hexwordADFields); 284 EXPECT_FALSE(entry->src.symptomID); 285 } 286 287 TEST_F(RegistryTest, TestBadJSON) 288 { 289 auto path = RegistryTest::writeData("bad {} json"); 290 291 Registry registry{path}; 292 293 EXPECT_FALSE(registry.lookup("foo", LookupType::name)); 294 } 295 296 // Test the helper functions the use the pel_values data. 297 TEST_F(RegistryTest, TestHelperFunctions) 298 { 299 using namespace openpower::pels::message::helper; 300 EXPECT_EQ(getSubsystem("input_power_source"), 0xA1); 301 EXPECT_THROW(getSubsystem("foo"), std::runtime_error); 302 303 EXPECT_EQ(getSeverity("symptom_recovered"), 0x71); 304 EXPECT_THROW(getSeverity("foo"), std::runtime_error); 305 306 EXPECT_EQ(getEventType("dump_notification"), 0x08); 307 EXPECT_THROW(getEventType("foo"), std::runtime_error); 308 309 EXPECT_EQ(getEventScope("possibly_multiple_platforms"), 0x04); 310 EXPECT_THROW(getEventScope("foo"), std::runtime_error); 311 312 std::vector<std::string> flags{"service_action", "dont_report", 313 "termination"}; 314 EXPECT_EQ(getActionFlags(flags), 0x9100); 315 316 flags.clear(); 317 flags.push_back("foo"); 318 EXPECT_THROW(getActionFlags(flags), std::runtime_error); 319 } 320 321 TEST_F(RegistryTest, TestGetSRCReasonCode) 322 { 323 using namespace openpower::pels::message::helper; 324 EXPECT_EQ(getSRCReasonCode(R"({"ReasonCode": "0x5555"})"_json, "foo"), 325 0x5555); 326 327 EXPECT_THROW(getSRCReasonCode(R"({"ReasonCode": "ZZZZ"})"_json, "foo"), 328 std::runtime_error); 329 } 330 331 TEST_F(RegistryTest, TestGetSRCType) 332 { 333 using namespace openpower::pels::message::helper; 334 EXPECT_EQ(getSRCType(R"({"Type": "11"})"_json, "foo"), 0x11); 335 EXPECT_EQ(getSRCType(R"({"Type": "BF"})"_json, "foo"), 0xBF); 336 337 EXPECT_THROW(getSRCType(R"({"Type": "1"})"_json, "foo"), 338 std::runtime_error); 339 340 EXPECT_THROW(getSRCType(R"({"Type": "111"})"_json, "foo"), 341 std::runtime_error); 342 } 343 344 TEST_F(RegistryTest, TestGetSRCHexwordFields) 345 { 346 using namespace openpower::pels::message::helper; 347 const auto hexwords = R"( 348 {"Words6To9": 349 { 350 "8": 351 { 352 "Description": "TEST", 353 "AdditionalDataPropSource": "TEST" 354 } 355 } 356 })"_json; 357 358 auto fields = getSRCHexwordFields(hexwords, "foo"); 359 EXPECT_TRUE(fields); 360 auto word = fields->find(8); 361 EXPECT_NE(word, fields->end()); 362 363 const auto theInvalidRWord = R"( 364 {"Words6To9": 365 { 366 "R": 367 { 368 "Description": "TEST", 369 "AdditionalDataPropSource": "TEST" 370 } 371 } 372 })"_json; 373 374 EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"), 375 std::runtime_error); 376 } 377 378 TEST_F(RegistryTest, TestGetSRCSymptomIDFields) 379 { 380 using namespace openpower::pels::message::helper; 381 const auto sID = R"( 382 { 383 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord5"] 384 })"_json; 385 386 auto fields = getSRCSymptomIDFields(sID, "foo"); 387 EXPECT_NE(std::find(fields->begin(), fields->end(), 3), fields->end()); 388 EXPECT_NE(std::find(fields->begin(), fields->end(), 4), fields->end()); 389 EXPECT_NE(std::find(fields->begin(), fields->end(), 5), fields->end()); 390 391 const auto badField = R"( 392 { 393 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord"] 394 })"_json; 395 396 EXPECT_THROW(getSRCSymptomIDFields(badField, "foo"), std::runtime_error); 397 } 398 399 TEST_F(RegistryTest, TestGetComponentID) 400 { 401 using namespace openpower::pels::message::helper; 402 403 // Get it from the JSON 404 auto id = getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json, 405 "foo"); 406 EXPECT_EQ(id, 0x4200); 407 408 // Get it from the reason code on a 0xBD SRC 409 id = getComponentID(0xBD, 0x6700, R"({})"_json, "foo"); 410 EXPECT_EQ(id, 0x6700); 411 412 // Not present on a 0x11 SRC 413 EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"), 414 std::runtime_error); 415 } 416 417 // Test when callouts are in the JSON. 418 TEST_F(RegistryTest, TestGetCallouts) 419 { 420 std::vector<std::string> names; 421 422 { 423 // Callouts without AD, that depend on system type, 424 // where there is a default entry without a system type. 425 auto json = R"( 426 [ 427 { 428 "System": "system1", 429 "CalloutList": 430 [ 431 { 432 "Priority": "high", 433 "LocCode": "P1-C1" 434 }, 435 { 436 "Priority": "low", 437 "LocCode": "P1" 438 }, 439 { 440 "Priority": "low", 441 "SymbolicFRU": "service_docs" 442 }, 443 { 444 "Priority": "low", 445 "SymbolicFRUTrusted": "air_mover", 446 "UseInventoryLocCode": true 447 } 448 ] 449 }, 450 { 451 "CalloutList": 452 [ 453 { 454 "Priority": "medium", 455 "Procedure": "bmc_code" 456 }, 457 { 458 "Priority": "low", 459 "LocCode": "P3-C8", 460 "SymbolicFRUTrusted": "service_docs" 461 } 462 ] 463 464 } 465 ])"_json; 466 467 AdditionalData ad; 468 names.push_back("system1"); 469 470 auto callouts = Registry::getCallouts(json, names, ad); 471 EXPECT_EQ(callouts.size(), 4); 472 EXPECT_EQ(callouts[0].priority, "high"); 473 EXPECT_EQ(callouts[0].locCode, "P1-C1"); 474 EXPECT_EQ(callouts[0].procedure, ""); 475 EXPECT_EQ(callouts[0].symbolicFRU, ""); 476 EXPECT_EQ(callouts[0].symbolicFRUTrusted, ""); 477 EXPECT_EQ(callouts[1].priority, "low"); 478 EXPECT_EQ(callouts[1].locCode, "P1"); 479 EXPECT_EQ(callouts[1].procedure, ""); 480 EXPECT_EQ(callouts[1].symbolicFRU, ""); 481 EXPECT_EQ(callouts[1].symbolicFRUTrusted, ""); 482 EXPECT_EQ(callouts[2].priority, "low"); 483 EXPECT_EQ(callouts[2].locCode, ""); 484 EXPECT_EQ(callouts[2].procedure, ""); 485 EXPECT_EQ(callouts[2].symbolicFRU, "service_docs"); 486 EXPECT_EQ(callouts[2].symbolicFRUTrusted, ""); 487 EXPECT_EQ(callouts[3].priority, "low"); 488 EXPECT_EQ(callouts[3].locCode, ""); 489 EXPECT_EQ(callouts[3].procedure, ""); 490 EXPECT_EQ(callouts[3].symbolicFRU, ""); 491 EXPECT_EQ(callouts[3].symbolicFRUTrusted, "air_mover"); 492 EXPECT_EQ(callouts[3].useInventoryLocCode, true); 493 494 // system2 isn't in the JSON, so it will pick the default one 495 names[0] = "system2"; 496 callouts = Registry::getCallouts(json, names, ad); 497 EXPECT_EQ(callouts.size(), 2); 498 EXPECT_EQ(callouts[0].priority, "medium"); 499 EXPECT_EQ(callouts[0].locCode, ""); 500 EXPECT_EQ(callouts[0].procedure, "bmc_code"); 501 EXPECT_EQ(callouts[0].symbolicFRU, ""); 502 EXPECT_EQ(callouts[1].priority, "low"); 503 EXPECT_EQ(callouts[1].locCode, "P3-C8"); 504 EXPECT_EQ(callouts[1].procedure, ""); 505 EXPECT_EQ(callouts[1].symbolicFRU, ""); 506 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "service_docs"); 507 EXPECT_EQ(callouts[1].useInventoryLocCode, false); 508 } 509 510 // Empty JSON array (treated as an error) 511 { 512 auto json = R"([])"_json; 513 AdditionalData ad; 514 names[0] = "system1"; 515 EXPECT_THROW(Registry::getCallouts(json, names, ad), 516 std::runtime_error); 517 } 518 519 { 520 // Callouts without AD, that depend on system type, 521 // where there isn't a default entry without a system type. 522 auto json = R"( 523 [ 524 { 525 "System": "system1", 526 "CalloutList": 527 [ 528 { 529 "Priority": "high", 530 "LocCode": "P1-C1" 531 }, 532 { 533 "Priority": "low", 534 "LocCode": "P1", 535 "SymbolicFRU": "1234567" 536 } 537 ] 538 }, 539 { 540 "System": "system2", 541 "CalloutList": 542 [ 543 { 544 "Priority": "medium", 545 "LocCode": "P7", 546 "CalloutType": "tool_fru" 547 } 548 ] 549 550 } 551 ])"_json; 552 553 AdditionalData ad; 554 names[0] = "system1"; 555 556 auto callouts = Registry::getCallouts(json, names, ad); 557 EXPECT_EQ(callouts.size(), 2); 558 EXPECT_EQ(callouts[0].priority, "high"); 559 EXPECT_EQ(callouts[0].locCode, "P1-C1"); 560 EXPECT_EQ(callouts[0].procedure, ""); 561 EXPECT_EQ(callouts[0].symbolicFRU, ""); 562 EXPECT_EQ(callouts[0].symbolicFRUTrusted, ""); 563 EXPECT_EQ(callouts[1].priority, "low"); 564 EXPECT_EQ(callouts[1].locCode, "P1"); 565 EXPECT_EQ(callouts[1].procedure, ""); 566 EXPECT_EQ(callouts[1].symbolicFRU, "1234567"); 567 EXPECT_EQ(callouts[1].symbolicFRUTrusted, ""); 568 569 names[0] = "system2"; 570 callouts = Registry::getCallouts(json, names, ad); 571 EXPECT_EQ(callouts.size(), 1); 572 EXPECT_EQ(callouts[0].priority, "medium"); 573 EXPECT_EQ(callouts[0].locCode, "P7"); 574 EXPECT_EQ(callouts[0].procedure, ""); 575 EXPECT_EQ(callouts[0].symbolicFRU, ""); 576 EXPECT_EQ(callouts[0].symbolicFRUTrusted, ""); 577 578 // There is no entry for system3 or a default system, 579 // so this should fail. 580 names[0] = "system3"; 581 EXPECT_THROW(Registry::getCallouts(json, names, ad), 582 std::runtime_error); 583 } 584 585 { 586 // Callouts that use the AdditionalData key PROC_NUM 587 // as an index into them, along with a system type. 588 // It supports PROC_NUMs 0 and 1. 589 auto json = R"( 590 { 591 "ADName": "PROC_NUM", 592 "CalloutsWithTheirADValues": 593 [ 594 { 595 "ADValue": "0", 596 "Callouts": 597 [ 598 { 599 "System": "system3", 600 "CalloutList": 601 [ 602 { 603 "Priority": "high", 604 "LocCode": "P1-C5" 605 }, 606 { 607 "Priority": "medium", 608 "LocCode": "P1-C6", 609 "SymbolicFRU": "1234567" 610 }, 611 { 612 "Priority": "low", 613 "Procedure": "bmc_code", 614 "CalloutType": "config_procedure" 615 } 616 ] 617 }, 618 { 619 "CalloutList": 620 [ 621 { 622 "Priority": "low", 623 "LocCode": "P55" 624 } 625 ] 626 } 627 ] 628 }, 629 { 630 "ADValue": "1", 631 "Callouts": 632 [ 633 { 634 "CalloutList": 635 [ 636 { 637 "Priority": "high", 638 "LocCode": "P1-C6", 639 "CalloutType": "external_fru" 640 } 641 ] 642 } 643 ] 644 } 645 ] 646 })"_json; 647 648 { 649 // Find callouts for PROC_NUM 0 on system3 650 std::vector<std::string> adData{"PROC_NUM=0"}; 651 AdditionalData ad{adData}; 652 names[0] = "system3"; 653 654 auto callouts = Registry::getCallouts(json, names, ad); 655 EXPECT_EQ(callouts.size(), 3); 656 EXPECT_EQ(callouts[0].priority, "high"); 657 EXPECT_EQ(callouts[0].locCode, "P1-C5"); 658 EXPECT_EQ(callouts[0].procedure, ""); 659 EXPECT_EQ(callouts[0].symbolicFRU, ""); 660 EXPECT_EQ(callouts[0].symbolicFRUTrusted, ""); 661 EXPECT_EQ(callouts[1].priority, "medium"); 662 EXPECT_EQ(callouts[1].locCode, "P1-C6"); 663 EXPECT_EQ(callouts[1].procedure, ""); 664 EXPECT_EQ(callouts[1].symbolicFRU, "1234567"); 665 EXPECT_EQ(callouts[1].symbolicFRUTrusted, ""); 666 EXPECT_EQ(callouts[2].priority, "low"); 667 EXPECT_EQ(callouts[2].locCode, ""); 668 EXPECT_EQ(callouts[2].procedure, "bmc_code"); 669 EXPECT_EQ(callouts[2].symbolicFRU, ""); 670 EXPECT_EQ(callouts[2].symbolicFRUTrusted, ""); 671 672 // Find callouts for PROC_NUM 0 that uses the default system entry. 673 names[0] = "system99"; 674 675 callouts = Registry::getCallouts(json, names, ad); 676 EXPECT_EQ(callouts.size(), 1); 677 EXPECT_EQ(callouts[0].priority, "low"); 678 EXPECT_EQ(callouts[0].locCode, "P55"); 679 EXPECT_EQ(callouts[0].procedure, ""); 680 EXPECT_EQ(callouts[0].symbolicFRU, ""); 681 EXPECT_EQ(callouts[0].symbolicFRUTrusted, ""); 682 } 683 { 684 // Find callouts for PROC_NUM 1 that uses a default system entry. 685 std::vector<std::string> adData{"PROC_NUM=1"}; 686 AdditionalData ad{adData}; 687 names[0] = "system1"; 688 689 auto callouts = Registry::getCallouts(json, names, ad); 690 EXPECT_EQ(callouts.size(), 1); 691 EXPECT_EQ(callouts[0].priority, "high"); 692 EXPECT_EQ(callouts[0].locCode, "P1-C6"); 693 EXPECT_EQ(callouts[0].procedure, ""); 694 EXPECT_EQ(callouts[0].symbolicFRU, ""); 695 EXPECT_EQ(callouts[0].symbolicFRUTrusted, ""); 696 } 697 { 698 // There is no entry for PROC_NUM 2, so no callouts 699 std::vector<std::string> adData{"PROC_NUM=2"}; 700 AdditionalData ad{adData}; 701 702 auto callouts = Registry::getCallouts(json, names, ad); 703 EXPECT_TRUE(callouts.empty()); 704 } 705 } 706 707 { 708 // Callouts with a 'CalloutsWhenNoADMatch' section that will 709 // be used when the AdditionalData value doesn't match. 710 auto json = R"( 711 { 712 "ADName": "PROC_NUM", 713 "CalloutsWithTheirADValues": 714 [ 715 { 716 "ADValue": "0", 717 "Callouts": 718 [ 719 { 720 "CalloutList": 721 [ 722 { 723 "Priority": "high", 724 "LocCode": "P0-C0" 725 } 726 ] 727 } 728 ] 729 } 730 ], 731 "CalloutsWhenNoADMatch": [ 732 { 733 "CalloutList": [ 734 { 735 "Priority": "medium", 736 "LocCode": "P1-C1" 737 } 738 ] 739 } 740 ] 741 })"_json; 742 743 // There isn't an entry in the JSON for a PROC_NUM of 8 744 // so it should choose the P1-C1 callout. 745 std::vector<std::string> adData{"PROC_NUM=8"}; 746 AdditionalData ad{adData}; 747 names.clear(); 748 749 auto callouts = Registry::getCallouts(json, names, ad); 750 EXPECT_EQ(callouts.size(), 1); 751 EXPECT_EQ(callouts[0].priority, "medium"); 752 EXPECT_EQ(callouts[0].locCode, "P1-C1"); 753 } 754 } 755 756 TEST_F(RegistryTest, TestNoSubsystem) 757 { 758 auto path = RegistryTest::writeData(registryData); 759 Registry registry{path}; 760 761 auto entry = registry.lookup("xyz.openbmc_project.Common.Error.Timeout", 762 LookupType::name); 763 ASSERT_TRUE(entry); 764 EXPECT_FALSE(entry->subsystem); 765 } 766 767 TEST_F(RegistryTest, TestJournalSectionCapture) 768 { 769 auto path = RegistryTest::writeData(registryData); 770 Registry registry{path}; 771 772 auto entry = registry.lookup("xyz.openbmc_project.Journal.Capture", 773 LookupType::name); 774 ASSERT_TRUE(entry); 775 776 const auto& jc = entry->journalCapture; 777 ASSERT_TRUE(jc); 778 ASSERT_TRUE(std::holds_alternative<AppCaptureList>(*jc)); 779 const auto& acl = std::get<AppCaptureList>(*jc); 780 781 ASSERT_EQ(acl.size(), 2); 782 783 EXPECT_EQ(acl[0].syslogID, "test1"); 784 EXPECT_EQ(acl[0].numLines, 5); 785 786 EXPECT_EQ(acl[1].syslogID, "test2"); 787 EXPECT_EQ(acl[1].numLines, 6); 788 } 789