blob: 08eefc4113b0d78a1283ab0805bfd958e10ac99c [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 {
79 "description": "Failing unit number",
80 "AdditionalDataPropSource": "PS_NUM"
81 },
82
83 "7":
84 {
85 "description": "bad voltage",
86 "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());
183 EXPECT_EQ(word->second, "PS_NUM");
184
185 word = (*hexwords).find(7);
186 EXPECT_NE(word, (*hexwords).end());
187 EXPECT_EQ(word->second, "VOLTAGE");
188
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 {
299 "AdditionalDataPropSource": "TEST"
300 }
301 }
302 })"_json;
303
304 auto fields = getSRCHexwordFields(hexwords, "foo");
305 EXPECT_TRUE(fields);
306 auto word = fields->find(8);
307 EXPECT_NE(word, fields->end());
308
309 const auto theInvalidRWord = R"(
310 {"Words6To9":
311 {
312 "R":
313 {
314 "AdditionalDataPropSource": "TEST"
315 }
316 }
317 })"_json;
318
319 EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"),
320 std::runtime_error);
321}
322
323TEST_F(RegistryTest, TestGetSRCSymptomIDFields)
324{
325 using namespace openpower::pels::message::helper;
326 const auto sID = R"(
327 {
328 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord5"]
329 })"_json;
330
331 auto fields = getSRCSymptomIDFields(sID, "foo");
332 EXPECT_NE(std::find(fields->begin(), fields->end(), 3), fields->end());
333 EXPECT_NE(std::find(fields->begin(), fields->end(), 4), fields->end());
334 EXPECT_NE(std::find(fields->begin(), fields->end(), 5), fields->end());
335
336 const auto badField = R"(
337 {
338 "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord"]
339 })"_json;
340
341 EXPECT_THROW(getSRCSymptomIDFields(badField, "foo"), std::runtime_error);
342}
343
344TEST_F(RegistryTest, TestGetComponentID)
345{
346 using namespace openpower::pels::message::helper;
347
348 // Get it from the JSON
349 auto id =
350 getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json, "foo");
351 EXPECT_EQ(id, 0x4200);
352
353 // Get it from the reason code on a 0xBD SRC
354 id = getComponentID(0xBD, 0x6700, R"({})"_json, "foo");
355 EXPECT_EQ(id, 0x6700);
356
357 // Not present on a 0x11 SRC
358 EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"),
359 std::runtime_error);
360}
Matt Spinler6b427cc2020-04-09 09:42:59 -0500361
362// Test when callouts are in the JSON.
363TEST_F(RegistryTest, TestGetCallouts)
364{
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500365 std::vector<std::string> names;
366
Matt Spinler6b427cc2020-04-09 09:42:59 -0500367 {
368 // Callouts without AD, that depend on system type,
369 // where there is a default entry without a system type.
370 auto json = R"(
371 [
372 {
373 "System": "system1",
374 "CalloutList":
375 [
376 {
377 "Priority": "high",
378 "LocCode": "P1-C1"
379 },
380 {
381 "Priority": "low",
382 "LocCode": "P1"
383 },
384 {
385 "Priority": "low",
386 "SymbolicFRU": "service_docs"
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500387 },
388 {
389 "Priority": "low",
390 "SymbolicFRUTrusted": "air_mover",
391 "UseInventoryLocCode": true
Matt Spinler6b427cc2020-04-09 09:42:59 -0500392 }
393 ]
394 },
395 {
396 "CalloutList":
397 [
398 {
399 "Priority": "medium",
400 "Procedure": "no_vpd_for_fru"
401 },
402 {
403 "Priority": "low",
404 "LocCode": "P3-C8",
405 "SymbolicFRUTrusted": "service_docs"
406 }
407 ]
408
409 }
410 ])"_json;
411
412 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500413 names.push_back("system1");
Matt Spinler6b427cc2020-04-09 09:42:59 -0500414
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500415 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500416 EXPECT_EQ(callouts.size(), 4);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500417 EXPECT_EQ(callouts[0].priority, "high");
418 EXPECT_EQ(callouts[0].locCode, "P1-C1");
419 EXPECT_EQ(callouts[0].procedure, "");
420 EXPECT_EQ(callouts[0].symbolicFRU, "");
421 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
422 EXPECT_EQ(callouts[1].priority, "low");
423 EXPECT_EQ(callouts[1].locCode, "P1");
424 EXPECT_EQ(callouts[1].procedure, "");
425 EXPECT_EQ(callouts[1].symbolicFRU, "");
426 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
427 EXPECT_EQ(callouts[2].priority, "low");
428 EXPECT_EQ(callouts[2].locCode, "");
429 EXPECT_EQ(callouts[2].procedure, "");
430 EXPECT_EQ(callouts[2].symbolicFRU, "service_docs");
431 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500432 EXPECT_EQ(callouts[3].priority, "low");
433 EXPECT_EQ(callouts[3].locCode, "");
434 EXPECT_EQ(callouts[3].procedure, "");
435 EXPECT_EQ(callouts[3].symbolicFRU, "");
436 EXPECT_EQ(callouts[3].symbolicFRUTrusted, "air_mover");
437 EXPECT_EQ(callouts[3].useInventoryLocCode, true);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500438
439 // system2 isn't in the JSON, so it will pick the default one
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500440 names[0] = "system2";
441 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500442 EXPECT_EQ(callouts.size(), 2);
443 EXPECT_EQ(callouts[0].priority, "medium");
444 EXPECT_EQ(callouts[0].locCode, "");
445 EXPECT_EQ(callouts[0].procedure, "no_vpd_for_fru");
446 EXPECT_EQ(callouts[0].symbolicFRU, "");
447 EXPECT_EQ(callouts[1].priority, "low");
448 EXPECT_EQ(callouts[1].locCode, "P3-C8");
449 EXPECT_EQ(callouts[1].procedure, "");
450 EXPECT_EQ(callouts[1].symbolicFRU, "");
451 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "service_docs");
Matt Spinlerf00f9d02020-10-23 09:14:22 -0500452 EXPECT_EQ(callouts[1].useInventoryLocCode, false);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500453 }
454
455 // Empty JSON array (treated as an error)
456 {
457 auto json = R"([])"_json;
458 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500459 names[0] = "system1";
460 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500461 std::runtime_error);
462 }
463
464 {
465 // Callouts without AD, that depend on system type,
466 // where there isn't a default entry without a system type.
467 auto json = R"(
468 [
469 {
470 "System": "system1",
471 "CalloutList":
472 [
473 {
474 "Priority": "high",
475 "LocCode": "P1-C1"
476 },
477 {
478 "Priority": "low",
479 "LocCode": "P1",
480 "SymbolicFRU": "1234567"
481 }
482 ]
483 },
484 {
485 "System": "system2",
486 "CalloutList":
487 [
488 {
489 "Priority": "medium",
490 "LocCode": "P7",
491 "CalloutType": "tool_fru"
492 }
493 ]
494
495 }
496 ])"_json;
497
498 AdditionalData ad;
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500499 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500500
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500501 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500502 EXPECT_EQ(callouts.size(), 2);
503 EXPECT_EQ(callouts[0].priority, "high");
504 EXPECT_EQ(callouts[0].locCode, "P1-C1");
505 EXPECT_EQ(callouts[0].procedure, "");
506 EXPECT_EQ(callouts[0].symbolicFRU, "");
507 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
508 EXPECT_EQ(callouts[1].priority, "low");
509 EXPECT_EQ(callouts[1].locCode, "P1");
510 EXPECT_EQ(callouts[1].procedure, "");
511 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
512 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
513
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500514 names[0] = "system2";
515 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500516 EXPECT_EQ(callouts.size(), 1);
517 EXPECT_EQ(callouts[0].priority, "medium");
518 EXPECT_EQ(callouts[0].locCode, "P7");
519 EXPECT_EQ(callouts[0].procedure, "");
520 EXPECT_EQ(callouts[0].symbolicFRU, "");
521 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
522
523 // There is no entry for system3 or a default system,
524 // so this should fail.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500525 names[0] = "system3";
526 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500527 std::runtime_error);
528 }
529
530 {
531 // Callouts that use the AdditionalData key PROC_NUM
532 // as an index into them, along with a system type.
533 // It supports PROC_NUMs 0 and 1.
534 auto json = R"(
535 {
536 "ADName": "PROC_NUM",
537 "CalloutsWithTheirADValues":
538 [
539 {
540 "ADValue": "0",
541 "Callouts":
542 [
543 {
544 "System": "system3",
545 "CalloutList":
546 [
547 {
548 "Priority": "high",
549 "LocCode": "P1-C5"
550 },
551 {
552 "Priority": "medium",
553 "LocCode": "P1-C6",
554 "SymbolicFRU": "1234567"
555 },
556 {
557 "Priority": "low",
558 "Procedure": "no_vpd_for_fru",
559 "CalloutType": "config_procedure"
560 }
561 ]
562 },
563 {
564 "CalloutList":
565 [
566 {
567 "Priority": "low",
568 "LocCode": "P55"
569 }
570 ]
571 }
572 ]
573 },
574 {
575 "ADValue": "1",
576 "Callouts":
577 [
578 {
579 "CalloutList":
580 [
581 {
582 "Priority": "high",
583 "LocCode": "P1-C6",
584 "CalloutType": "external_fru"
585 }
586 ]
587 }
588 ]
589 }
590 ]
591 })"_json;
592
593 {
594 // Find callouts for PROC_NUM 0 on system3
595 std::vector<std::string> adData{"PROC_NUM=0"};
596 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500597 names[0] = "system3";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500598
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500599 auto callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500600 EXPECT_EQ(callouts.size(), 3);
601 EXPECT_EQ(callouts[0].priority, "high");
602 EXPECT_EQ(callouts[0].locCode, "P1-C5");
603 EXPECT_EQ(callouts[0].procedure, "");
604 EXPECT_EQ(callouts[0].symbolicFRU, "");
605 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
606 EXPECT_EQ(callouts[1].priority, "medium");
607 EXPECT_EQ(callouts[1].locCode, "P1-C6");
608 EXPECT_EQ(callouts[1].procedure, "");
609 EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
610 EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
611 EXPECT_EQ(callouts[2].priority, "low");
612 EXPECT_EQ(callouts[2].locCode, "");
613 EXPECT_EQ(callouts[2].procedure, "no_vpd_for_fru");
614 EXPECT_EQ(callouts[2].symbolicFRU, "");
615 EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
616
617 // Find callouts for PROC_NUM 0 that uses the default system entry.
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500618 names[0] = "system99";
619
620 callouts = Registry::getCallouts(json, names, ad);
Matt Spinler6b427cc2020-04-09 09:42:59 -0500621 EXPECT_EQ(callouts.size(), 1);
622 EXPECT_EQ(callouts[0].priority, "low");
623 EXPECT_EQ(callouts[0].locCode, "P55");
624 EXPECT_EQ(callouts[0].procedure, "");
625 EXPECT_EQ(callouts[0].symbolicFRU, "");
626 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
627 }
628 {
629 // Find callouts for PROC_NUM 1 that uses a default system entry.
630 std::vector<std::string> adData{"PROC_NUM=1"};
631 AdditionalData ad{adData};
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500632 names[0] = "system1";
Matt Spinler6b427cc2020-04-09 09:42:59 -0500633
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500634 auto 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, "high");
637 EXPECT_EQ(callouts[0].locCode, "P1-C6");
638 EXPECT_EQ(callouts[0].procedure, "");
639 EXPECT_EQ(callouts[0].symbolicFRU, "");
640 EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
641 }
642 {
643 // There is no entry for PROC_NUM 2, it will fail.
644 std::vector<std::string> adData{"PROC_NUM=2"};
645 AdditionalData ad{adData};
646
Matt Spinler6ea4d5f2020-05-20 13:31:07 -0500647 EXPECT_THROW(Registry::getCallouts(json, names, ad),
Matt Spinler6b427cc2020-04-09 09:42:59 -0500648 std::runtime_error);
649 }
650 }
651}