blob: 12a205f27d279e896e5a88a24c7fce0cabf95ce1 [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 }
88 }
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +080089 },
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 ]
Matt Spinler711f1122022-12-15 11:41:20 -0600103 },
104
105 "JournalCapture":
106 {
107 "NumLines": 7
Matt Spinler367144c2019-09-19 15:33:52 -0500108 }
Matt Spinler23970b02022-02-25 16:34:46 -0600109 },
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 }
Matt Spinler711f1122022-12-15 11:41:20 -0600124 },
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 }
Matt Spinler367144c2019-09-19 15:33:52 -0500154 }
155 ]
156}
157)";
158
159class 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
184fs::path RegistryTest::regDir{};
185
186TEST_F(RegistryTest, TestNoEntry)
187{
188 auto path = RegistryTest::writeData(registryData);
189 Registry registry{path};
190
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800191 auto entry = registry.lookup("foo", LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500192 EXPECT_FALSE(entry);
193}
194
195TEST_F(RegistryTest, TestFindEntry)
196{
197 auto path = RegistryTest::writeData(registryData);
198 Registry registry{path};
199
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800200 auto entry = registry.lookup("xyz.openbmc_project.Power.OverVoltage",
201 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500202 ASSERT_TRUE(entry);
203 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
204 EXPECT_EQ(entry->subsystem, 0x62);
Matt Spinleraadccc82020-04-10 14:33:42 -0500205
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
Matt Spinlere07f9152019-11-01 10:48:36 -0500217 EXPECT_EQ(*(entry->actionFlags), 0xA800);
Matt Spinler367144c2019-09-19 15:33:52 -0500218 EXPECT_EQ(*(entry->mfgActionFlags), 0x4000);
Matt Spinler93e29322019-09-20 11:16:15 -0500219 EXPECT_EQ(entry->componentID, 0x2300);
Matt Spinler367144c2019-09-19 15:33:52 -0500220 EXPECT_FALSE(entry->eventType);
221 EXPECT_FALSE(entry->eventScope);
222
Matt Spinler93e29322019-09-20 11:16:15 -0500223 EXPECT_EQ(entry->src.type, 0xBD);
224 EXPECT_EQ(entry->src.reasonCode, 0x2333);
Matt Spinler93e29322019-09-20 11:16:15 -0500225
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());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800232 EXPECT_EQ(std::get<0>(word->second), "PS_NUM");
Matt Spinler93e29322019-09-20 11:16:15 -0500233
234 word = (*hexwords).find(7);
235 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800236 EXPECT_EQ(std::get<0>(word->second), "VOLTAGE");
Matt Spinler93e29322019-09-20 11:16:15 -0500237
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());
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800244
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
Matt Spinler711f1122022-12-15 11:41:20 -0600252 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
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800257 entry = registry.lookup("0x2333", LookupType::reasonCode);
258 ASSERT_TRUE(entry);
259 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
Matt Spinler367144c2019-09-19 15:33:52 -0500260}
261
262// Check the entry that mostly uses defaults
263TEST_F(RegistryTest, TestFindEntryMinimal)
264{
265 auto path = RegistryTest::writeData(registryData);
266 Registry registry{path};
267
Patrick Williams2544b412022-10-04 08:41:06 -0500268 auto entry = registry.lookup("xyz.openbmc_project.Power.Fault",
269 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500270 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);
Matt Spinlere07f9152019-11-01 10:48:36 -0500276 EXPECT_FALSE(entry->actionFlags);
Matt Spinler93e29322019-09-20 11:16:15 -0500277 EXPECT_EQ(entry->componentID, 0x2000);
Matt Spinler367144c2019-09-19 15:33:52 -0500278 EXPECT_FALSE(entry->eventType);
279 EXPECT_FALSE(entry->eventScope);
Matt Spinler93e29322019-09-20 11:16:15 -0500280
281 EXPECT_EQ(entry->src.reasonCode, 0x2030);
282 EXPECT_EQ(entry->src.type, 0xBD);
Matt Spinler93e29322019-09-20 11:16:15 -0500283 EXPECT_FALSE(entry->src.hexwordADFields);
284 EXPECT_FALSE(entry->src.symptomID);
Matt Spinler367144c2019-09-19 15:33:52 -0500285}
286
287TEST_F(RegistryTest, TestBadJSON)
288{
289 auto path = RegistryTest::writeData("bad {} json");
290
291 Registry registry{path};
292
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800293 EXPECT_FALSE(registry.lookup("foo", LookupType::name));
Matt Spinler367144c2019-09-19 15:33:52 -0500294}
295
296// Test the helper functions the use the pel_values data.
297TEST_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}
Matt Spinler93e29322019-09-20 11:16:15 -0500320
321TEST_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
331TEST_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
344TEST_F(RegistryTest, TestGetSRCHexwordFields)
345{
346 using namespace openpower::pels::message::helper;
347 const auto hexwords = R"(
348 {"Words6To9":
349 {
350 "8":
351 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800352 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500353 "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 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800368 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500369 "AdditionalDataPropSource": "TEST"
370 }
371 }
372 })"_json;
373
374 EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"),
375 std::runtime_error);
376}
377
378TEST_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
399TEST_F(RegistryTest, TestGetComponentID)
400{
401 using namespace openpower::pels::message::helper;
402
403 // Get it from the JSON
Patrick Williams2544b412022-10-04 08:41:06 -0500404 auto id = getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json,
405 "foo");
Matt Spinler93e29322019-09-20 11:16:15 -0500406 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}
Matt Spinler6b427cc2020-04-09 09:42:59 -0500416
417// Test when callouts are in the JSON.
418TEST_F(RegistryTest, TestGetCallouts)
419{
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500420 std::vector<std::string> names;
421
Matt Spinler6b427cc2020-04-09 09:42:59 -0500422 {
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"
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500442 },
443 {
444 "Priority": "low",
445 "SymbolicFRUTrusted": "air_mover",
446 "UseInventoryLocCode": true
Matt Spinler6b427cc2020-04-09 09:42:59 -0500447 }
448 ]
449 },
450 {
451 "CalloutList":
452 [
453 {
454 "Priority": "medium",
Matt Spinler479b6922021-08-17 16:34:59 -0500455 "Procedure": "bmc_code"
Matt Spinler6b427cc2020-04-09 09:42:59 -0500456 },
457 {
458 "Priority": "low",
459 "LocCode": "P3-C8",
460 "SymbolicFRUTrusted": "service_docs"
461 }
462 ]
463
464 }
465 ])"_json;
466
467 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500468 names.push_back("system1");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500469
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500470 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500471 EXPECT_EQ(callouts.size(), 4);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500472 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, "");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500487 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);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500493
494 // system2 isn't in the JSON, so it will pick the default one
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500495 names[0] = "system2";
496 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500497 EXPECT_EQ(callouts.size(), 2);
498 EXPECT_EQ(callouts[0].priority, "medium");
499 EXPECT_EQ(callouts[0].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500500 EXPECT_EQ(callouts[0].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500501 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");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500507 EXPECT_EQ(callouts[1].useInventoryLocCode, false);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500508 }
509
510 // Empty JSON array (treated as an error)
511 {
512 auto json = R"([])"_json;
513 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500514 names[0] = "system1";
515 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500516 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;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500554 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500555
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500556 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500557 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
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500569 names[0] = "system2";
570 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500571 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.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500580 names[0] = "system3";
581 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500582 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",
Matt Spinler479b6922021-08-17 16:34:59 -0500613 "Procedure": "bmc_code",
Matt Spinler6b427cc2020-04-09 09:42:59 -0500614 "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};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500652 names[0] = "system3";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500653
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500654 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500655 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, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500668 EXPECT_EQ(callouts[2].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500669 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.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500673 names[0] = "system99";
674
675 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500676 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};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500687 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500688
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500689 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500690 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 {
Matt Spinlerf397afc2021-01-29 11:21:44 -0600698 // There is no entry for PROC_NUM 2, so no callouts
Matt Spinler6b427cc2020-04-09 09:42:59 -0500699 std::vector<std::string> adData{"PROC_NUM=2"};
700 AdditionalData ad{adData};
701
Matt Spinlerf397afc2021-01-29 11:21:44 -0600702 auto callouts = Registry::getCallouts(json, names, ad);
703 EXPECT_TRUE(callouts.empty());
Matt Spinler6b427cc2020-04-09 09:42:59 -0500704 }
705 }
Matt Spinler3d923312022-08-01 09:52:55 -0500706
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 }
Matt Spinler6b427cc2020-04-09 09:42:59 -0500754}
Matt Spinler23970b02022-02-25 16:34:46 -0600755
756TEST_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}
Matt Spinler711f1122022-12-15 11:41:20 -0600766
767TEST_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}