pseq: Parsing support for chassis_template array
Add JSON parsing support for an array of chassis_template elements in
the phosphor-power-sequencer configuration file.
Tested:
* Ran automated tests.
Change-Id: Id9277c1eb938fd8c08c292fbe6c898507d2faced
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
diff --git a/phosphor-power-sequencer/src/config_file_parser.cpp b/phosphor-power-sequencer/src/config_file_parser.cpp
index 18fe32e..9e4a18d 100644
--- a/phosphor-power-sequencer/src/config_file_parser.cpp
+++ b/phosphor-power-sequencer/src/config_file_parser.cpp
@@ -95,7 +95,8 @@
{
std::unique_ptr<Chassis> parseChassis(
- const json& element, std::map<std::string, JSONRefWrapper> chassisTemplates,
+ const json& element,
+ const std::map<std::string, JSONRefWrapper>& chassisTemplates,
Services& services)
{
verifyIsObject(element);
@@ -148,7 +149,8 @@
}
std::vector<std::unique_ptr<Chassis>> parseChassisArray(
- const json& element, std::map<std::string, JSONRefWrapper> chassisTemplates,
+ const json& element,
+ const std::map<std::string, JSONRefWrapper>& chassisTemplates,
Services& services)
{
verifyIsArray(element);
@@ -251,6 +253,18 @@
return {id, JSONRefWrapper{element}};
}
+std::map<std::string, JSONRefWrapper> parseChassisTemplateArray(
+ const json& element)
+{
+ verifyIsArray(element);
+ std::map<std::string, JSONRefWrapper> chassisTemplates;
+ for (auto& chassisTemplateElement : element)
+ {
+ chassisTemplates.emplace(parseChassisTemplate(chassisTemplateElement));
+ }
+ return chassisTemplates;
+}
+
GPIO parseGPIO(const json& element,
const std::map<std::string, std::string>& variables)
{
diff --git a/phosphor-power-sequencer/src/config_file_parser.hpp b/phosphor-power-sequencer/src/config_file_parser.hpp
index 665029e..f43ad0e 100644
--- a/phosphor-power-sequencer/src/config_file_parser.hpp
+++ b/phosphor-power-sequencer/src/config_file_parser.hpp
@@ -99,7 +99,8 @@
* @return Chassis object
*/
std::unique_ptr<Chassis> parseChassis(
- const json& element, std::map<std::string, JSONRefWrapper> chassisTemplates,
+ const json& element,
+ const std::map<std::string, JSONRefWrapper>& chassisTemplates,
Services& services);
/**
@@ -115,7 +116,8 @@
* @return vector of Chassis objects
*/
std::vector<std::unique_ptr<Chassis>> parseChassisArray(
- const json& element, std::map<std::string, JSONRefWrapper> chassisTemplates,
+ const json& element,
+ const std::map<std::string, JSONRefWrapper>& chassisTemplates,
Services& services);
/**
@@ -142,6 +144,17 @@
*
* Returns the template ID and a C++ reference_wrapper to the JSON element.
*
+ * A chassis_template object cannot be fully parsed in isolation. It is a
+ * template that contains variables.
+ *
+ * The chassis_template object is used by one or more chassis objects to avoid
+ * duplicate JSON. The chassis objects define chassis-specific values for the
+ * template variables.
+ *
+ * When the chassis object is parsed, the chassis_template JSON will be
+ * re-parsed, and the template variables will be replaced with the
+ * chassis-specific values.
+ *
* Throws an exception if parsing fails.
*
* @param element JSON element
@@ -151,6 +164,22 @@
const json& element);
/**
+ * Parses a JSON element containing an array of chassis_template objects.
+ *
+ * Returns a map of template IDs to chassis_template JSON elements.
+ *
+ * Note that chassis_template objects cannot be fully parsed in isolation. See
+ * parseChassisTemplate() for more information.
+ *
+ * Throws an exception if parsing fails.
+ *
+ * @param element JSON element
+ * @return chassis templates map
+ */
+std::map<std::string, JSONRefWrapper> parseChassisTemplateArray(
+ const json& element);
+
+/**
* Parses a JSON element containing a GPIO.
*
* Returns the corresponding C++ GPIO object.
diff --git a/phosphor-power-sequencer/test/config_file_parser_tests.cpp b/phosphor-power-sequencer/test/config_file_parser_tests.cpp
index 3f0797c..2fdf5af 100644
--- a/phosphor-power-sequencer/test/config_file_parser_tests.cpp
+++ b/phosphor-power-sequencer/test/config_file_parser_tests.cpp
@@ -1198,6 +1198,90 @@
}
}
+TEST(ConfigFileParserTests, ParseChassisTemplateArray)
+{
+ // Test where works: Array is empty
+ {
+ const json element = R"(
+ [
+ ]
+ )"_json;
+ auto chassisTemplates = parseChassisTemplateArray(element);
+ EXPECT_EQ(chassisTemplates.size(), 0);
+ }
+
+ // Test where works: Array is not empty
+ {
+ const json element = R"(
+ [
+ {
+ "id": "foo_chassis",
+ "number": "${chassis_number}",
+ "inventory_path": "/xyz/openbmc_project/inventory/system/chassis${chassis_number}",
+ "power_sequencers": []
+ },
+ {
+ "id": "bar_chassis",
+ "number": "${number}",
+ "inventory_path": "/xyz/openbmc_project/inventory/system/bar_chassis${number}",
+ "power_sequencers": []
+ }
+ ]
+ )"_json;
+ auto chassisTemplates = parseChassisTemplateArray(element);
+ EXPECT_EQ(chassisTemplates.size(), 2);
+ EXPECT_EQ(chassisTemplates.at("foo_chassis").get()["number"],
+ "${chassis_number}");
+ EXPECT_EQ(
+ chassisTemplates.at("foo_chassis").get()["inventory_path"],
+ "/xyz/openbmc_project/inventory/system/chassis${chassis_number}");
+ EXPECT_EQ(chassisTemplates.at("bar_chassis").get()["number"],
+ "${number}");
+ EXPECT_EQ(chassisTemplates.at("bar_chassis").get()["inventory_path"],
+ "/xyz/openbmc_project/inventory/system/bar_chassis${number}");
+ }
+
+ // Test where fails: Element is not an array
+ try
+ {
+ const json element = R"(
+ {
+ "foo": "bar"
+ }
+ )"_json;
+ parseChassisTemplateArray(element);
+ ADD_FAILURE() << "Should not have reached this line.";
+ }
+ catch (const std::invalid_argument& e)
+ {
+ EXPECT_STREQ(e.what(), "Element is not an array");
+ }
+
+ // Test where fails: Element within array is invalid
+ try
+ {
+ const json element = R"(
+ [
+ {
+ "id": "foo_chassis",
+ "number": "${chassis_number}",
+ "inventory_path": "/xyz/openbmc_project/inventory/system/chassis${chassis_number}",
+ "power_sequencers": []
+ },
+ {
+ "id": "bar_chassis"
+ }
+ ]
+ )"_json;
+ parseChassisTemplateArray(element);
+ ADD_FAILURE() << "Should not have reached this line.";
+ }
+ catch (const std::invalid_argument& e)
+ {
+ EXPECT_STREQ(e.what(), "Required property missing: number");
+ }
+}
+
TEST(ConfigFileParserTests, ParseGPIO)
{
// Test where works: Only required properties specified