summaryrefslogtreecommitdiffstats
path: root/test/openpower-pels/src_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/openpower-pels/src_test.cpp')
-rw-r--r--test/openpower-pels/src_test.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/test/openpower-pels/src_test.cpp b/test/openpower-pels/src_test.cpp
new file mode 100644
index 0000000..b966344
--- /dev/null
+++ b/test/openpower-pels/src_test.cpp
@@ -0,0 +1,261 @@
+/**
+ * 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/src.hpp"
+#include "pel_utils.hpp"
+
+#include <fstream>
+
+#include <gtest/gtest.h>
+
+using namespace openpower::pels;
+namespace fs = std::filesystem;
+
+const auto testRegistry = R"(
+{
+"PELs":
+[
+ {
+ "Name": "xyz.openbmc_project.Error.Test",
+ "Subsystem": "bmc_firmware",
+ "SRC":
+ {
+ "ReasonCode": "0xABCD",
+ "Words6To9":
+ {
+ "6":
+ {
+ "Description": "Component ID",
+ "AdditionalDataPropSource": "COMPID"
+ },
+ "7":
+ {
+ "Description": "Failure count",
+ "AdditionalDataPropSource": "FREQUENCY"
+ },
+ "8":
+ {
+ "Description": "Time period",
+ "AdditionalDataPropSource": "DURATION"
+ },
+ "9":
+ {
+ "Description": "Error code",
+ "AdditionalDataPropSource": "ERRORCODE"
+ }
+ }
+ },
+ "Documentation":
+ {
+ "Description": "A Component Fault",
+ "Message": "Comp %1 failed %2 times over %3 secs with ErrorCode %4",
+ "MessageArgSources":
+ [
+ "SRCWord6", "SRCWord7", "SRCWord8", "SRCWord9"
+ ]
+ }
+ }
+]
+}
+)";
+
+class SRCTest : public ::testing::Test
+{
+ protected:
+ static void SetUpTestCase()
+ {
+ char path[] = "/tmp/srctestXXXXXX";
+ 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 SRCTest::regDir{};
+
+TEST_F(SRCTest, UnflattenFlattenTestNoCallouts)
+{
+ auto data = pelDataFactory(TestPELType::primarySRCSection);
+
+ Stream stream{data};
+ SRC src{stream};
+
+ EXPECT_TRUE(src.valid());
+
+ EXPECT_EQ(src.header().id, 0x5053);
+ EXPECT_EQ(src.header().size, 0x50);
+ EXPECT_EQ(src.header().version, 0x01);
+ EXPECT_EQ(src.header().subType, 0x01);
+ EXPECT_EQ(src.header().componentID, 0x0202);
+
+ EXPECT_EQ(src.version(), 0x02);
+ EXPECT_EQ(src.flags(), 0x00);
+ EXPECT_EQ(src.hexWordCount(), 9);
+ EXPECT_EQ(src.size(), 0x48);
+
+ const auto& hexwords = src.hexwordData();
+ EXPECT_EQ(0x02020255, hexwords[0]);
+ EXPECT_EQ(0x03030310, hexwords[1]);
+ EXPECT_EQ(0x04040404, hexwords[2]);
+ EXPECT_EQ(0x05050505, hexwords[3]);
+ EXPECT_EQ(0x06060606, hexwords[4]);
+ EXPECT_EQ(0x07070707, hexwords[5]);
+ EXPECT_EQ(0x08080808, hexwords[6]);
+ EXPECT_EQ(0x09090909, hexwords[7]);
+
+ EXPECT_EQ(src.asciiString(), "BD8D5678 ");
+ EXPECT_FALSE(src.callouts());
+
+ // Flatten
+ std::vector<uint8_t> newData;
+ Stream newStream{newData};
+
+ src.flatten(newStream);
+ EXPECT_EQ(data, newData);
+}
+
+TEST_F(SRCTest, UnflattenFlattenTest2Callouts)
+{
+ auto data = pelDataFactory(TestPELType::primarySRCSection2Callouts);
+
+ Stream stream{data};
+ SRC src{stream};
+
+ EXPECT_TRUE(src.valid());
+ EXPECT_EQ(src.flags(), 0x01); // Additional sections within the SRC.
+
+ // Spot check the SRC fields, but they're the same as above
+ EXPECT_EQ(src.asciiString(), "BD8D5678 ");
+
+ // There should be 2 callouts
+ const auto& calloutsSection = src.callouts();
+ ASSERT_TRUE(calloutsSection);
+ const auto& callouts = calloutsSection->callouts();
+ EXPECT_EQ(callouts.size(), 2);
+
+ // spot check that each callout has the right substructures
+ EXPECT_TRUE(callouts.front()->fruIdentity());
+ EXPECT_FALSE(callouts.front()->pceIdentity());
+ EXPECT_FALSE(callouts.front()->mru());
+
+ EXPECT_TRUE(callouts.back()->fruIdentity());
+ EXPECT_TRUE(callouts.back()->pceIdentity());
+ EXPECT_TRUE(callouts.back()->mru());
+
+ // Flatten
+ std::vector<uint8_t> newData;
+ Stream newStream{newData};
+
+ src.flatten(newStream);
+ EXPECT_EQ(data, newData);
+}
+
+// Create an SRC from the message registry
+TEST_F(SRCTest, CreateTestNoCallouts)
+{
+ message::Entry entry;
+ entry.src.type = 0xBD;
+ entry.src.reasonCode = 0xABCD;
+ entry.subsystem = 0x42;
+ entry.src.powerFault = true;
+ entry.src.hexwordADFields = {{5, "TEST1"}, // Not a user defined word
+ {6, "TEST1"},
+ {7, "TEST2"},
+ {8, "TEST3"},
+ {9, "TEST4"}};
+
+ // Values for the SRC words pointed to above
+ std::vector<std::string> adData{"TEST1=0x12345678", "TEST2=12345678",
+ "TEST3=0XDEF", "TEST4=Z"};
+ AdditionalData ad{adData};
+ SRC src{entry, ad};
+
+ EXPECT_TRUE(src.valid());
+ EXPECT_TRUE(src.isPowerFaultEvent());
+ EXPECT_EQ(src.size(), baseSRCSize);
+
+ const auto& hexwords = src.hexwordData();
+
+ // The spec always refers to SRC words 2 - 9, and as the hexwordData()
+ // array index starts at 0 use the math in the [] below to make it easier
+ // to tell what is being accessed.
+ EXPECT_EQ(hexwords[2 - 2] & 0xF0000000, 0); // Partition dump status
+ EXPECT_EQ(hexwords[2 - 2] & 0x00F00000, 0); // Partition boot type
+ EXPECT_EQ(hexwords[2 - 2] & 0x000000FF, 0x55); // SRC format
+ EXPECT_EQ(hexwords[3 - 2] & 0x000000FF, 0x10); // BMC position
+
+ // Validate more fields here as the code starts filling them in.
+
+ // Ensure hex word 5 wasn't allowed to be set to TEST1's contents
+ EXPECT_EQ(hexwords[5 - 2], 0);
+
+ // The user defined hex word fields specifed in the additional data.
+ EXPECT_EQ(hexwords[6 - 2], 0x12345678); // TEST1
+ EXPECT_EQ(hexwords[7 - 2], 12345678); // TEST2
+ EXPECT_EQ(hexwords[8 - 2], 0xdef); // TEST3
+ EXPECT_EQ(hexwords[9 - 2], 0); // TEST4, but can't convert a 'Z'
+
+ EXPECT_EQ(src.asciiString(), "BD42ABCD ");
+
+ // No callouts
+ EXPECT_FALSE(src.callouts());
+
+ // May as well spot check the flatten/unflatten
+ std::vector<uint8_t> data;
+ Stream stream{data};
+ src.flatten(stream);
+
+ stream.offset(0);
+ SRC newSRC{stream};
+
+ EXPECT_TRUE(newSRC.valid());
+ EXPECT_EQ(newSRC.isPowerFaultEvent(), src.isPowerFaultEvent());
+ EXPECT_EQ(newSRC.asciiString(), src.asciiString());
+ EXPECT_FALSE(newSRC.callouts());
+}
+
+// Test the getErrorDetails function
+TEST_F(SRCTest, MessageSubstitutionTest)
+{
+ auto path = SRCTest::writeData(testRegistry);
+ message::Registry registry{path};
+ auto entry = registry.lookup("0xABCD", message::LookupType::reasonCode);
+
+ std::vector<std::string> adData{"COMPID=0x1", "FREQUENCY=0x4",
+ "DURATION=30", "ERRORCODE=0x01ABCDEF"};
+ AdditionalData ad{adData};
+
+ SRC src{*entry, ad};
+ EXPECT_TRUE(src.valid());
+
+ auto errorDetails = src.getErrorDetails(registry, DetailLevel::message);
+ ASSERT_TRUE(errorDetails);
+ EXPECT_EQ(
+ errorDetails.value(),
+ "Comp 0x1 failed 0x4 times over 0x1E secs with ErrorCode 0x1ABCDEF");
+}
OpenPOWER on IntegriCloud