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
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);
+}