PEL: Find message registry callouts to use
Add Registry::getCallouts() to find, based on the system type and
AdditionalData property, the callouts that apply for the callout JSON
passed in. This will be used to choose the callouts to add to a PEL
based on the system and current failure informaton.
These files describe the actual JSON format:
* extensions/openpower-pels/registry/README.md
* extensions/openpower-pels/registry/schema/schema.json
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I5901e459981b10f6c338d3ef827d9128338dca50
diff --git a/test/openpower-pels/registry_test.cpp b/test/openpower-pels/registry_test.cpp
index 2944ce0..92c1b14 100644
--- a/test/openpower-pels/registry_test.cpp
+++ b/test/openpower-pels/registry_test.cpp
@@ -22,6 +22,7 @@
#include <gtest/gtest.h>
using namespace openpower::pels::message;
+using namespace openpower::pels;
namespace fs = std::filesystem;
const auto registryData = R"(
@@ -334,3 +335,270 @@
EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"),
std::runtime_error);
}
+
+// Test when callouts are in the JSON.
+TEST_F(RegistryTest, TestGetCallouts)
+{
+ {
+ // Callouts without AD, that depend on system type,
+ // where there is a default entry without a system type.
+ auto json = R"(
+ [
+ {
+ "System": "system1",
+ "CalloutList":
+ [
+ {
+ "Priority": "high",
+ "LocCode": "P1-C1"
+ },
+ {
+ "Priority": "low",
+ "LocCode": "P1"
+ },
+ {
+ "Priority": "low",
+ "SymbolicFRU": "service_docs"
+ }
+ ]
+ },
+ {
+ "CalloutList":
+ [
+ {
+ "Priority": "medium",
+ "Procedure": "no_vpd_for_fru"
+ },
+ {
+ "Priority": "low",
+ "LocCode": "P3-C8",
+ "SymbolicFRUTrusted": "service_docs"
+ }
+ ]
+
+ }
+ ])"_json;
+
+ AdditionalData ad;
+
+ auto callouts = Registry::getCallouts(json, "system1", ad);
+ EXPECT_EQ(callouts.size(), 3);
+ EXPECT_EQ(callouts[0].priority, "high");
+ EXPECT_EQ(callouts[0].locCode, "P1-C1");
+ EXPECT_EQ(callouts[0].procedure, "");
+ EXPECT_EQ(callouts[0].symbolicFRU, "");
+ EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
+ EXPECT_EQ(callouts[1].priority, "low");
+ EXPECT_EQ(callouts[1].locCode, "P1");
+ EXPECT_EQ(callouts[1].procedure, "");
+ EXPECT_EQ(callouts[1].symbolicFRU, "");
+ EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
+ EXPECT_EQ(callouts[2].priority, "low");
+ EXPECT_EQ(callouts[2].locCode, "");
+ EXPECT_EQ(callouts[2].procedure, "");
+ EXPECT_EQ(callouts[2].symbolicFRU, "service_docs");
+ EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
+
+ // system2 isn't in the JSON, so it will pick the default one
+ callouts = Registry::getCallouts(json, "system2", ad);
+ EXPECT_EQ(callouts.size(), 2);
+ EXPECT_EQ(callouts[0].priority, "medium");
+ EXPECT_EQ(callouts[0].locCode, "");
+ EXPECT_EQ(callouts[0].procedure, "no_vpd_for_fru");
+ EXPECT_EQ(callouts[0].symbolicFRU, "");
+ EXPECT_EQ(callouts[1].priority, "low");
+ EXPECT_EQ(callouts[1].locCode, "P3-C8");
+ EXPECT_EQ(callouts[1].procedure, "");
+ EXPECT_EQ(callouts[1].symbolicFRU, "");
+ EXPECT_EQ(callouts[1].symbolicFRUTrusted, "service_docs");
+ }
+
+ // Empty JSON array (treated as an error)
+ {
+ auto json = R"([])"_json;
+ AdditionalData ad;
+ EXPECT_THROW(Registry::getCallouts(json, "system1", ad),
+ std::runtime_error);
+ }
+
+ {
+ // Callouts without AD, that depend on system type,
+ // where there isn't a default entry without a system type.
+ auto json = R"(
+ [
+ {
+ "System": "system1",
+ "CalloutList":
+ [
+ {
+ "Priority": "high",
+ "LocCode": "P1-C1"
+ },
+ {
+ "Priority": "low",
+ "LocCode": "P1",
+ "SymbolicFRU": "1234567"
+ }
+ ]
+ },
+ {
+ "System": "system2",
+ "CalloutList":
+ [
+ {
+ "Priority": "medium",
+ "LocCode": "P7",
+ "CalloutType": "tool_fru"
+ }
+ ]
+
+ }
+ ])"_json;
+
+ AdditionalData ad;
+
+ auto callouts = Registry::getCallouts(json, "system1", ad);
+ EXPECT_EQ(callouts.size(), 2);
+ EXPECT_EQ(callouts[0].priority, "high");
+ EXPECT_EQ(callouts[0].locCode, "P1-C1");
+ EXPECT_EQ(callouts[0].procedure, "");
+ EXPECT_EQ(callouts[0].symbolicFRU, "");
+ EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
+ EXPECT_EQ(callouts[1].priority, "low");
+ EXPECT_EQ(callouts[1].locCode, "P1");
+ EXPECT_EQ(callouts[1].procedure, "");
+ EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
+ EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
+
+ callouts = Registry::getCallouts(json, "system2", ad);
+ EXPECT_EQ(callouts.size(), 1);
+ EXPECT_EQ(callouts[0].priority, "medium");
+ EXPECT_EQ(callouts[0].locCode, "P7");
+ EXPECT_EQ(callouts[0].procedure, "");
+ EXPECT_EQ(callouts[0].symbolicFRU, "");
+ EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
+
+ // There is no entry for system3 or a default system,
+ // so this should fail.
+ EXPECT_THROW(Registry::getCallouts(json, "system3", ad),
+ std::runtime_error);
+ }
+
+ {
+ // Callouts that use the AdditionalData key PROC_NUM
+ // as an index into them, along with a system type.
+ // It supports PROC_NUMs 0 and 1.
+ auto json = R"(
+ {
+ "ADName": "PROC_NUM",
+ "CalloutsWithTheirADValues":
+ [
+ {
+ "ADValue": "0",
+ "Callouts":
+ [
+ {
+ "System": "system3",
+ "CalloutList":
+ [
+ {
+ "Priority": "high",
+ "LocCode": "P1-C5"
+ },
+ {
+ "Priority": "medium",
+ "LocCode": "P1-C6",
+ "SymbolicFRU": "1234567"
+ },
+ {
+ "Priority": "low",
+ "Procedure": "no_vpd_for_fru",
+ "CalloutType": "config_procedure"
+ }
+ ]
+ },
+ {
+ "CalloutList":
+ [
+ {
+ "Priority": "low",
+ "LocCode": "P55"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "ADValue": "1",
+ "Callouts":
+ [
+ {
+ "CalloutList":
+ [
+ {
+ "Priority": "high",
+ "LocCode": "P1-C6",
+ "CalloutType": "external_fru"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ })"_json;
+
+ {
+ // Find callouts for PROC_NUM 0 on system3
+ std::vector<std::string> adData{"PROC_NUM=0"};
+ AdditionalData ad{adData};
+
+ auto callouts = Registry::getCallouts(json, "system3", ad);
+ EXPECT_EQ(callouts.size(), 3);
+ EXPECT_EQ(callouts[0].priority, "high");
+ EXPECT_EQ(callouts[0].locCode, "P1-C5");
+ EXPECT_EQ(callouts[0].procedure, "");
+ EXPECT_EQ(callouts[0].symbolicFRU, "");
+ EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
+ EXPECT_EQ(callouts[1].priority, "medium");
+ EXPECT_EQ(callouts[1].locCode, "P1-C6");
+ EXPECT_EQ(callouts[1].procedure, "");
+ EXPECT_EQ(callouts[1].symbolicFRU, "1234567");
+ EXPECT_EQ(callouts[1].symbolicFRUTrusted, "");
+ EXPECT_EQ(callouts[2].priority, "low");
+ EXPECT_EQ(callouts[2].locCode, "");
+ EXPECT_EQ(callouts[2].procedure, "no_vpd_for_fru");
+ EXPECT_EQ(callouts[2].symbolicFRU, "");
+ EXPECT_EQ(callouts[2].symbolicFRUTrusted, "");
+
+ // Find callouts for PROC_NUM 0 that uses the default system entry.
+ callouts = Registry::getCallouts(json, "system99", ad);
+ EXPECT_EQ(callouts.size(), 1);
+ EXPECT_EQ(callouts[0].priority, "low");
+ EXPECT_EQ(callouts[0].locCode, "P55");
+ EXPECT_EQ(callouts[0].procedure, "");
+ EXPECT_EQ(callouts[0].symbolicFRU, "");
+ EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
+ }
+ {
+ // Find callouts for PROC_NUM 1 that uses a default system entry.
+ std::vector<std::string> adData{"PROC_NUM=1"};
+ AdditionalData ad{adData};
+
+ auto callouts = Registry::getCallouts(json, "system1", ad);
+ EXPECT_EQ(callouts.size(), 1);
+ EXPECT_EQ(callouts[0].priority, "high");
+ EXPECT_EQ(callouts[0].locCode, "P1-C6");
+ EXPECT_EQ(callouts[0].procedure, "");
+ EXPECT_EQ(callouts[0].symbolicFRU, "");
+ EXPECT_EQ(callouts[0].symbolicFRUTrusted, "");
+ }
+ {
+ // There is no entry for PROC_NUM 2, it will fail.
+ std::vector<std::string> adData{"PROC_NUM=2"};
+ AdditionalData ad{adData};
+
+ EXPECT_THROW(Registry::getCallouts(json, "system1", ad),
+ std::runtime_error);
+ }
+ }
+}