summaryrefslogtreecommitdiffstats
path: root/test/openpower-pels/registry_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/openpower-pels/registry_test.cpp')
-rw-r--r--test/openpower-pels/registry_test.cpp336
1 files changed, 336 insertions, 0 deletions
diff --git a/test/openpower-pels/registry_test.cpp b/test/openpower-pels/registry_test.cpp
new file mode 100644
index 0000000..2944ce0
--- /dev/null
+++ b/test/openpower-pels/registry_test.cpp
@@ -0,0 +1,336 @@
+/**
+ * Copyright © 2019 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "extensions/openpower-pels/registry.hpp"
+
+#include <filesystem>
+#include <fstream>
+#include <nlohmann/json.hpp>
+
+#include <gtest/gtest.h>
+
+using namespace openpower::pels::message;
+namespace fs = std::filesystem;
+
+const auto registryData = R"(
+{
+ "PELs":
+ [
+ {
+ "Name": "xyz.openbmc_project.Power.Fault",
+ "Subsystem": "power_supply",
+
+ "SRC":
+ {
+ "ReasonCode": "0x2030"
+ },
+
+ "Documentation":
+ {
+ "Description": "A PGOOD Fault",
+ "Message": "PS had a PGOOD Fault"
+ }
+ },
+
+ {
+ "Name": "xyz.openbmc_project.Power.OverVoltage",
+ "Subsystem": "power_control_hw",
+ "Severity": "unrecoverable",
+ "MfgSeverity": "non_error",
+ "ActionFlags": ["service_action", "report", "call_home"],
+ "MfgActionFlags": ["hidden"],
+
+ "SRC":
+ {
+ "ReasonCode": "0x2333",
+ "Type": "BD",
+ "SymptomIDFields": ["SRCWord5", "SRCWord6", "SRCWord7"],
+ "PowerFault": true,
+ "Words6To9":
+ {
+ "6":
+ {
+ "description": "Failing unit number",
+ "AdditionalDataPropSource": "PS_NUM"
+ },
+
+ "7":
+ {
+ "description": "bad voltage",
+ "AdditionalDataPropSource": "VOLTAGE"
+ }
+ }
+ },
+
+ "Documentation":
+ {
+ "Description": "A PGOOD Fault",
+ "Message": "PS %1 had a PGOOD Fault",
+ "MessageArgSources":
+ [
+ "SRCWord6"
+ ],
+ "Notes": [
+ "In the UserData section there is a JSON",
+ "dump that provides debug information."
+ ]
+ }
+ }
+ ]
+}
+)";
+
+class RegistryTest : public ::testing::Test
+{
+ protected:
+ static void SetUpTestCase()
+ {
+ char path[] = "/tmp/regtestXXXXXX";
+ regDir = mkdtemp(path);
+ }
+
+ static void TearDownTestCase()
+ {
+ fs::remove_all(regDir);
+ }
+
+ static std::string writeData(const char* data)
+ {
+ fs::path path = regDir / "registry.json";
+ std::ofstream stream{path};
+ stream << data;
+ return path;
+ }
+
+ static fs::path regDir;
+};
+
+fs::path RegistryTest::regDir{};
+
+TEST_F(RegistryTest, TestNoEntry)
+{
+ auto path = RegistryTest::writeData(registryData);
+ Registry registry{path};
+
+ auto entry = registry.lookup("foo", LookupType::name);
+ EXPECT_FALSE(entry);
+}
+
+TEST_F(RegistryTest, TestFindEntry)
+{
+ auto path = RegistryTest::writeData(registryData);
+ Registry registry{path};
+
+ auto entry = registry.lookup("xyz.openbmc_project.Power.OverVoltage",
+ LookupType::name);
+ ASSERT_TRUE(entry);
+ EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
+ EXPECT_EQ(entry->subsystem, 0x62);
+ EXPECT_EQ(*(entry->severity), 0x40);
+ EXPECT_EQ(*(entry->mfgSeverity), 0x00);
+ EXPECT_EQ(*(entry->actionFlags), 0xA800);
+ EXPECT_EQ(*(entry->mfgActionFlags), 0x4000);
+ EXPECT_EQ(entry->componentID, 0x2300);
+ EXPECT_FALSE(entry->eventType);
+ EXPECT_FALSE(entry->eventScope);
+
+ EXPECT_EQ(entry->src.type, 0xBD);
+ EXPECT_EQ(entry->src.reasonCode, 0x2333);
+ EXPECT_EQ(*(entry->src.powerFault), true);
+
+ auto& hexwords = entry->src.hexwordADFields;
+ EXPECT_TRUE(hexwords);
+ EXPECT_EQ((*hexwords).size(), 2);
+
+ auto word = (*hexwords).find(6);
+ EXPECT_NE(word, (*hexwords).end());
+ EXPECT_EQ(word->second, "PS_NUM");
+
+ word = (*hexwords).find(7);
+ EXPECT_NE(word, (*hexwords).end());
+ EXPECT_EQ(word->second, "VOLTAGE");
+
+ auto& sid = entry->src.symptomID;
+ EXPECT_TRUE(sid);
+ EXPECT_EQ((*sid).size(), 3);
+ EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 5), (*sid).end());
+ EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 6), (*sid).end());
+ EXPECT_NE(std::find((*sid).begin(), (*sid).end(), 7), (*sid).end());
+
+ EXPECT_EQ(entry->doc.description, "A PGOOD Fault");
+ EXPECT_EQ(entry->doc.message, "PS %1 had a PGOOD Fault");
+ auto& hexwordSource = entry->doc.messageArgSources;
+ EXPECT_TRUE(hexwordSource);
+ EXPECT_EQ((*hexwordSource).size(), 1);
+ EXPECT_EQ((*hexwordSource).front(), "SRCWord6");
+
+ entry = registry.lookup("0x2333", LookupType::reasonCode);
+ ASSERT_TRUE(entry);
+ EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.OverVoltage");
+}
+
+// Check the entry that mostly uses defaults
+TEST_F(RegistryTest, TestFindEntryMinimal)
+{
+ auto path = RegistryTest::writeData(registryData);
+ Registry registry{path};
+
+ auto entry =
+ registry.lookup("xyz.openbmc_project.Power.Fault", LookupType::name);
+ ASSERT_TRUE(entry);
+ EXPECT_EQ(entry->name, "xyz.openbmc_project.Power.Fault");
+ EXPECT_EQ(entry->subsystem, 0x61);
+ EXPECT_FALSE(entry->severity);
+ EXPECT_FALSE(entry->mfgSeverity);
+ EXPECT_FALSE(entry->mfgActionFlags);
+ EXPECT_FALSE(entry->actionFlags);
+ EXPECT_EQ(entry->componentID, 0x2000);
+ EXPECT_FALSE(entry->eventType);
+ EXPECT_FALSE(entry->eventScope);
+
+ EXPECT_EQ(entry->src.reasonCode, 0x2030);
+ EXPECT_EQ(entry->src.type, 0xBD);
+ EXPECT_FALSE(entry->src.powerFault);
+ EXPECT_FALSE(entry->src.hexwordADFields);
+ EXPECT_FALSE(entry->src.symptomID);
+}
+
+TEST_F(RegistryTest, TestBadJSON)
+{
+ auto path = RegistryTest::writeData("bad {} json");
+
+ Registry registry{path};
+
+ EXPECT_FALSE(registry.lookup("foo", LookupType::name));
+}
+
+// Test the helper functions the use the pel_values data.
+TEST_F(RegistryTest, TestHelperFunctions)
+{
+ using namespace openpower::pels::message::helper;
+ EXPECT_EQ(getSubsystem("input_power_source"), 0xA1);
+ EXPECT_THROW(getSubsystem("foo"), std::runtime_error);
+
+ EXPECT_EQ(getSeverity("symptom_recovered"), 0x71);
+ EXPECT_THROW(getSeverity("foo"), std::runtime_error);
+
+ EXPECT_EQ(getEventType("dump_notification"), 0x08);
+ EXPECT_THROW(getEventType("foo"), std::runtime_error);
+
+ EXPECT_EQ(getEventScope("possibly_multiple_platforms"), 0x04);
+ EXPECT_THROW(getEventScope("foo"), std::runtime_error);
+
+ std::vector<std::string> flags{"service_action", "dont_report",
+ "termination"};
+ EXPECT_EQ(getActionFlags(flags), 0x9100);
+
+ flags.clear();
+ flags.push_back("foo");
+ EXPECT_THROW(getActionFlags(flags), std::runtime_error);
+}
+
+TEST_F(RegistryTest, TestGetSRCReasonCode)
+{
+ using namespace openpower::pels::message::helper;
+ EXPECT_EQ(getSRCReasonCode(R"({"ReasonCode": "0x5555"})"_json, "foo"),
+ 0x5555);
+
+ EXPECT_THROW(getSRCReasonCode(R"({"ReasonCode": "ZZZZ"})"_json, "foo"),
+ std::runtime_error);
+}
+
+TEST_F(RegistryTest, TestGetSRCType)
+{
+ using namespace openpower::pels::message::helper;
+ EXPECT_EQ(getSRCType(R"({"Type": "11"})"_json, "foo"), 0x11);
+ EXPECT_EQ(getSRCType(R"({"Type": "BF"})"_json, "foo"), 0xBF);
+
+ EXPECT_THROW(getSRCType(R"({"Type": "1"})"_json, "foo"),
+ std::runtime_error);
+
+ EXPECT_THROW(getSRCType(R"({"Type": "111"})"_json, "foo"),
+ std::runtime_error);
+}
+
+TEST_F(RegistryTest, TestGetSRCHexwordFields)
+{
+ using namespace openpower::pels::message::helper;
+ const auto hexwords = R"(
+ {"Words6To9":
+ {
+ "8":
+ {
+ "AdditionalDataPropSource": "TEST"
+ }
+ }
+ })"_json;
+
+ auto fields = getSRCHexwordFields(hexwords, "foo");
+ EXPECT_TRUE(fields);
+ auto word = fields->find(8);
+ EXPECT_NE(word, fields->end());
+
+ const auto theInvalidRWord = R"(
+ {"Words6To9":
+ {
+ "R":
+ {
+ "AdditionalDataPropSource": "TEST"
+ }
+ }
+ })"_json;
+
+ EXPECT_THROW(getSRCHexwordFields(theInvalidRWord, "foo"),
+ std::runtime_error);
+}
+
+TEST_F(RegistryTest, TestGetSRCSymptomIDFields)
+{
+ using namespace openpower::pels::message::helper;
+ const auto sID = R"(
+ {
+ "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord5"]
+ })"_json;
+
+ auto fields = getSRCSymptomIDFields(sID, "foo");
+ EXPECT_NE(std::find(fields->begin(), fields->end(), 3), fields->end());
+ EXPECT_NE(std::find(fields->begin(), fields->end(), 4), fields->end());
+ EXPECT_NE(std::find(fields->begin(), fields->end(), 5), fields->end());
+
+ const auto badField = R"(
+ {
+ "SymptomIDFields": ["SRCWord3", "SRCWord4", "SRCWord"]
+ })"_json;
+
+ EXPECT_THROW(getSRCSymptomIDFields(badField, "foo"), std::runtime_error);
+}
+
+TEST_F(RegistryTest, TestGetComponentID)
+{
+ using namespace openpower::pels::message::helper;
+
+ // Get it from the JSON
+ auto id =
+ getComponentID(0xBD, 0x4200, R"({"ComponentID":"0x4200"})"_json, "foo");
+ EXPECT_EQ(id, 0x4200);
+
+ // Get it from the reason code on a 0xBD SRC
+ id = getComponentID(0xBD, 0x6700, R"({})"_json, "foo");
+ EXPECT_EQ(id, 0x6700);
+
+ // Not present on a 0x11 SRC
+ EXPECT_THROW(getComponentID(0x11, 0x8800, R"({})"_json, "foo"),
+ std::runtime_error);
+}
OpenPOWER on IntegriCloud