blob: 2f715bb3b908e65eee4055ed2af0b04178d3fb20 [file] [log] [blame]
Matt Spinler97f7abc2019-11-06 09:40:23 -06001/**
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 */
Matt Spinler367144c2019-09-19 15:33:52 -050016#include "extensions/openpower-pels/registry.hpp"
17
Patrick Williams2544b412022-10-04 08:41:06 -050018#include <nlohmann/json.hpp>
19
Matt Spinler367144c2019-09-19 15:33:52 -050020#include <filesystem>
21#include <fstream>
Matt Spinler367144c2019-09-19 15:33:52 -050022
23#include <gtest/gtest.h>
24
25using namespace openpower::pels::message;
Matt Spinler6b427cc2020-04-09 09:42:59 -050026using namespace openpower::pels;
Matt Spinler367144c2019-09-19 15:33:52 -050027namespace fs = std::filesystem;
28
29const auto registryData = R"(
30{
31 "PELs":
32 [
33 {
34 "Name": "xyz.openbmc_project.Power.Fault",
35 "Subsystem": "power_supply",
Matt Spinler367144c2019-09-19 15:33:52 -050036
37 "SRC":
38 {
39 "ReasonCode": "0x2030"
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +080040 },
41
42 "Documentation":
43 {
44 "Description": "A PGOOD Fault",
45 "Message": "PS had a PGOOD Fault"
Matt Spinler367144c2019-09-19 15:33:52 -050046 }
47 },
48
49 {
50 "Name": "xyz.openbmc_project.Power.OverVoltage",
51 "Subsystem": "power_control_hw",
Matt Spinleraadccc82020-04-10 14:33:42 -050052 "Severity":
53 [
54 {
55 "System": "systemA",
56 "SevValue": "unrecoverable"
57 },
58 {
59 "System": "systemB",
60 "SevValue": "recovered"
61 },
62 {
63 "SevValue": "predictive"
64 }
65 ],
Matt Spinler367144c2019-09-19 15:33:52 -050066 "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"],
Matt Spinler367144c2019-09-19 15:33:52 -050075 "Words6To9":
76 {
77 "6":
78 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +080079 "Description": "Failing unit number",
Matt Spinler367144c2019-09-19 15:33:52 -050080 "AdditionalDataPropSource": "PS_NUM"
81 },
82
83 "7":
84 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +080085 "Description": "bad voltage",
Matt Spinler367144c2019-09-19 15:33:52 -050086 "AdditionalDataPropSource": "VOLTAGE"
87 }
Matt Spinler3fe93e92023-04-14 14:06:59 -050088 },
Matt Spinlerda5b76b2023-06-01 15:56:57 -050089 "DeconfigFlag": true,
90 "CheckstopFlag": true
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +080091 },
92
93 "Documentation":
94 {
95 "Description": "A PGOOD Fault",
96 "Message": "PS %1 had a PGOOD Fault",
97 "MessageArgSources":
98 [
99 "SRCWord6"
100 ],
101 "Notes": [
102 "In the UserData section there is a JSON",
103 "dump that provides debug information."
104 ]
Matt Spinler711f1122022-12-15 11:41:20 -0600105 },
106
107 "JournalCapture":
108 {
109 "NumLines": 7
Matt Spinler367144c2019-09-19 15:33:52 -0500110 }
Matt Spinler23970b02022-02-25 16:34:46 -0600111 },
112
113 {
114 "Name": "xyz.openbmc_project.Common.Error.Timeout",
115 "PossibleSubsystems": ["processor", "memory"],
116
117 "SRC":
118 {
119 "ReasonCode": "0x2030"
120 },
121 "Documentation":
122 {
123 "Description": "A PGOOD Fault",
124 "Message": "PS had a PGOOD Fault"
125 }
Matt Spinler711f1122022-12-15 11:41:20 -0600126 },
127
128 {
129 "Name": "xyz.openbmc_project.Journal.Capture",
130 "Subsystem": "power_supply",
131
132 "SRC":
133 {
134 "ReasonCode": "0x2030"
135 },
136
137 "Documentation":
138 {
139 "Description": "journal capture test",
140 "Message": "journal capture test"
141 },
142
143 "JournalCapture":
144 {
145 "Sections": [
146 {
147 "NumLines": 5,
148 "SyslogID": "test1"
149 },
150 {
151 "NumLines": 6,
152 "SyslogID": "test2"
153 }
154 ]
155 }
Matt Spinler367144c2019-09-19 15:33:52 -0500156 }
157 ]
158}
159)";
160
161class RegistryTest : public ::testing::Test
162{
163 protected:
164 static void SetUpTestCase()
165 {
166 char path[] = "/tmp/regtestXXXXXX";
167 regDir = mkdtemp(path);
168 }
169
170 static void TearDownTestCase()
171 {
172 fs::remove_all(regDir);
173 }
174
175 static std::string writeData(const char* data)
176 {
177 fs::path path = regDir / "registry.json";
178 std::ofstream stream{path};
179 stream << data;
180 return path;
181 }
182
183 static fs::path regDir;
184};
185
186fs::path RegistryTest::regDir{};
187
188TEST_F(RegistryTest, TestNoEntry)
189{
190 auto path = RegistryTest::writeData(registryData);
191 Registry registry{path};
192
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800193 auto entry = registry.lookup("foo", LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500194 EXPECT_FALSE(entry);
195}
196
197TEST_F(RegistryTest, TestFindEntry)
198{
199 auto path = RegistryTest::writeData(registryData);
200 Registry registry{path};
201
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800202 auto entry = registry.lookup("xyz.openbmc_project.Power.OverVoltage",
203 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500204 ASSERT_TRUE(entry);
205 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
206 EXPECT_EQ(entry->subsystem, 0x62);
Matt Spinleraadccc82020-04-10 14:33:42 -0500207
208 ASSERT_EQ(entry->severity->size(), 3);
209 EXPECT_EQ((*entry->severity)[0].severity, 0x40);
210 EXPECT_EQ((*entry->severity)[0].system, "systemA");
211 EXPECT_EQ((*entry->severity)[1].severity, 0x10);
212 EXPECT_EQ((*entry->severity)[1].system, "systemB");
213 EXPECT_EQ((*entry->severity)[2].severity, 0x20);
214 EXPECT_EQ((*entry->severity)[2].system, "");
215
216 EXPECT_EQ(entry->mfgSeverity->size(), 1);
217 EXPECT_EQ((*entry->mfgSeverity)[0].severity, 0x00);
218
Matt Spinlere07f9152019-11-01 10:48:36 -0500219 EXPECT_EQ(*(entry->actionFlags), 0xA800);
Matt Spinler367144c2019-09-19 15:33:52 -0500220 EXPECT_EQ(*(entry->mfgActionFlags), 0x4000);
Matt Spinler93e29322019-09-20 11:16:15 -0500221 EXPECT_EQ(entry->componentID, 0x2300);
Matt Spinler367144c2019-09-19 15:33:52 -0500222 EXPECT_FALSE(entry->eventType);
223 EXPECT_FALSE(entry->eventScope);
224
Matt Spinler93e29322019-09-20 11:16:15 -0500225 EXPECT_EQ(entry->src.type, 0xBD);
226 EXPECT_EQ(entry->src.reasonCode, 0x2333);
Matt Spinler3fe93e92023-04-14 14:06:59 -0500227 EXPECT_TRUE(entry->src.deconfigFlag);
Matt Spinlerda5b76b2023-06-01 15:56:57 -0500228 EXPECT_TRUE(entry->src.checkstopFlag);
Matt Spinler93e29322019-09-20 11:16:15 -0500229
230 auto& hexwords = entry->src.hexwordADFields;
231 EXPECT_TRUE(hexwords);
232 EXPECT_EQ((*hexwords).size(), 2);
233
234 auto word = (*hexwords).find(6);
235 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800236 EXPECT_EQ(std::get<0>(word->second), "PS_NUM");
Matt Spinler93e29322019-09-20 11:16:15 -0500237
238 word = (*hexwords).find(7);
239 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800240 EXPECT_EQ(std::get<0>(word->second), "VOLTAGE");
Matt Spinler93e29322019-09-20 11:16:15 -0500241
242 auto& sid = entry->src.symptomID;
243 EXPECT_TRUE(sid);
244 EXPECT_EQ((*sid).size(), 3);
245 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 5), (*sid).end());
246 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 6), (*sid).end());
247 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 7), (*sid).end());
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800248
249 EXPECT_EQ(entry->doc.description, "A PGOOD Fault");
250 EXPECT_EQ(entry->doc.message, "PS %1 had a PGOOD Fault");
251 auto& hexwordSource = entry->doc.messageArgSources;
252 EXPECT_TRUE(hexwordSource);
253 EXPECT_EQ((*hexwordSource).size(), 1);
254 EXPECT_EQ((*hexwordSource).front(), "SRCWord6");
255
Matt Spinler711f1122022-12-15 11:41:20 -0600256 const auto& jc = entry->journalCapture;
257 ASSERT_TRUE(jc);
258 ASSERT_TRUE(std::holds_alternative<size_t>(*jc));
259 EXPECT_EQ(std::get<size_t>(*jc), 7);
260
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800261 entry = registry.lookup("0x2333", LookupType::reasonCode);
262 ASSERT_TRUE(entry);
263 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
Matt Spinler367144c2019-09-19 15:33:52 -0500264}
265
266// Check the entry that mostly uses defaults
267TEST_F(RegistryTest, TestFindEntryMinimal)
268{
269 auto path = RegistryTest::writeData(registryData);
270 Registry registry{path};
271
Patrick Williams2544b412022-10-04 08:41:06 -0500272 auto entry = registry.lookup("xyz.openbmc_project.Power.Fault",
273 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500274 ASSERT_TRUE(entry);
275 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.Fault");
276 EXPECT_EQ(entry->subsystem, 0x61);
277 EXPECT_FALSE(entry->severity);
278 EXPECT_FALSE(entry->mfgSeverity);
279 EXPECT_FALSE(entry->mfgActionFlags);
Matt Spinlere07f9152019-11-01 10:48:36 -0500280 EXPECT_FALSE(entry->actionFlags);
Matt Spinler93e29322019-09-20 11:16:15 -0500281 EXPECT_EQ(entry->componentID, 0x2000);
Matt Spinler367144c2019-09-19 15:33:52 -0500282 EXPECT_FALSE(entry->eventType);
283 EXPECT_FALSE(entry->eventScope);
Matt Spinler93e29322019-09-20 11:16:15 -0500284
285 EXPECT_EQ(entry->src.reasonCode, 0x2030);
286 EXPECT_EQ(entry->src.type, 0xBD);
Matt Spinler93e29322019-09-20 11:16:15 -0500287 EXPECT_FALSE(entry->src.hexwordADFields);
288 EXPECT_FALSE(entry->src.symptomID);
Matt Spinler3fe93e92023-04-14 14:06:59 -0500289 EXPECT_FALSE(entry->src.deconfigFlag);
Matt Spinlerda5b76b2023-06-01 15:56:57 -0500290 EXPECT_FALSE(entry->src.checkstopFlag);
Matt Spinler367144c2019-09-19 15:33:52 -0500291}
292
293TEST_F(RegistryTest, TestBadJSON)
294{
295 auto path = RegistryTest::writeData("bad {} json");
296
297 Registry registry{path};
298
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800299 EXPECT_FALSE(registry.lookup("foo", LookupType::name));
Matt Spinler367144c2019-09-19 15:33:52 -0500300}
301
302// Test the helper functions the use the pel_values data.
303TEST_F(RegistryTest, TestHelperFunctions)
304{
305 using namespace openpower::pels::message::helper;
306 EXPECT_EQ(getSubsystem("input_power_source"), 0xA1);
307 EXPECT_THROW(getSubsystem("foo"), std::runtime_error);
308
309 EXPECT_EQ(getSeverity("symptom_recovered"), 0x71);
310 EXPECT_THROW(getSeverity("foo"), std::runtime_error);
311
312 EXPECT_EQ(getEventType("dump_notification"), 0x08);
313 EXPECT_THROW(getEventType("foo"), std::runtime_error);
314
315 EXPECT_EQ(getEventScope("possibly_multiple_platforms"), 0x04);
316 EXPECT_THROW(getEventScope("foo"), std::runtime_error);
317
318 std::vector<std::string> flags{"service_action", "dont_report",
319 "termination"};
320 EXPECT_EQ(getActionFlags(flags), 0x9100);
321
322 flags.clear();
323 flags.push_back("foo");
324 EXPECT_THROW(getActionFlags(flags), std::runtime_error);
325}
Matt Spinler93e29322019-09-20 11:16:15 -0500326
327TEST_F(RegistryTest, TestGetSRCReasonCode)
328{
329 using namespace openpower::pels::message::helper;
330 EXPECT_EQ(getSRCReasonCode(R"({"ReasonCode": "0x5555"})"_json, "foo"),
331 0x5555);
332
333 EXPECT_THROW(getSRCReasonCode(R"({"ReasonCode": "ZZZZ"})"_json, "foo"),
334 std::runtime_error);
335}
336
337TEST_F(RegistryTest, TestGetSRCType)
338{
339 using namespace openpower::pels::message::helper;
340 EXPECT_EQ(getSRCType(R"({"Type": "11"})"_json, "foo"), 0x11);
341 EXPECT_EQ(getSRCType(R"({"Type": "BF"})"_json, "foo"), 0xBF);
342
343 EXPECT_THROW(getSRCType(R"({"Type": "1"})"_json, "foo"),
344 std::runtime_error);
345
346 EXPECT_THROW(getSRCType(R"({"Type": "111"})"_json, "foo"),
347 std::runtime_error);
348}
349
350TEST_F(RegistryTest, TestGetSRCHexwordFields)
351{
352 using namespace openpower::pels::message::helper;
353 const auto hexwords = R"(
354 {"Words6To9":
355 {
356 "8":
357 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800358 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500359 "AdditionalDataPropSource": "TEST"
360 }
361 }
362 })"_json;
363
364 auto fields = getSRCHexwordFields(hexwords, "foo");
365 EXPECT_TRUE(fields);
366 auto word = fields->find(8);
367 EXPECT_NE(word, fields->end());
368
369 const auto theInvalidRWord = R"(
370 {"Words6To9":
371 {
372 "R":
373 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800374 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500375 "AdditionalDataPropSource": "TEST"
376 }
377 }
378 })"_json;
379
380 EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"),
381 std::runtime_error);
382}
383
384TEST_F(RegistryTest, TestGetSRCSymptomIDFields)
385{
386 using namespace openpower::pels::message::helper;
387 const auto sID = R"(
388 {
389 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord5"]
390 })"_json;
391
392 auto fields = getSRCSymptomIDFields(sID, "foo");
393 EXPECT_NE(std::find(fields->begin(), fields->end(), 3), fields->end());
394 EXPECT_NE(std::find(fields->begin(), fields->end(), 4), fields->end());
395 EXPECT_NE(std::find(fields->begin(), fields->end(), 5), fields->end());
396
397 const auto badField = R"(
398 {
399 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord"]
400 })"_json;
401
402 EXPECT_THROW(getSRCSymptomIDFields(badField, "foo"), std::runtime_error);
403}
404
405TEST_F(RegistryTest, TestGetComponentID)
406{
407 using namespace openpower::pels::message::helper;
408
409 // Get it from the JSON
Patrick Williams2544b412022-10-04 08:41:06 -0500410 auto id = getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json,
411 "foo");
Matt Spinler93e29322019-09-20 11:16:15 -0500412 EXPECT_EQ(id, 0x4200);
413
414 // Get it from the reason code on a 0xBD SRC
415 id = getComponentID(0xBD, 0x6700, R"({})"_json, "foo");
416 EXPECT_EQ(id, 0x6700);
417
418 // Not present on a 0x11 SRC
419 EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"),
420 std::runtime_error);
421}
Matt Spinler6b427cc2020-04-09 09:42:59 -0500422
423// Test when callouts are in the JSON.
424TEST_F(RegistryTest, TestGetCallouts)
425{
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500426 std::vector<std::string> names;
427
Matt Spinler6b427cc2020-04-09 09:42:59 -0500428 {
429 // Callouts without AD, that depend on system type,
430 // where there is a default entry without a system type.
431 auto json = R"(
432 [
433 {
434 "System": "system1",
435 "CalloutList":
436 [
437 {
438 "Priority": "high",
439 "LocCode": "P1-C1"
440 },
441 {
442 "Priority": "low",
443 "LocCode": "P1"
444 },
445 {
446 "Priority": "low",
447 "SymbolicFRU": "service_docs"
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500448 },
449 {
450 "Priority": "low",
451 "SymbolicFRUTrusted": "air_mover",
452 "UseInventoryLocCode": true
Matt Spinler6b427cc2020-04-09 09:42:59 -0500453 }
454 ]
455 },
456 {
457 "CalloutList":
458 [
459 {
460 "Priority": "medium",
Matt Spinler479b6922021-08-17 16:34:59 -0500461 "Procedure": "bmc_code"
Matt Spinler6b427cc2020-04-09 09:42:59 -0500462 },
463 {
464 "Priority": "low",
465 "LocCode": "P3-C8",
466 "SymbolicFRUTrusted": "service_docs"
467 }
468 ]
469
470 }
471 ])"_json;
472
473 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500474 names.push_back("system1");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500475
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500476 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500477 EXPECT_EQ(callouts.size(), 4);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500478 EXPECT_EQ(callouts[0].priority, "high");
479 EXPECT_EQ(callouts[0].locCode, "P1-C1");
480 EXPECT_EQ(callouts[0].procedure, "");
481 EXPECT_EQ(callouts[0].symbolicFRU, "");
482 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
483 EXPECT_EQ(callouts[1].priority, "low");
484 EXPECT_EQ(callouts[1].locCode, "P1");
485 EXPECT_EQ(callouts[1].procedure, "");
486 EXPECT_EQ(callouts[1].symbolicFRU, "");
487 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
488 EXPECT_EQ(callouts[2].priority, "low");
489 EXPECT_EQ(callouts[2].locCode, "");
490 EXPECT_EQ(callouts[2].procedure, "");
491 EXPECT_EQ(callouts[2].symbolicFRU, "service_docs");
492 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500493 EXPECT_EQ(callouts[3].priority, "low");
494 EXPECT_EQ(callouts[3].locCode, "");
495 EXPECT_EQ(callouts[3].procedure, "");
496 EXPECT_EQ(callouts[3].symbolicFRU, "");
497 EXPECT_EQ(callouts[3].symbolicFRUTrusted, "air_mover");
498 EXPECT_EQ(callouts[3].useInventoryLocCode, true);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500499
500 // system2 isn't in the JSON, so it will pick the default one
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500501 names[0] = "system2";
502 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500503 EXPECT_EQ(callouts.size(), 2);
504 EXPECT_EQ(callouts[0].priority, "medium");
505 EXPECT_EQ(callouts[0].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500506 EXPECT_EQ(callouts[0].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500507 EXPECT_EQ(callouts[0].symbolicFRU, "");
508 EXPECT_EQ(callouts[1].priority, "low");
509 EXPECT_EQ(callouts[1].locCode, "P3-C8");
510 EXPECT_EQ(callouts[1].procedure, "");
511 EXPECT_EQ(callouts[1].symbolicFRU, "");
512 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "service_docs");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500513 EXPECT_EQ(callouts[1].useInventoryLocCode, false);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500514 }
515
516 // Empty JSON array (treated as an error)
517 {
518 auto json = R"([])"_json;
519 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500520 names[0] = "system1";
521 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500522 std::runtime_error);
523 }
524
525 {
526 // Callouts without AD, that depend on system type,
527 // where there isn't a default entry without a system type.
528 auto json = R"(
529 [
530 {
531 "System": "system1",
532 "CalloutList":
533 [
534 {
535 "Priority": "high",
536 "LocCode": "P1-C1"
537 },
538 {
539 "Priority": "low",
540 "LocCode": "P1",
541 "SymbolicFRU": "1234567"
542 }
543 ]
544 },
545 {
546 "System": "system2",
547 "CalloutList":
548 [
549 {
550 "Priority": "medium",
551 "LocCode": "P7",
552 "CalloutType": "tool_fru"
553 }
554 ]
555
556 }
557 ])"_json;
558
559 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500560 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500561
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500562 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500563 EXPECT_EQ(callouts.size(), 2);
564 EXPECT_EQ(callouts[0].priority, "high");
565 EXPECT_EQ(callouts[0].locCode, "P1-C1");
566 EXPECT_EQ(callouts[0].procedure, "");
567 EXPECT_EQ(callouts[0].symbolicFRU, "");
568 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
569 EXPECT_EQ(callouts[1].priority, "low");
570 EXPECT_EQ(callouts[1].locCode, "P1");
571 EXPECT_EQ(callouts[1].procedure, "");
572 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
573 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
574
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500575 names[0] = "system2";
576 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500577 EXPECT_EQ(callouts.size(), 1);
578 EXPECT_EQ(callouts[0].priority, "medium");
579 EXPECT_EQ(callouts[0].locCode, "P7");
580 EXPECT_EQ(callouts[0].procedure, "");
581 EXPECT_EQ(callouts[0].symbolicFRU, "");
582 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
583
584 // There is no entry for system3 or a default system,
585 // so this should fail.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500586 names[0] = "system3";
587 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500588 std::runtime_error);
589 }
590
591 {
592 // Callouts that use the AdditionalData key PROC_NUM
593 // as an index into them, along with a system type.
594 // It supports PROC_NUMs 0 and 1.
595 auto json = R"(
596 {
597 "ADName": "PROC_NUM",
598 "CalloutsWithTheirADValues":
599 [
600 {
601 "ADValue": "0",
602 "Callouts":
603 [
604 {
605 "System": "system3",
606 "CalloutList":
607 [
608 {
609 "Priority": "high",
610 "LocCode": "P1-C5"
611 },
612 {
613 "Priority": "medium",
614 "LocCode": "P1-C6",
615 "SymbolicFRU": "1234567"
616 },
617 {
618 "Priority": "low",
Matt Spinler479b6922021-08-17 16:34:59 -0500619 "Procedure": "bmc_code",
Matt Spinler6b427cc2020-04-09 09:42:59 -0500620 "CalloutType": "config_procedure"
621 }
622 ]
623 },
624 {
625 "CalloutList":
626 [
627 {
628 "Priority": "low",
629 "LocCode": "P55"
630 }
631 ]
632 }
633 ]
634 },
635 {
636 "ADValue": "1",
637 "Callouts":
638 [
639 {
640 "CalloutList":
641 [
642 {
643 "Priority": "high",
644 "LocCode": "P1-C6",
645 "CalloutType": "external_fru"
646 }
647 ]
648 }
649 ]
650 }
651 ]
652 })"_json;
653
654 {
655 // Find callouts for PROC_NUM 0 on system3
656 std::vector<std::string> adData{"PROC_NUM=0"};
657 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500658 names[0] = "system3";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500659
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500660 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500661 EXPECT_EQ(callouts.size(), 3);
662 EXPECT_EQ(callouts[0].priority, "high");
663 EXPECT_EQ(callouts[0].locCode, "P1-C5");
664 EXPECT_EQ(callouts[0].procedure, "");
665 EXPECT_EQ(callouts[0].symbolicFRU, "");
666 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
667 EXPECT_EQ(callouts[1].priority, "medium");
668 EXPECT_EQ(callouts[1].locCode, "P1-C6");
669 EXPECT_EQ(callouts[1].procedure, "");
670 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
671 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
672 EXPECT_EQ(callouts[2].priority, "low");
673 EXPECT_EQ(callouts[2].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500674 EXPECT_EQ(callouts[2].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500675 EXPECT_EQ(callouts[2].symbolicFRU, "");
676 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
677
678 // Find callouts for PROC_NUM 0 that uses the default system entry.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500679 names[0] = "system99";
680
681 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500682 EXPECT_EQ(callouts.size(), 1);
683 EXPECT_EQ(callouts[0].priority, "low");
684 EXPECT_EQ(callouts[0].locCode, "P55");
685 EXPECT_EQ(callouts[0].procedure, "");
686 EXPECT_EQ(callouts[0].symbolicFRU, "");
687 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
688 }
689 {
690 // Find callouts for PROC_NUM 1 that uses a default system entry.
691 std::vector<std::string> adData{"PROC_NUM=1"};
692 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500693 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500694
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500695 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500696 EXPECT_EQ(callouts.size(), 1);
697 EXPECT_EQ(callouts[0].priority, "high");
698 EXPECT_EQ(callouts[0].locCode, "P1-C6");
699 EXPECT_EQ(callouts[0].procedure, "");
700 EXPECT_EQ(callouts[0].symbolicFRU, "");
701 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
702 }
703 {
Matt Spinlerf397afc2021-01-29 11:21:44 -0600704 // There is no entry for PROC_NUM 2, so no callouts
Matt Spinler6b427cc2020-04-09 09:42:59 -0500705 std::vector<std::string> adData{"PROC_NUM=2"};
706 AdditionalData ad{adData};
707
Matt Spinlerf397afc2021-01-29 11:21:44 -0600708 auto callouts = Registry::getCallouts(json, names, ad);
709 EXPECT_TRUE(callouts.empty());
Matt Spinler6b427cc2020-04-09 09:42:59 -0500710 }
711 }
Matt Spinler3d923312022-08-01 09:52:55 -0500712
713 {
714 // Callouts with a 'CalloutsWhenNoADMatch' section that will
715 // be used when the AdditionalData value doesn't match.
716 auto json = R"(
717 {
718 "ADName": "PROC_NUM",
719 "CalloutsWithTheirADValues":
720 [
721 {
722 "ADValue": "0",
723 "Callouts":
724 [
725 {
726 "CalloutList":
727 [
728 {
729 "Priority": "high",
730 "LocCode": "P0-C0"
731 }
732 ]
733 }
734 ]
735 }
736 ],
737 "CalloutsWhenNoADMatch": [
738 {
739 "CalloutList": [
740 {
741 "Priority": "medium",
742 "LocCode": "P1-C1"
743 }
744 ]
745 }
746 ]
747 })"_json;
748
749 // There isn't an entry in the JSON for a PROC_NUM of 8
750 // so it should choose the P1-C1 callout.
751 std::vector<std::string> adData{"PROC_NUM=8"};
752 AdditionalData ad{adData};
753 names.clear();
754
755 auto callouts = Registry::getCallouts(json, names, ad);
756 EXPECT_EQ(callouts.size(), 1);
757 EXPECT_EQ(callouts[0].priority, "medium");
758 EXPECT_EQ(callouts[0].locCode, "P1-C1");
759 }
Matt Spinler6b427cc2020-04-09 09:42:59 -0500760}
Matt Spinler23970b02022-02-25 16:34:46 -0600761
762TEST_F(RegistryTest, TestNoSubsystem)
763{
764 auto path = RegistryTest::writeData(registryData);
765 Registry registry{path};
766
767 auto entry = registry.lookup("xyz.openbmc_project.Common.Error.Timeout",
768 LookupType::name);
769 ASSERT_TRUE(entry);
770 EXPECT_FALSE(entry->subsystem);
771}
Matt Spinler711f1122022-12-15 11:41:20 -0600772
773TEST_F(RegistryTest, TestJournalSectionCapture)
774{
775 auto path = RegistryTest::writeData(registryData);
776 Registry registry{path};
777
778 auto entry = registry.lookup("xyz.openbmc_project.Journal.Capture",
779 LookupType::name);
780 ASSERT_TRUE(entry);
781
782 const auto& jc = entry->journalCapture;
783 ASSERT_TRUE(jc);
784 ASSERT_TRUE(std::holds_alternative<AppCaptureList>(*jc));
785 const auto& acl = std::get<AppCaptureList>(*jc);
786
787 ASSERT_EQ(acl.size(), 2);
788
789 EXPECT_EQ(acl[0].syslogID, "test1");
790 EXPECT_EQ(acl[0].numLines, 5);
791
792 EXPECT_EQ(acl[1].syslogID, "test2");
793 EXPECT_EQ(acl[1].numLines, 6);
794}