psu-ng: Validate supported model and count

Check that the power supply model and number match the expected
combination specified in the supported configurations. Log an error if
no match is found.

Tested: Verified an error log is created if there was a mismatch in
        Rainier 2U.

Change-Id: I2c81fac8f0bdb7f1205a3f81104b0ba419f1192f
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 2ab8cfb..fdb5d52 100644
--- a/phosphor-power-supply/psu_manager.cpp
+++ b/phosphor-power-supply/psu_manager.cpp
@@ -419,7 +419,7 @@
 
 void PSUManager::validateConfig()
 {
-    if (!runValidateConfig)
+    if (!runValidateConfig || supportedConfigs.empty())
     {
         return;
     }
@@ -427,6 +427,8 @@
     // 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)
     {
@@ -435,6 +437,10 @@
         {
             continue;
         }
+        if (p->isPresent())
+        {
+            presentCount++;
+        }
         if (model.empty())
         {
             model = psuModel;
@@ -460,6 +466,39 @@
             return;
         }
     }
+
+    // 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)
+        {
+            continue;
+        }
+        if (presentCount != config.second.powerSupplyCount)
+        {
+            additionalData["EXPECTED_COUNT"] =
+                std::to_string(config.second.powerSupplyCount);
+            continue;
+        }
+        supported = true;
+        runValidateConfig = false;
+        break;
+    }
+    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;
+    }
 }
 
 } // namespace phosphor::power::manager