18a3afd70SShawn McCarney /**
28a3afd70SShawn McCarney  * Copyright © 2020 IBM Corporation
38a3afd70SShawn McCarney  *
48a3afd70SShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
58a3afd70SShawn McCarney  * you may not use this file except in compliance with the License.
68a3afd70SShawn McCarney  * You may obtain a copy of the License at
78a3afd70SShawn McCarney  *
88a3afd70SShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
98a3afd70SShawn McCarney  *
108a3afd70SShawn McCarney  * Unless required by applicable law or agreed to in writing, software
118a3afd70SShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
128a3afd70SShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138a3afd70SShawn McCarney  * See the License for the specific language governing permissions and
148a3afd70SShawn McCarney  * limitations under the License.
158a3afd70SShawn McCarney  */
16525e20c9SShawn McCarney #include "action.hpp"
178a3afd70SShawn McCarney #include "chassis.hpp"
18525e20c9SShawn McCarney #include "configuration.hpp"
198a3afd70SShawn McCarney #include "device.hpp"
208a3afd70SShawn McCarney #include "i2c_interface.hpp"
21db0b833cSShawn McCarney #include "id_map.hpp"
22525e20c9SShawn McCarney #include "mock_journal.hpp"
2323243f84SBob King #include "mock_services.hpp"
24050531f5SShawn McCarney #include "mocked_i2c_interface.hpp"
25a2c81a61SBob King #include "pmbus_read_sensor_action.hpp"
26525e20c9SShawn McCarney #include "presence_detection.hpp"
27525e20c9SShawn McCarney #include "rail.hpp"
28525e20c9SShawn McCarney #include "rule.hpp"
29525e20c9SShawn McCarney #include "system.hpp"
308a3afd70SShawn McCarney #include "test_utils.hpp"
318a3afd70SShawn McCarney 
328a3afd70SShawn McCarney #include <memory>
338a3afd70SShawn McCarney #include <stdexcept>
34525e20c9SShawn McCarney #include <string>
358a3afd70SShawn McCarney #include <utility>
368a3afd70SShawn McCarney #include <vector>
378a3afd70SShawn McCarney 
38a2c81a61SBob King #include <gmock/gmock.h>
398a3afd70SShawn McCarney #include <gtest/gtest.h>
408a3afd70SShawn McCarney 
418a3afd70SShawn McCarney using namespace phosphor::power::regulators;
428a3afd70SShawn McCarney using namespace phosphor::power::regulators::test_utils;
438a3afd70SShawn McCarney 
44a2c81a61SBob King using ::testing::A;
45050531f5SShawn McCarney using ::testing::Return;
46a2c81a61SBob King using ::testing::TypedEq;
47050531f5SShawn McCarney 
488a3afd70SShawn McCarney TEST(ChassisTests, Constructor)
498a3afd70SShawn McCarney {
508a3afd70SShawn McCarney     // Test where works: Only required parameters are specified
518a3afd70SShawn McCarney     {
528a3afd70SShawn McCarney         Chassis chassis{2};
538a3afd70SShawn McCarney         EXPECT_EQ(chassis.getNumber(), 2);
548a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices().size(), 0);
558a3afd70SShawn McCarney     }
568a3afd70SShawn McCarney 
578a3afd70SShawn McCarney     // Test where works: All parameters are specified
588a3afd70SShawn McCarney     {
598a3afd70SShawn McCarney         // Create vector of Device objects
608a3afd70SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
61db0b833cSShawn McCarney         devices.emplace_back(createDevice("vdd_reg1"));
62db0b833cSShawn McCarney         devices.emplace_back(createDevice("vdd_reg2"));
638a3afd70SShawn McCarney 
648a3afd70SShawn McCarney         // Create Chassis
658a3afd70SShawn McCarney         Chassis chassis{1, std::move(devices)};
668a3afd70SShawn McCarney         EXPECT_EQ(chassis.getNumber(), 1);
678a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices().size(), 2);
688a3afd70SShawn McCarney     }
698a3afd70SShawn McCarney 
708a3afd70SShawn McCarney     // Test where fails: Invalid chassis number < 1
718a3afd70SShawn McCarney     try
728a3afd70SShawn McCarney     {
738a3afd70SShawn McCarney         Chassis chassis{0};
748a3afd70SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
758a3afd70SShawn McCarney     }
768a3afd70SShawn McCarney     catch (const std::invalid_argument& e)
778a3afd70SShawn McCarney     {
788a3afd70SShawn McCarney         EXPECT_STREQ(e.what(), "Invalid chassis number: 0");
798a3afd70SShawn McCarney     }
808a3afd70SShawn McCarney     catch (...)
818a3afd70SShawn McCarney     {
828a3afd70SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
838a3afd70SShawn McCarney     }
848a3afd70SShawn McCarney }
858a3afd70SShawn McCarney 
86db0b833cSShawn McCarney TEST(ChassisTests, AddToIDMap)
87db0b833cSShawn McCarney {
88db0b833cSShawn McCarney     // Create vector of Device objects
89db0b833cSShawn McCarney     std::vector<std::unique_ptr<Device>> devices{};
90db0b833cSShawn McCarney     devices.emplace_back(createDevice("reg1", {"rail1"}));
91db0b833cSShawn McCarney     devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
92db0b833cSShawn McCarney     devices.emplace_back(createDevice("reg3"));
93db0b833cSShawn McCarney 
94db0b833cSShawn McCarney     // Create Chassis
95db0b833cSShawn McCarney     Chassis chassis{1, std::move(devices)};
96db0b833cSShawn McCarney 
97db0b833cSShawn McCarney     // Add Device and Rail objects within the Chassis to an IDMap
98db0b833cSShawn McCarney     IDMap idMap{};
99db0b833cSShawn McCarney     chassis.addToIDMap(idMap);
100db0b833cSShawn McCarney 
101db0b833cSShawn McCarney     // Verify all Devices are in the IDMap
102db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getDevice("reg1"));
103db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getDevice("reg2"));
104db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getDevice("reg3"));
105db0b833cSShawn McCarney     EXPECT_THROW(idMap.getDevice("reg4"), std::invalid_argument);
106db0b833cSShawn McCarney 
107db0b833cSShawn McCarney     // Verify all Rails are in the IDMap
108db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getRail("rail1"));
109db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getRail("rail2a"));
110db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getRail("rail2b"));
111db0b833cSShawn McCarney     EXPECT_THROW(idMap.getRail("rail3"), std::invalid_argument);
112db0b833cSShawn McCarney }
113db0b833cSShawn McCarney 
114050531f5SShawn McCarney TEST(ChassisTests, CloseDevices)
115050531f5SShawn McCarney {
116050531f5SShawn McCarney     // Test where no devices were specified in constructor
117050531f5SShawn McCarney     {
118d692d6dfSBob King         // Create mock services.  Expect logDebug() to be called.
119d692d6dfSBob King         MockServices services{};
120d692d6dfSBob King         MockJournal& journal = services.getMockJournal();
121d692d6dfSBob King         EXPECT_CALL(journal, logDebug("Closing devices in chassis 2")).Times(1);
122d692d6dfSBob King 
123050531f5SShawn McCarney         // Create Chassis
124050531f5SShawn McCarney         Chassis chassis{2};
125050531f5SShawn McCarney 
126050531f5SShawn McCarney         // Call closeDevices()
127d692d6dfSBob King         chassis.closeDevices(services);
128050531f5SShawn McCarney     }
129050531f5SShawn McCarney 
130050531f5SShawn McCarney     // Test where devices were specified in constructor
131050531f5SShawn McCarney     {
132050531f5SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
133050531f5SShawn McCarney 
134d692d6dfSBob King         // Create mock services.  Expect logDebug() to be called.
135d692d6dfSBob King         MockServices services{};
136d692d6dfSBob King         MockJournal& journal = services.getMockJournal();
137d692d6dfSBob King         EXPECT_CALL(journal, logDebug("Closing devices in chassis 1")).Times(1);
138d692d6dfSBob King 
139050531f5SShawn McCarney         // Create Device vdd0_reg
140050531f5SShawn McCarney         {
141050531f5SShawn McCarney             // Create mock I2CInterface: isOpen() and close() should be called
142050531f5SShawn McCarney             std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
143050531f5SShawn McCarney                 std::make_unique<i2c::MockedI2CInterface>();
144050531f5SShawn McCarney             EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
145050531f5SShawn McCarney             EXPECT_CALL(*i2cInterface, close).Times(1);
146050531f5SShawn McCarney 
147050531f5SShawn McCarney             // Create Device
148*a76898f1SBob King             std::unique_ptr<Device> device =
149*a76898f1SBob King                 std::make_unique<Device>("vdd0_reg", true,
150*a76898f1SBob King                                          "/xyz/openbmc_project/inventory/"
151*a76898f1SBob King                                          "system/chassis/motherboard/vdd0_reg",
152050531f5SShawn McCarney                                          std::move(i2cInterface));
153050531f5SShawn McCarney             devices.emplace_back(std::move(device));
154050531f5SShawn McCarney         }
155050531f5SShawn McCarney 
156050531f5SShawn McCarney         // Create Device vdd1_reg
157050531f5SShawn McCarney         {
158050531f5SShawn McCarney             // Create mock I2CInterface: isOpen() and close() should be called
159050531f5SShawn McCarney             std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
160050531f5SShawn McCarney                 std::make_unique<i2c::MockedI2CInterface>();
161050531f5SShawn McCarney             EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
162050531f5SShawn McCarney             EXPECT_CALL(*i2cInterface, close).Times(1);
163050531f5SShawn McCarney 
164050531f5SShawn McCarney             // Create Device
165*a76898f1SBob King             std::unique_ptr<Device> device =
166*a76898f1SBob King                 std::make_unique<Device>("vdd1_reg", true,
167*a76898f1SBob King                                          "/xyz/openbmc_project/inventory/"
168*a76898f1SBob King                                          "system/chassis/motherboard/vdd1_reg",
169050531f5SShawn McCarney                                          std::move(i2cInterface));
170050531f5SShawn McCarney             devices.emplace_back(std::move(device));
171050531f5SShawn McCarney         }
172050531f5SShawn McCarney 
173050531f5SShawn McCarney         // Create Chassis
174050531f5SShawn McCarney         Chassis chassis{1, std::move(devices)};
175050531f5SShawn McCarney 
176050531f5SShawn McCarney         // Call closeDevices()
177d692d6dfSBob King         chassis.closeDevices(services);
178050531f5SShawn McCarney     }
179050531f5SShawn McCarney }
180050531f5SShawn McCarney 
181525e20c9SShawn McCarney TEST(ChassisTests, Configure)
182525e20c9SShawn McCarney {
183525e20c9SShawn McCarney     // Test where no devices were specified in constructor
184525e20c9SShawn McCarney     {
1855cfe5103SBob King         // Create mock services.  Expect logInfo() to be called.
18623243f84SBob King         MockServices services{};
1875cfe5103SBob King         MockJournal& journal = services.getMockJournal();
1885cfe5103SBob King         EXPECT_CALL(journal, logInfo("Configuring chassis 1")).Times(1);
1895cfe5103SBob King         EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
1905cfe5103SBob King         EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
19123243f84SBob King 
192525e20c9SShawn McCarney         // Create Chassis
193525e20c9SShawn McCarney         std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(1);
194525e20c9SShawn McCarney         Chassis* chassisPtr = chassis.get();
195525e20c9SShawn McCarney 
196525e20c9SShawn McCarney         // Create System that contains Chassis
197525e20c9SShawn McCarney         std::vector<std::unique_ptr<Rule>> rules{};
198525e20c9SShawn McCarney         std::vector<std::unique_ptr<Chassis>> chassisVec{};
199525e20c9SShawn McCarney         chassisVec.emplace_back(std::move(chassis));
200525e20c9SShawn McCarney         System system{std::move(rules), std::move(chassisVec)};
201525e20c9SShawn McCarney 
202525e20c9SShawn McCarney         // Call configure()
20323243f84SBob King         chassisPtr->configure(services, system);
204525e20c9SShawn McCarney     }
205525e20c9SShawn McCarney 
206525e20c9SShawn McCarney     // Test where devices were specified in constructor
207525e20c9SShawn McCarney     {
208525e20c9SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
209525e20c9SShawn McCarney 
2105cfe5103SBob King         // Create mock services.  Expect logInfo() and logDebug() to be called.
2115cfe5103SBob King         MockServices services{};
2125cfe5103SBob King         MockJournal& journal = services.getMockJournal();
2135cfe5103SBob King         EXPECT_CALL(journal, logInfo("Configuring chassis 2")).Times(1);
2145cfe5103SBob King         EXPECT_CALL(journal, logDebug("Configuring vdd0_reg: volts=1.300000"))
2155cfe5103SBob King             .Times(1);
2165cfe5103SBob King         EXPECT_CALL(journal, logDebug("Configuring vdd1_reg: volts=1.200000"))
2175cfe5103SBob King             .Times(1);
2185cfe5103SBob King         EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
2195cfe5103SBob King 
220525e20c9SShawn McCarney         // Create Device vdd0_reg
221525e20c9SShawn McCarney         {
222525e20c9SShawn McCarney             // Create Configuration
223525e20c9SShawn McCarney             std::vector<std::unique_ptr<Action>> actions{};
224525e20c9SShawn McCarney             std::unique_ptr<Configuration> configuration =
225525e20c9SShawn McCarney                 std::make_unique<Configuration>(1.3, std::move(actions));
226525e20c9SShawn McCarney 
227525e20c9SShawn McCarney             // Create Device
228525e20c9SShawn McCarney             std::unique_ptr<i2c::I2CInterface> i2cInterface =
229525e20c9SShawn McCarney                 createI2CInterface();
230525e20c9SShawn McCarney             std::unique_ptr<PresenceDetection> presenceDetection{};
231525e20c9SShawn McCarney             std::unique_ptr<Device> device = std::make_unique<Device>(
232*a76898f1SBob King                 "vdd0_reg", true,
233*a76898f1SBob King                 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
234*a76898f1SBob King                 "vdd0_reg",
235525e20c9SShawn McCarney                 std::move(i2cInterface), std::move(presenceDetection),
236525e20c9SShawn McCarney                 std::move(configuration));
237525e20c9SShawn McCarney             devices.emplace_back(std::move(device));
238525e20c9SShawn McCarney         }
239525e20c9SShawn McCarney 
240525e20c9SShawn McCarney         // Create Device vdd1_reg
241525e20c9SShawn McCarney         {
242525e20c9SShawn McCarney             // Create Configuration
243525e20c9SShawn McCarney             std::vector<std::unique_ptr<Action>> actions{};
244525e20c9SShawn McCarney             std::unique_ptr<Configuration> configuration =
245525e20c9SShawn McCarney                 std::make_unique<Configuration>(1.2, std::move(actions));
246525e20c9SShawn McCarney 
247525e20c9SShawn McCarney             // Create Device
248525e20c9SShawn McCarney             std::unique_ptr<i2c::I2CInterface> i2cInterface =
249525e20c9SShawn McCarney                 createI2CInterface();
250525e20c9SShawn McCarney             std::unique_ptr<PresenceDetection> presenceDetection{};
251525e20c9SShawn McCarney             std::unique_ptr<Device> device = std::make_unique<Device>(
252*a76898f1SBob King                 "vdd1_reg", true,
253*a76898f1SBob King                 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
254*a76898f1SBob King                 "vdd1_reg",
255525e20c9SShawn McCarney                 std::move(i2cInterface), std::move(presenceDetection),
256525e20c9SShawn McCarney                 std::move(configuration));
257525e20c9SShawn McCarney             devices.emplace_back(std::move(device));
258525e20c9SShawn McCarney         }
259525e20c9SShawn McCarney 
260525e20c9SShawn McCarney         // Create Chassis
261525e20c9SShawn McCarney         std::unique_ptr<Chassis> chassis =
262525e20c9SShawn McCarney             std::make_unique<Chassis>(2, std::move(devices));
263525e20c9SShawn McCarney         Chassis* chassisPtr = chassis.get();
264525e20c9SShawn McCarney 
265525e20c9SShawn McCarney         // Create System that contains Chassis
266525e20c9SShawn McCarney         std::vector<std::unique_ptr<Rule>> rules{};
267525e20c9SShawn McCarney         std::vector<std::unique_ptr<Chassis>> chassisVec{};
268525e20c9SShawn McCarney         chassisVec.emplace_back(std::move(chassis));
269525e20c9SShawn McCarney         System system{std::move(rules), std::move(chassisVec)};
270525e20c9SShawn McCarney 
271525e20c9SShawn McCarney         // Call configure()
27223243f84SBob King         chassisPtr->configure(services, system);
273525e20c9SShawn McCarney     }
274525e20c9SShawn McCarney }
275525e20c9SShawn McCarney 
2768a3afd70SShawn McCarney TEST(ChassisTests, GetDevices)
2778a3afd70SShawn McCarney {
2788a3afd70SShawn McCarney     // Test where no devices were specified in constructor
2798a3afd70SShawn McCarney     {
2808a3afd70SShawn McCarney         Chassis chassis{2};
2818a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices().size(), 0);
2828a3afd70SShawn McCarney     }
2838a3afd70SShawn McCarney 
2848a3afd70SShawn McCarney     // Test where devices were specified in constructor
2858a3afd70SShawn McCarney     {
2868a3afd70SShawn McCarney         // Create vector of Device objects
2878a3afd70SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
288db0b833cSShawn McCarney         devices.emplace_back(createDevice("vdd_reg1"));
289db0b833cSShawn McCarney         devices.emplace_back(createDevice("vdd_reg2"));
2908a3afd70SShawn McCarney 
2918a3afd70SShawn McCarney         // Create Chassis
2928a3afd70SShawn McCarney         Chassis chassis{1, std::move(devices)};
2938a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices().size(), 2);
2948a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices()[0]->getID(), "vdd_reg1");
2958a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices()[1]->getID(), "vdd_reg2");
2968a3afd70SShawn McCarney     }
2978a3afd70SShawn McCarney }
2988a3afd70SShawn McCarney 
2998a3afd70SShawn McCarney TEST(ChassisTests, GetNumber)
3008a3afd70SShawn McCarney {
3018a3afd70SShawn McCarney     Chassis chassis{3};
3028a3afd70SShawn McCarney     EXPECT_EQ(chassis.getNumber(), 3);
3038a3afd70SShawn McCarney }
304a2c81a61SBob King 
305a2c81a61SBob King TEST(ChassisTests, MonitorSensors)
306a2c81a61SBob King {
307a2c81a61SBob King     // Test where no devices were specified in constructor
308a2c81a61SBob King     {
3098a55292dSBob King         // Create mock services.  No logging should occur.
3108a55292dSBob King         MockServices services{};
3118a55292dSBob King         MockJournal& journal = services.getMockJournal();
3128a55292dSBob King         EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
3138a55292dSBob King         EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
3148a55292dSBob King 
315a2c81a61SBob King         // Create Chassis
316a2c81a61SBob King         std::vector<std::unique_ptr<Device>> devices{};
317a2c81a61SBob King         std::unique_ptr<Chassis> chassis =
318a2c81a61SBob King             std::make_unique<Chassis>(1, std::move(devices));
319a2c81a61SBob King         Chassis* chassisPtr = chassis.get();
320a2c81a61SBob King 
321a2c81a61SBob King         // Create System that contains Chassis
322a2c81a61SBob King         std::vector<std::unique_ptr<Rule>> rules{};
323a2c81a61SBob King         std::vector<std::unique_ptr<Chassis>> chassisVec{};
324a2c81a61SBob King         chassisVec.emplace_back(std::move(chassis));
325a2c81a61SBob King         System system{std::move(rules), std::move(chassisVec)};
326a2c81a61SBob King 
327a2c81a61SBob King         // Call monitorSensors().  Should do nothing.
3288a55292dSBob King         chassisPtr->monitorSensors(services, system);
329a2c81a61SBob King     }
330a2c81a61SBob King 
331a2c81a61SBob King     // Test where devices were specified in constructor
332a2c81a61SBob King     {
3338a55292dSBob King         // Create mock services.  No logging should occur.
3348a55292dSBob King         MockServices services{};
3358a55292dSBob King         MockJournal& journal = services.getMockJournal();
3368a55292dSBob King         EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
3378a55292dSBob King         EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
3388a55292dSBob King 
339a2c81a61SBob King         std::vector<std::unique_ptr<Device>> devices{};
340a2c81a61SBob King 
341a2c81a61SBob King         // Create PMBusReadSensorAction
342a2c81a61SBob King         pmbus_utils::SensorValueType type{pmbus_utils::SensorValueType::iout};
343a2c81a61SBob King         uint8_t command = 0x8C;
344a2c81a61SBob King         pmbus_utils::SensorDataFormat format{
345a2c81a61SBob King             pmbus_utils::SensorDataFormat::linear_11};
346a2c81a61SBob King         std::optional<int8_t> exponent{};
347a2c81a61SBob King         std::unique_ptr<PMBusReadSensorAction> action =
348a2c81a61SBob King             std::make_unique<PMBusReadSensorAction>(type, command, format,
349a2c81a61SBob King                                                     exponent);
350a2c81a61SBob King 
351a2c81a61SBob King         // Create mock I2CInterface.  A two-byte read should occur.
352a2c81a61SBob King         std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
353a2c81a61SBob King             std::make_unique<i2c::MockedI2CInterface>();
354a2c81a61SBob King         EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
355a2c81a61SBob King         EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x8C), A<uint16_t&>()))
356a2c81a61SBob King             .Times(1);
357a2c81a61SBob King 
358a2c81a61SBob King         // Create SensorMonitoring
359a2c81a61SBob King         std::vector<std::unique_ptr<Action>> actions{};
360a2c81a61SBob King         actions.emplace_back(std::move(action));
361a2c81a61SBob King         std::unique_ptr<SensorMonitoring> sensorMonitoring =
362a2c81a61SBob King             std::make_unique<SensorMonitoring>(std::move(actions));
363a2c81a61SBob King 
364a2c81a61SBob King         // Create Rail
365a2c81a61SBob King         std::vector<std::unique_ptr<Rail>> rails{};
366a2c81a61SBob King         std::unique_ptr<Configuration> configuration{};
367a2c81a61SBob King         std::unique_ptr<Rail> rail = std::make_unique<Rail>(
368a2c81a61SBob King             "vdd0", std::move(configuration), std::move(sensorMonitoring));
369a2c81a61SBob King         rails.emplace_back(std::move(rail));
370a2c81a61SBob King 
371a2c81a61SBob King         // Create Device
372a2c81a61SBob King         std::unique_ptr<PresenceDetection> presenceDetection{};
373a2c81a61SBob King         std::unique_ptr<Configuration> deviceConfiguration{};
374a2c81a61SBob King         std::unique_ptr<Device> device = std::make_unique<Device>(
375*a76898f1SBob King             "reg1", true,
376*a76898f1SBob King             "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
377a2c81a61SBob King             std::move(i2cInterface), std::move(presenceDetection),
378a2c81a61SBob King             std::move(deviceConfiguration), std::move(rails));
379a2c81a61SBob King 
380a2c81a61SBob King         // Create Chassis
381a2c81a61SBob King         devices.emplace_back(std::move(device));
382a2c81a61SBob King         std::unique_ptr<Chassis> chassis =
383a2c81a61SBob King             std::make_unique<Chassis>(1, std::move(devices));
384a2c81a61SBob King         Chassis* chassisPtr = chassis.get();
385a2c81a61SBob King 
386a2c81a61SBob King         // Create System that contains Chassis
387a2c81a61SBob King         std::vector<std::unique_ptr<Rule>> rules{};
388a2c81a61SBob King         std::vector<std::unique_ptr<Chassis>> chassisVec{};
389a2c81a61SBob King         chassisVec.emplace_back(std::move(chassis));
390a2c81a61SBob King         System system{std::move(rules), std::move(chassisVec)};
391a2c81a61SBob King 
392a2c81a61SBob King         // Call monitorSensors()
3938a55292dSBob King         chassisPtr->monitorSensors(services, system);
394a2c81a61SBob King     }
395a2c81a61SBob King }
396