xref: /openbmc/phosphor-power/phosphor-regulators/test/rail_tests.cpp (revision fa2734d69e5382d720a84ad0c3278d561b610245)
1a2461b34SShawn McCarney /**
2a2461b34SShawn McCarney  * Copyright © 2019 IBM Corporation
3a2461b34SShawn McCarney  *
4a2461b34SShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
5a2461b34SShawn McCarney  * you may not use this file except in compliance with the License.
6a2461b34SShawn McCarney  * You may obtain a copy of the License at
7a2461b34SShawn McCarney  *
8a2461b34SShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
9a2461b34SShawn McCarney  *
10a2461b34SShawn McCarney  * Unless required by applicable law or agreed to in writing, software
11a2461b34SShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
12a2461b34SShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a2461b34SShawn McCarney  * See the License for the specific language governing permissions and
14a2461b34SShawn McCarney  * limitations under the License.
15a2461b34SShawn McCarney  */
164bf310e3SShawn McCarney #include "action.hpp"
17779b9565SShawn McCarney #include "chassis.hpp"
184bf310e3SShawn McCarney #include "configuration.hpp"
19779b9565SShawn McCarney #include "device.hpp"
20779b9565SShawn McCarney #include "i2c_interface.hpp"
214bf310e3SShawn McCarney #include "mock_action.hpp"
222ccf9617SShawn McCarney #include "mock_error_logging.hpp"
23779b9565SShawn McCarney #include "mock_journal.hpp"
2417bac89eSShawn McCarney #include "mock_sensors.hpp"
2523243f84SBob King #include "mock_services.hpp"
26779b9565SShawn McCarney #include "mocked_i2c_interface.hpp"
2732252599SShawn McCarney #include "phase_fault_detection.hpp"
28779b9565SShawn McCarney #include "presence_detection.hpp"
29a2461b34SShawn McCarney #include "rail.hpp"
30779b9565SShawn McCarney #include "rule.hpp"
314bf310e3SShawn McCarney #include "sensor_monitoring.hpp"
322f9e14f6SShawn McCarney #include "sensors.hpp"
33779b9565SShawn McCarney #include "system.hpp"
342ccf9617SShawn McCarney #include "test_sdbus_error.hpp"
354bf310e3SShawn McCarney 
364bf310e3SShawn McCarney #include <memory>
374bf310e3SShawn McCarney #include <optional>
384bf310e3SShawn McCarney #include <utility>
394bf310e3SShawn McCarney #include <vector>
40a2461b34SShawn McCarney 
41eb7bec4aSShawn McCarney #include <gmock/gmock.h>
42a2461b34SShawn McCarney #include <gtest/gtest.h>
43a2461b34SShawn McCarney 
44a2461b34SShawn McCarney using namespace phosphor::power::regulators;
45a2461b34SShawn McCarney 
467b743431SBob King using ::testing::A;
47779b9565SShawn McCarney using ::testing::Return;
482ccf9617SShawn McCarney using ::testing::Throw;
497b743431SBob King using ::testing::TypedEq;
50779b9565SShawn McCarney 
51cb3f6a63SShawn McCarney static const std::string chassisInvPath{
52cb3f6a63SShawn McCarney     "/xyz/openbmc_project/inventory/system/chassis"};
53cb3f6a63SShawn McCarney 
TEST(RailTests,Constructor)54a2461b34SShawn McCarney TEST(RailTests, Constructor)
55a2461b34SShawn McCarney {
564bf310e3SShawn McCarney     // Test where only required parameters are specified
574bf310e3SShawn McCarney     {
584bf310e3SShawn McCarney         Rail rail{"vdd0"};
594afb285eSShawn McCarney         EXPECT_EQ(rail.getID(), "vdd0");
604bf310e3SShawn McCarney         EXPECT_EQ(rail.getConfiguration(), nullptr);
614bf310e3SShawn McCarney         EXPECT_EQ(rail.getSensorMonitoring(), nullptr);
624bf310e3SShawn McCarney     }
634bf310e3SShawn McCarney 
644bf310e3SShawn McCarney     // Test where all parameters are specified
654bf310e3SShawn McCarney     {
664bf310e3SShawn McCarney         // Create Configuration
674bf310e3SShawn McCarney         std::optional<double> volts{1.3};
684bf310e3SShawn McCarney         std::vector<std::unique_ptr<Action>> actions{};
694bf310e3SShawn McCarney         actions.push_back(std::make_unique<MockAction>());
704bf310e3SShawn McCarney         actions.push_back(std::make_unique<MockAction>());
714bf310e3SShawn McCarney         std::unique_ptr<Configuration> configuration =
724bf310e3SShawn McCarney             std::make_unique<Configuration>(volts, std::move(actions));
734bf310e3SShawn McCarney 
744bf310e3SShawn McCarney         // Create SensorMonitoring
754bf310e3SShawn McCarney         actions.clear();
764bf310e3SShawn McCarney         actions.push_back(std::make_unique<MockAction>());
774bf310e3SShawn McCarney         std::unique_ptr<SensorMonitoring> sensorMonitoring =
784bf310e3SShawn McCarney             std::make_unique<SensorMonitoring>(std::move(actions));
794bf310e3SShawn McCarney 
804bf310e3SShawn McCarney         // Create Rail
814bf310e3SShawn McCarney         Rail rail{"vddr1", std::move(configuration),
824bf310e3SShawn McCarney                   std::move(sensorMonitoring)};
834bf310e3SShawn McCarney         EXPECT_EQ(rail.getID(), "vddr1");
844bf310e3SShawn McCarney         EXPECT_NE(rail.getConfiguration(), nullptr);
854bf310e3SShawn McCarney         EXPECT_EQ(rail.getConfiguration()->getVolts().has_value(), true);
864bf310e3SShawn McCarney         EXPECT_EQ(rail.getConfiguration()->getVolts().value(), 1.3);
874bf310e3SShawn McCarney         EXPECT_EQ(rail.getConfiguration()->getActions().size(), 2);
884bf310e3SShawn McCarney         EXPECT_NE(rail.getSensorMonitoring(), nullptr);
894bf310e3SShawn McCarney         EXPECT_EQ(rail.getSensorMonitoring()->getActions().size(), 1);
904bf310e3SShawn McCarney     }
914bf310e3SShawn McCarney }
924bf310e3SShawn McCarney 
TEST(RailTests,ClearErrorHistory)932ccf9617SShawn McCarney TEST(RailTests, ClearErrorHistory)
942ccf9617SShawn McCarney {
952ccf9617SShawn McCarney     // Create SensorMonitoring.  Will fail with a DBus exception.
962ccf9617SShawn McCarney     std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
972ccf9617SShawn McCarney     EXPECT_CALL(*action, execute)
982ccf9617SShawn McCarney         .WillRepeatedly(Throw(TestSDBusError{"Unable to set sensor value"}));
992ccf9617SShawn McCarney     std::vector<std::unique_ptr<Action>> actions{};
1002ccf9617SShawn McCarney     actions.emplace_back(std::move(action));
1012ccf9617SShawn McCarney     std::unique_ptr<SensorMonitoring> sensorMonitoring =
1022ccf9617SShawn McCarney         std::make_unique<SensorMonitoring>(std::move(actions));
1032ccf9617SShawn McCarney 
1042ccf9617SShawn McCarney     // Create Rail
1052ccf9617SShawn McCarney     std::unique_ptr<Configuration> configuration{};
1062ccf9617SShawn McCarney     std::unique_ptr<Rail> rail = std::make_unique<Rail>(
1072ccf9617SShawn McCarney         "vddr1", std::move(configuration), std::move(sensorMonitoring));
1082ccf9617SShawn McCarney     Rail* railPtr = rail.get();
1092ccf9617SShawn McCarney 
1102ccf9617SShawn McCarney     // Create Device that contains Rail
1112ccf9617SShawn McCarney     std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
1122ccf9617SShawn McCarney         std::make_unique<i2c::MockedI2CInterface>();
1132ccf9617SShawn McCarney     std::unique_ptr<PresenceDetection> presenceDetection{};
1142ccf9617SShawn McCarney     std::unique_ptr<Configuration> deviceConfiguration{};
11532252599SShawn McCarney     std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
1162ccf9617SShawn McCarney     std::vector<std::unique_ptr<Rail>> rails{};
1172ccf9617SShawn McCarney     rails.emplace_back(std::move(rail));
1182ccf9617SShawn McCarney     std::unique_ptr<Device> device = std::make_unique<Device>(
1192ccf9617SShawn McCarney         "reg1", true,
1202ccf9617SShawn McCarney         "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
1212ccf9617SShawn McCarney         std::move(i2cInterface), std::move(presenceDetection),
12232252599SShawn McCarney         std::move(deviceConfiguration), std::move(phaseFaultDetection),
12332252599SShawn McCarney         std::move(rails));
1242ccf9617SShawn McCarney     Device* devicePtr = device.get();
1252ccf9617SShawn McCarney 
1262ccf9617SShawn McCarney     // Create Chassis that contains Device
1272ccf9617SShawn McCarney     std::vector<std::unique_ptr<Device>> devices{};
1282ccf9617SShawn McCarney     devices.emplace_back(std::move(device));
1292ccf9617SShawn McCarney     std::unique_ptr<Chassis> chassis =
1302ccf9617SShawn McCarney         std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
1312ccf9617SShawn McCarney     Chassis* chassisPtr = chassis.get();
1322ccf9617SShawn McCarney 
1332ccf9617SShawn McCarney     // Create System that contains Chassis
1342ccf9617SShawn McCarney     std::vector<std::unique_ptr<Rule>> rules{};
1352ccf9617SShawn McCarney     std::vector<std::unique_ptr<Chassis>> chassisVec{};
1362ccf9617SShawn McCarney     chassisVec.emplace_back(std::move(chassis));
1372ccf9617SShawn McCarney     System system{std::move(rules), std::move(chassisVec)};
1382ccf9617SShawn McCarney 
139*fa2734d6SShawn McCarney     // Create lambda that sets MockServices expectations.  The lambda allows
140*fa2734d6SShawn McCarney     // us to set expectations multiple times without duplicate code.
141*fa2734d6SShawn McCarney     auto setExpectations = [](MockServices& services) {
142*fa2734d6SShawn McCarney         // Expect Sensors service to be called 10 times
1432ccf9617SShawn McCarney         MockSensors& sensors = services.getMockSensors();
1442ccf9617SShawn McCarney         EXPECT_CALL(sensors, startRail).Times(10);
1452ccf9617SShawn McCarney         EXPECT_CALL(sensors, setValue).Times(0);
146*fa2734d6SShawn McCarney         EXPECT_CALL(sensors, endRail(true)).Times(10);
1472ccf9617SShawn McCarney 
148*fa2734d6SShawn McCarney         // Expect Journal service to be called 6 times to log error messages
1492ccf9617SShawn McCarney         MockJournal& journal = services.getMockJournal();
1502ccf9617SShawn McCarney         EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
1512ccf9617SShawn McCarney             .Times(6);
1522ccf9617SShawn McCarney         EXPECT_CALL(journal, logError(A<const std::string&>())).Times(6);
1532ccf9617SShawn McCarney 
154*fa2734d6SShawn McCarney         // Expect ErrorLogging service to be called once to log a DBus error
1552ccf9617SShawn McCarney         MockErrorLogging& errorLogging = services.getMockErrorLogging();
156*fa2734d6SShawn McCarney         EXPECT_CALL(errorLogging, logDBusError).Times(1);
157*fa2734d6SShawn McCarney     };
1582ccf9617SShawn McCarney 
159*fa2734d6SShawn McCarney     // Monitor sensors 10 times.  Verify errors logged.
160*fa2734d6SShawn McCarney     {
161*fa2734d6SShawn McCarney         // Create mock services.  Set expectations via lambda.
162*fa2734d6SShawn McCarney         MockServices services{};
163*fa2734d6SShawn McCarney         setExpectations(services);
164*fa2734d6SShawn McCarney 
165*fa2734d6SShawn McCarney         for (int i = 1; i <= 10; ++i)
1662ccf9617SShawn McCarney         {
1672ccf9617SShawn McCarney             railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
1682ccf9617SShawn McCarney         }
169*fa2734d6SShawn McCarney     }
1702ccf9617SShawn McCarney 
1712ccf9617SShawn McCarney     // Clear error history
1722ccf9617SShawn McCarney     railPtr->clearErrorHistory();
1732ccf9617SShawn McCarney 
174*fa2734d6SShawn McCarney     // Monitor sensors 10 more times.  Verify errors logged again.
175*fa2734d6SShawn McCarney     {
176*fa2734d6SShawn McCarney         // Create mock services.  Set expectations via lambda.
177*fa2734d6SShawn McCarney         MockServices services{};
178*fa2734d6SShawn McCarney         setExpectations(services);
179*fa2734d6SShawn McCarney 
180*fa2734d6SShawn McCarney         for (int i = 1; i <= 10; ++i)
1812ccf9617SShawn McCarney         {
1822ccf9617SShawn McCarney             railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
1832ccf9617SShawn McCarney         }
1842ccf9617SShawn McCarney     }
185*fa2734d6SShawn McCarney }
1862ccf9617SShawn McCarney 
TEST(RailTests,Configure)187779b9565SShawn McCarney TEST(RailTests, Configure)
188779b9565SShawn McCarney {
189779b9565SShawn McCarney     // Test where Configuration was not specified in constructor
190779b9565SShawn McCarney     {
1915cfe5103SBob King         // Create mock services.  No logging should occur.
19223243f84SBob King         MockServices services{};
1935cfe5103SBob King         MockJournal& journal = services.getMockJournal();
1945cfe5103SBob King         EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
1955cfe5103SBob King         EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
19623243f84SBob King 
197779b9565SShawn McCarney         // Create Rail
198779b9565SShawn McCarney         std::unique_ptr<Rail> rail = std::make_unique<Rail>("vdd0");
199779b9565SShawn McCarney         Rail* railPtr = rail.get();
200779b9565SShawn McCarney 
201779b9565SShawn McCarney         // Create Device that contains Rail
202779b9565SShawn McCarney         std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
203779b9565SShawn McCarney             std::make_unique<i2c::MockedI2CInterface>();
204779b9565SShawn McCarney         std::unique_ptr<PresenceDetection> presenceDetection{};
205779b9565SShawn McCarney         std::unique_ptr<Configuration> deviceConfiguration{};
20632252599SShawn McCarney         std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
207779b9565SShawn McCarney         std::vector<std::unique_ptr<Rail>> rails{};
208779b9565SShawn McCarney         rails.emplace_back(std::move(rail));
209779b9565SShawn McCarney         std::unique_ptr<Device> device = std::make_unique<Device>(
210a76898f1SBob King             "reg1", true,
211a76898f1SBob King             "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
212779b9565SShawn McCarney             std::move(i2cInterface), std::move(presenceDetection),
21332252599SShawn McCarney             std::move(deviceConfiguration), std::move(phaseFaultDetection),
21432252599SShawn McCarney             std::move(rails));
215779b9565SShawn McCarney         Device* devicePtr = device.get();
216779b9565SShawn McCarney 
217779b9565SShawn McCarney         // Create Chassis that contains Device
218779b9565SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
219779b9565SShawn McCarney         devices.emplace_back(std::move(device));
220779b9565SShawn McCarney         std::unique_ptr<Chassis> chassis =
221cb3f6a63SShawn McCarney             std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
222779b9565SShawn McCarney         Chassis* chassisPtr = chassis.get();
223779b9565SShawn McCarney 
224779b9565SShawn McCarney         // Create System that contains Chassis
225779b9565SShawn McCarney         std::vector<std::unique_ptr<Rule>> rules{};
226779b9565SShawn McCarney         std::vector<std::unique_ptr<Chassis>> chassisVec{};
227779b9565SShawn McCarney         chassisVec.emplace_back(std::move(chassis));
228779b9565SShawn McCarney         System system{std::move(rules), std::move(chassisVec)};
229779b9565SShawn McCarney 
2305cfe5103SBob King         // Call configure().
23123243f84SBob King         railPtr->configure(services, system, *chassisPtr, *devicePtr);
232779b9565SShawn McCarney     }
233779b9565SShawn McCarney 
234779b9565SShawn McCarney     // Test where Configuration was specified in constructor
235779b9565SShawn McCarney     {
2365cfe5103SBob King         // Create mock services.  Expect logDebug() to be called.
23723243f84SBob King         MockServices services{};
2385cfe5103SBob King         MockJournal& journal = services.getMockJournal();
2395cfe5103SBob King         EXPECT_CALL(journal, logDebug("Configuring vddr1: volts=1.300000"))
2405cfe5103SBob King             .Times(1);
2415cfe5103SBob King         EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
24223243f84SBob King 
243779b9565SShawn McCarney         // Create Configuration
244779b9565SShawn McCarney         std::optional<double> volts{1.3};
245779b9565SShawn McCarney         std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
246779b9565SShawn McCarney         EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
247779b9565SShawn McCarney         std::vector<std::unique_ptr<Action>> actions{};
248779b9565SShawn McCarney         actions.emplace_back(std::move(action));
249779b9565SShawn McCarney         std::unique_ptr<Configuration> configuration =
250779b9565SShawn McCarney             std::make_unique<Configuration>(volts, std::move(actions));
251779b9565SShawn McCarney 
252779b9565SShawn McCarney         // Create Rail
253779b9565SShawn McCarney         std::unique_ptr<Rail> rail =
254779b9565SShawn McCarney             std::make_unique<Rail>("vddr1", std::move(configuration));
255779b9565SShawn McCarney         Rail* railPtr = rail.get();
256779b9565SShawn McCarney 
257779b9565SShawn McCarney         // Create Device that contains Rail
258779b9565SShawn McCarney         std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
259779b9565SShawn McCarney             std::make_unique<i2c::MockedI2CInterface>();
260779b9565SShawn McCarney         std::unique_ptr<PresenceDetection> presenceDetection{};
261779b9565SShawn McCarney         std::unique_ptr<Configuration> deviceConfiguration{};
26232252599SShawn McCarney         std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
263779b9565SShawn McCarney         std::vector<std::unique_ptr<Rail>> rails{};
264779b9565SShawn McCarney         rails.emplace_back(std::move(rail));
265779b9565SShawn McCarney         std::unique_ptr<Device> device = std::make_unique<Device>(
266a76898f1SBob King             "reg1", true,
267a76898f1SBob King             "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
268779b9565SShawn McCarney             std::move(i2cInterface), std::move(presenceDetection),
26932252599SShawn McCarney             std::move(deviceConfiguration), std::move(phaseFaultDetection),
27032252599SShawn McCarney             std::move(rails));
271779b9565SShawn McCarney         Device* devicePtr = device.get();
272779b9565SShawn McCarney 
273779b9565SShawn McCarney         // Create Chassis that contains Device
274779b9565SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
275779b9565SShawn McCarney         devices.emplace_back(std::move(device));
276779b9565SShawn McCarney         std::unique_ptr<Chassis> chassis =
277cb3f6a63SShawn McCarney             std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
278779b9565SShawn McCarney         Chassis* chassisPtr = chassis.get();
279779b9565SShawn McCarney 
280779b9565SShawn McCarney         // Create System that contains Chassis
281779b9565SShawn McCarney         std::vector<std::unique_ptr<Rule>> rules{};
282779b9565SShawn McCarney         std::vector<std::unique_ptr<Chassis>> chassisVec{};
283779b9565SShawn McCarney         chassisVec.emplace_back(std::move(chassis));
284779b9565SShawn McCarney         System system{std::move(rules), std::move(chassisVec)};
285779b9565SShawn McCarney 
2865cfe5103SBob King         // Call configure().
28723243f84SBob King         railPtr->configure(services, system, *chassisPtr, *devicePtr);
288779b9565SShawn McCarney     }
289779b9565SShawn McCarney }
290779b9565SShawn McCarney 
TEST(RailTests,GetConfiguration)2914bf310e3SShawn McCarney TEST(RailTests, GetConfiguration)
2924bf310e3SShawn McCarney {
2934bf310e3SShawn McCarney     // Test where Configuration was not specified in constructor
2944bf310e3SShawn McCarney     {
2954bf310e3SShawn McCarney         Rail rail{"vdd0"};
2964bf310e3SShawn McCarney         EXPECT_EQ(rail.getConfiguration(), nullptr);
2974bf310e3SShawn McCarney     }
2984bf310e3SShawn McCarney 
2994bf310e3SShawn McCarney     // Test where Configuration was specified in constructor
3004bf310e3SShawn McCarney     {
3014bf310e3SShawn McCarney         // Create Configuration
3024bf310e3SShawn McCarney         std::optional<double> volts{3.2};
3034bf310e3SShawn McCarney         std::vector<std::unique_ptr<Action>> actions{};
3044bf310e3SShawn McCarney         actions.push_back(std::make_unique<MockAction>());
3054bf310e3SShawn McCarney         std::unique_ptr<Configuration> configuration =
3064bf310e3SShawn McCarney             std::make_unique<Configuration>(volts, std::move(actions));
3074bf310e3SShawn McCarney 
3084bf310e3SShawn McCarney         // Create Rail
3094bf310e3SShawn McCarney         Rail rail{"vddr1", std::move(configuration)};
3104bf310e3SShawn McCarney         EXPECT_NE(rail.getConfiguration(), nullptr);
3114bf310e3SShawn McCarney         EXPECT_EQ(rail.getConfiguration()->getVolts().has_value(), true);
3124bf310e3SShawn McCarney         EXPECT_EQ(rail.getConfiguration()->getVolts().value(), 3.2);
3134bf310e3SShawn McCarney         EXPECT_EQ(rail.getConfiguration()->getActions().size(), 1);
3144bf310e3SShawn McCarney     }
315a2461b34SShawn McCarney }
316a2461b34SShawn McCarney 
TEST(RailTests,GetID)3174afb285eSShawn McCarney TEST(RailTests, GetID)
318a2461b34SShawn McCarney {
3194bf310e3SShawn McCarney     Rail rail{"vio2"};
3204afb285eSShawn McCarney     EXPECT_EQ(rail.getID(), "vio2");
321a2461b34SShawn McCarney }
3224bf310e3SShawn McCarney 
TEST(RailTests,MonitorSensors)3237b743431SBob King TEST(RailTests, MonitorSensors)
3247b743431SBob King {
3257b743431SBob King     // Test where SensorMonitoring was not specified in constructor
3267b743431SBob King     {
32717bac89eSShawn McCarney         // Create mock services.  No Sensors methods should be called.
3288a55292dSBob King         MockServices services{};
32917bac89eSShawn McCarney         MockSensors& sensors = services.getMockSensors();
33017bac89eSShawn McCarney         EXPECT_CALL(sensors, startRail).Times(0);
33117bac89eSShawn McCarney         EXPECT_CALL(sensors, setValue).Times(0);
33217bac89eSShawn McCarney         EXPECT_CALL(sensors, endRail).Times(0);
3337b743431SBob King 
3347b743431SBob King         // Create Rail
3357b743431SBob King         std::unique_ptr<Rail> rail = std::make_unique<Rail>("vdd0");
3367b743431SBob King         Rail* railPtr = rail.get();
3377b743431SBob King 
3387b743431SBob King         // Create Device that contains Rail
33917bac89eSShawn McCarney         std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
34017bac89eSShawn McCarney             std::make_unique<i2c::MockedI2CInterface>();
3417b743431SBob King         std::unique_ptr<PresenceDetection> presenceDetection{};
3427b743431SBob King         std::unique_ptr<Configuration> deviceConfiguration{};
34332252599SShawn McCarney         std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
3447b743431SBob King         std::vector<std::unique_ptr<Rail>> rails{};
3457b743431SBob King         rails.emplace_back(std::move(rail));
3467b743431SBob King         std::unique_ptr<Device> device = std::make_unique<Device>(
347a76898f1SBob King             "reg1", true,
348a76898f1SBob King             "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
3497b743431SBob King             std::move(i2cInterface), std::move(presenceDetection),
35032252599SShawn McCarney             std::move(deviceConfiguration), std::move(phaseFaultDetection),
35132252599SShawn McCarney             std::move(rails));
3527b743431SBob King         Device* devicePtr = device.get();
3537b743431SBob King 
3547b743431SBob King         // Create Chassis that contains Device
3557b743431SBob King         std::vector<std::unique_ptr<Device>> devices{};
3567b743431SBob King         devices.emplace_back(std::move(device));
3577b743431SBob King         std::unique_ptr<Chassis> chassis =
358cb3f6a63SShawn McCarney             std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
3597b743431SBob King         Chassis* chassisPtr = chassis.get();
3607b743431SBob King 
3617b743431SBob King         // Create System that contains Chassis
3627b743431SBob King         std::vector<std::unique_ptr<Rule>> rules{};
3637b743431SBob King         std::vector<std::unique_ptr<Chassis>> chassisVec{};
3647b743431SBob King         chassisVec.emplace_back(std::move(chassis));
3657b743431SBob King         System system{std::move(rules), std::move(chassisVec)};
3667b743431SBob King 
36717bac89eSShawn McCarney         // Call monitorSensors()
3688a55292dSBob King         railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
3697b743431SBob King     }
3707b743431SBob King 
3717b743431SBob King     // Test where SensorMonitoring was specified in constructor
3727b743431SBob King     {
37317bac89eSShawn McCarney         // Create mock services.  Set Sensors service expectations.
3748a55292dSBob King         MockServices services{};
37517bac89eSShawn McCarney         MockSensors& sensors = services.getMockSensors();
37617bac89eSShawn McCarney         EXPECT_CALL(sensors,
37717bac89eSShawn McCarney                     startRail("vddr1",
37817bac89eSShawn McCarney                               "/xyz/openbmc_project/inventory/system/chassis/"
37917bac89eSShawn McCarney                               "motherboard/reg1",
38017bac89eSShawn McCarney                               chassisInvPath))
3817b743431SBob King             .Times(1);
38217bac89eSShawn McCarney         EXPECT_CALL(sensors, setValue).Times(0);
38317bac89eSShawn McCarney         EXPECT_CALL(sensors, endRail(false)).Times(1);
3847b743431SBob King 
3857b743431SBob King         // Create SensorMonitoring
38617bac89eSShawn McCarney         std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
38717bac89eSShawn McCarney         EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
3887b743431SBob King         std::vector<std::unique_ptr<Action>> actions{};
3897b743431SBob King         actions.emplace_back(std::move(action));
3907b743431SBob King         std::unique_ptr<SensorMonitoring> sensorMonitoring =
3917b743431SBob King             std::make_unique<SensorMonitoring>(std::move(actions));
3927b743431SBob King 
3937b743431SBob King         // Create Rail
3947b743431SBob King         std::unique_ptr<Configuration> configuration{};
3957b743431SBob King         std::unique_ptr<Rail> rail = std::make_unique<Rail>(
3967b743431SBob King             "vddr1", std::move(configuration), std::move(sensorMonitoring));
3977b743431SBob King         Rail* railPtr = rail.get();
3987b743431SBob King 
3997b743431SBob King         // Create Device that contains Rail
40017bac89eSShawn McCarney         std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
40117bac89eSShawn McCarney             std::make_unique<i2c::MockedI2CInterface>();
4027b743431SBob King         std::unique_ptr<PresenceDetection> presenceDetection{};
4037b743431SBob King         std::unique_ptr<Configuration> deviceConfiguration{};
40432252599SShawn McCarney         std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
4057b743431SBob King         std::vector<std::unique_ptr<Rail>> rails{};
4067b743431SBob King         rails.emplace_back(std::move(rail));
4077b743431SBob King         std::unique_ptr<Device> device = std::make_unique<Device>(
408a76898f1SBob King             "reg1", true,
409a76898f1SBob King             "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
4107b743431SBob King             std::move(i2cInterface), std::move(presenceDetection),
41132252599SShawn McCarney             std::move(deviceConfiguration), std::move(phaseFaultDetection),
41232252599SShawn McCarney             std::move(rails));
4137b743431SBob King         Device* devicePtr = device.get();
4147b743431SBob King 
4157b743431SBob King         // Create Chassis that contains Device
4167b743431SBob King         std::vector<std::unique_ptr<Device>> devices{};
4177b743431SBob King         devices.emplace_back(std::move(device));
4187b743431SBob King         std::unique_ptr<Chassis> chassis =
419cb3f6a63SShawn McCarney             std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
4207b743431SBob King         Chassis* chassisPtr = chassis.get();
4217b743431SBob King 
4227b743431SBob King         // Create System that contains Chassis
4237b743431SBob King         std::vector<std::unique_ptr<Rule>> rules{};
4247b743431SBob King         std::vector<std::unique_ptr<Chassis>> chassisVec{};
4257b743431SBob King         chassisVec.emplace_back(std::move(chassis));
4267b743431SBob King         System system{std::move(rules), std::move(chassisVec)};
4277b743431SBob King 
42817bac89eSShawn McCarney         // Call monitorSensors()
4298a55292dSBob King         railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
4307b743431SBob King     }
4317b743431SBob King }
4327b743431SBob King 
TEST(RailTests,GetSensorMonitoring)4334bf310e3SShawn McCarney TEST(RailTests, GetSensorMonitoring)
4344bf310e3SShawn McCarney {
4354bf310e3SShawn McCarney     // Test where SensorMonitoring was not specified in constructor
4364bf310e3SShawn McCarney     {
4374bf310e3SShawn McCarney         Rail rail{"vdd0", nullptr, nullptr};
4384bf310e3SShawn McCarney         EXPECT_EQ(rail.getSensorMonitoring(), nullptr);
4394bf310e3SShawn McCarney     }
4404bf310e3SShawn McCarney 
4414bf310e3SShawn McCarney     // Test where SensorMonitoring was specified in constructor
4424bf310e3SShawn McCarney     {
4434bf310e3SShawn McCarney         std::unique_ptr<Configuration> configuration{};
4444bf310e3SShawn McCarney 
4454bf310e3SShawn McCarney         // Create SensorMonitoring
4464bf310e3SShawn McCarney         std::vector<std::unique_ptr<Action>> actions{};
4474bf310e3SShawn McCarney         actions.push_back(std::make_unique<MockAction>());
4484bf310e3SShawn McCarney         actions.push_back(std::make_unique<MockAction>());
4494bf310e3SShawn McCarney         std::unique_ptr<SensorMonitoring> sensorMonitoring =
4504bf310e3SShawn McCarney             std::make_unique<SensorMonitoring>(std::move(actions));
4514bf310e3SShawn McCarney 
4524bf310e3SShawn McCarney         // Create Rail
4534bf310e3SShawn McCarney         Rail rail{"vddr1", std::move(configuration),
4544bf310e3SShawn McCarney                   std::move(sensorMonitoring)};
4554bf310e3SShawn McCarney         EXPECT_NE(rail.getSensorMonitoring(), nullptr);
4564bf310e3SShawn McCarney         EXPECT_EQ(rail.getSensorMonitoring()->getActions().size(), 2);
4574bf310e3SShawn McCarney     }
4584bf310e3SShawn McCarney }
459