blob: 6a13fc69ebfdfaeb4d7793f5331950a8b7807585 [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 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);
Matt Spinler93e29322019-09-20 11:16:15 -0500190
191 auto& hexwords = entry->src.hexwordADFields;
192 EXPECT_TRUE(hexwords);
193 EXPECT_EQ((*hexwords).size(), 2);
194
195 auto word = (*hexwords).find(6);
196 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800197 EXPECT_EQ(std::get<0>(word->second), "PS_NUM");
Matt Spinler93e29322019-09-20 11:16:15 -0500198
199 word = (*hexwords).find(7);
200 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800201 EXPECT_EQ(std::get<0>(word->second), "VOLTAGE");
Matt Spinler93e29322019-09-20 11:16:15 -0500202
203 auto& sid = entry->src.symptomID;
204 EXPECT_TRUE(sid);
205 EXPECT_EQ((*sid).size(), 3);
206 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 5), (*sid).end());
207 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 6), (*sid).end());
208 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 7), (*sid).end());
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800209
210 EXPECT_EQ(entry->doc.description, "A PGOOD Fault");
211 EXPECT_EQ(entry->doc.message, "PS %1 had a PGOOD Fault");
212 auto& hexwordSource = entry->doc.messageArgSources;
213 EXPECT_TRUE(hexwordSource);
214 EXPECT_EQ((*hexwordSource).size(), 1);
215 EXPECT_EQ((*hexwordSource).front(), "SRCWord6");
216
217 entry = registry.lookup("0x2333", LookupType::reasonCode);
218 ASSERT_TRUE(entry);
219 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
Matt Spinler367144c2019-09-19 15:33:52 -0500220}
221
222// Check the entry that mostly uses defaults
223TEST_F(RegistryTest, TestFindEntryMinimal)
224{
225 auto path = RegistryTest::writeData(registryData);
226 Registry registry{path};
227
Patrick Williams2544b412022-10-04 08:41:06 -0500228 auto entry = registry.lookup("xyz.openbmc_project.Power.Fault",
229 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500230 ASSERT_TRUE(entry);
231 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.Fault");
232 EXPECT_EQ(entry->subsystem, 0x61);
233 EXPECT_FALSE(entry->severity);
234 EXPECT_FALSE(entry->mfgSeverity);
235 EXPECT_FALSE(entry->mfgActionFlags);
Matt Spinlere07f9152019-11-01 10:48:36 -0500236 EXPECT_FALSE(entry->actionFlags);
Matt Spinler93e29322019-09-20 11:16:15 -0500237 EXPECT_EQ(entry->componentID, 0x2000);
Matt Spinler367144c2019-09-19 15:33:52 -0500238 EXPECT_FALSE(entry->eventType);
239 EXPECT_FALSE(entry->eventScope);
Matt Spinler93e29322019-09-20 11:16:15 -0500240
241 EXPECT_EQ(entry->src.reasonCode, 0x2030);
242 EXPECT_EQ(entry->src.type, 0xBD);
Matt Spinler93e29322019-09-20 11:16:15 -0500243 EXPECT_FALSE(entry->src.hexwordADFields);
244 EXPECT_FALSE(entry->src.symptomID);
Matt Spinler367144c2019-09-19 15:33:52 -0500245}
246
247TEST_F(RegistryTest, TestBadJSON)
248{
249 auto path = RegistryTest::writeData("bad {} json");
250
251 Registry registry{path};
252
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800253 EXPECT_FALSE(registry.lookup("foo", LookupType::name));
Matt Spinler367144c2019-09-19 15:33:52 -0500254}
255
256// Test the helper functions the use the pel_values data.
257TEST_F(RegistryTest, TestHelperFunctions)
258{
259 using namespace openpower::pels::message::helper;
260 EXPECT_EQ(getSubsystem("input_power_source"), 0xA1);
261 EXPECT_THROW(getSubsystem("foo"), std::runtime_error);
262
263 EXPECT_EQ(getSeverity("symptom_recovered"), 0x71);
264 EXPECT_THROW(getSeverity("foo"), std::runtime_error);
265
266 EXPECT_EQ(getEventType("dump_notification"), 0x08);
267 EXPECT_THROW(getEventType("foo"), std::runtime_error);
268
269 EXPECT_EQ(getEventScope("possibly_multiple_platforms"), 0x04);
270 EXPECT_THROW(getEventScope("foo"), std::runtime_error);
271
272 std::vector<std::string> flags{"service_action", "dont_report",
273 "termination"};
274 EXPECT_EQ(getActionFlags(flags), 0x9100);
275
276 flags.clear();
277 flags.push_back("foo");
278 EXPECT_THROW(getActionFlags(flags), std::runtime_error);
279}
Matt Spinler93e29322019-09-20 11:16:15 -0500280
281TEST_F(RegistryTest, TestGetSRCReasonCode)
282{
283 using namespace openpower::pels::message::helper;
284 EXPECT_EQ(getSRCReasonCode(R"({"ReasonCode": "0x5555"})"_json, "foo"),
285 0x5555);
286
287 EXPECT_THROW(getSRCReasonCode(R"({"ReasonCode": "ZZZZ"})"_json, "foo"),
288 std::runtime_error);
289}
290
291TEST_F(RegistryTest, TestGetSRCType)
292{
293 using namespace openpower::pels::message::helper;
294 EXPECT_EQ(getSRCType(R"({"Type": "11"})"_json, "foo"), 0x11);
295 EXPECT_EQ(getSRCType(R"({"Type": "BF"})"_json, "foo"), 0xBF);
296
297 EXPECT_THROW(getSRCType(R"({"Type": "1"})"_json, "foo"),
298 std::runtime_error);
299
300 EXPECT_THROW(getSRCType(R"({"Type": "111"})"_json, "foo"),
301 std::runtime_error);
302}
303
304TEST_F(RegistryTest, TestGetSRCHexwordFields)
305{
306 using namespace openpower::pels::message::helper;
307 const auto hexwords = R"(
308 {"Words6To9":
309 {
310 "8":
311 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800312 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500313 "AdditionalDataPropSource": "TEST"
314 }
315 }
316 })"_json;
317
318 auto fields = getSRCHexwordFields(hexwords, "foo");
319 EXPECT_TRUE(fields);
320 auto word = fields->find(8);
321 EXPECT_NE(word, fields->end());
322
323 const auto theInvalidRWord = R"(
324 {"Words6To9":
325 {
326 "R":
327 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800328 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500329 "AdditionalDataPropSource": "TEST"
330 }
331 }
332 })"_json;
333
334 EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"),
335 std::runtime_error);
336}
337
338TEST_F(RegistryTest, TestGetSRCSymptomIDFields)
339{
340 using namespace openpower::pels::message::helper;
341 const auto sID = R"(
342 {
343 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord5"]
344 })"_json;
345
346 auto fields = getSRCSymptomIDFields(sID, "foo");
347 EXPECT_NE(std::find(fields->begin(), fields->end(), 3), fields->end());
348 EXPECT_NE(std::find(fields->begin(), fields->end(), 4), fields->end());
349 EXPECT_NE(std::find(fields->begin(), fields->end(), 5), fields->end());
350
351 const auto badField = R"(
352 {
353 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord"]
354 })"_json;
355
356 EXPECT_THROW(getSRCSymptomIDFields(badField, "foo"), std::runtime_error);
357}
358
359TEST_F(RegistryTest, TestGetComponentID)
360{
361 using namespace openpower::pels::message::helper;
362
363 // Get it from the JSON
Patrick Williams2544b412022-10-04 08:41:06 -0500364 auto id = getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json,
365 "foo");
Matt Spinler93e29322019-09-20 11:16:15 -0500366 EXPECT_EQ(id, 0x4200);
367
368 // Get it from the reason code on a 0xBD SRC
369 id = getComponentID(0xBD, 0x6700, R"({})"_json, "foo");
370 EXPECT_EQ(id, 0x6700);
371
372 // Not present on a 0x11 SRC
373 EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"),
374 std::runtime_error);
375}
Matt Spinler6b427cc2020-04-09 09:42:59 -0500376
377// Test when callouts are in the JSON.
378TEST_F(RegistryTest, TestGetCallouts)
379{
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500380 std::vector<std::string> names;
381
Matt Spinler6b427cc2020-04-09 09:42:59 -0500382 {
383 // Callouts without AD, that depend on system type,
384 // where there is a default entry without a system type.
385 auto json = R"(
386 [
387 {
388 "System": "system1",
389 "CalloutList":
390 [
391 {
392 "Priority": "high",
393 "LocCode": "P1-C1"
394 },
395 {
396 "Priority": "low",
397 "LocCode": "P1"
398 },
399 {
400 "Priority": "low",
401 "SymbolicFRU": "service_docs"
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500402 },
403 {
404 "Priority": "low",
405 "SymbolicFRUTrusted": "air_mover",
406 "UseInventoryLocCode": true
Matt Spinler6b427cc2020-04-09 09:42:59 -0500407 }
408 ]
409 },
410 {
411 "CalloutList":
412 [
413 {
414 "Priority": "medium",
Matt Spinler479b6922021-08-17 16:34:59 -0500415 "Procedure": "bmc_code"
Matt Spinler6b427cc2020-04-09 09:42:59 -0500416 },
417 {
418 "Priority": "low",
419 "LocCode": "P3-C8",
420 "SymbolicFRUTrusted": "service_docs"
421 }
422 ]
423
424 }
425 ])"_json;
426
427 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500428 names.push_back("system1");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500429
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500430 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500431 EXPECT_EQ(callouts.size(), 4);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500432 EXPECT_EQ(callouts[0].priority, "high");
433 EXPECT_EQ(callouts[0].locCode, "P1-C1");
434 EXPECT_EQ(callouts[0].procedure, "");
435 EXPECT_EQ(callouts[0].symbolicFRU, "");
436 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
437 EXPECT_EQ(callouts[1].priority, "low");
438 EXPECT_EQ(callouts[1].locCode, "P1");
439 EXPECT_EQ(callouts[1].procedure, "");
440 EXPECT_EQ(callouts[1].symbolicFRU, "");
441 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
442 EXPECT_EQ(callouts[2].priority, "low");
443 EXPECT_EQ(callouts[2].locCode, "");
444 EXPECT_EQ(callouts[2].procedure, "");
445 EXPECT_EQ(callouts[2].symbolicFRU, "service_docs");
446 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500447 EXPECT_EQ(callouts[3].priority, "low");
448 EXPECT_EQ(callouts[3].locCode, "");
449 EXPECT_EQ(callouts[3].procedure, "");
450 EXPECT_EQ(callouts[3].symbolicFRU, "");
451 EXPECT_EQ(callouts[3].symbolicFRUTrusted, "air_mover");
452 EXPECT_EQ(callouts[3].useInventoryLocCode, true);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500453
454 // system2 isn't in the JSON, so it will pick the default one
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500455 names[0] = "system2";
456 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500457 EXPECT_EQ(callouts.size(), 2);
458 EXPECT_EQ(callouts[0].priority, "medium");
459 EXPECT_EQ(callouts[0].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500460 EXPECT_EQ(callouts[0].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500461 EXPECT_EQ(callouts[0].symbolicFRU, "");
462 EXPECT_EQ(callouts[1].priority, "low");
463 EXPECT_EQ(callouts[1].locCode, "P3-C8");
464 EXPECT_EQ(callouts[1].procedure, "");
465 EXPECT_EQ(callouts[1].symbolicFRU, "");
466 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "service_docs");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500467 EXPECT_EQ(callouts[1].useInventoryLocCode, false);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500468 }
469
470 // Empty JSON array (treated as an error)
471 {
472 auto json = R"([])"_json;
473 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500474 names[0] = "system1";
475 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500476 std::runtime_error);
477 }
478
479 {
480 // Callouts without AD, that depend on system type,
481 // where there isn't a default entry without a system type.
482 auto json = R"(
483 [
484 {
485 "System": "system1",
486 "CalloutList":
487 [
488 {
489 "Priority": "high",
490 "LocCode": "P1-C1"
491 },
492 {
493 "Priority": "low",
494 "LocCode": "P1",
495 "SymbolicFRU": "1234567"
496 }
497 ]
498 },
499 {
500 "System": "system2",
501 "CalloutList":
502 [
503 {
504 "Priority": "medium",
505 "LocCode": "P7",
506 "CalloutType": "tool_fru"
507 }
508 ]
509
510 }
511 ])"_json;
512
513 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500514 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500515
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500516 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500517 EXPECT_EQ(callouts.size(), 2);
518 EXPECT_EQ(callouts[0].priority, "high");
519 EXPECT_EQ(callouts[0].locCode, "P1-C1");
520 EXPECT_EQ(callouts[0].procedure, "");
521 EXPECT_EQ(callouts[0].symbolicFRU, "");
522 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
523 EXPECT_EQ(callouts[1].priority, "low");
524 EXPECT_EQ(callouts[1].locCode, "P1");
525 EXPECT_EQ(callouts[1].procedure, "");
526 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
527 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
528
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500529 names[0] = "system2";
530 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500531 EXPECT_EQ(callouts.size(), 1);
532 EXPECT_EQ(callouts[0].priority, "medium");
533 EXPECT_EQ(callouts[0].locCode, "P7");
534 EXPECT_EQ(callouts[0].procedure, "");
535 EXPECT_EQ(callouts[0].symbolicFRU, "");
536 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
537
538 // There is no entry for system3 or a default system,
539 // so this should fail.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500540 names[0] = "system3";
541 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500542 std::runtime_error);
543 }
544
545 {
546 // Callouts that use the AdditionalData key PROC_NUM
547 // as an index into them, along with a system type.
548 // It supports PROC_NUMs 0 and 1.
549 auto json = R"(
550 {
551 "ADName": "PROC_NUM",
552 "CalloutsWithTheirADValues":
553 [
554 {
555 "ADValue": "0",
556 "Callouts":
557 [
558 {
559 "System": "system3",
560 "CalloutList":
561 [
562 {
563 "Priority": "high",
564 "LocCode": "P1-C5"
565 },
566 {
567 "Priority": "medium",
568 "LocCode": "P1-C6",
569 "SymbolicFRU": "1234567"
570 },
571 {
572 "Priority": "low",
Matt Spinler479b6922021-08-17 16:34:59 -0500573 "Procedure": "bmc_code",
Matt Spinler6b427cc2020-04-09 09:42:59 -0500574 "CalloutType": "config_procedure"
575 }
576 ]
577 },
578 {
579 "CalloutList":
580 [
581 {
582 "Priority": "low",
583 "LocCode": "P55"
584 }
585 ]
586 }
587 ]
588 },
589 {
590 "ADValue": "1",
591 "Callouts":
592 [
593 {
594 "CalloutList":
595 [
596 {
597 "Priority": "high",
598 "LocCode": "P1-C6",
599 "CalloutType": "external_fru"
600 }
601 ]
602 }
603 ]
604 }
605 ]
606 })"_json;
607
608 {
609 // Find callouts for PROC_NUM 0 on system3
610 std::vector<std::string> adData{"PROC_NUM=0"};
611 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500612 names[0] = "system3";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500613
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500614 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500615 EXPECT_EQ(callouts.size(), 3);
616 EXPECT_EQ(callouts[0].priority, "high");
617 EXPECT_EQ(callouts[0].locCode, "P1-C5");
618 EXPECT_EQ(callouts[0].procedure, "");
619 EXPECT_EQ(callouts[0].symbolicFRU, "");
620 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
621 EXPECT_EQ(callouts[1].priority, "medium");
622 EXPECT_EQ(callouts[1].locCode, "P1-C6");
623 EXPECT_EQ(callouts[1].procedure, "");
624 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
625 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
626 EXPECT_EQ(callouts[2].priority, "low");
627 EXPECT_EQ(callouts[2].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500628 EXPECT_EQ(callouts[2].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500629 EXPECT_EQ(callouts[2].symbolicFRU, "");
630 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
631
632 // Find callouts for PROC_NUM 0 that uses the default system entry.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500633 names[0] = "system99";
634
635 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500636 EXPECT_EQ(callouts.size(), 1);
637 EXPECT_EQ(callouts[0].priority, "low");
638 EXPECT_EQ(callouts[0].locCode, "P55");
639 EXPECT_EQ(callouts[0].procedure, "");
640 EXPECT_EQ(callouts[0].symbolicFRU, "");
641 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
642 }
643 {
644 // Find callouts for PROC_NUM 1 that uses a default system entry.
645 std::vector<std::string> adData{"PROC_NUM=1"};
646 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500647 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500648
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500649 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500650 EXPECT_EQ(callouts.size(), 1);
651 EXPECT_EQ(callouts[0].priority, "high");
652 EXPECT_EQ(callouts[0].locCode, "P1-C6");
653 EXPECT_EQ(callouts[0].procedure, "");
654 EXPECT_EQ(callouts[0].symbolicFRU, "");
655 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
656 }
657 {
Matt Spinlerf397afc2021-01-29 11:21:44 -0600658 // There is no entry for PROC_NUM 2, so no callouts
Matt Spinler6b427cc2020-04-09 09:42:59 -0500659 std::vector<std::string> adData{"PROC_NUM=2"};
660 AdditionalData ad{adData};
661
Matt Spinlerf397afc2021-01-29 11:21:44 -0600662 auto callouts = Registry::getCallouts(json, names, ad);
663 EXPECT_TRUE(callouts.empty());
Matt Spinler6b427cc2020-04-09 09:42:59 -0500664 }
665 }
Matt Spinler3d923312022-08-01 09:52:55 -0500666
667 {
668 // Callouts with a 'CalloutsWhenNoADMatch' section that will
669 // be used when the AdditionalData value doesn't match.
670 auto json = R"(
671 {
672 "ADName": "PROC_NUM",
673 "CalloutsWithTheirADValues":
674 [
675 {
676 "ADValue": "0",
677 "Callouts":
678 [
679 {
680 "CalloutList":
681 [
682 {
683 "Priority": "high",
684 "LocCode": "P0-C0"
685 }
686 ]
687 }
688 ]
689 }
690 ],
691 "CalloutsWhenNoADMatch": [
692 {
693 "CalloutList": [
694 {
695 "Priority": "medium",
696 "LocCode": "P1-C1"
697 }
698 ]
699 }
700 ]
701 })"_json;
702
703 // There isn't an entry in the JSON for a PROC_NUM of 8
704 // so it should choose the P1-C1 callout.
705 std::vector<std::string> adData{"PROC_NUM=8"};
706 AdditionalData ad{adData};
707 names.clear();
708
709 auto callouts = Registry::getCallouts(json, names, ad);
710 EXPECT_EQ(callouts.size(), 1);
711 EXPECT_EQ(callouts[0].priority, "medium");
712 EXPECT_EQ(callouts[0].locCode, "P1-C1");
713 }
Matt Spinler6b427cc2020-04-09 09:42:59 -0500714}
Matt Spinler23970b02022-02-25 16:34:46 -0600715
716TEST_F(RegistryTest, TestNoSubsystem)
717{
718 auto path = RegistryTest::writeData(registryData);
719 Registry registry{path};
720
721 auto entry = registry.lookup("xyz.openbmc_project.Common.Error.Timeout",
722 LookupType::name);
723 ASSERT_TRUE(entry);
724 EXPECT_FALSE(entry->subsystem);
725}