pseq: Create Chassis class
Create a C++ Chassis class that corresponds to the JSON "chassis" object
in the config file.
Eventually more function will be added to this class, but for the
initial version only implement the required support for the JSON
properties.
Create automated test cases for the new class.
Tested:
* Ran automated test cases.
Change-Id: I66bd795f894b3376a5cb65294db7dbb6cf37e891
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
diff --git a/phosphor-power-sequencer/src/chassis.hpp b/phosphor-power-sequencer/src/chassis.hpp
new file mode 100644
index 0000000..8227953
--- /dev/null
+++ b/phosphor-power-sequencer/src/chassis.hpp
@@ -0,0 +1,116 @@
+/**
+ * Copyright © 2025 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.
+ */
+#pragma once
+
+#include "power_sequencer_device.hpp"
+
+#include <stddef.h> // for size_t
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace phosphor::power::sequencer
+{
+
+/**
+ * @class Chassis
+ *
+ * A chassis within the system.
+ *
+ * Chassis are typically a physical enclosure that contains system components
+ * such as CPUs, fans, power supplies, and PCIe cards. A chassis can be
+ * stand-alone, such as a tower or desktop. A chassis can also be designed to be
+ * mounted in an equipment rack.
+ */
+class Chassis
+{
+ public:
+ // Specify which compiler-generated methods we want
+ Chassis() = delete;
+ Chassis(const Chassis&) = delete;
+ Chassis(Chassis&&) = delete;
+ Chassis& operator=(const Chassis&) = delete;
+ Chassis& operator=(Chassis&&) = delete;
+ ~Chassis() = default;
+
+ /**
+ * Constructor.
+ *
+ * @param number Chassis number within the system. Must be >= 1.
+ * @param inventoryPath D-Bus inventory path of the chassis
+ * @param powerSequencers Power sequencer devices within the chassis
+ */
+ explicit Chassis(
+ size_t number, const std::string& inventoryPath,
+ std::vector<std::unique_ptr<PowerSequencerDevice>> powerSequencers) :
+ number{number}, inventoryPath{inventoryPath},
+ powerSequencers{std::move(powerSequencers)}
+ {}
+
+ /**
+ * Returns the chassis number within the system.
+ *
+ * @return chassis number
+ */
+ size_t getNumber() const
+ {
+ return number;
+ }
+
+ /**
+ * Returns the D-Bus inventory path of the chassis.
+ *
+ * @return inventory path
+ */
+ const std::string& getInventoryPath() const
+ {
+ return inventoryPath;
+ }
+
+ /**
+ * Returns the power sequencer devices within the chassis.
+ *
+ * @return power sequencer devices
+ */
+ const std::vector<std::unique_ptr<PowerSequencerDevice>>&
+ getPowerSequencers() const
+ {
+ return powerSequencers;
+ }
+
+ private:
+ /**
+ * Chassis number within the system.
+ *
+ * Chassis numbers start at 1 because chassis 0 represents the entire
+ * system.
+ */
+ size_t number;
+
+ /**
+ * D-Bus inventory path of the chassis.
+ */
+ std::string inventoryPath{};
+
+ /**
+ * Power sequencer devices within the chassis.
+ */
+ std::vector<std::unique_ptr<PowerSequencerDevice>> powerSequencers{};
+};
+
+} // namespace phosphor::power::sequencer
diff --git a/phosphor-power-sequencer/test/chassis_tests.cpp b/phosphor-power-sequencer/test/chassis_tests.cpp
new file mode 100644
index 0000000..6cc248e
--- /dev/null
+++ b/phosphor-power-sequencer/test/chassis_tests.cpp
@@ -0,0 +1,119 @@
+/**
+ * Copyright © 2025 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 "chassis.hpp"
+#include "mock_services.hpp"
+#include "power_sequencer_device.hpp"
+#include "rail.hpp"
+#include "services.hpp"
+#include "ucd90160_device.hpp"
+
+#include <stddef.h> // for size_t
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+using namespace phosphor::power::sequencer;
+
+/**
+ * Creates a PowerSequencerDevice instance.
+ *
+ * PowerSequencerDevice is an abstract base class. The actual object type
+ * created is a UCD90160Device.
+ *
+ * @param bus I2C bus for the device
+ * @param address I2C address for the device
+ * @param services System services like hardware presence and the journal
+ * @return PowerSequencerDevice instance
+ */
+std::unique_ptr<PowerSequencerDevice> createPowerSequencer(
+ uint8_t bus, uint16_t address, Services& services)
+{
+ std::string powerControlGPIOName{"power-chassis-control"};
+ std::string powerGoodGPIOName{"power-chassis-good"};
+ std::vector<std::unique_ptr<Rail>> rails;
+ return std::make_unique<UCD90160Device>(
+ bus, address, powerControlGPIOName, powerGoodGPIOName, std::move(rails),
+ services);
+}
+
+TEST(ChassisTests, Constructor)
+{
+ MockServices services;
+
+ size_t number{1};
+ std::string inventoryPath{"/xyz/openbmc_project/inventory/system/chassis"};
+ std::vector<std::unique_ptr<PowerSequencerDevice>> powerSequencers;
+ powerSequencers.emplace_back(createPowerSequencer(3, 0x70, services));
+ Chassis chassis{number, inventoryPath, std::move(powerSequencers)};
+
+ EXPECT_EQ(chassis.getNumber(), number);
+ EXPECT_EQ(chassis.getInventoryPath(), inventoryPath);
+ EXPECT_EQ(chassis.getPowerSequencers().size(), 1);
+ EXPECT_EQ(chassis.getPowerSequencers()[0]->getBus(), 3);
+ EXPECT_EQ(chassis.getPowerSequencers()[0]->getAddress(), 0x70);
+}
+
+TEST(ChassisTests, GetNumber)
+{
+ MockServices services;
+
+ size_t number{2};
+ std::string inventoryPath{"/xyz/openbmc_project/inventory/system/chassis2"};
+ std::vector<std::unique_ptr<PowerSequencerDevice>> powerSequencers;
+ Chassis chassis{number, inventoryPath, std::move(powerSequencers)};
+
+ EXPECT_EQ(chassis.getNumber(), number);
+}
+
+TEST(ChassisTests, GetInventoryPath)
+{
+ MockServices services;
+
+ size_t number{3};
+ std::string inventoryPath{
+ "/xyz/openbmc_project/inventory/system/chassis_3"};
+ std::vector<std::unique_ptr<PowerSequencerDevice>> powerSequencers;
+ Chassis chassis{number, inventoryPath, std::move(powerSequencers)};
+
+ EXPECT_EQ(chassis.getInventoryPath(), inventoryPath);
+}
+
+TEST(ChassisTests, GetPowerSequencers)
+{
+ MockServices services;
+
+ size_t number{2};
+ std::string inventoryPath{"/xyz/openbmc_project/inventory/system/chassis2"};
+ std::vector<std::unique_ptr<PowerSequencerDevice>> powerSequencers;
+ powerSequencers.emplace_back(createPowerSequencer(3, 0x70, services));
+ powerSequencers.emplace_back(createPowerSequencer(4, 0x32, services));
+ powerSequencers.emplace_back(createPowerSequencer(10, 0x16, services));
+ Chassis chassis{number, inventoryPath, std::move(powerSequencers)};
+
+ EXPECT_EQ(chassis.getPowerSequencers().size(), 3);
+ EXPECT_EQ(chassis.getPowerSequencers()[0]->getBus(), 3);
+ EXPECT_EQ(chassis.getPowerSequencers()[0]->getAddress(), 0x70);
+ EXPECT_EQ(chassis.getPowerSequencers()[1]->getBus(), 4);
+ EXPECT_EQ(chassis.getPowerSequencers()[1]->getAddress(), 0x32);
+ EXPECT_EQ(chassis.getPowerSequencers()[2]->getBus(), 10);
+ EXPECT_EQ(chassis.getPowerSequencers()[2]->getAddress(), 0x16);
+}
diff --git a/phosphor-power-sequencer/test/meson.build b/phosphor-power-sequencer/test/meson.build
index a920f98..3d3126d 100644
--- a/phosphor-power-sequencer/test/meson.build
+++ b/phosphor-power-sequencer/test/meson.build
@@ -2,6 +2,7 @@
'phosphor-power-sequencer-tests',
executable(
'phosphor-power-sequencer-tests',
+ 'chassis_tests.cpp',
'config_file_parser_error_tests.cpp',
'config_file_parser_tests.cpp',
'pmbus_driver_device_tests.cpp',