blob: c7d88c9fdcebb6ab905aab6df6e94f4149ef1ec4 [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 }
104 }
105 ]
106}
107)";
108
109class RegistryTest : public ::testing::Test
110{
111 protected:
112 static void SetUpTestCase()
113 {
114 char path[] = "/tmp/regtestXXXXXX";
115 regDir = mkdtemp(path);
116 }
117
118 static void TearDownTestCase()
119 {
120 fs::remove_all(regDir);
121 }
122
123 static std::string writeData(const char* data)
124 {
125 fs::path path = regDir / "registry.json";
126 std::ofstream stream{path};
127 stream << data;
128 return path;
129 }
130
131 static fs::path regDir;
132};
133
134fs::path RegistryTest::regDir{};
135
136TEST_F(RegistryTest, TestNoEntry)
137{
138 auto path = RegistryTest::writeData(registryData);
139 Registry registry{path};
140
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800141 auto entry = registry.lookup("foo", LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500142 EXPECT_FALSE(entry);
143}
144
145TEST_F(RegistryTest, TestFindEntry)
146{
147 auto path = RegistryTest::writeData(registryData);
148 Registry registry{path};
149
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800150 auto entry = registry.lookup("xyz.openbmc_project.Power.OverVoltage",
151 LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500152 ASSERT_TRUE(entry);
153 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
154 EXPECT_EQ(entry->subsystem, 0x62);
Matt Spinleraadccc82020-04-10 14:33:42 -0500155
156 ASSERT_EQ(entry->severity->size(), 3);
157 EXPECT_EQ((*entry->severity)[0].severity, 0x40);
158 EXPECT_EQ((*entry->severity)[0].system, "systemA");
159 EXPECT_EQ((*entry->severity)[1].severity, 0x10);
160 EXPECT_EQ((*entry->severity)[1].system, "systemB");
161 EXPECT_EQ((*entry->severity)[2].severity, 0x20);
162 EXPECT_EQ((*entry->severity)[2].system, "");
163
164 EXPECT_EQ(entry->mfgSeverity->size(), 1);
165 EXPECT_EQ((*entry->mfgSeverity)[0].severity, 0x00);
166
Matt Spinlere07f9152019-11-01 10:48:36 -0500167 EXPECT_EQ(*(entry->actionFlags), 0xA800);
Matt Spinler367144c2019-09-19 15:33:52 -0500168 EXPECT_EQ(*(entry->mfgActionFlags), 0x4000);
Matt Spinler93e29322019-09-20 11:16:15 -0500169 EXPECT_EQ(entry->componentID, 0x2300);
Matt Spinler367144c2019-09-19 15:33:52 -0500170 EXPECT_FALSE(entry->eventType);
171 EXPECT_FALSE(entry->eventScope);
172
Matt Spinler93e29322019-09-20 11:16:15 -0500173 EXPECT_EQ(entry->src.type, 0xBD);
174 EXPECT_EQ(entry->src.reasonCode, 0x2333);
175 EXPECT_EQ(*(entry->src.powerFault), true);
176
177 auto& hexwords = entry->src.hexwordADFields;
178 EXPECT_TRUE(hexwords);
179 EXPECT_EQ((*hexwords).size(), 2);
180
181 auto word = (*hexwords).find(6);
182 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800183 EXPECT_EQ(std::get<0>(word->second), "PS_NUM");
Matt Spinler93e29322019-09-20 11:16:15 -0500184
185 word = (*hexwords).find(7);
186 EXPECT_NE(word, (*hexwords).end());
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800187 EXPECT_EQ(std::get<0>(word->second), "VOLTAGE");
Matt Spinler93e29322019-09-20 11:16:15 -0500188
189 auto& sid = entry->src.symptomID;
190 EXPECT_TRUE(sid);
191 EXPECT_EQ((*sid).size(), 3);
192 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 5), (*sid).end());
193 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 6), (*sid).end());
194 EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 7), (*sid).end());
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800195
196 EXPECT_EQ(entry->doc.description, "A PGOOD Fault");
197 EXPECT_EQ(entry->doc.message, "PS %1 had a PGOOD Fault");
198 auto& hexwordSource = entry->doc.messageArgSources;
199 EXPECT_TRUE(hexwordSource);
200 EXPECT_EQ((*hexwordSource).size(), 1);
201 EXPECT_EQ((*hexwordSource).front(), "SRCWord6");
202
203 entry = registry.lookup("0x2333", LookupType::reasonCode);
204 ASSERT_TRUE(entry);
205 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
Matt Spinler367144c2019-09-19 15:33:52 -0500206}
207
208// Check the entry that mostly uses defaults
209TEST_F(RegistryTest, TestFindEntryMinimal)
210{
211 auto path = RegistryTest::writeData(registryData);
212 Registry registry{path};
213
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800214 auto entry =
215 registry.lookup("xyz.openbmc_project.Power.Fault", LookupType::name);
Matt Spinler367144c2019-09-19 15:33:52 -0500216 ASSERT_TRUE(entry);
217 EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.Fault");
218 EXPECT_EQ(entry->subsystem, 0x61);
219 EXPECT_FALSE(entry->severity);
220 EXPECT_FALSE(entry->mfgSeverity);
221 EXPECT_FALSE(entry->mfgActionFlags);
Matt Spinlere07f9152019-11-01 10:48:36 -0500222 EXPECT_FALSE(entry->actionFlags);
Matt Spinler93e29322019-09-20 11:16:15 -0500223 EXPECT_EQ(entry->componentID, 0x2000);
Matt Spinler367144c2019-09-19 15:33:52 -0500224 EXPECT_FALSE(entry->eventType);
225 EXPECT_FALSE(entry->eventScope);
Matt Spinler93e29322019-09-20 11:16:15 -0500226
227 EXPECT_EQ(entry->src.reasonCode, 0x2030);
228 EXPECT_EQ(entry->src.type, 0xBD);
229 EXPECT_FALSE(entry->src.powerFault);
230 EXPECT_FALSE(entry->src.hexwordADFields);
231 EXPECT_FALSE(entry->src.symptomID);
Matt Spinler367144c2019-09-19 15:33:52 -0500232}
233
234TEST_F(RegistryTest, TestBadJSON)
235{
236 auto path = RegistryTest::writeData("bad {} json");
237
238 Registry registry{path};
239
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800240 EXPECT_FALSE(registry.lookup("foo", LookupType::name));
Matt Spinler367144c2019-09-19 15:33:52 -0500241}
242
243// Test the helper functions the use the pel_values data.
244TEST_F(RegistryTest, TestHelperFunctions)
245{
246 using namespace openpower::pels::message::helper;
247 EXPECT_EQ(getSubsystem("input_power_source"), 0xA1);
248 EXPECT_THROW(getSubsystem("foo"), std::runtime_error);
249
250 EXPECT_EQ(getSeverity("symptom_recovered"), 0x71);
251 EXPECT_THROW(getSeverity("foo"), std::runtime_error);
252
253 EXPECT_EQ(getEventType("dump_notification"), 0x08);
254 EXPECT_THROW(getEventType("foo"), std::runtime_error);
255
256 EXPECT_EQ(getEventScope("possibly_multiple_platforms"), 0x04);
257 EXPECT_THROW(getEventScope("foo"), std::runtime_error);
258
259 std::vector<std::string> flags{"service_action", "dont_report",
260 "termination"};
261 EXPECT_EQ(getActionFlags(flags), 0x9100);
262
263 flags.clear();
264 flags.push_back("foo");
265 EXPECT_THROW(getActionFlags(flags), std::runtime_error);
266}
Matt Spinler93e29322019-09-20 11:16:15 -0500267
268TEST_F(RegistryTest, TestGetSRCReasonCode)
269{
270 using namespace openpower::pels::message::helper;
271 EXPECT_EQ(getSRCReasonCode(R"({"ReasonCode": "0x5555"})"_json, "foo"),
272 0x5555);
273
274 EXPECT_THROW(getSRCReasonCode(R"({"ReasonCode": "ZZZZ"})"_json, "foo"),
275 std::runtime_error);
276}
277
278TEST_F(RegistryTest, TestGetSRCType)
279{
280 using namespace openpower::pels::message::helper;
281 EXPECT_EQ(getSRCType(R"({"Type": "11"})"_json, "foo"), 0x11);
282 EXPECT_EQ(getSRCType(R"({"Type": "BF"})"_json, "foo"), 0xBF);
283
284 EXPECT_THROW(getSRCType(R"({"Type": "1"})"_json, "foo"),
285 std::runtime_error);
286
287 EXPECT_THROW(getSRCType(R"({"Type": "111"})"_json, "foo"),
288 std::runtime_error);
289}
290
291TEST_F(RegistryTest, TestGetSRCHexwordFields)
292{
293 using namespace openpower::pels::message::helper;
294 const auto hexwords = R"(
295 {"Words6To9":
296 {
297 "8":
298 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800299 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500300 "AdditionalDataPropSource": "TEST"
301 }
302 }
303 })"_json;
304
305 auto fields = getSRCHexwordFields(hexwords, "foo");
306 EXPECT_TRUE(fields);
307 auto word = fields->find(8);
308 EXPECT_NE(word, fields->end());
309
310 const auto theInvalidRWord = R"(
311 {"Words6To9":
312 {
313 "R":
314 {
Harisuddin Mohamed Isa1a1b0df2020-11-23 16:34:36 +0800315 "Description": "TEST",
Matt Spinler93e29322019-09-20 11:16:15 -0500316 "AdditionalDataPropSource": "TEST"
317 }
318 }
319 })"_json;
320
321 EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"),
322 std::runtime_error);
323}
324
325TEST_F(RegistryTest, TestGetSRCSymptomIDFields)
326{
327 using namespace openpower::pels::message::helper;
328 const auto sID = R"(
329 {
330 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord5"]
331 })"_json;
332
333 auto fields = getSRCSymptomIDFields(sID, "foo");
334 EXPECT_NE(std::find(fields->begin(), fields->end(), 3), fields->end());
335 EXPECT_NE(std::find(fields->begin(), fields->end(), 4), fields->end());
336 EXPECT_NE(std::find(fields->begin(), fields->end(), 5), fields->end());
337
338 const auto badField = R"(
339 {
340 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord"]
341 })"_json;
342
343 EXPECT_THROW(getSRCSymptomIDFields(badField, "foo"), std::runtime_error);
344}
345
346TEST_F(RegistryTest, TestGetComponentID)
347{
348 using namespace openpower::pels::message::helper;
349
350 // Get it from the JSON
351 auto id =
352 getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json, "foo");
353 EXPECT_EQ(id, 0x4200);
354
355 // Get it from the reason code on a 0xBD SRC
356 id = getComponentID(0xBD, 0x6700, R"({})"_json, "foo");
357 EXPECT_EQ(id, 0x6700);
358
359 // Not present on a 0x11 SRC
360 EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"),
361 std::runtime_error);
362}
Matt Spinler6b427cc2020-04-09 09:42:59 -0500363
364// Test when callouts are in the JSON.
365TEST_F(RegistryTest, TestGetCallouts)
366{
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500367 std::vector<std::string> names;
368
Matt Spinler6b427cc2020-04-09 09:42:59 -0500369 {
370 // Callouts without AD, that depend on system type,
371 // where there is a default entry without a system type.
372 auto json = R"(
373 [
374 {
375 "System": "system1",
376 "CalloutList":
377 [
378 {
379 "Priority": "high",
380 "LocCode": "P1-C1"
381 },
382 {
383 "Priority": "low",
384 "LocCode": "P1"
385 },
386 {
387 "Priority": "low",
388 "SymbolicFRU": "service_docs"
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500389 },
390 {
391 "Priority": "low",
392 "SymbolicFRUTrusted": "air_mover",
393 "UseInventoryLocCode": true
Matt Spinler6b427cc2020-04-09 09:42:59 -0500394 }
395 ]
396 },
397 {
398 "CalloutList":
399 [
400 {
401 "Priority": "medium",
Matt Spinler479b6922021-08-17 16:34:59 -0500402 "Procedure": "bmc_code"
Matt Spinler6b427cc2020-04-09 09:42:59 -0500403 },
404 {
405 "Priority": "low",
406 "LocCode": "P3-C8",
407 "SymbolicFRUTrusted": "service_docs"
408 }
409 ]
410
411 }
412 ])"_json;
413
414 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500415 names.push_back("system1");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500416
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500417 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500418 EXPECT_EQ(callouts.size(), 4);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500419 EXPECT_EQ(callouts[0].priority, "high");
420 EXPECT_EQ(callouts[0].locCode, "P1-C1");
421 EXPECT_EQ(callouts[0].procedure, "");
422 EXPECT_EQ(callouts[0].symbolicFRU, "");
423 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
424 EXPECT_EQ(callouts[1].priority, "low");
425 EXPECT_EQ(callouts[1].locCode, "P1");
426 EXPECT_EQ(callouts[1].procedure, "");
427 EXPECT_EQ(callouts[1].symbolicFRU, "");
428 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
429 EXPECT_EQ(callouts[2].priority, "low");
430 EXPECT_EQ(callouts[2].locCode, "");
431 EXPECT_EQ(callouts[2].procedure, "");
432 EXPECT_EQ(callouts[2].symbolicFRU, "service_docs");
433 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500434 EXPECT_EQ(callouts[3].priority, "low");
435 EXPECT_EQ(callouts[3].locCode, "");
436 EXPECT_EQ(callouts[3].procedure, "");
437 EXPECT_EQ(callouts[3].symbolicFRU, "");
438 EXPECT_EQ(callouts[3].symbolicFRUTrusted, "air_mover");
439 EXPECT_EQ(callouts[3].useInventoryLocCode, true);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500440
441 // system2 isn't in the JSON, so it will pick the default one
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500442 names[0] = "system2";
443 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500444 EXPECT_EQ(callouts.size(), 2);
445 EXPECT_EQ(callouts[0].priority, "medium");
446 EXPECT_EQ(callouts[0].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500447 EXPECT_EQ(callouts[0].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500448 EXPECT_EQ(callouts[0].symbolicFRU, "");
449 EXPECT_EQ(callouts[1].priority, "low");
450 EXPECT_EQ(callouts[1].locCode, "P3-C8");
451 EXPECT_EQ(callouts[1].procedure, "");
452 EXPECT_EQ(callouts[1].symbolicFRU, "");
453 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "service_docs");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500454 EXPECT_EQ(callouts[1].useInventoryLocCode, false);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500455 }
456
457 // Empty JSON array (treated as an error)
458 {
459 auto json = R"([])"_json;
460 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500461 names[0] = "system1";
462 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500463 std::runtime_error);
464 }
465
466 {
467 // Callouts without AD, that depend on system type,
468 // where there isn't a default entry without a system type.
469 auto json = R"(
470 [
471 {
472 "System": "system1",
473 "CalloutList":
474 [
475 {
476 "Priority": "high",
477 "LocCode": "P1-C1"
478 },
479 {
480 "Priority": "low",
481 "LocCode": "P1",
482 "SymbolicFRU": "1234567"
483 }
484 ]
485 },
486 {
487 "System": "system2",
488 "CalloutList":
489 [
490 {
491 "Priority": "medium",
492 "LocCode": "P7",
493 "CalloutType": "tool_fru"
494 }
495 ]
496
497 }
498 ])"_json;
499
500 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500501 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500502
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500503 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500504 EXPECT_EQ(callouts.size(), 2);
505 EXPECT_EQ(callouts[0].priority, "high");
506 EXPECT_EQ(callouts[0].locCode, "P1-C1");
507 EXPECT_EQ(callouts[0].procedure, "");
508 EXPECT_EQ(callouts[0].symbolicFRU, "");
509 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
510 EXPECT_EQ(callouts[1].priority, "low");
511 EXPECT_EQ(callouts[1].locCode, "P1");
512 EXPECT_EQ(callouts[1].procedure, "");
513 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
514 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
515
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500516 names[0] = "system2";
517 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500518 EXPECT_EQ(callouts.size(), 1);
519 EXPECT_EQ(callouts[0].priority, "medium");
520 EXPECT_EQ(callouts[0].locCode, "P7");
521 EXPECT_EQ(callouts[0].procedure, "");
522 EXPECT_EQ(callouts[0].symbolicFRU, "");
523 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
524
525 // There is no entry for system3 or a default system,
526 // so this should fail.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500527 names[0] = "system3";
528 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500529 std::runtime_error);
530 }
531
532 {
533 // Callouts that use the AdditionalData key PROC_NUM
534 // as an index into them, along with a system type.
535 // It supports PROC_NUMs 0 and 1.
536 auto json = R"(
537 {
538 "ADName": "PROC_NUM",
539 "CalloutsWithTheirADValues":
540 [
541 {
542 "ADValue": "0",
543 "Callouts":
544 [
545 {
546 "System": "system3",
547 "CalloutList":
548 [
549 {
550 "Priority": "high",
551 "LocCode": "P1-C5"
552 },
553 {
554 "Priority": "medium",
555 "LocCode": "P1-C6",
556 "SymbolicFRU": "1234567"
557 },
558 {
559 "Priority": "low",
Matt Spinler479b6922021-08-17 16:34:59 -0500560 "Procedure": "bmc_code",
Matt Spinler6b427cc2020-04-09 09:42:59 -0500561 "CalloutType": "config_procedure"
562 }
563 ]
564 },
565 {
566 "CalloutList":
567 [
568 {
569 "Priority": "low",
570 "LocCode": "P55"
571 }
572 ]
573 }
574 ]
575 },
576 {
577 "ADValue": "1",
578 "Callouts":
579 [
580 {
581 "CalloutList":
582 [
583 {
584 "Priority": "high",
585 "LocCode": "P1-C6",
586 "CalloutType": "external_fru"
587 }
588 ]
589 }
590 ]
591 }
592 ]
593 })"_json;
594
595 {
596 // Find callouts for PROC_NUM 0 on system3
597 std::vector<std::string> adData{"PROC_NUM=0"};
598 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500599 names[0] = "system3";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500600
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500601 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500602 EXPECT_EQ(callouts.size(), 3);
603 EXPECT_EQ(callouts[0].priority, "high");
604 EXPECT_EQ(callouts[0].locCode, "P1-C5");
605 EXPECT_EQ(callouts[0].procedure, "");
606 EXPECT_EQ(callouts[0].symbolicFRU, "");
607 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
608 EXPECT_EQ(callouts[1].priority, "medium");
609 EXPECT_EQ(callouts[1].locCode, "P1-C6");
610 EXPECT_EQ(callouts[1].procedure, "");
611 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
612 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
613 EXPECT_EQ(callouts[2].priority, "low");
614 EXPECT_EQ(callouts[2].locCode, "");
Matt Spinler479b6922021-08-17 16:34:59 -0500615 EXPECT_EQ(callouts[2].procedure, "bmc_code");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500616 EXPECT_EQ(callouts[2].symbolicFRU, "");
617 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
618
619 // Find callouts for PROC_NUM 0 that uses the default system entry.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500620 names[0] = "system99";
621
622 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500623 EXPECT_EQ(callouts.size(), 1);
624 EXPECT_EQ(callouts[0].priority, "low");
625 EXPECT_EQ(callouts[0].locCode, "P55");
626 EXPECT_EQ(callouts[0].procedure, "");
627 EXPECT_EQ(callouts[0].symbolicFRU, "");
628 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
629 }
630 {
631 // Find callouts for PROC_NUM 1 that uses a default system entry.
632 std::vector<std::string> adData{"PROC_NUM=1"};
633 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500634 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500635
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500636 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500637 EXPECT_EQ(callouts.size(), 1);
638 EXPECT_EQ(callouts[0].priority, "high");
639 EXPECT_EQ(callouts[0].locCode, "P1-C6");
640 EXPECT_EQ(callouts[0].procedure, "");
641 EXPECT_EQ(callouts[0].symbolicFRU, "");
642 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
643 }
644 {
Matt Spinlerf397afc2021-01-29 11:21:44 -0600645 // There is no entry for PROC_NUM 2, so no callouts
Matt Spinler6b427cc2020-04-09 09:42:59 -0500646 std::vector<std::string> adData{"PROC_NUM=2"};
647 AdditionalData ad{adData};
648
Matt Spinlerf397afc2021-01-29 11:21:44 -0600649 auto callouts = Registry::getCallouts(json, names, ad);
650 EXPECT_TRUE(callouts.empty());
Matt Spinler6b427cc2020-04-09 09:42:59 -0500651 }
652 }
653}