blob: de7eb27a8c333529621a9acface75f511ebf8dae [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"],
Matt Spinler367144c2019-09-19 15:33:52 -050074 "Words6To9":
75 {
76 "6":
77 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +080078 "Description": "Failing unit number",
Matt Spinler367144c2019-09-19 15:33:52 -050079 "AdditionalDataPropSource": "PS_NUM"
80 },
81
82 "7":
83 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +080084 "Description": "bad voltage",
Matt Spinler367144c2019-09-19 15:33:52 -050085 "AdditionalDataPropSource": "VOLTAGE"
86 }
87 }
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +080088 },
89
90 "Documentation":
91 {
92 "Description": "A PGOOD Fault",
93 "Message": "PS %1 had a PGOOD Fault",
94 "MessageArgSources":
95 [
96 "SRCWord6"
97 ],
98 "Notes": [
99 "In the UserData section there is a JSON",
100 "dump that provides debug information."
101 ]
Matt Spinler367144c2019-09-19 15:33:52 -0500102 }
Matt Spinler23970b02022-02-25 16:34:46 -0600103 },
104
105 {
106 "Name": "xyz.openbmc_project.Common.Error.Timeout",
107 "PossibleSubsystems": ["processor", "memory"],
108
109 "SRC":
110 {
111 "ReasonCode": "0x2030"
112 },
113 "Documentation":
114 {
115 "Description": "A PGOOD Fault",
116 "Message": "PS had a PGOOD Fault"
117 }
Matt Spinler367144c2019-09-19 15:33:52 -0500118 }
119 ]
120}
121)";
122
123class RegistryTest : public ::testing::Test
124{
125 protected:
126 static void SetUpTestCase()
127 {
128 char path[] = "/tmp/regtestXXXXXX";
129 regDir = mkdtemp(path);
130 }
131
132 static void TearDownTestCase()
133 {
134 fs::remove_all(regDir);
135 }
136
137 static std::string writeData(const char* data)
138 {
139 fs::path path = regDir / "registry.json";
140 std::ofstream stream{path};
141 stream << data;
142 return path;
143 }
144
145 static fs::path regDir;
146};
147
148fs::path RegistryTest::regDir{};
149
150TEST_F(RegistryTest, TestNoEntry)
151{
152 auto path = RegistryTest::writeData(registryData);
153 Registry registry{path};
154
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800155 auto entry = registry.lookup("foo", LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500156 EXPECT_FALSE(entry);
157}
158
159TEST_F(RegistryTest, TestFindEntry)
160{
161 auto path = RegistryTest::writeData(registryData);
162 Registry registry{path};
163
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800164 auto entry = registry.lookup("xyz.openbmc_project.Power.OverVoltage",
165 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500166 ASSERT_TRUE(entry);
167 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
168 EXPECT_EQ(entry->subsystem, 0x62);
Matt Spinleraadccc82020-04-10 14:33:42 -0500169
170 ASSERT_EQ(entry->severity->size(), 3);
171 EXPECT_EQ((*entry->severity)[0].severity, 0x40);
172 EXPECT_EQ((*entry->severity)[0].system, "systemA");
173 EXPECT_EQ((*entry->severity)[1].severity, 0x10);
174 EXPECT_EQ((*entry->severity)[1].system, "systemB");
175 EXPECT_EQ((*entry->severity)[2].severity, 0x20);
176 EXPECT_EQ((*entry->severity)[2].system, "");
177
178 EXPECT_EQ(entry->mfgSeverity->size(), 1);
179 EXPECT_EQ((*entry->mfgSeverity)[0].severity, 0x00);
180
Matt Spinlere07f9152019-11-01 10:48:36 -0500181 EXPECT_EQ(*(entry->actionFlags), 0xA800);
Matt Spinler367144c2019-09-19 15:33:52 -0500182 EXPECT_EQ(*(entry->mfgActionFlags), 0x4000);
Matt Spinler93e29322019-09-20 11:16:15 -0500183 EXPECT_EQ(entry->componentID, 0x2300);
Matt Spinler367144c2019-09-19 15:33:52 -0500184 EXPECT_FALSE(entry->eventType);
185 EXPECT_FALSE(entry->eventScope);
186
Matt Spinler93e29322019-09-20 11:16:15 -0500187 EXPECT_EQ(entry->src.type, 0xBD);
188 EXPECT_EQ(entry->src.reasonCode, 0x2333);
Matt Spinler93e29322019-09-20 11:16:15 -0500189
190 auto& hexwords = entry->src.hexwordADFields;
191 EXPECT_TRUE(hexwords);
192 EXPECT_EQ((*hexwords).size(), 2);
193
194 auto word = (*hexwords).find(6);
195 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800196 EXPECT_EQ(std::get<0>(word->second), "PS_NUM");
Matt Spinler93e29322019-09-20 11:16:15 -0500197
198 word = (*hexwords).find(7);
199 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800200 EXPECT_EQ(std::get<0>(word->second), "VOLTAGE");
Matt Spinler93e29322019-09-20 11:16:15 -0500201
202 auto& sid = entry->src.symptomID;
203 EXPECT_TRUE(sid);
204 EXPECT_EQ((*sid).size(), 3);
205 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 5), (*sid).end());
206 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 6), (*sid).end());
207 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 7), (*sid).end());
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800208
209 EXPECT_EQ(entry->doc.description, "A PGOOD Fault");
210 EXPECT_EQ(entry->doc.message, "PS %1 had a PGOOD Fault");
211 auto& hexwordSource = entry->doc.messageArgSources;
212 EXPECT_TRUE(hexwordSource);
213 EXPECT_EQ((*hexwordSource).size(), 1);
214 EXPECT_EQ((*hexwordSource).front(), "SRCWord6");
215
216 entry = registry.lookup("0x2333", LookupType::reasonCode);
217 ASSERT_TRUE(entry);
218 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
Matt Spinler367144c2019-09-19 15:33:52 -0500219}
220
221// Check the entry that mostly uses defaults
222TEST_F(RegistryTest, TestFindEntryMinimal)
223{
224 auto path = RegistryTest::writeData(registryData);
225 Registry registry{path};
226
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800227 auto entry =
228 registry.lookup("xyz.openbmc_project.Power.Fault", LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500229 ASSERT_TRUE(entry);
230 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.Fault");
231 EXPECT_EQ(entry->subsystem, 0x61);
232 EXPECT_FALSE(entry->severity);
233 EXPECT_FALSE(entry->mfgSeverity);
234 EXPECT_FALSE(entry->mfgActionFlags);
Matt Spinlere07f9152019-11-01 10:48:36 -0500235 EXPECT_FALSE(entry->actionFlags);
Matt Spinler93e29322019-09-20 11:16:15 -0500236 EXPECT_EQ(entry->componentID, 0x2000);
Matt Spinler367144c2019-09-19 15:33:52 -0500237 EXPECT_FALSE(entry->eventType);
238 EXPECT_FALSE(entry->eventScope);
Matt Spinler93e29322019-09-20 11:16:15 -0500239
240 EXPECT_EQ(entry->src.reasonCode, 0x2030);
241 EXPECT_EQ(entry->src.type, 0xBD);
Matt Spinler93e29322019-09-20 11:16:15 -0500242 EXPECT_FALSE(entry->src.hexwordADFields);
243 EXPECT_FALSE(entry->src.symptomID);
Matt Spinler367144c2019-09-19 15:33:52 -0500244}
245
246TEST_F(RegistryTest, TestBadJSON)
247{
248 auto path = RegistryTest::writeData("bad {} json");
249
250 Registry registry{path};
251
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800252 EXPECT_FALSE(registry.lookup("foo", LookupType::name));
Matt Spinler367144c2019-09-19 15:33:52 -0500253}
254
255// Test the helper functions the use the pel_values data.
256TEST_F(RegistryTest, TestHelperFunctions)
257{
258 using namespace openpower::pels::message::helper;
259 EXPECT_EQ(getSubsystem("input_power_source"), 0xA1);
260 EXPECT_THROW(getSubsystem("foo"), std::runtime_error);
261
262 EXPECT_EQ(getSeverity("symptom_recovered"), 0x71);
263 EXPECT_THROW(getSeverity("foo"), std::runtime_error);
264
265 EXPECT_EQ(getEventType("dump_notification"), 0x08);
266 EXPECT_THROW(getEventType("foo"), std::runtime_error);
267
268 EXPECT_EQ(getEventScope("possibly_multiple_platforms"), 0x04);
269 EXPECT_THROW(getEventScope("foo"), std::runtime_error);
270
271 std::vector<std::string> flags{"service_action", "dont_report",
272 "termination"};
273 EXPECT_EQ(getActionFlags(flags), 0x9100);
274
275 flags.clear();
276 flags.push_back("foo");
277 EXPECT_THROW(getActionFlags(flags), std::runtime_error);
278}
Matt Spinler93e29322019-09-20 11:16:15 -0500279
280TEST_F(RegistryTest, TestGetSRCReasonCode)
281{
282 using namespace openpower::pels::message::helper;
283 EXPECT_EQ(getSRCReasonCode(R"({"ReasonCode": "0x5555"})"_json, "foo"),
284 0x5555);
285
286 EXPECT_THROW(getSRCReasonCode(R"({"ReasonCode": "ZZZZ"})"_json, "foo"),
287 std::runtime_error);
288}
289
290TEST_F(RegistryTest, TestGetSRCType)
291{
292 using namespace openpower::pels::message::helper;
293 EXPECT_EQ(getSRCType(R"({"Type": "11"})"_json, "foo"), 0x11);
294 EXPECT_EQ(getSRCType(R"({"Type": "BF"})"_json, "foo"), 0xBF);
295
296 EXPECT_THROW(getSRCType(R"({"Type": "1"})"_json, "foo"),
297 std::runtime_error);
298
299 EXPECT_THROW(getSRCType(R"({"Type": "111"})"_json, "foo"),
300 std::runtime_error);
301}
302
303TEST_F(RegistryTest, TestGetSRCHexwordFields)
304{
305 using namespace openpower::pels::message::helper;
306 const auto hexwords = R"(
307 {"Words6To9":
308 {
309 "8":
310 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800311 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500312 "AdditionalDataPropSource": "TEST"
313 }
314 }
315 })"_json;
316
317 auto fields = getSRCHexwordFields(hexwords, "foo");
318 EXPECT_TRUE(fields);
319 auto word = fields->find(8);
320 EXPECT_NE(word, fields->end());
321
322 const auto theInvalidRWord = R"(
323 {"Words6To9":
324 {
325 "R":
326 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800327 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500328 "AdditionalDataPropSource": "TEST"
329 }
330 }
331 })"_json;
332
333 EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"),
334 std::runtime_error);
335}
336
337TEST_F(RegistryTest, TestGetSRCSymptomIDFields)
338{
339 using namespace openpower::pels::message::helper;
340 const auto sID = R"(
341 {
342 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord5"]
343 })"_json;
344
345 auto fields = getSRCSymptomIDFields(sID, "foo");
346 EXPECT_NE(std::find(fields->begin(), fields->end(), 3), fields->end());
347 EXPECT_NE(std::find(fields->begin(), fields->end(), 4), fields->end());
348 EXPECT_NE(std::find(fields->begin(), fields->end(), 5), fields->end());
349
350 const auto badField = R"(
351 {
352 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord"]
353 })"_json;
354
355 EXPECT_THROW(getSRCSymptomIDFields(badField, "foo"), std::runtime_error);
356}
357
358TEST_F(RegistryTest, TestGetComponentID)
359{
360 using namespace openpower::pels::message::helper;
361
362 // Get it from the JSON
363 auto id =
364 getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json, "foo");
365 EXPECT_EQ(id, 0x4200);
366
367 // Get it from the reason code on a 0xBD SRC
368 id = getComponentID(0xBD, 0x6700, R"({})"_json, "foo");
369 EXPECT_EQ(id, 0x6700);
370
371 // Not present on a 0x11 SRC
372 EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"),
373 std::runtime_error);
374}
Matt Spinler6b427cc2020-04-09 09:42:59 -0500375
376// Test when callouts are in the JSON.
377TEST_F(RegistryTest, TestGetCallouts)
378{
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500379 std::vector<std::string> names;
380
Matt Spinler6b427cc2020-04-09 09:42:59 -0500381 {
382 // Callouts without AD, that depend on system type,
383 // where there is a default entry without a system type.
384 auto json = R"(
385 [
386 {
387 "System": "system1",
388 "CalloutList":
389 [
390 {
391 "Priority": "high",
392 "LocCode": "P1-C1"
393 },
394 {
395 "Priority": "low",
396 "LocCode": "P1"
397 },
398 {
399 "Priority": "low",
400 "SymbolicFRU": "service_docs"
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500401 },
402 {
403 "Priority": "low",
404 "SymbolicFRUTrusted": "air_mover",
405 "UseInventoryLocCode": true
Matt Spinler6b427cc2020-04-09 09:42:59 -0500406 }
407 ]
408 },
409 {
410 "CalloutList":
411 [
412 {
413 "Priority": "medium",
Matt Spinler479b6922021-08-17 16:34:59 -0500414 "Procedure": "bmc_code"
Matt Spinler6b427cc2020-04-09 09:42:59 -0500415 },
416 {
417 "Priority": "low",
418 "LocCode": "P3-C8",
419 "SymbolicFRUTrusted": "service_docs"
420 }
421 ]
422
423 }
424 ])"_json;
425
426 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500427 names.push_back("system1");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500428
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500429 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500430 EXPECT_EQ(callouts.size(), 4);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500431 EXPECT_EQ(callouts[0].priority, "high");
432 EXPECT_EQ(callouts[0].locCode, "P1-C1");
433 EXPECT_EQ(callouts[0].procedure, "");
434 EXPECT_EQ(callouts[0].symbolicFRU, "");
435 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
436 EXPECT_EQ(callouts[1].priority, "low");
437 EXPECT_EQ(callouts[1].locCode, "P1");
438 EXPECT_EQ(callouts[1].procedure, "");
439 EXPECT_EQ(callouts[1].symbolicFRU, "");
440 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
441 EXPECT_EQ(callouts[2].priority, "low");
442 EXPECT_EQ(callouts[2].locCode, "");
443 EXPECT_EQ(callouts[2].procedure, "");
444 EXPECT_EQ(callouts[2].symbolicFRU, "service_docs");
445 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500446 EXPECT_EQ(callouts[3].priority, "low");
447 EXPECT_EQ(callouts[3].locCode, "");
448 EXPECT_EQ(callouts[3].procedure, "");
449 EXPECT_EQ(callouts[3].symbolicFRU, "");
450 EXPECT_EQ(callouts[3].symbolicFRUTrusted, "air_mover");
451 EXPECT_EQ(callouts[3].useInventoryLocCode, true);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500452
453 // system2 isn't in the JSON, so it will pick the default one
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500454 names[0] = "system2";
455 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500456 EXPECT_EQ(callouts.size(), 2);
457 EXPECT_EQ(callouts[0].priority, "medium");
458 EXPECT_EQ(callouts[0].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500459 EXPECT_EQ(callouts[0].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500460 EXPECT_EQ(callouts[0].symbolicFRU, "");
461 EXPECT_EQ(callouts[1].priority, "low");
462 EXPECT_EQ(callouts[1].locCode, "P3-C8");
463 EXPECT_EQ(callouts[1].procedure, "");
464 EXPECT_EQ(callouts[1].symbolicFRU, "");
465 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "service_docs");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500466 EXPECT_EQ(callouts[1].useInventoryLocCode, false);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500467 }
468
469 // Empty JSON array (treated as an error)
470 {
471 auto json = R"([])"_json;
472 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500473 names[0] = "system1";
474 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500475 std::runtime_error);
476 }
477
478 {
479 // Callouts without AD, that depend on system type,
480 // where there isn't a default entry without a system type.
481 auto json = R"(
482 [
483 {
484 "System": "system1",
485 "CalloutList":
486 [
487 {
488 "Priority": "high",
489 "LocCode": "P1-C1"
490 },
491 {
492 "Priority": "low",
493 "LocCode": "P1",
494 "SymbolicFRU": "1234567"
495 }
496 ]
497 },
498 {
499 "System": "system2",
500 "CalloutList":
501 [
502 {
503 "Priority": "medium",
504 "LocCode": "P7",
505 "CalloutType": "tool_fru"
506 }
507 ]
508
509 }
510 ])"_json;
511
512 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500513 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500514
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500515 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500516 EXPECT_EQ(callouts.size(), 2);
517 EXPECT_EQ(callouts[0].priority, "high");
518 EXPECT_EQ(callouts[0].locCode, "P1-C1");
519 EXPECT_EQ(callouts[0].procedure, "");
520 EXPECT_EQ(callouts[0].symbolicFRU, "");
521 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
522 EXPECT_EQ(callouts[1].priority, "low");
523 EXPECT_EQ(callouts[1].locCode, "P1");
524 EXPECT_EQ(callouts[1].procedure, "");
525 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
526 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
527
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500528 names[0] = "system2";
529 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500530 EXPECT_EQ(callouts.size(), 1);
531 EXPECT_EQ(callouts[0].priority, "medium");
532 EXPECT_EQ(callouts[0].locCode, "P7");
533 EXPECT_EQ(callouts[0].procedure, "");
534 EXPECT_EQ(callouts[0].symbolicFRU, "");
535 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
536
537 // There is no entry for system3 or a default system,
538 // so this should fail.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500539 names[0] = "system3";
540 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500541 std::runtime_error);
542 }
543
544 {
545 // Callouts that use the AdditionalData key PROC_NUM
546 // as an index into them, along with a system type.
547 // It supports PROC_NUMs 0 and 1.
548 auto json = R"(
549 {
550 "ADName": "PROC_NUM",
551 "CalloutsWithTheirADValues":
552 [
553 {
554 "ADValue": "0",
555 "Callouts":
556 [
557 {
558 "System": "system3",
559 "CalloutList":
560 [
561 {
562 "Priority": "high",
563 "LocCode": "P1-C5"
564 },
565 {
566 "Priority": "medium",
567 "LocCode": "P1-C6",
568 "SymbolicFRU": "1234567"
569 },
570 {
571 "Priority": "low",
Matt Spinler479b6922021-08-17 16:34:59 -0500572 "Procedure": "bmc_code",
Matt Spinler6b427cc2020-04-09 09:42:59 -0500573 "CalloutType": "config_procedure"
574 }
575 ]
576 },
577 {
578 "CalloutList":
579 [
580 {
581 "Priority": "low",
582 "LocCode": "P55"
583 }
584 ]
585 }
586 ]
587 },
588 {
589 "ADValue": "1",
590 "Callouts":
591 [
592 {
593 "CalloutList":
594 [
595 {
596 "Priority": "high",
597 "LocCode": "P1-C6",
598 "CalloutType": "external_fru"
599 }
600 ]
601 }
602 ]
603 }
604 ]
605 })"_json;
606
607 {
608 // Find callouts for PROC_NUM 0 on system3
609 std::vector<std::string> adData{"PROC_NUM=0"};
610 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500611 names[0] = "system3";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500612
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500613 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500614 EXPECT_EQ(callouts.size(), 3);
615 EXPECT_EQ(callouts[0].priority, "high");
616 EXPECT_EQ(callouts[0].locCode, "P1-C5");
617 EXPECT_EQ(callouts[0].procedure, "");
618 EXPECT_EQ(callouts[0].symbolicFRU, "");
619 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
620 EXPECT_EQ(callouts[1].priority, "medium");
621 EXPECT_EQ(callouts[1].locCode, "P1-C6");
622 EXPECT_EQ(callouts[1].procedure, "");
623 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
624 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
625 EXPECT_EQ(callouts[2].priority, "low");
626 EXPECT_EQ(callouts[2].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500627 EXPECT_EQ(callouts[2].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500628 EXPECT_EQ(callouts[2].symbolicFRU, "");
629 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
630
631 // Find callouts for PROC_NUM 0 that uses the default system entry.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500632 names[0] = "system99";
633
634 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500635 EXPECT_EQ(callouts.size(), 1);
636 EXPECT_EQ(callouts[0].priority, "low");
637 EXPECT_EQ(callouts[0].locCode, "P55");
638 EXPECT_EQ(callouts[0].procedure, "");
639 EXPECT_EQ(callouts[0].symbolicFRU, "");
640 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
641 }
642 {
643 // Find callouts for PROC_NUM 1 that uses a default system entry.
644 std::vector<std::string> adData{"PROC_NUM=1"};
645 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500646 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500647
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500648 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500649 EXPECT_EQ(callouts.size(), 1);
650 EXPECT_EQ(callouts[0].priority, "high");
651 EXPECT_EQ(callouts[0].locCode, "P1-C6");
652 EXPECT_EQ(callouts[0].procedure, "");
653 EXPECT_EQ(callouts[0].symbolicFRU, "");
654 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
655 }
656 {
Matt Spinlerf397afc2021-01-29 11:21:44 -0600657 // There is no entry for PROC_NUM 2, so no callouts
Matt Spinler6b427cc2020-04-09 09:42:59 -0500658 std::vector<std::string> adData{"PROC_NUM=2"};
659 AdditionalData ad{adData};
660
Matt Spinlerf397afc2021-01-29 11:21:44 -0600661 auto callouts = Registry::getCallouts(json, names, ad);
662 EXPECT_TRUE(callouts.empty());
Matt Spinler6b427cc2020-04-09 09:42:59 -0500663 }
664 }
665}
Matt Spinler23970b02022-02-25 16:34:46 -0600666
667TEST_F(RegistryTest, TestNoSubsystem)
668{
669 auto path = RegistryTest::writeData(registryData);
670 Registry registry{path};
671
672 auto entry = registry.lookup("xyz.openbmc_project.Common.Error.Timeout",
673 LookupType::name);
674 ASSERT_TRUE(entry);
675 EXPECT_FALSE(entry->subsystem);
676}