psu-ng: Move PSU validation logic to its own function

Move the PSU validation logic into a separate function so that it can be
called from additional places, such as the analyze() function, which
will check if the required PSUs are present before logging an error for
missing PSUs.
Also use std::count_if to get the number of present PSUs to make the
logic cleaner.

The only difference with the new function is that there's no difference
between a failure due to mismatched model names and failure due to
missing PSUs. The original logic would set the validation flag on
mismatched model names to not run again. The new scenario is that if EM
starts after psu-monitor and there is one or more PSUs with a mismatched
model name, then the same error will be created every time there's a new
EM PSU interface added.

Tested: Verified with debug logs that the validation logic remained the
same after the change.

Change-Id: Iced7afc34f566be1ce479c03639b780ecd7fdd53
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/phosphor-power-supply/psu_manager.cpp b/phosphor-power-supply/psu_manager.cpp
index 63473f7..1940eea 100644
--- a/phosphor-power-supply/psu_manager.cpp
+++ b/phosphor-power-supply/psu_manager.cpp
@@ -441,56 +441,59 @@
         return;
     }
 
+    std::map<std::string, std::string> additionalData;
+    auto supported = hasRequiredPSUs(additionalData);
+    if (supported)
+    {
+        runValidateConfig = false;
+        return;
+    }
+
+    // Validation failed, create an error log.
+    // Return without setting the runValidateConfig flag to false because
+    // it may be that an additional supported configuration interface is
+    // added and we need to validate it to see if it matches this system.
+    createError("xyz.openbmc_project.Power.PowerSupply.Error.NotSupported",
+                additionalData);
+}
+
+bool PSUManager::hasRequiredPSUs(
+    std::map<std::string, std::string>& additionalData)
+{
     // Check that all PSUs have the same model name. Initialize the model
     // variable with the first PSU name found, then use it as a base to compare
     // against the rest of the PSUs.
-    // Also record the number of present PSUs to verify afterwards.
-    auto presentCount = 0;
     std::string model{};
-    for (const auto& p : psus)
+    for (const auto& psu : psus)
     {
-        auto psuModel = p->getModelName();
+        auto psuModel = psu->getModelName();
         if (psuModel.empty())
         {
             continue;
         }
-        if (p->isPresent())
-        {
-            presentCount++;
-        }
         if (model.empty())
         {
             model = psuModel;
             continue;
         }
-        if (psuModel.compare(model) != 0)
+        if (psuModel != model)
         {
-            log<level::ERR>(
-                fmt::format("Mismatched power supply models: {}, {}",
-                            model.c_str(), psuModel.c_str())
-                    .c_str());
-            std::map<std::string, std::string> additionalData;
             additionalData["EXPECTED_MODEL"] = model;
             additionalData["ACTUAL_MODEL"] = psuModel;
-            additionalData["CALLOUT_INVENTORY_PATH"] = p->getInventoryPath();
-            createError(
-                "xyz.openbmc_project.Power.PowerSupply.Error.NotSupported",
-                additionalData);
-
-            // No need to do the validation anymore, a mismatched model needs to
-            // be fixed by the user.
-            runValidateConfig = false;
-            return;
+            additionalData["CALLOUT_INVENTORY_PATH"] = psu->getInventoryPath();
+            return false;
         }
     }
 
+    auto presentCount =
+        std::count_if(psus.begin(), psus.end(),
+                      [](const auto& psu) { return psu->isPresent(); });
+
     // Validate the supported configurations. A system may support more than one
     // power supply model configuration.
-    bool supported = false;
-    std::map<std::string, std::string> additionalData;
     for (const auto& config : supportedConfigs)
     {
-        if (config.first.compare(model) != 0)
+        if (config.first != model)
         {
             continue;
         }
@@ -498,24 +501,13 @@
         {
             additionalData["EXPECTED_COUNT"] =
                 std::to_string(config.second.powerSupplyCount);
+            additionalData["ACTUAL_COUNT"] = std::to_string(presentCount);
             continue;
         }
-        supported = true;
-        runValidateConfig = false;
-        break;
+        return true;
     }
-    if (!supported)
-    {
-        additionalData["ACTUAL_MODEL"] = model;
-        additionalData["ACTUAL_COUNT"] = std::to_string(presentCount);
-        createError("xyz.openbmc_project.Power.PowerSupply.Error.NotSupported",
-                    additionalData);
 
-        // Return without setting the runValidateConfig flag to false because
-        // it may be that an additional supported configuration interface is
-        // added and we need to validate it to see if it matches this system.
-        return;
-    }
+    return false;
 }
 
 } // namespace phosphor::power::manager