regulators: Complete compare_vpd action

Complete implementation of the compare_vpd action in the JSON
configuration file.  For more information about this action see
https://github.com/openbmc/phosphor-power/blob/master/phosphor-regulators/docs/config_file/compare_vpd.md

Implement the execute() method of the CompareVPDAction class.  Obtain
the actual VPD keyword value from the VPD service and compare it with
the expected value.

Also improve doxygen for the execute() method of the
ComparePresenceAction class.

Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
Change-Id: Ieb93806245babe6782fef95209bed8eed5b32578
diff --git a/phosphor-regulators/src/actions/compare_presence_action.hpp b/phosphor-regulators/src/actions/compare_presence_action.hpp
index b16c98f..f2038d1 100644
--- a/phosphor-regulators/src/actions/compare_presence_action.hpp
+++ b/phosphor-regulators/src/actions/compare_presence_action.hpp
@@ -44,7 +44,8 @@
     /**
      * Constructor.
      *
-     * @param fru Field-Replaceable Unit (FRU)
+     * @param fru Field-Replaceable Unit (FRU). Specify the D-Bus inventory path
+     *            of the FRU.
      * @param value Expected presence value
      */
     explicit ComparePresenceAction(const std::string& fru, bool value) :
@@ -55,8 +56,13 @@
     /**
      * Executes this action.
      *
-     * @param environment Action execution environment.
-     * @return true
+     * Compares the actual presence value to the expected value.
+     *
+     * Throws an exception if an error occurs.
+     *
+     * @param environment action execution environment
+     * @return true if the actual presence value equals the expected value,
+     *         otherwise returns false
      */
     virtual bool execute(ActionEnvironment& environment) override;
 
@@ -91,7 +97,7 @@
     /**
      * Field-Replaceable Unit (FRU) for this action.
      *
-     * Specify the D-Bus inventory path of the FRU.
+     * The D-Bus inventory path of the FRU.
      */
     const std::string fru{};
 
diff --git a/phosphor-regulators/src/actions/compare_vpd_action.cpp b/phosphor-regulators/src/actions/compare_vpd_action.cpp
new file mode 100644
index 0000000..1049cee
--- /dev/null
+++ b/phosphor-regulators/src/actions/compare_vpd_action.cpp
@@ -0,0 +1,58 @@
+/**
+ * Copyright © 2021 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 "compare_vpd_action.hpp"
+
+#include "action_error.hpp"
+
+#include <exception>
+#include <sstream>
+
+namespace phosphor::power::regulators
+{
+
+bool CompareVPDAction::execute(ActionEnvironment& environment)
+{
+    bool isEqual{false};
+    try
+    {
+        // Get actual VPD keyword value
+        std::string actualValue =
+            environment.getServices().getVPD().getValue(fru, keyword);
+
+        // Check if actual value equals expected value
+        isEqual = (actualValue == value);
+    }
+    catch (const std::exception& e)
+    {
+        // Nest exception within an ActionError so the caller will have both the
+        // low level error information and the action information.
+        std::throw_with_nested(ActionError(*this));
+    }
+    return isEqual;
+}
+
+std::string CompareVPDAction::toString() const
+{
+    std::ostringstream ss;
+    ss << "compare_vpd: { ";
+    ss << "fru: " << fru << ", ";
+    ss << "keyword: " << keyword << ", ";
+    ss << "value: " << value << " }";
+    return ss.str();
+}
+
+} // namespace phosphor::power::regulators
diff --git a/phosphor-regulators/src/actions/compare_vpd_action.hpp b/phosphor-regulators/src/actions/compare_vpd_action.hpp
index 7dc5136..af7e085 100644
--- a/phosphor-regulators/src/actions/compare_vpd_action.hpp
+++ b/phosphor-regulators/src/actions/compare_vpd_action.hpp
@@ -18,7 +18,6 @@
 #include "action.hpp"
 #include "action_environment.hpp"
 
-#include <sstream>
 #include <string>
 
 namespace phosphor::power::regulators
@@ -62,16 +61,15 @@
     /**
      * Executes this action.
      *
-     * TODO: Not implemented yet
+     * Compares the actual VPD keyword value to the expected value.
      *
-     * @param environment Action execution environment.
-     * @return true
+     * Throws an exception if an error occurs.
+     *
+     * @param environment action execution environment
+     * @return true if the keyword value equals the expected value, otherwise
+     *         returns false
      */
-    virtual bool execute(ActionEnvironment& /* environment */) override
-    {
-        // TODO: Not implemented yet
-        return true;
-    }
+    virtual bool execute(ActionEnvironment& environment) override;
 
     /**
      * Returns the Field-Replaceable Unit (FRU).
@@ -108,20 +106,13 @@
      *
      * @return description of action
      */
-    virtual std::string toString() const override
-    {
-        std::ostringstream ss;
-        ss << "compare_vpd: { ";
-        ss << "fru: " << fru << ", ";
-        ss << "keyword: " << keyword << ", ";
-        ss << "value: " << value << " }";
-
-        return ss.str();
-    }
+    virtual std::string toString() const override;
 
   private:
     /**
-     * Field-Replaceable Unit (FRU) that contains the VPD.
+     * Field-Replaceable Unit (FRU) for this action.
+     *
+     * The D-Bus inventory path of the FRU.
      */
     const std::string fru{};