summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-09-11 14:29:46 -0500
committerMatt Spinler <spinler@us.ibm.com>2019-09-27 14:26:15 -0500
commit09d6400fb70d5324c0ed026d1084fc51cb495216 (patch)
treed34884de1ee2a7474007ab06eb8e4bae898bae30
parent1a94cc38fc2885eac2b7674cc75837debea26eb8 (diff)
downloadphosphor-logging-09d6400fb70d5324c0ed026d1084fc51cb495216.tar.gz
phosphor-logging-09d6400fb70d5324c0ed026d1084fc51cb495216.zip
PEL: Add FailingMTMS PEL section class
This PEL section contains the Machine Type-Model and Serial number of the enclosure and is required for BMC PELs. In the constructor that creates the section from scratch, it gets those values from the DataInterface class. This commit doesn't hook this section into the PEL class as there are some prerequisites that still need to be done first. Signed-off-by: Matt Spinler <spinler@us.ibm.com> Change-Id: I24d679b57751afb00539691defef180191ea8fc7
-rw-r--r--extensions/openpower-pels/failing_mtms.cpp97
-rw-r--r--extensions/openpower-pels/failing_mtms.hpp102
-rw-r--r--extensions/openpower-pels/openpower-pels.mk1
-rw-r--r--extensions/openpower-pels/pel_types.hpp5
-rw-r--r--test/openpower-pels/Makefile.include10
-rw-r--r--test/openpower-pels/failing_mtms_test.cpp118
-rw-r--r--test/openpower-pels/mocks.hpp21
7 files changed, 354 insertions, 0 deletions
diff --git a/extensions/openpower-pels/failing_mtms.cpp b/extensions/openpower-pels/failing_mtms.cpp
new file mode 100644
index 0000000..0b02f2d
--- /dev/null
+++ b/extensions/openpower-pels/failing_mtms.cpp
@@ -0,0 +1,97 @@
+#include "failing_mtms.hpp"
+
+#include "pel_types.hpp"
+
+#include <phosphor-logging/log.hpp>
+
+namespace openpower
+{
+namespace pels
+{
+
+using namespace phosphor::logging;
+static constexpr uint8_t failingMTMSVersion = 0x01;
+
+FailingMTMS::FailingMTMS(const DataInterfaceBase& dataIface) :
+ _mtms(dataIface.getMachineTypeModel(), dataIface.getMachineSerialNumber())
+{
+ _header.id = static_cast<uint16_t>(SectionID::failingMTMS);
+ _header.size = FailingMTMS::flattenedSize();
+ _header.version = failingMTMSVersion;
+ _header.subType = 0;
+ _header.componentID = static_cast<uint16_t>(ComponentID::phosphorLogging);
+}
+
+FailingMTMS::FailingMTMS(Stream& pel)
+{
+ try
+ {
+ unflatten(pel);
+ validate();
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>("Cannot unflatten failing MTM section",
+ entry("ERROR=%s", e.what()));
+ _valid = false;
+ }
+}
+
+void FailingMTMS::validate()
+{
+ bool failed = false;
+
+ if (header().id != static_cast<uint16_t>(SectionID::failingMTMS))
+ {
+ log<level::ERR>("Invalid failing MTMS section ID",
+ entry("ID=0x%X", header().id));
+ failed = true;
+ }
+
+ if (header().version != failingMTMSVersion)
+ {
+ log<level::ERR>("Invalid failing MTMS version",
+ entry("VERSION=0x%X", header().version));
+ failed = true;
+ }
+
+ _valid = (failed) ? false : true;
+}
+
+std::string FailingMTMS::getMachineTypeModel()
+{
+ std::string mtmString;
+ const auto& mtm = _mtms.machineTypeAndModel();
+
+ for (size_t i = 0; (i < MTMS::mtmSize) && (mtm[i] != 0); i++)
+ {
+ mtmString.push_back(mtm[i]);
+ }
+ return mtmString;
+}
+
+std::string FailingMTMS::getMachineSerialNumber()
+{
+ std::string snString;
+ const auto& sn = _mtms.machineSerialNumber();
+
+ // Get everything up to the 0s.
+ for (size_t i = 0; (i < MTMS::snSize) && (sn[i] != 0); i++)
+ {
+ snString.push_back(sn[i]);
+ }
+ return snString;
+}
+
+void FailingMTMS::flatten(Stream& stream)
+{
+ stream << _header << _mtms;
+}
+
+void FailingMTMS::unflatten(Stream& stream)
+{
+ stream >> _header >> _mtms;
+}
+
+} // namespace pels
+} // namespace openpower
diff --git a/extensions/openpower-pels/failing_mtms.hpp b/extensions/openpower-pels/failing_mtms.hpp
new file mode 100644
index 0000000..209eaa9
--- /dev/null
+++ b/extensions/openpower-pels/failing_mtms.hpp
@@ -0,0 +1,102 @@
+#pragma once
+
+#include "data_interface.hpp"
+#include "mtms.hpp"
+#include "section.hpp"
+#include "stream.hpp"
+
+namespace openpower
+{
+namespace pels
+{
+
+/**
+ * @class FailingMTMS
+ *
+ * This represents the Failing Enclosure MTMS section in a PEL.
+ * It is a required section. In the BMC case, the enclosure is
+ * the system enclosure.
+ */
+class FailingMTMS : public Section
+{
+ public:
+ FailingMTMS() = delete;
+ ~FailingMTMS() = default;
+ FailingMTMS(const FailingMTMS&) = default;
+ FailingMTMS& operator=(const FailingMTMS&) = default;
+ FailingMTMS(FailingMTMS&&) = default;
+ FailingMTMS& operator=(FailingMTMS&&) = default;
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] dataIface - The object to use to obtain
+ * the MTM and SN.
+ */
+ explicit FailingMTMS(const DataInterfaceBase& dataIface);
+
+ /**
+ * @brief Constructor
+ *
+ * Fills in this class's data fields from the stream.
+ *
+ * @param[in] pel - the PEL data stream
+ */
+ explicit FailingMTMS(Stream& pel);
+
+ /**
+ * @brief Flatten the section into the stream
+ *
+ * @param[in] stream - The stream to write to
+ */
+ void flatten(Stream& stream) override;
+
+ /**
+ * @brief Returns the size of this section when flattened into a PEL
+ *
+ * @return size_t - the size of the section
+ */
+ static constexpr size_t flattenedSize()
+ {
+ return Section::flattenedSize() + MTMS::flattenedSize();
+ }
+
+ /**
+ * @brief Returns the machine type+model as a string
+ *
+ * @return std::string the MTM
+ */
+ std::string getMachineTypeModel();
+
+ /**
+ * @brief Returns the machine serial number as a string
+ *
+ * @return std::string the serial number
+ */
+ std::string getMachineSerialNumber();
+
+ private:
+ /**
+ * @brief Validates the section contents
+ *
+ * Updates _valid (in Section) with the results.
+ */
+ void validate() override;
+
+ /**
+ * @brief Fills in the object from the stream data
+ *
+ * @param[in] stream - The stream to read from
+ */
+ void unflatten(Stream& stream);
+
+ /**
+ * @brief The structure that holds the TM and SN fields.
+ * This is also used in other places in the PEL.
+ */
+ MTMS _mtms;
+};
+
+} // namespace pels
+
+} // namespace openpower
diff --git a/extensions/openpower-pels/openpower-pels.mk b/extensions/openpower-pels/openpower-pels.mk
index 21eb719..4f424f7 100644
--- a/extensions/openpower-pels/openpower-pels.mk
+++ b/extensions/openpower-pels/openpower-pels.mk
@@ -2,6 +2,7 @@ phosphor_log_manager_SOURCES += \
extensions/openpower-pels/bcd_time.cpp \
extensions/openpower-pels/data_interface.cpp \
extensions/openpower-pels/entry_points.cpp \
+ extensions/openpower-pels/failing_mtms.cpp \
extensions/openpower-pels/log_id.cpp \
extensions/openpower-pels/manager.cpp \
extensions/openpower-pels/mtms.cpp \
diff --git a/extensions/openpower-pels/pel_types.hpp b/extensions/openpower-pels/pel_types.hpp
index 5b4149f..caa75c2 100644
--- a/extensions/openpower-pels/pel_types.hpp
+++ b/extensions/openpower-pels/pel_types.hpp
@@ -5,6 +5,11 @@ namespace openpower
namespace pels
{
+enum class ComponentID
+{
+ phosphorLogging = 0x2000
+};
+
/**
* @brief PEL section IDs
*/
diff --git a/test/openpower-pels/Makefile.include b/test/openpower-pels/Makefile.include
index 124970d..fefbbc6 100644
--- a/test/openpower-pels/Makefile.include
+++ b/test/openpower-pels/Makefile.include
@@ -3,6 +3,7 @@ TESTS += $(check_PROGRAMS)
check_PROGRAMS += \
additional_data_test \
bcd_time_test \
+ failing_mtms_test \
log_id_test \
mtms_test \
pel_test \
@@ -113,3 +114,12 @@ mtms_test_LDADD = \
$(test_ldadd) \
$(top_builddir)/extensions/openpower-pels/mtms.o
mtms_test_LDFLAGS = $(test_ldflags)
+
+failing_mtms_test_SOURCES = %reldir%/failing_mtms_test.cpp
+failing_mtms_test_CPPFLAGS = $(test_cppflags)
+failing_mtms_test_CXXFLAGS = $(test_cxxflags)
+failing_mtms_test_LDADD = \
+ $(test_ldadd) \
+ $(top_builddir)/extensions/openpower-pels/failing_mtms.o \
+ $(top_builddir)/extensions/openpower-pels/mtms.o
+failing_mtms_test_LDFLAGS = $(test_ldflags)
diff --git a/test/openpower-pels/failing_mtms_test.cpp b/test/openpower-pels/failing_mtms_test.cpp
new file mode 100644
index 0000000..001f840
--- /dev/null
+++ b/test/openpower-pels/failing_mtms_test.cpp
@@ -0,0 +1,118 @@
+#include "extensions/openpower-pels/failing_mtms.hpp"
+#include "mocks.hpp"
+
+#include <gtest/gtest.h>
+
+using namespace openpower::pels;
+using ::testing::Return;
+
+TEST(FailingMTMSTest, SizeTest)
+{
+ EXPECT_EQ(FailingMTMS::flattenedSize(), 28);
+}
+
+TEST(FailingMTMSTest, ConstructorTest)
+{
+ // Note: the TypeModel field is 8B, and the SN field is 12B
+ {
+ MockDataInterface dataIface;
+
+ EXPECT_CALL(dataIface, getMachineTypeModel())
+ .WillOnce(Return("AAAA-BBB"));
+
+ EXPECT_CALL(dataIface, getMachineSerialNumber())
+ .WillOnce(Return("123456789ABC"));
+
+ FailingMTMS fm{dataIface};
+
+ // Check the section header
+ EXPECT_EQ(fm.header().id, 0x4D54);
+ EXPECT_EQ(fm.header().size, FailingMTMS::flattenedSize());
+ EXPECT_EQ(fm.header().version, 0x01);
+ EXPECT_EQ(fm.header().subType, 0x00);
+ EXPECT_EQ(fm.header().componentID, 0x2000);
+
+ EXPECT_EQ(fm.getMachineTypeModel(), "AAAA-BBB");
+ EXPECT_EQ(fm.getMachineSerialNumber(), "123456789ABC");
+ }
+
+ // longer than the max - will truncate
+ {
+ MockDataInterface dataIface;
+
+ EXPECT_CALL(dataIface, getMachineTypeModel())
+ .WillOnce(Return("AAAA-BBBTOOLONG"));
+
+ EXPECT_CALL(dataIface, getMachineSerialNumber())
+ .WillOnce(Return("123456789ABCTOOLONG"));
+
+ FailingMTMS fm{dataIface};
+
+ EXPECT_EQ(fm.getMachineTypeModel(), "AAAA-BBB");
+ EXPECT_EQ(fm.getMachineSerialNumber(), "123456789ABC");
+ }
+
+ // shorter than the max
+ {
+ MockDataInterface dataIface;
+
+ EXPECT_CALL(dataIface, getMachineTypeModel()).WillOnce(Return("A"));
+
+ EXPECT_CALL(dataIface, getMachineSerialNumber()).WillOnce(Return("1"));
+
+ FailingMTMS fm{dataIface};
+
+ EXPECT_EQ(fm.getMachineTypeModel(), "A");
+ EXPECT_EQ(fm.getMachineSerialNumber(), "1");
+ }
+}
+
+TEST(FailingMTMSTest, StreamConstructorTest)
+{
+ std::vector<uint8_t> data{0x4D, 0x54, 0x00, 0x1C, 0x01, 0x00, 0x20,
+ 0x00, 'T', 'T', 'T', 'T', '-', 'M',
+ 'M', 'M', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'A', 'B', 'C'};
+ Stream stream{data};
+ FailingMTMS fm{stream};
+
+ EXPECT_EQ(fm.valid(), true);
+
+ EXPECT_EQ(fm.header().id, 0x4D54);
+ EXPECT_EQ(fm.header().size, FailingMTMS::flattenedSize());
+ EXPECT_EQ(fm.header().version, 0x01);
+ EXPECT_EQ(fm.header().subType, 0x00);
+ EXPECT_EQ(fm.header().componentID, 0x2000);
+
+ EXPECT_EQ(fm.getMachineTypeModel(), "TTTT-MMM");
+ EXPECT_EQ(fm.getMachineSerialNumber(), "123456789ABC");
+}
+
+TEST(FailingMTMSTest, BadStreamConstructorTest)
+{
+ // too short
+ std::vector<uint8_t> data{
+ 0x4D, 0x54, 0x00, 0x1C, 0x01, 0x00, 0x20, 0x00, 'T', 'T',
+ };
+ Stream stream{data};
+ FailingMTMS fm{stream};
+
+ EXPECT_EQ(fm.valid(), false);
+}
+
+TEST(FailingMTMSTest, FlattenTest)
+{
+ std::vector<uint8_t> data{0x4D, 0x54, 0x00, 0x1C, 0x01, 0x00, 0x20,
+ 0x00, 'T', 'T', 'T', 'T', '-', 'M',
+ 'M', 'M', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'A', 'B', 'C'};
+ Stream stream{data};
+ FailingMTMS fm{stream};
+
+ // flatten and check results
+ std::vector<uint8_t> newData;
+ Stream newStream{newData};
+
+ fm.flatten(newStream);
+ EXPECT_EQ(data, newData);
+}
diff --git a/test/openpower-pels/mocks.hpp b/test/openpower-pels/mocks.hpp
new file mode 100644
index 0000000..f6bd86a
--- /dev/null
+++ b/test/openpower-pels/mocks.hpp
@@ -0,0 +1,21 @@
+#include "extensions/openpower-pels/data_interface.hpp"
+
+#include <gmock/gmock.h>
+
+namespace openpower
+{
+namespace pels
+{
+
+class MockDataInterface : public DataInterfaceBase
+{
+ public:
+ MockDataInterface()
+ {
+ }
+ MOCK_CONST_METHOD0(getMachineTypeModel, std::string());
+ MOCK_CONST_METHOD0(getMachineSerialNumber, std::string());
+};
+
+} // namespace pels
+} // namespace openpower
OpenPOWER on IntegriCloud