blob: b33c07e0bb3eafa29223a0e780a00e22f4a1e3f8 [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 },
89 "DeconfigFlag": true
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +080090 },
91
92 "Documentation":
93 {
94 "Description": "A PGOOD Fault",
95 "Message": "PS %1 had a PGOOD Fault",
96 "MessageArgSources":
97 [
98 "SRCWord6"
99 ],
100 "Notes": [
101 "In the UserData section there is a JSON",
102 "dump that provides debug information."
103 ]
Matt Spinler711f1122022-12-15 11:41:20 -0600104 },
105
106 "JournalCapture":
107 {
108 "NumLines": 7
Matt Spinler367144c2019-09-19 15:33:52 -0500109 }
Matt Spinler23970b02022-02-25 16:34:46 -0600110 },
111
112 {
113 "Name": "xyz.openbmc_project.Common.Error.Timeout",
114 "PossibleSubsystems": ["processor", "memory"],
115
116 "SRC":
117 {
118 "ReasonCode": "0x2030"
119 },
120 "Documentation":
121 {
122 "Description": "A PGOOD Fault",
123 "Message": "PS had a PGOOD Fault"
124 }
Matt Spinler711f1122022-12-15 11:41:20 -0600125 },
126
127 {
128 "Name": "xyz.openbmc_project.Journal.Capture",
129 "Subsystem": "power_supply",
130
131 "SRC":
132 {
133 "ReasonCode": "0x2030"
134 },
135
136 "Documentation":
137 {
138 "Description": "journal capture test",
139 "Message": "journal capture test"
140 },
141
142 "JournalCapture":
143 {
144 "Sections": [
145 {
146 "NumLines": 5,
147 "SyslogID": "test1"
148 },
149 {
150 "NumLines": 6,
151 "SyslogID": "test2"
152 }
153 ]
154 }
Matt Spinler367144c2019-09-19 15:33:52 -0500155 }
156 ]
157}
158)";
159
160class RegistryTest : public ::testing::Test
161{
162 protected:
163 static void SetUpTestCase()
164 {
165 char path[] = "/tmp/regtestXXXXXX";
166 regDir = mkdtemp(path);
167 }
168
169 static void TearDownTestCase()
170 {
171 fs::remove_all(regDir);
172 }
173
174 static std::string writeData(const char* data)
175 {
176 fs::path path = regDir / "registry.json";
177 std::ofstream stream{path};
178 stream << data;
179 return path;
180 }
181
182 static fs::path regDir;
183};
184
185fs::path RegistryTest::regDir{};
186
187TEST_F(RegistryTest, TestNoEntry)
188{
189 auto path = RegistryTest::writeData(registryData);
190 Registry registry{path};
191
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800192 auto entry = registry.lookup("foo", LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500193 EXPECT_FALSE(entry);
194}
195
196TEST_F(RegistryTest, TestFindEntry)
197{
198 auto path = RegistryTest::writeData(registryData);
199 Registry registry{path};
200
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800201 auto entry = registry.lookup("xyz.openbmc_project.Power.OverVoltage",
202 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500203 ASSERT_TRUE(entry);
204 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
205 EXPECT_EQ(entry->subsystem, 0x62);
Matt Spinleraadccc82020-04-10 14:33:42 -0500206
207 ASSERT_EQ(entry->severity->size(), 3);
208 EXPECT_EQ((*entry->severity)[0].severity, 0x40);
209 EXPECT_EQ((*entry->severity)[0].system, "systemA");
210 EXPECT_EQ((*entry->severity)[1].severity, 0x10);
211 EXPECT_EQ((*entry->severity)[1].system, "systemB");
212 EXPECT_EQ((*entry->severity)[2].severity, 0x20);
213 EXPECT_EQ((*entry->severity)[2].system, "");
214
215 EXPECT_EQ(entry->mfgSeverity->size(), 1);
216 EXPECT_EQ((*entry->mfgSeverity)[0].severity, 0x00);
217
Matt Spinlere07f9152019-11-01 10:48:36 -0500218 EXPECT_EQ(*(entry->actionFlags), 0xA800);
Matt Spinler367144c2019-09-19 15:33:52 -0500219 EXPECT_EQ(*(entry->mfgActionFlags), 0x4000);
Matt Spinler93e29322019-09-20 11:16:15 -0500220 EXPECT_EQ(entry->componentID, 0x2300);
Matt Spinler367144c2019-09-19 15:33:52 -0500221 EXPECT_FALSE(entry->eventType);
222 EXPECT_FALSE(entry->eventScope);
223
Matt Spinler93e29322019-09-20 11:16:15 -0500224 EXPECT_EQ(entry->src.type, 0xBD);
225 EXPECT_EQ(entry->src.reasonCode, 0x2333);
Matt Spinler3fe93e92023-04-14 14:06:59 -0500226 EXPECT_TRUE(entry->src.deconfigFlag);
Matt Spinler93e29322019-09-20 11:16:15 -0500227
228 auto& hexwords = entry->src.hexwordADFields;
229 EXPECT_TRUE(hexwords);
230 EXPECT_EQ((*hexwords).size(), 2);
231
232 auto word = (*hexwords).find(6);
233 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800234 EXPECT_EQ(std::get<0>(word->second), "PS_NUM");
Matt Spinler93e29322019-09-20 11:16:15 -0500235
236 word = (*hexwords).find(7);
237 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800238 EXPECT_EQ(std::get<0>(word->second), "VOLTAGE");
Matt Spinler93e29322019-09-20 11:16:15 -0500239
240 auto& sid = entry->src.symptomID;
241 EXPECT_TRUE(sid);
242 EXPECT_EQ((*sid).size(), 3);
243 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 5), (*sid).end());
244 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 6), (*sid).end());
245 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 7), (*sid).end());
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800246
247 EXPECT_EQ(entry->doc.description, "A PGOOD Fault");
248 EXPECT_EQ(entry->doc.message, "PS %1 had a PGOOD Fault");
249 auto& hexwordSource = entry->doc.messageArgSources;
250 EXPECT_TRUE(hexwordSource);
251 EXPECT_EQ((*hexwordSource).size(), 1);
252 EXPECT_EQ((*hexwordSource).front(), "SRCWord6");
253
Matt Spinler711f1122022-12-15 11:41:20 -0600254 const auto& jc = entry->journalCapture;
255 ASSERT_TRUE(jc);
256 ASSERT_TRUE(std::holds_alternative<size_t>(*jc));
257 EXPECT_EQ(std::get<size_t>(*jc), 7);
258
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800259 entry = registry.lookup("0x2333", LookupType::reasonCode);
260 ASSERT_TRUE(entry);
261 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
Matt Spinler367144c2019-09-19 15:33:52 -0500262}
263
264// Check the entry that mostly uses defaults
265TEST_F(RegistryTest, TestFindEntryMinimal)
266{
267 auto path = RegistryTest::writeData(registryData);
268 Registry registry{path};
269
Patrick Williams2544b412022-10-04 08:41:06 -0500270 auto entry = registry.lookup("xyz.openbmc_project.Power.Fault",
271 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500272 ASSERT_TRUE(entry);
273 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.Fault");
274 EXPECT_EQ(entry->subsystem, 0x61);
275 EXPECT_FALSE(entry->severity);
276 EXPECT_FALSE(entry->mfgSeverity);
277 EXPECT_FALSE(entry->mfgActionFlags);
Matt Spinlere07f9152019-11-01 10:48:36 -0500278 EXPECT_FALSE(entry->actionFlags);
Matt Spinler93e29322019-09-20 11:16:15 -0500279 EXPECT_EQ(entry->componentID, 0x2000);
Matt Spinler367144c2019-09-19 15:33:52 -0500280 EXPECT_FALSE(entry->eventType);
281 EXPECT_FALSE(entry->eventScope);
Matt Spinler93e29322019-09-20 11:16:15 -0500282
283 EXPECT_EQ(entry->src.reasonCode, 0x2030);
284 EXPECT_EQ(entry->src.type, 0xBD);
Matt Spinler93e29322019-09-20 11:16:15 -0500285 EXPECT_FALSE(entry->src.hexwordADFields);
286 EXPECT_FALSE(entry->src.symptomID);
Matt Spinler3fe93e92023-04-14 14:06:59 -0500287 EXPECT_FALSE(entry->src.deconfigFlag);
Matt Spinler367144c2019-09-19 15:33:52 -0500288}
289
290TEST_F(RegistryTest, TestBadJSON)
291{
292 auto path = RegistryTest::writeData("bad {} json");
293
294 Registry registry{path};
295
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800296 EXPECT_FALSE(registry.lookup("foo", LookupType::name));
Matt Spinler367144c2019-09-19 15:33:52 -0500297}
298
299// Test the helper functions the use the pel_values data.
300TEST_F(RegistryTest, TestHelperFunctions)
301{
302 using namespace openpower::pels::message::helper;
303 EXPECT_EQ(getSubsystem("input_power_source"), 0xA1);
304 EXPECT_THROW(getSubsystem("foo"), std::runtime_error);
305
306 EXPECT_EQ(getSeverity("symptom_recovered"), 0x71);
307 EXPECT_THROW(getSeverity("foo"), std::runtime_error);
308
309 EXPECT_EQ(getEventType("dump_notification"), 0x08);
310 EXPECT_THROW(getEventType("foo"), std::runtime_error);
311
312 EXPECT_EQ(getEventScope("possibly_multiple_platforms"), 0x04);
313 EXPECT_THROW(getEventScope("foo"), std::runtime_error);
314
315 std::vector<std::string> flags{"service_action", "dont_report",
316 "termination"};
317 EXPECT_EQ(getActionFlags(flags), 0x9100);
318
319 flags.clear();
320 flags.push_back("foo");
321 EXPECT_THROW(getActionFlags(flags), std::runtime_error);
322}
Matt Spinler93e29322019-09-20 11:16:15 -0500323
324TEST_F(RegistryTest, TestGetSRCReasonCode)
325{
326 using namespace openpower::pels::message::helper;
327 EXPECT_EQ(getSRCReasonCode(R"({"ReasonCode": "0x5555"})"_json, "foo"),
328 0x5555);
329
330 EXPECT_THROW(getSRCReasonCode(R"({"ReasonCode": "ZZZZ"})"_json, "foo"),
331 std::runtime_error);
332}
333
334TEST_F(RegistryTest, TestGetSRCType)
335{
336 using namespace openpower::pels::message::helper;
337 EXPECT_EQ(getSRCType(R"({"Type": "11"})"_json, "foo"), 0x11);
338 EXPECT_EQ(getSRCType(R"({"Type": "BF"})"_json, "foo"), 0xBF);
339
340 EXPECT_THROW(getSRCType(R"({"Type": "1"})"_json, "foo"),
341 std::runtime_error);
342
343 EXPECT_THROW(getSRCType(R"({"Type": "111"})"_json, "foo"),
344 std::runtime_error);
345}
346
347TEST_F(RegistryTest, TestGetSRCHexwordFields)
348{
349 using namespace openpower::pels::message::helper;
350 const auto hexwords = R"(
351 {"Words6To9":
352 {
353 "8":
354 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800355 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500356 "AdditionalDataPropSource": "TEST"
357 }
358 }
359 })"_json;
360
361 auto fields = getSRCHexwordFields(hexwords, "foo");
362 EXPECT_TRUE(fields);
363 auto word = fields->find(8);
364 EXPECT_NE(word, fields->end());
365
366 const auto theInvalidRWord = R"(
367 {"Words6To9":
368 {
369 "R":
370 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800371 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500372 "AdditionalDataPropSource": "TEST"
373 }
374 }
375 })"_json;
376
377 EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"),
378 std::runtime_error);
379}
380
381TEST_F(RegistryTest, TestGetSRCSymptomIDFields)
382{
383 using namespace openpower::pels::message::helper;
384 const auto sID = R"(
385 {
386 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord5"]
387 })"_json;
388
389 auto fields = getSRCSymptomIDFields(sID, "foo");
390 EXPECT_NE(std::find(fields->begin(), fields->end(), 3), fields->end());
391 EXPECT_NE(std::find(fields->begin(), fields->end(), 4), fields->end());
392 EXPECT_NE(std::find(fields->begin(), fields->end(), 5), fields->end());
393
394 const auto badField = R"(
395 {
396 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord"]
397 })"_json;
398
399 EXPECT_THROW(getSRCSymptomIDFields(badField, "foo"), std::runtime_error);
400}
401
402TEST_F(RegistryTest, TestGetComponentID)
403{
404 using namespace openpower::pels::message::helper;
405
406 // Get it from the JSON
Patrick Williams2544b412022-10-04 08:41:06 -0500407 auto id = getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json,
408 "foo");
Matt Spinler93e29322019-09-20 11:16:15 -0500409 EXPECT_EQ(id, 0x4200);
410
411 // Get it from the reason code on a 0xBD SRC
412 id = getComponentID(0xBD, 0x6700, R"({})"_json, "foo");
413 EXPECT_EQ(id, 0x6700);
414
415 // Not present on a 0x11 SRC
416 EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"),
417 std::runtime_error);
418}
Matt Spinler6b427cc2020-04-09 09:42:59 -0500419
420// Test when callouts are in the JSON.
421TEST_F(RegistryTest, TestGetCallouts)
422{
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500423 std::vector<std::string> names;
424
Matt Spinler6b427cc2020-04-09 09:42:59 -0500425 {
426 // Callouts without AD, that depend on system type,
427 // where there is a default entry without a system type.
428 auto json = R"(
429 [
430 {
431 "System": "system1",
432 "CalloutList":
433 [
434 {
435 "Priority": "high",
436 "LocCode": "P1-C1"
437 },
438 {
439 "Priority": "low",
440 "LocCode": "P1"
441 },
442 {
443 "Priority": "low",
444 "SymbolicFRU": "service_docs"
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500445 },
446 {
447 "Priority": "low",
448 "SymbolicFRUTrusted": "air_mover",
449 "UseInventoryLocCode": true
Matt Spinler6b427cc2020-04-09 09:42:59 -0500450 }
451 ]
452 },
453 {
454 "CalloutList":
455 [
456 {
457 "Priority": "medium",
Matt Spinler479b6922021-08-17 16:34:59 -0500458 "Procedure": "bmc_code"
Matt Spinler6b427cc2020-04-09 09:42:59 -0500459 },
460 {
461 "Priority": "low",
462 "LocCode": "P3-C8",
463 "SymbolicFRUTrusted": "service_docs"
464 }
465 ]
466
467 }
468 ])"_json;
469
470 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500471 names.push_back("system1");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500472
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500473 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500474 EXPECT_EQ(callouts.size(), 4);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500475 EXPECT_EQ(callouts[0].priority, "high");
476 EXPECT_EQ(callouts[0].locCode, "P1-C1");
477 EXPECT_EQ(callouts[0].procedure, "");
478 EXPECT_EQ(callouts[0].symbolicFRU, "");
479 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
480 EXPECT_EQ(callouts[1].priority, "low");
481 EXPECT_EQ(callouts[1].locCode, "P1");
482 EXPECT_EQ(callouts[1].procedure, "");
483 EXPECT_EQ(callouts[1].symbolicFRU, "");
484 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
485 EXPECT_EQ(callouts[2].priority, "low");
486 EXPECT_EQ(callouts[2].locCode, "");
487 EXPECT_EQ(callouts[2].procedure, "");
488 EXPECT_EQ(callouts[2].symbolicFRU, "service_docs");
489 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500490 EXPECT_EQ(callouts[3].priority, "low");
491 EXPECT_EQ(callouts[3].locCode, "");
492 EXPECT_EQ(callouts[3].procedure, "");
493 EXPECT_EQ(callouts[3].symbolicFRU, "");
494 EXPECT_EQ(callouts[3].symbolicFRUTrusted, "air_mover");
495 EXPECT_EQ(callouts[3].useInventoryLocCode, true);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500496
497 // system2 isn't in the JSON, so it will pick the default one
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500498 names[0] = "system2";
499 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500500 EXPECT_EQ(callouts.size(), 2);
501 EXPECT_EQ(callouts[0].priority, "medium");
502 EXPECT_EQ(callouts[0].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500503 EXPECT_EQ(callouts[0].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500504 EXPECT_EQ(callouts[0].symbolicFRU, "");
505 EXPECT_EQ(callouts[1].priority, "low");
506 EXPECT_EQ(callouts[1].locCode, "P3-C8");
507 EXPECT_EQ(callouts[1].procedure, "");
508 EXPECT_EQ(callouts[1].symbolicFRU, "");
509 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "service_docs");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500510 EXPECT_EQ(callouts[1].useInventoryLocCode, false);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500511 }
512
513 // Empty JSON array (treated as an error)
514 {
515 auto json = R"([])"_json;
516 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500517 names[0] = "system1";
518 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500519 std::runtime_error);
520 }
521
522 {
523 // Callouts without AD, that depend on system type,
524 // where there isn't a default entry without a system type.
525 auto json = R"(
526 [
527 {
528 "System": "system1",
529 "CalloutList":
530 [
531 {
532 "Priority": "high",
533 "LocCode": "P1-C1"
534 },
535 {
536 "Priority": "low",
537 "LocCode": "P1",
538 "SymbolicFRU": "1234567"
539 }
540 ]
541 },
542 {
543 "System": "system2",
544 "CalloutList":
545 [
546 {
547 "Priority": "medium",
548 "LocCode": "P7",
549 "CalloutType": "tool_fru"
550 }
551 ]
552
553 }
554 ])"_json;
555
556 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500557 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500558
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500559 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500560 EXPECT_EQ(callouts.size(), 2);
561 EXPECT_EQ(callouts[0].priority, "high");
562 EXPECT_EQ(callouts[0].locCode, "P1-C1");
563 EXPECT_EQ(callouts[0].procedure, "");
564 EXPECT_EQ(callouts[0].symbolicFRU, "");
565 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
566 EXPECT_EQ(callouts[1].priority, "low");
567 EXPECT_EQ(callouts[1].locCode, "P1");
568 EXPECT_EQ(callouts[1].procedure, "");
569 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
570 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
571
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500572 names[0] = "system2";
573 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500574 EXPECT_EQ(callouts.size(), 1);
575 EXPECT_EQ(callouts[0].priority, "medium");
576 EXPECT_EQ(callouts[0].locCode, "P7");
577 EXPECT_EQ(callouts[0].procedure, "");
578 EXPECT_EQ(callouts[0].symbolicFRU, "");
579 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
580
581 // There is no entry for system3 or a default system,
582 // so this should fail.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500583 names[0] = "system3";
584 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500585 std::runtime_error);
586 }
587
588 {
589 // Callouts that use the AdditionalData key PROC_NUM
590 // as an index into them, along with a system type.
591 // It supports PROC_NUMs 0 and 1.
592 auto json = R"(
593 {
594 "ADName": "PROC_NUM",
595 "CalloutsWithTheirADValues":
596 [
597 {
598 "ADValue": "0",
599 "Callouts":
600 [
601 {
602 "System": "system3",
603 "CalloutList":
604 [
605 {
606 "Priority": "high",
607 "LocCode": "P1-C5"
608 },
609 {
610 "Priority": "medium",
611 "LocCode": "P1-C6",
612 "SymbolicFRU": "1234567"
613 },
614 {
615 "Priority": "low",
Matt Spinler479b6922021-08-17 16:34:59 -0500616 "Procedure": "bmc_code",
Matt Spinler6b427cc2020-04-09 09:42:59 -0500617 "CalloutType": "config_procedure"
618 }
619 ]
620 },
621 {
622 "CalloutList":
623 [
624 {
625 "Priority": "low",
626 "LocCode": "P55"
627 }
628 ]
629 }
630 ]
631 },
632 {
633 "ADValue": "1",
634 "Callouts":
635 [
636 {
637 "CalloutList":
638 [
639 {
640 "Priority": "high",
641 "LocCode": "P1-C6",
642 "CalloutType": "external_fru"
643 }
644 ]
645 }
646 ]
647 }
648 ]
649 })"_json;
650
651 {
652 // Find callouts for PROC_NUM 0 on system3
653 std::vector<std::string> adData{"PROC_NUM=0"};
654 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500655 names[0] = "system3";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500656
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500657 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500658 EXPECT_EQ(callouts.size(), 3);
659 EXPECT_EQ(callouts[0].priority, "high");
660 EXPECT_EQ(callouts[0].locCode, "P1-C5");
661 EXPECT_EQ(callouts[0].procedure, "");
662 EXPECT_EQ(callouts[0].symbolicFRU, "");
663 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
664 EXPECT_EQ(callouts[1].priority, "medium");
665 EXPECT_EQ(callouts[1].locCode, "P1-C6");
666 EXPECT_EQ(callouts[1].procedure, "");
667 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
668 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
669 EXPECT_EQ(callouts[2].priority, "low");
670 EXPECT_EQ(callouts[2].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500671 EXPECT_EQ(callouts[2].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500672 EXPECT_EQ(callouts[2].symbolicFRU, "");
673 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
674
675 // Find callouts for PROC_NUM 0 that uses the default system entry.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500676 names[0] = "system99";
677
678 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500679 EXPECT_EQ(callouts.size(), 1);
680 EXPECT_EQ(callouts[0].priority, "low");
681 EXPECT_EQ(callouts[0].locCode, "P55");
682 EXPECT_EQ(callouts[0].procedure, "");
683 EXPECT_EQ(callouts[0].symbolicFRU, "");
684 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
685 }
686 {
687 // Find callouts for PROC_NUM 1 that uses a default system entry.
688 std::vector<std::string> adData{"PROC_NUM=1"};
689 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500690 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500691
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500692 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500693 EXPECT_EQ(callouts.size(), 1);
694 EXPECT_EQ(callouts[0].priority, "high");
695 EXPECT_EQ(callouts[0].locCode, "P1-C6");
696 EXPECT_EQ(callouts[0].procedure, "");
697 EXPECT_EQ(callouts[0].symbolicFRU, "");
698 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
699 }
700 {
Matt Spinlerf397afc2021-01-29 11:21:44 -0600701 // There is no entry for PROC_NUM 2, so no callouts
Matt Spinler6b427cc2020-04-09 09:42:59 -0500702 std::vector<std::string> adData{"PROC_NUM=2"};
703 AdditionalData ad{adData};
704
Matt Spinlerf397afc2021-01-29 11:21:44 -0600705 auto callouts = Registry::getCallouts(json, names, ad);
706 EXPECT_TRUE(callouts.empty());
Matt Spinler6b427cc2020-04-09 09:42:59 -0500707 }
708 }
Matt Spinler3d923312022-08-01 09:52:55 -0500709
710 {
711 // Callouts with a 'CalloutsWhenNoADMatch' section that will
712 // be used when the AdditionalData value doesn't match.
713 auto json = R"(
714 {
715 "ADName": "PROC_NUM",
716 "CalloutsWithTheirADValues":
717 [
718 {
719 "ADValue": "0",
720 "Callouts":
721 [
722 {
723 "CalloutList":
724 [
725 {
726 "Priority": "high",
727 "LocCode": "P0-C0"
728 }
729 ]
730 }
731 ]
732 }
733 ],
734 "CalloutsWhenNoADMatch": [
735 {
736 "CalloutList": [
737 {
738 "Priority": "medium",
739 "LocCode": "P1-C1"
740 }
741 ]
742 }
743 ]
744 })"_json;
745
746 // There isn't an entry in the JSON for a PROC_NUM of 8
747 // so it should choose the P1-C1 callout.
748 std::vector<std::string> adData{"PROC_NUM=8"};
749 AdditionalData ad{adData};
750 names.clear();
751
752 auto callouts = Registry::getCallouts(json, names, ad);
753 EXPECT_EQ(callouts.size(), 1);
754 EXPECT_EQ(callouts[0].priority, "medium");
755 EXPECT_EQ(callouts[0].locCode, "P1-C1");
756 }
Matt Spinler6b427cc2020-04-09 09:42:59 -0500757}
Matt Spinler23970b02022-02-25 16:34:46 -0600758
759TEST_F(RegistryTest, TestNoSubsystem)
760{
761 auto path = RegistryTest::writeData(registryData);
762 Registry registry{path};
763
764 auto entry = registry.lookup("xyz.openbmc_project.Common.Error.Timeout",
765 LookupType::name);
766 ASSERT_TRUE(entry);
767 EXPECT_FALSE(entry->subsystem);
768}
Matt Spinler711f1122022-12-15 11:41:20 -0600769
770TEST_F(RegistryTest, TestJournalSectionCapture)
771{
772 auto path = RegistryTest::writeData(registryData);
773 Registry registry{path};
774
775 auto entry = registry.lookup("xyz.openbmc_project.Journal.Capture",
776 LookupType::name);
777 ASSERT_TRUE(entry);
778
779 const auto& jc = entry->journalCapture;
780 ASSERT_TRUE(jc);
781 ASSERT_TRUE(std::holds_alternative<AppCaptureList>(*jc));
782 const auto& acl = std::get<AppCaptureList>(*jc);
783
784 ASSERT_EQ(acl.size(), 2);
785
786 EXPECT_EQ(acl[0].syslogID, "test1");
787 EXPECT_EQ(acl[0].numLines, 5);
788
789 EXPECT_EQ(acl[1].syslogID, "test2");
790 EXPECT_EQ(acl[1].numLines, 6);
791}