blob: 5cfd5e583da24df75aba8ee8e523c6b0271c6aee [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
18#include <filesystem>
19#include <fstream>
20#include <nlohmann/json.hpp>
21
22#include <gtest/gtest.h>
23
24using namespace openpower::pels::message;
Matt Spinler6b427cc2020-04-09 09:42:59 -050025using namespace openpower::pels;
Matt Spinler367144c2019-09-19 15:33:52 -050026namespace fs = std::filesystem;
27
28const auto registryData = R"(
29{
30 "PELs":
31 [
32 {
33 "Name": "xyz.openbmc_project.Power.Fault",
34 "Subsystem": "power_supply",
Matt Spinler367144c2019-09-19 15:33:52 -050035
36 "SRC":
37 {
38 "ReasonCode": "0x2030"
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +080039 },
40
41 "Documentation":
42 {
43 "Description": "A PGOOD Fault",
44 "Message": "PS had a PGOOD Fault"
Matt Spinler367144c2019-09-19 15:33:52 -050045 }
46 },
47
48 {
49 "Name": "xyz.openbmc_project.Power.OverVoltage",
50 "Subsystem": "power_control_hw",
Matt Spinleraadccc82020-04-10 14:33:42 -050051 "Severity":
52 [
53 {
54 "System": "systemA",
55 "SevValue": "unrecoverable"
56 },
57 {
58 "System": "systemB",
59 "SevValue": "recovered"
60 },
61 {
62 "SevValue": "predictive"
63 }
64 ],
Matt Spinler367144c2019-09-19 15:33:52 -050065 "MfgSeverity": "non_error",
66 "ActionFlags": ["service_action", "report", "call_home"],
67 "MfgActionFlags": ["hidden"],
68
69 "SRC":
70 {
71 "ReasonCode": "0x2333",
72 "Type": "BD",
73 "SymptomIDFields": ["SRCWord5", "SRCWord6", "SRCWord7"],
74 "PowerFault": true,
75 "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 Spinler367144c2019-09-19 15:33:52 -0500103 }
Matt Spinler23970b02022-02-25 16:34:46 -0600104 },
105
106 {
107 "Name": "xyz.openbmc_project.Common.Error.Timeout",
108 "PossibleSubsystems": ["processor", "memory"],
109
110 "SRC":
111 {
112 "ReasonCode": "0x2030"
113 },
114 "Documentation":
115 {
116 "Description": "A PGOOD Fault",
117 "Message": "PS had a PGOOD Fault"
118 }
Matt Spinler367144c2019-09-19 15:33:52 -0500119 }
120 ]
121}
122)";
123
124class RegistryTest : public ::testing::Test
125{
126 protected:
127 static void SetUpTestCase()
128 {
129 char path[] = "/tmp/regtestXXXXXX";
130 regDir = mkdtemp(path);
131 }
132
133 static void TearDownTestCase()
134 {
135 fs::remove_all(regDir);
136 }
137
138 static std::string writeData(const char* data)
139 {
140 fs::path path = regDir / "registry.json";
141 std::ofstream stream{path};
142 stream << data;
143 return path;
144 }
145
146 static fs::path regDir;
147};
148
149fs::path RegistryTest::regDir{};
150
151TEST_F(RegistryTest, TestNoEntry)
152{
153 auto path = RegistryTest::writeData(registryData);
154 Registry registry{path};
155
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800156 auto entry = registry.lookup("foo", LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500157 EXPECT_FALSE(entry);
158}
159
160TEST_F(RegistryTest, TestFindEntry)
161{
162 auto path = RegistryTest::writeData(registryData);
163 Registry registry{path};
164
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800165 auto entry = registry.lookup("xyz.openbmc_project.Power.OverVoltage",
166 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500167 ASSERT_TRUE(entry);
168 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
169 EXPECT_EQ(entry->subsystem, 0x62);
Matt Spinleraadccc82020-04-10 14:33:42 -0500170
171 ASSERT_EQ(entry->severity->size(), 3);
172 EXPECT_EQ((*entry->severity)[0].severity, 0x40);
173 EXPECT_EQ((*entry->severity)[0].system, "systemA");
174 EXPECT_EQ((*entry->severity)[1].severity, 0x10);
175 EXPECT_EQ((*entry->severity)[1].system, "systemB");
176 EXPECT_EQ((*entry->severity)[2].severity, 0x20);
177 EXPECT_EQ((*entry->severity)[2].system, "");
178
179 EXPECT_EQ(entry->mfgSeverity->size(), 1);
180 EXPECT_EQ((*entry->mfgSeverity)[0].severity, 0x00);
181
Matt Spinlere07f9152019-11-01 10:48:36 -0500182 EXPECT_EQ(*(entry->actionFlags), 0xA800);
Matt Spinler367144c2019-09-19 15:33:52 -0500183 EXPECT_EQ(*(entry->mfgActionFlags), 0x4000);
Matt Spinler93e29322019-09-20 11:16:15 -0500184 EXPECT_EQ(entry->componentID, 0x2300);
Matt Spinler367144c2019-09-19 15:33:52 -0500185 EXPECT_FALSE(entry->eventType);
186 EXPECT_FALSE(entry->eventScope);
187
Matt Spinler93e29322019-09-20 11:16:15 -0500188 EXPECT_EQ(entry->src.type, 0xBD);
189 EXPECT_EQ(entry->src.reasonCode, 0x2333);
190 EXPECT_EQ(*(entry->src.powerFault), true);
191
192 auto& hexwords = entry->src.hexwordADFields;
193 EXPECT_TRUE(hexwords);
194 EXPECT_EQ((*hexwords).size(), 2);
195
196 auto word = (*hexwords).find(6);
197 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800198 EXPECT_EQ(std::get<0>(word->second), "PS_NUM");
Matt Spinler93e29322019-09-20 11:16:15 -0500199
200 word = (*hexwords).find(7);
201 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800202 EXPECT_EQ(std::get<0>(word->second), "VOLTAGE");
Matt Spinler93e29322019-09-20 11:16:15 -0500203
204 auto& sid = entry->src.symptomID;
205 EXPECT_TRUE(sid);
206 EXPECT_EQ((*sid).size(), 3);
207 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 5), (*sid).end());
208 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 6), (*sid).end());
209 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 7), (*sid).end());
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800210
211 EXPECT_EQ(entry->doc.description, "A PGOOD Fault");
212 EXPECT_EQ(entry->doc.message, "PS %1 had a PGOOD Fault");
213 auto& hexwordSource = entry->doc.messageArgSources;
214 EXPECT_TRUE(hexwordSource);
215 EXPECT_EQ((*hexwordSource).size(), 1);
216 EXPECT_EQ((*hexwordSource).front(), "SRCWord6");
217
218 entry = registry.lookup("0x2333", LookupType::reasonCode);
219 ASSERT_TRUE(entry);
220 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
Matt Spinler367144c2019-09-19 15:33:52 -0500221}
222
223// Check the entry that mostly uses defaults
224TEST_F(RegistryTest, TestFindEntryMinimal)
225{
226 auto path = RegistryTest::writeData(registryData);
227 Registry registry{path};
228
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800229 auto entry =
230 registry.lookup("xyz.openbmc_project.Power.Fault", LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500231 ASSERT_TRUE(entry);
232 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.Fault");
233 EXPECT_EQ(entry->subsystem, 0x61);
234 EXPECT_FALSE(entry->severity);
235 EXPECT_FALSE(entry->mfgSeverity);
236 EXPECT_FALSE(entry->mfgActionFlags);
Matt Spinlere07f9152019-11-01 10:48:36 -0500237 EXPECT_FALSE(entry->actionFlags);
Matt Spinler93e29322019-09-20 11:16:15 -0500238 EXPECT_EQ(entry->componentID, 0x2000);
Matt Spinler367144c2019-09-19 15:33:52 -0500239 EXPECT_FALSE(entry->eventType);
240 EXPECT_FALSE(entry->eventScope);
Matt Spinler93e29322019-09-20 11:16:15 -0500241
242 EXPECT_EQ(entry->src.reasonCode, 0x2030);
243 EXPECT_EQ(entry->src.type, 0xBD);
244 EXPECT_FALSE(entry->src.powerFault);
245 EXPECT_FALSE(entry->src.hexwordADFields);
246 EXPECT_FALSE(entry->src.symptomID);
Matt Spinler367144c2019-09-19 15:33:52 -0500247}
248
249TEST_F(RegistryTest, TestBadJSON)
250{
251 auto path = RegistryTest::writeData("bad {} json");
252
253 Registry registry{path};
254
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800255 EXPECT_FALSE(registry.lookup("foo", LookupType::name));
Matt Spinler367144c2019-09-19 15:33:52 -0500256}
257
258// Test the helper functions the use the pel_values data.
259TEST_F(RegistryTest, TestHelperFunctions)
260{
261 using namespace openpower::pels::message::helper;
262 EXPECT_EQ(getSubsystem("input_power_source"), 0xA1);
263 EXPECT_THROW(getSubsystem("foo"), std::runtime_error);
264
265 EXPECT_EQ(getSeverity("symptom_recovered"), 0x71);
266 EXPECT_THROW(getSeverity("foo"), std::runtime_error);
267
268 EXPECT_EQ(getEventType("dump_notification"), 0x08);
269 EXPECT_THROW(getEventType("foo"), std::runtime_error);
270
271 EXPECT_EQ(getEventScope("possibly_multiple_platforms"), 0x04);
272 EXPECT_THROW(getEventScope("foo"), std::runtime_error);
273
274 std::vector<std::string> flags{"service_action", "dont_report",
275 "termination"};
276 EXPECT_EQ(getActionFlags(flags), 0x9100);
277
278 flags.clear();
279 flags.push_back("foo");
280 EXPECT_THROW(getActionFlags(flags), std::runtime_error);
281}
Matt Spinler93e29322019-09-20 11:16:15 -0500282
283TEST_F(RegistryTest, TestGetSRCReasonCode)
284{
285 using namespace openpower::pels::message::helper;
286 EXPECT_EQ(getSRCReasonCode(R"({"ReasonCode": "0x5555"})"_json, "foo"),
287 0x5555);
288
289 EXPECT_THROW(getSRCReasonCode(R"({"ReasonCode": "ZZZZ"})"_json, "foo"),
290 std::runtime_error);
291}
292
293TEST_F(RegistryTest, TestGetSRCType)
294{
295 using namespace openpower::pels::message::helper;
296 EXPECT_EQ(getSRCType(R"({"Type": "11"})"_json, "foo"), 0x11);
297 EXPECT_EQ(getSRCType(R"({"Type": "BF"})"_json, "foo"), 0xBF);
298
299 EXPECT_THROW(getSRCType(R"({"Type": "1"})"_json, "foo"),
300 std::runtime_error);
301
302 EXPECT_THROW(getSRCType(R"({"Type": "111"})"_json, "foo"),
303 std::runtime_error);
304}
305
306TEST_F(RegistryTest, TestGetSRCHexwordFields)
307{
308 using namespace openpower::pels::message::helper;
309 const auto hexwords = R"(
310 {"Words6To9":
311 {
312 "8":
313 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800314 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500315 "AdditionalDataPropSource": "TEST"
316 }
317 }
318 })"_json;
319
320 auto fields = getSRCHexwordFields(hexwords, "foo");
321 EXPECT_TRUE(fields);
322 auto word = fields->find(8);
323 EXPECT_NE(word, fields->end());
324
325 const auto theInvalidRWord = R"(
326 {"Words6To9":
327 {
328 "R":
329 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800330 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500331 "AdditionalDataPropSource": "TEST"
332 }
333 }
334 })"_json;
335
336 EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"),
337 std::runtime_error);
338}
339
340TEST_F(RegistryTest, TestGetSRCSymptomIDFields)
341{
342 using namespace openpower::pels::message::helper;
343 const auto sID = R"(
344 {
345 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord5"]
346 })"_json;
347
348 auto fields = getSRCSymptomIDFields(sID, "foo");
349 EXPECT_NE(std::find(fields->begin(), fields->end(), 3), fields->end());
350 EXPECT_NE(std::find(fields->begin(), fields->end(), 4), fields->end());
351 EXPECT_NE(std::find(fields->begin(), fields->end(), 5), fields->end());
352
353 const auto badField = R"(
354 {
355 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord"]
356 })"_json;
357
358 EXPECT_THROW(getSRCSymptomIDFields(badField, "foo"), std::runtime_error);
359}
360
361TEST_F(RegistryTest, TestGetComponentID)
362{
363 using namespace openpower::pels::message::helper;
364
365 // Get it from the JSON
366 auto id =
367 getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json, "foo");
368 EXPECT_EQ(id, 0x4200);
369
370 // Get it from the reason code on a 0xBD SRC
371 id = getComponentID(0xBD, 0x6700, R"({})"_json, "foo");
372 EXPECT_EQ(id, 0x6700);
373
374 // Not present on a 0x11 SRC
375 EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"),
376 std::runtime_error);
377}
Matt Spinler6b427cc2020-04-09 09:42:59 -0500378
379// Test when callouts are in the JSON.
380TEST_F(RegistryTest, TestGetCallouts)
381{
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500382 std::vector<std::string> names;
383
Matt Spinler6b427cc2020-04-09 09:42:59 -0500384 {
385 // Callouts without AD, that depend on system type,
386 // where there is a default entry without a system type.
387 auto json = R"(
388 [
389 {
390 "System": "system1",
391 "CalloutList":
392 [
393 {
394 "Priority": "high",
395 "LocCode": "P1-C1"
396 },
397 {
398 "Priority": "low",
399 "LocCode": "P1"
400 },
401 {
402 "Priority": "low",
403 "SymbolicFRU": "service_docs"
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500404 },
405 {
406 "Priority": "low",
407 "SymbolicFRUTrusted": "air_mover",
408 "UseInventoryLocCode": true
Matt Spinler6b427cc2020-04-09 09:42:59 -0500409 }
410 ]
411 },
412 {
413 "CalloutList":
414 [
415 {
416 "Priority": "medium",
Matt Spinler479b6922021-08-17 16:34:59 -0500417 "Procedure": "bmc_code"
Matt Spinler6b427cc2020-04-09 09:42:59 -0500418 },
419 {
420 "Priority": "low",
421 "LocCode": "P3-C8",
422 "SymbolicFRUTrusted": "service_docs"
423 }
424 ]
425
426 }
427 ])"_json;
428
429 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500430 names.push_back("system1");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500431
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500432 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500433 EXPECT_EQ(callouts.size(), 4);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500434 EXPECT_EQ(callouts[0].priority, "high");
435 EXPECT_EQ(callouts[0].locCode, "P1-C1");
436 EXPECT_EQ(callouts[0].procedure, "");
437 EXPECT_EQ(callouts[0].symbolicFRU, "");
438 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
439 EXPECT_EQ(callouts[1].priority, "low");
440 EXPECT_EQ(callouts[1].locCode, "P1");
441 EXPECT_EQ(callouts[1].procedure, "");
442 EXPECT_EQ(callouts[1].symbolicFRU, "");
443 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
444 EXPECT_EQ(callouts[2].priority, "low");
445 EXPECT_EQ(callouts[2].locCode, "");
446 EXPECT_EQ(callouts[2].procedure, "");
447 EXPECT_EQ(callouts[2].symbolicFRU, "service_docs");
448 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500449 EXPECT_EQ(callouts[3].priority, "low");
450 EXPECT_EQ(callouts[3].locCode, "");
451 EXPECT_EQ(callouts[3].procedure, "");
452 EXPECT_EQ(callouts[3].symbolicFRU, "");
453 EXPECT_EQ(callouts[3].symbolicFRUTrusted, "air_mover");
454 EXPECT_EQ(callouts[3].useInventoryLocCode, true);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500455
456 // system2 isn't in the JSON, so it will pick the default one
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500457 names[0] = "system2";
458 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500459 EXPECT_EQ(callouts.size(), 2);
460 EXPECT_EQ(callouts[0].priority, "medium");
461 EXPECT_EQ(callouts[0].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500462 EXPECT_EQ(callouts[0].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500463 EXPECT_EQ(callouts[0].symbolicFRU, "");
464 EXPECT_EQ(callouts[1].priority, "low");
465 EXPECT_EQ(callouts[1].locCode, "P3-C8");
466 EXPECT_EQ(callouts[1].procedure, "");
467 EXPECT_EQ(callouts[1].symbolicFRU, "");
468 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "service_docs");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500469 EXPECT_EQ(callouts[1].useInventoryLocCode, false);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500470 }
471
472 // Empty JSON array (treated as an error)
473 {
474 auto json = R"([])"_json;
475 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500476 names[0] = "system1";
477 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500478 std::runtime_error);
479 }
480
481 {
482 // Callouts without AD, that depend on system type,
483 // where there isn't a default entry without a system type.
484 auto json = R"(
485 [
486 {
487 "System": "system1",
488 "CalloutList":
489 [
490 {
491 "Priority": "high",
492 "LocCode": "P1-C1"
493 },
494 {
495 "Priority": "low",
496 "LocCode": "P1",
497 "SymbolicFRU": "1234567"
498 }
499 ]
500 },
501 {
502 "System": "system2",
503 "CalloutList":
504 [
505 {
506 "Priority": "medium",
507 "LocCode": "P7",
508 "CalloutType": "tool_fru"
509 }
510 ]
511
512 }
513 ])"_json;
514
515 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500516 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500517
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500518 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500519 EXPECT_EQ(callouts.size(), 2);
520 EXPECT_EQ(callouts[0].priority, "high");
521 EXPECT_EQ(callouts[0].locCode, "P1-C1");
522 EXPECT_EQ(callouts[0].procedure, "");
523 EXPECT_EQ(callouts[0].symbolicFRU, "");
524 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
525 EXPECT_EQ(callouts[1].priority, "low");
526 EXPECT_EQ(callouts[1].locCode, "P1");
527 EXPECT_EQ(callouts[1].procedure, "");
528 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
529 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
530
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500531 names[0] = "system2";
532 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500533 EXPECT_EQ(callouts.size(), 1);
534 EXPECT_EQ(callouts[0].priority, "medium");
535 EXPECT_EQ(callouts[0].locCode, "P7");
536 EXPECT_EQ(callouts[0].procedure, "");
537 EXPECT_EQ(callouts[0].symbolicFRU, "");
538 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
539
540 // There is no entry for system3 or a default system,
541 // so this should fail.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500542 names[0] = "system3";
543 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500544 std::runtime_error);
545 }
546
547 {
548 // Callouts that use the AdditionalData key PROC_NUM
549 // as an index into them, along with a system type.
550 // It supports PROC_NUMs 0 and 1.
551 auto json = R"(
552 {
553 "ADName": "PROC_NUM",
554 "CalloutsWithTheirADValues":
555 [
556 {
557 "ADValue": "0",
558 "Callouts":
559 [
560 {
561 "System": "system3",
562 "CalloutList":
563 [
564 {
565 "Priority": "high",
566 "LocCode": "P1-C5"
567 },
568 {
569 "Priority": "medium",
570 "LocCode": "P1-C6",
571 "SymbolicFRU": "1234567"
572 },
573 {
574 "Priority": "low",
Matt Spinler479b6922021-08-17 16:34:59 -0500575 "Procedure": "bmc_code",
Matt Spinler6b427cc2020-04-09 09:42:59 -0500576 "CalloutType": "config_procedure"
577 }
578 ]
579 },
580 {
581 "CalloutList":
582 [
583 {
584 "Priority": "low",
585 "LocCode": "P55"
586 }
587 ]
588 }
589 ]
590 },
591 {
592 "ADValue": "1",
593 "Callouts":
594 [
595 {
596 "CalloutList":
597 [
598 {
599 "Priority": "high",
600 "LocCode": "P1-C6",
601 "CalloutType": "external_fru"
602 }
603 ]
604 }
605 ]
606 }
607 ]
608 })"_json;
609
610 {
611 // Find callouts for PROC_NUM 0 on system3
612 std::vector<std::string> adData{"PROC_NUM=0"};
613 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500614 names[0] = "system3";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500615
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500616 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500617 EXPECT_EQ(callouts.size(), 3);
618 EXPECT_EQ(callouts[0].priority, "high");
619 EXPECT_EQ(callouts[0].locCode, "P1-C5");
620 EXPECT_EQ(callouts[0].procedure, "");
621 EXPECT_EQ(callouts[0].symbolicFRU, "");
622 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
623 EXPECT_EQ(callouts[1].priority, "medium");
624 EXPECT_EQ(callouts[1].locCode, "P1-C6");
625 EXPECT_EQ(callouts[1].procedure, "");
626 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
627 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
628 EXPECT_EQ(callouts[2].priority, "low");
629 EXPECT_EQ(callouts[2].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500630 EXPECT_EQ(callouts[2].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500631 EXPECT_EQ(callouts[2].symbolicFRU, "");
632 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
633
634 // Find callouts for PROC_NUM 0 that uses the default system entry.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500635 names[0] = "system99";
636
637 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500638 EXPECT_EQ(callouts.size(), 1);
639 EXPECT_EQ(callouts[0].priority, "low");
640 EXPECT_EQ(callouts[0].locCode, "P55");
641 EXPECT_EQ(callouts[0].procedure, "");
642 EXPECT_EQ(callouts[0].symbolicFRU, "");
643 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
644 }
645 {
646 // Find callouts for PROC_NUM 1 that uses a default system entry.
647 std::vector<std::string> adData{"PROC_NUM=1"};
648 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500649 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500650
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500651 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500652 EXPECT_EQ(callouts.size(), 1);
653 EXPECT_EQ(callouts[0].priority, "high");
654 EXPECT_EQ(callouts[0].locCode, "P1-C6");
655 EXPECT_EQ(callouts[0].procedure, "");
656 EXPECT_EQ(callouts[0].symbolicFRU, "");
657 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
658 }
659 {
Matt Spinlerf397afc2021-01-29 11:21:44 -0600660 // There is no entry for PROC_NUM 2, so no callouts
Matt Spinler6b427cc2020-04-09 09:42:59 -0500661 std::vector<std::string> adData{"PROC_NUM=2"};
662 AdditionalData ad{adData};
663
Matt Spinlerf397afc2021-01-29 11:21:44 -0600664 auto callouts = Registry::getCallouts(json, names, ad);
665 EXPECT_TRUE(callouts.empty());
Matt Spinler6b427cc2020-04-09 09:42:59 -0500666 }
667 }
668}
Matt Spinler23970b02022-02-25 16:34:46 -0600669
670TEST_F(RegistryTest, TestNoSubsystem)
671{
672 auto path = RegistryTest::writeData(registryData);
673 Registry registry{path};
674
675 auto entry = registry.lookup("xyz.openbmc_project.Common.Error.Timeout",
676 LookupType::name);
677 ASSERT_TRUE(entry);
678 EXPECT_FALSE(entry->subsystem);
679}