PEL: Store system boot state in user data section

For every incoming pel data interface watches the dbus property
that includes the latest boot progress/state value. This value would be
captured and stored in user data section of pel.

Signed-off-by: Sumit Kumar <sumit_kumar@in.ibm.com>
Change-Id: Ie48e7ee9fdd965af672f4bd563f8c9fc3bfacc43
diff --git a/extensions/openpower-pels/data_interface.cpp b/extensions/openpower-pels/data_interface.cpp
index 393c2fe..c21bf5d 100644
--- a/extensions/openpower-pels/data_interface.cpp
+++ b/extensions/openpower-pels/data_interface.cpp
@@ -115,6 +115,7 @@
     _properties.emplace_back(std::make_unique<PropertyWatcher<DataInterface>>(
         bus, object_path::hostState, interface::bootProgress, "BootProgress",
         *this, [this](const auto& value) {
+            this->_bootState = std::get<std::string>(value);
             auto status = Progress::convertProgressStagesFromString(
                 std::get<std::string>(value));
 
diff --git a/extensions/openpower-pels/data_interface.hpp b/extensions/openpower-pels/data_interface.hpp
index 482b4f1..2469bb5 100644
--- a/extensions/openpower-pels/data_interface.hpp
+++ b/extensions/openpower-pels/data_interface.hpp
@@ -195,6 +195,16 @@
     }
 
     /**
+     * @brief Returns the Boot state
+     *
+     * @return std::string - The Boot state property value
+     */
+    virtual std::string getBootState() const
+    {
+        return _bootState;
+    }
+
+    /**
      * @brief Returns the motherboard CCIN
      *
      * @return std::string The motherboard CCIN
@@ -420,6 +430,11 @@
      * @brief The host state property
      */
     std::string _hostState;
+
+    /**
+     * @brief The boot state property
+     */
+    std::string _bootState;
 };
 
 /**
diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp
index 3c27447..a6e4d3d 100644
--- a/extensions/openpower-pels/pel.cpp
+++ b/extensions/openpower-pels/pel.cpp
@@ -670,6 +670,7 @@
     json["BMCState"] = lastSegment('.', dataIface.getBMCState());
     json["ChassisState"] = lastSegment('.', dataIface.getChassisState());
     json["HostState"] = lastSegment('.', dataIface.getHostState());
+    json["BootState"] = lastSegment('.', dataIface.getBootState());
 }
 
 std::unique_ptr<UserData>
diff --git a/test/openpower-pels/mocks.hpp b/test/openpower-pels/mocks.hpp
index 80b4a5e..6d130ab 100644
--- a/test/openpower-pels/mocks.hpp
+++ b/test/openpower-pels/mocks.hpp
@@ -49,6 +49,7 @@
                 (const override));
     MOCK_METHOD(std::vector<bool>, checkDumpStatus,
                 (const std::vector<std::string>&), (const override));
+    MOCK_METHOD(std::string, getBootState, (), (const override));
 
     void changeHostState(bool newState)
     {
diff --git a/test/openpower-pels/pel_test.cpp b/test/openpower-pels/pel_test.cpp
index f980c9d..322d0ca 100644
--- a/test/openpower-pels/pel_test.cpp
+++ b/test/openpower-pels/pel_test.cpp
@@ -413,6 +413,8 @@
     EXPECT_CALL(dataIface, getBMCState()).WillOnce(Return("State.Ready"));
     EXPECT_CALL(dataIface, getChassisState()).WillOnce(Return("State.On"));
     EXPECT_CALL(dataIface, getHostState()).WillOnce(Return("State.Off"));
+    EXPECT_CALL(dataIface, getBootState())
+        .WillOnce(Return("State.SystemInitComplete"));
     EXPECT_CALL(dataIface, getSystemIMKeyword())
         .WillOnce(Return(std::vector<uint8_t>{0, 1, 0x55, 0xAA}));
 
@@ -453,6 +455,9 @@
     state = json["HostState"].get<std::string>();
     EXPECT_EQ(state, "Off");
 
+    state = json["BootState"].get<std::string>();
+    EXPECT_EQ(state, "SystemInitComplete");
+
     auto keyword = json["System IM"].get<std::string>();
     EXPECT_EQ(keyword, "000155AA");
 }